summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2023-05-10 05:40:04 +0000
committerCoprDistGit <infra@openeuler.org>2023-05-10 05:40:04 +0000
commit06dea97fdd53ef8f2eba04163ab626c34cc9147e (patch)
tree8436b756bee6afdda867f4a6a48b05be9f2c54e5
parent98347edcbf964fb9dcf123fa398e6b368d0bd64f (diff)
automatic import of python-pedanticopeneuler20.03
-rw-r--r--.gitignore1
-rw-r--r--python-pedantic.spec741
-rw-r--r--sources1
3 files changed, 743 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..b8518ba 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/pedantic-1.14.5.tar.gz
diff --git a/python-pedantic.spec b/python-pedantic.spec
new file mode 100644
index 0000000..e30365d
--- /dev/null
+++ b/python-pedantic.spec
@@ -0,0 +1,741 @@
+%global _empty_manifest_terminate_build 0
+Name: python-pedantic
+Version: 1.14.5
+Release: 1
+Summary: Some useful Python decorators for cleaner software development.
+License: Apache-2.0 License
+URL: https://github.com/LostInDarkMath/pedantic-python-decorators
+Source0: https://mirrors.nju.edu.cn/pypi/web/packages/d0/c0/932100afca5462daa261c314ffc231127ae2d232914ca717508ba7221eb0/pedantic-1.14.5.tar.gz
+BuildArch: noarch
+
+
+%description
+# pedantic-python-decorators [![Build Status](https://travis-ci.com/LostInDarkMath/pedantic-python-decorators.svg?branch=master)](https://travis-ci.com/LostInDarkMath/pedantic-python-decorators) [![Coverage Status](https://coveralls.io/repos/github/LostInDarkMath/pedantic-python-decorators/badge.svg?branch=master)](https://coveralls.io/github/LostInDarkMath/pedantic-python-decorators?branch=master) [![PyPI version](https://badge.fury.io/py/pedantic.svg)](https://badge.fury.io/py/pedantic) [![Last Commit](https://badgen.net/github/last-commit/LostInDarkMath/pedantic-python-decorators?color=green)](https://GitHub.com/LostInDarkMath/pedantic-python-decorators) [![Stars](https://badgen.net/github/stars/LostInDarkMath/pedantic-python-decorators?color=green)](https://GitHub.com/LostInDarkMath/pedantic-python-decorators) [![Open Issues](https://badgen.net/github/open-issues/LostInDarkMath/pedantic-python-decorators?color=green)](https://GitHub.com/LostInDarkMath/pedantic-python-decorators/issues) [![Open PRs](https://badgen.net/github/open-prs/LostInDarkMath/pedantic-python-decorators?color=green)](https://GitHub.com/LostInDarkMath/pedantic-python-decorators/pulls)
+
+This packages includes many decorators that will make you write cleaner Python code.
+
+## Getting Started
+This package requires Python 3.7 or later.
+Python 3.6 is only supported by `pedantic` 1.9.1 or lower.
+There are multiple options for installing this package.
+
+### Option 1: Installing with pip from [Pypi](https://pypi.org/)
+Run `pip install pedantic`.
+
+### Option 2: Installing with pip and git
+1. Install [Git](https://git-scm.com/downloads) if you don't have it already.
+2. Run `pip install git+https://github.com/LostInDarkMath/pedantic-python-decorators.git@master`
+
+### Option 3: Offline installation using wheel
+1. Download the [latest release here](https://github.com/LostInDarkMath/PythonHelpers/releases/latest) by clicking on `pedantic-python-decorators-x.y.z-py-none-any.whl`.
+2. Execute `pip install pedantic-python-decorators-x.y.z-py3-none-any.whl`.
+
+## The [@pedantic](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/method_decorators.html#pedantic.method_decorators.pedantic) decorator - Type checking at runtime
+The `@pedantic` decorator does the following things:
+- The decorated function can only be called by using keyword arguments. Positional arguments are not accepted.
+- The decorated function must have [type annotations](https://docs.python.org/3/library/typing.html).
+- Each time the decorated function is called, pedantic checks that the passed arguments and the return value of the function matches the given type annotations.
+As a consequence, the arguments are also checked for `None`, because `None` is only a valid argument, if it is annotated via `typing.Optional`.
+- If the decorated function has a docstring which lists the arguments, the docstring is parsed and compared with the type annotations. In other words, pedantic ensures that the docstring is everytime up-to-date.
+Currently, only docstrings in the [Google style](https://google.github.io/styleguide/pyguide.html) are supported. **Note:** you need install the [docstring-parser](https://github.com/rr-/docstring_parser) to make this work.
+
+In a nutshell:
+`@pedantic` raises an `PedanticException` if one of the following happened:
+- The decorated function is called with positional arguments.
+- The function has no type annotation for their return type or one or more parameters do not have type annotations.
+- A type annotation is incorrect.
+- A type annotation misses type arguments, e.g. `typing.List` instead of `typing.List[int]`.
+- The documented arguments do not match the argument list or their type annotations.
+
+### Minimal example
+```python
+from typing import Union, List
+from pedantic import pedantic, pedantic_class
+
+@pedantic
+def get_sum_of(values: List[Union[int, float]]) -> Union[int, float]:
+ return sum(values)
+
+@pedantic_class
+class MyClass:
+ def __init__(self, x: float, y: int) -> None:
+ self.x = x
+ self.y = y
+
+ def print_sum(self) -> None:
+ print(get_sum_of(values=[self.x, self.y]))
+
+m = MyClass(x=3.14, y=2)
+m.print_sum()
+```
+
+
+## The [@validate]() decorator
+As the name suggests, with `@validate` you are able to validate the values that are passed to the decorated function.
+That is done in a highly customizable way.
+But the highest benefit of this decorator is that it makes it extremely easy to write decoupled easy testable, maintainable and scalable code.
+The following example shows the decoupled implementation of a configurable algorithm with the help of `@validate`:
+```python
+import os
+from dataclasses import dataclass
+
+from pedantic import validate, ExternalParameter, overrides, Validator, Parameter, Min, ReturnAs
+
+
+@dataclass(frozen=True)
+class Configuration:
+ iterations: int
+ max_error: float
+
+
+class ConfigurationValidator(Validator):
+ @overrides(Validator)
+ def validate(self, value: Configuration) -> Configuration:
+ if value.iterations < 1 or value.max_error < 0:
+ self.raise_exception(msg=f'Invalid configuration: {value}', value=value)
+
+ return value
+
+
+class ConfigFromEnvVar(ExternalParameter):
+ """ Reads the configuration from environment variables. """
+
+ @overrides(ExternalParameter)
+ def has_value(self) -> bool:
+ return 'iterations' in os.environ and 'max_error' in os.environ
+
+ @overrides(ExternalParameter)
+ def load_value(self) -> Configuration:
+ return Configuration(
+ iterations=int(os.environ['iterations']),
+ max_error=float(os.environ['max_error']),
+ )
+
+
+class ConfigFromFile(ExternalParameter):
+ """ Reads the configuration from a config file. """
+
+ @overrides(ExternalParameter)
+ def has_value(self) -> bool:
+ return os.path.isfile('config.csv')
+
+ @overrides(ExternalParameter)
+ def load_value(self) -> Configuration:
+ with open(file='config.csv', mode='r') as file:
+ content = file.readlines()
+ return Configuration(
+ iterations=int(content[0].strip('\n')),
+ max_error=float(content[1]),
+ )
+
+
+# choose your configuration source here:
+@validate(ConfigFromEnvVar(name='config', validators=[ConfigurationValidator()]), strict=False, return_as=ReturnAs.KWARGS_WITH_NONE)
+# @validate(ConfigFromFile(name='config', validators=[ConfigurationValidator()]), strict=False)
+
+# with strict_mode = True (which is the default)
+# you need to pass a Parameter for each parameter of the decorated function
+# @validate(
+# Parameter(name='value', validators=[Min(5, include_boundary=False)]),
+# ConfigFromFile(name='config', validators=[ConfigurationValidator()]),
+# )
+def my_algorithm(value: float, config: Configuration) -> float:
+ """
+ This method calculates something that depends on the given value with considering the configuration.
+ Note how well this small piece of code is designed:
+ - Fhe function my_algorithm() need a Configuration but has no knowledge where this come from.
+ - Furthermore, it doesn't care about parameter validation.
+ - The ConfigurationValidator doesn't know anything about the creation of the data.
+ - The @validate decorator is the only you need to change, if you want a different configuration source.
+ """
+ print(value)
+ print(config)
+ return value
+
+
+if __name__ == '__main__':
+ # we can call the function with a config like there is no decorator.
+ # This makes testing extremely easy: no config files, no environment variables or stuff like that
+ print(my_algorithm(value=2, config=Configuration(iterations=3, max_error=4.4)))
+
+ os.environ['iterations'] = '12'
+ os.environ['max_error'] = '3.1415'
+
+ # but we also can omit the config and load it implicitly by our custom Parameters
+ print(my_algorithm(value=42.0))
+```
+
+## List of all decorators in this package
+- [@count_calls](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_count_calls.html)
+- [@deprecated](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_deprecated.html)
+- [@does_same_as_function](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_does_same_as_function.html)
+- [@frozen_dataclass](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/cls_deco_frozen_dataclass.html#pedantic.decorators.cls_deco_frozen_dataclass.frozen_dataclass)
+- [@frozen_type_safe_dataclass](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/cls_deco_frozen_dataclass.html#pedantic.decorators.cls_deco_frozen_dataclass.frozen_type_safe_dataclass)
+- [@for_all_methods](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/class_decorators.html#pedantic.decorators.class_decorators.for_all_methods)
+- [@in_subprocess](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_in_subprocess.html)
+- [@mock](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_mock.html)
+- [@overrides](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_overrides.html)
+- [@pedantic](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_pedantic.html#pedantic.decorators.fn_deco_pedantic.pedantic)
+- [@pedantic_require_docstring](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_pedantic.html#pedantic.decorators.fn_deco_pedantic.pedantic_require_docstring)
+- [@pedantic_class](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/class_decorators.html#pedantic.decorators.class_decorators.pedantic_class)
+- [@pedantic_class_require_docstring](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/class_decorators.html#pedantic.decorators.class_decorators.pedantic_class_require_docstring)
+- [@rename_kwargs](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_rename_kwargs.html)
+- [@require_kwargs](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_require_kwargs.html)
+- [@timer](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_timer.html)
+- [@timer_class](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/class_decorators.html#pedantic.decorators.class_decorators.timer_class)
+- [@trace](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_trace.html)
+- [@trace_class](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/class_decorators.html#pedantic.decorators.class_decorators.trace_class)
+- [@trace_if_returns](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_trace_if_returns.html)
+- [@unimplemented](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_unimplemented.html)
+- [@validate](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_validate/fn_deco_validate.html)
+
+## List of all mixins in this package
+- [GenericMixin](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/mixins/generic_mixin.html)
+
+## Dependencies
+There are no hard dependencies. But if you want to use some advanced features you need to install the following packages:
+- [Docstring-Parser](https://github.com/rr-/docstring_parser) if you need to verify your docstrings.
+- [multiprocess](https://github.com/uqfoundation/multiprocess) if you want to use the `@in_subprocess` decorator
+- [flask](https://pypi.org/project/Flask/) if you want to you the request validators which are designed for `Flask` (see unit tests for examples):
+ - `FlaskParameter` (abstract class)
+ - `FlaskJsonParameter`
+ - `FlaskFormParameter`
+ - `FlaskPathParameter`
+ - `FlaskGetParameter`
+ - `FlaskHeaderParameter`
+ - `GenericFlaskDeserializer`
+
+## Contributing
+Feel free to contribute by submitting a pull request :)
+
+## Acknowledgments
+* [Rathaustreppe](https://github.com/rathaustreppe)
+* [Aran-Fey](https://stackoverflow.com/questions/55503673/how-do-i-check-if-a-value-matches-a-type-in-python/55504010#55504010)
+* [user395760](https://stackoverflow.com/questions/55503673/how-do-i-check-if-a-value-matches-a-type-in-python/55504010#55504010)
+
+## Risks and side effects
+The usage of decorators may affect the performance of your application.
+For this reason, I would highly recommend you to disable the decorators if your code runs in a productive environment.
+You can disable `pedantic` by set an environment variable:
+```
+export ENABLE_PEDANTIC=0
+```
+You can also disable or enable the environment variables in your project by calling a method:
+```python
+from pedantic import enable_pedantic, disable_pedantic
+enable_pedantic()
+```
+
+## Issues with compiled Python code
+This package is **not** compatible with compiled source code (e.g. with [Nuitka](https://github.com/Nuitka/Nuitka)).
+That's because it uses the `inspect` module from the standard library which will raise errors like `OSError: could not get source code` in case of compiled source code.
+
+
+Don't forget to check out the [documentation](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic).
+Happy coding!
+
+
+%package -n python3-pedantic
+Summary: Some useful Python decorators for cleaner software development.
+Provides: python-pedantic
+BuildRequires: python3-devel
+BuildRequires: python3-setuptools
+BuildRequires: python3-pip
+%description -n python3-pedantic
+# pedantic-python-decorators [![Build Status](https://travis-ci.com/LostInDarkMath/pedantic-python-decorators.svg?branch=master)](https://travis-ci.com/LostInDarkMath/pedantic-python-decorators) [![Coverage Status](https://coveralls.io/repos/github/LostInDarkMath/pedantic-python-decorators/badge.svg?branch=master)](https://coveralls.io/github/LostInDarkMath/pedantic-python-decorators?branch=master) [![PyPI version](https://badge.fury.io/py/pedantic.svg)](https://badge.fury.io/py/pedantic) [![Last Commit](https://badgen.net/github/last-commit/LostInDarkMath/pedantic-python-decorators?color=green)](https://GitHub.com/LostInDarkMath/pedantic-python-decorators) [![Stars](https://badgen.net/github/stars/LostInDarkMath/pedantic-python-decorators?color=green)](https://GitHub.com/LostInDarkMath/pedantic-python-decorators) [![Open Issues](https://badgen.net/github/open-issues/LostInDarkMath/pedantic-python-decorators?color=green)](https://GitHub.com/LostInDarkMath/pedantic-python-decorators/issues) [![Open PRs](https://badgen.net/github/open-prs/LostInDarkMath/pedantic-python-decorators?color=green)](https://GitHub.com/LostInDarkMath/pedantic-python-decorators/pulls)
+
+This packages includes many decorators that will make you write cleaner Python code.
+
+## Getting Started
+This package requires Python 3.7 or later.
+Python 3.6 is only supported by `pedantic` 1.9.1 or lower.
+There are multiple options for installing this package.
+
+### Option 1: Installing with pip from [Pypi](https://pypi.org/)
+Run `pip install pedantic`.
+
+### Option 2: Installing with pip and git
+1. Install [Git](https://git-scm.com/downloads) if you don't have it already.
+2. Run `pip install git+https://github.com/LostInDarkMath/pedantic-python-decorators.git@master`
+
+### Option 3: Offline installation using wheel
+1. Download the [latest release here](https://github.com/LostInDarkMath/PythonHelpers/releases/latest) by clicking on `pedantic-python-decorators-x.y.z-py-none-any.whl`.
+2. Execute `pip install pedantic-python-decorators-x.y.z-py3-none-any.whl`.
+
+## The [@pedantic](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/method_decorators.html#pedantic.method_decorators.pedantic) decorator - Type checking at runtime
+The `@pedantic` decorator does the following things:
+- The decorated function can only be called by using keyword arguments. Positional arguments are not accepted.
+- The decorated function must have [type annotations](https://docs.python.org/3/library/typing.html).
+- Each time the decorated function is called, pedantic checks that the passed arguments and the return value of the function matches the given type annotations.
+As a consequence, the arguments are also checked for `None`, because `None` is only a valid argument, if it is annotated via `typing.Optional`.
+- If the decorated function has a docstring which lists the arguments, the docstring is parsed and compared with the type annotations. In other words, pedantic ensures that the docstring is everytime up-to-date.
+Currently, only docstrings in the [Google style](https://google.github.io/styleguide/pyguide.html) are supported. **Note:** you need install the [docstring-parser](https://github.com/rr-/docstring_parser) to make this work.
+
+In a nutshell:
+`@pedantic` raises an `PedanticException` if one of the following happened:
+- The decorated function is called with positional arguments.
+- The function has no type annotation for their return type or one or more parameters do not have type annotations.
+- A type annotation is incorrect.
+- A type annotation misses type arguments, e.g. `typing.List` instead of `typing.List[int]`.
+- The documented arguments do not match the argument list or their type annotations.
+
+### Minimal example
+```python
+from typing import Union, List
+from pedantic import pedantic, pedantic_class
+
+@pedantic
+def get_sum_of(values: List[Union[int, float]]) -> Union[int, float]:
+ return sum(values)
+
+@pedantic_class
+class MyClass:
+ def __init__(self, x: float, y: int) -> None:
+ self.x = x
+ self.y = y
+
+ def print_sum(self) -> None:
+ print(get_sum_of(values=[self.x, self.y]))
+
+m = MyClass(x=3.14, y=2)
+m.print_sum()
+```
+
+
+## The [@validate]() decorator
+As the name suggests, with `@validate` you are able to validate the values that are passed to the decorated function.
+That is done in a highly customizable way.
+But the highest benefit of this decorator is that it makes it extremely easy to write decoupled easy testable, maintainable and scalable code.
+The following example shows the decoupled implementation of a configurable algorithm with the help of `@validate`:
+```python
+import os
+from dataclasses import dataclass
+
+from pedantic import validate, ExternalParameter, overrides, Validator, Parameter, Min, ReturnAs
+
+
+@dataclass(frozen=True)
+class Configuration:
+ iterations: int
+ max_error: float
+
+
+class ConfigurationValidator(Validator):
+ @overrides(Validator)
+ def validate(self, value: Configuration) -> Configuration:
+ if value.iterations < 1 or value.max_error < 0:
+ self.raise_exception(msg=f'Invalid configuration: {value}', value=value)
+
+ return value
+
+
+class ConfigFromEnvVar(ExternalParameter):
+ """ Reads the configuration from environment variables. """
+
+ @overrides(ExternalParameter)
+ def has_value(self) -> bool:
+ return 'iterations' in os.environ and 'max_error' in os.environ
+
+ @overrides(ExternalParameter)
+ def load_value(self) -> Configuration:
+ return Configuration(
+ iterations=int(os.environ['iterations']),
+ max_error=float(os.environ['max_error']),
+ )
+
+
+class ConfigFromFile(ExternalParameter):
+ """ Reads the configuration from a config file. """
+
+ @overrides(ExternalParameter)
+ def has_value(self) -> bool:
+ return os.path.isfile('config.csv')
+
+ @overrides(ExternalParameter)
+ def load_value(self) -> Configuration:
+ with open(file='config.csv', mode='r') as file:
+ content = file.readlines()
+ return Configuration(
+ iterations=int(content[0].strip('\n')),
+ max_error=float(content[1]),
+ )
+
+
+# choose your configuration source here:
+@validate(ConfigFromEnvVar(name='config', validators=[ConfigurationValidator()]), strict=False, return_as=ReturnAs.KWARGS_WITH_NONE)
+# @validate(ConfigFromFile(name='config', validators=[ConfigurationValidator()]), strict=False)
+
+# with strict_mode = True (which is the default)
+# you need to pass a Parameter for each parameter of the decorated function
+# @validate(
+# Parameter(name='value', validators=[Min(5, include_boundary=False)]),
+# ConfigFromFile(name='config', validators=[ConfigurationValidator()]),
+# )
+def my_algorithm(value: float, config: Configuration) -> float:
+ """
+ This method calculates something that depends on the given value with considering the configuration.
+ Note how well this small piece of code is designed:
+ - Fhe function my_algorithm() need a Configuration but has no knowledge where this come from.
+ - Furthermore, it doesn't care about parameter validation.
+ - The ConfigurationValidator doesn't know anything about the creation of the data.
+ - The @validate decorator is the only you need to change, if you want a different configuration source.
+ """
+ print(value)
+ print(config)
+ return value
+
+
+if __name__ == '__main__':
+ # we can call the function with a config like there is no decorator.
+ # This makes testing extremely easy: no config files, no environment variables or stuff like that
+ print(my_algorithm(value=2, config=Configuration(iterations=3, max_error=4.4)))
+
+ os.environ['iterations'] = '12'
+ os.environ['max_error'] = '3.1415'
+
+ # but we also can omit the config and load it implicitly by our custom Parameters
+ print(my_algorithm(value=42.0))
+```
+
+## List of all decorators in this package
+- [@count_calls](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_count_calls.html)
+- [@deprecated](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_deprecated.html)
+- [@does_same_as_function](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_does_same_as_function.html)
+- [@frozen_dataclass](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/cls_deco_frozen_dataclass.html#pedantic.decorators.cls_deco_frozen_dataclass.frozen_dataclass)
+- [@frozen_type_safe_dataclass](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/cls_deco_frozen_dataclass.html#pedantic.decorators.cls_deco_frozen_dataclass.frozen_type_safe_dataclass)
+- [@for_all_methods](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/class_decorators.html#pedantic.decorators.class_decorators.for_all_methods)
+- [@in_subprocess](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_in_subprocess.html)
+- [@mock](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_mock.html)
+- [@overrides](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_overrides.html)
+- [@pedantic](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_pedantic.html#pedantic.decorators.fn_deco_pedantic.pedantic)
+- [@pedantic_require_docstring](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_pedantic.html#pedantic.decorators.fn_deco_pedantic.pedantic_require_docstring)
+- [@pedantic_class](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/class_decorators.html#pedantic.decorators.class_decorators.pedantic_class)
+- [@pedantic_class_require_docstring](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/class_decorators.html#pedantic.decorators.class_decorators.pedantic_class_require_docstring)
+- [@rename_kwargs](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_rename_kwargs.html)
+- [@require_kwargs](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_require_kwargs.html)
+- [@timer](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_timer.html)
+- [@timer_class](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/class_decorators.html#pedantic.decorators.class_decorators.timer_class)
+- [@trace](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_trace.html)
+- [@trace_class](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/class_decorators.html#pedantic.decorators.class_decorators.trace_class)
+- [@trace_if_returns](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_trace_if_returns.html)
+- [@unimplemented](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_unimplemented.html)
+- [@validate](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_validate/fn_deco_validate.html)
+
+## List of all mixins in this package
+- [GenericMixin](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/mixins/generic_mixin.html)
+
+## Dependencies
+There are no hard dependencies. But if you want to use some advanced features you need to install the following packages:
+- [Docstring-Parser](https://github.com/rr-/docstring_parser) if you need to verify your docstrings.
+- [multiprocess](https://github.com/uqfoundation/multiprocess) if you want to use the `@in_subprocess` decorator
+- [flask](https://pypi.org/project/Flask/) if you want to you the request validators which are designed for `Flask` (see unit tests for examples):
+ - `FlaskParameter` (abstract class)
+ - `FlaskJsonParameter`
+ - `FlaskFormParameter`
+ - `FlaskPathParameter`
+ - `FlaskGetParameter`
+ - `FlaskHeaderParameter`
+ - `GenericFlaskDeserializer`
+
+## Contributing
+Feel free to contribute by submitting a pull request :)
+
+## Acknowledgments
+* [Rathaustreppe](https://github.com/rathaustreppe)
+* [Aran-Fey](https://stackoverflow.com/questions/55503673/how-do-i-check-if-a-value-matches-a-type-in-python/55504010#55504010)
+* [user395760](https://stackoverflow.com/questions/55503673/how-do-i-check-if-a-value-matches-a-type-in-python/55504010#55504010)
+
+## Risks and side effects
+The usage of decorators may affect the performance of your application.
+For this reason, I would highly recommend you to disable the decorators if your code runs in a productive environment.
+You can disable `pedantic` by set an environment variable:
+```
+export ENABLE_PEDANTIC=0
+```
+You can also disable or enable the environment variables in your project by calling a method:
+```python
+from pedantic import enable_pedantic, disable_pedantic
+enable_pedantic()
+```
+
+## Issues with compiled Python code
+This package is **not** compatible with compiled source code (e.g. with [Nuitka](https://github.com/Nuitka/Nuitka)).
+That's because it uses the `inspect` module from the standard library which will raise errors like `OSError: could not get source code` in case of compiled source code.
+
+
+Don't forget to check out the [documentation](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic).
+Happy coding!
+
+
+%package help
+Summary: Development documents and examples for pedantic
+Provides: python3-pedantic-doc
+%description help
+# pedantic-python-decorators [![Build Status](https://travis-ci.com/LostInDarkMath/pedantic-python-decorators.svg?branch=master)](https://travis-ci.com/LostInDarkMath/pedantic-python-decorators) [![Coverage Status](https://coveralls.io/repos/github/LostInDarkMath/pedantic-python-decorators/badge.svg?branch=master)](https://coveralls.io/github/LostInDarkMath/pedantic-python-decorators?branch=master) [![PyPI version](https://badge.fury.io/py/pedantic.svg)](https://badge.fury.io/py/pedantic) [![Last Commit](https://badgen.net/github/last-commit/LostInDarkMath/pedantic-python-decorators?color=green)](https://GitHub.com/LostInDarkMath/pedantic-python-decorators) [![Stars](https://badgen.net/github/stars/LostInDarkMath/pedantic-python-decorators?color=green)](https://GitHub.com/LostInDarkMath/pedantic-python-decorators) [![Open Issues](https://badgen.net/github/open-issues/LostInDarkMath/pedantic-python-decorators?color=green)](https://GitHub.com/LostInDarkMath/pedantic-python-decorators/issues) [![Open PRs](https://badgen.net/github/open-prs/LostInDarkMath/pedantic-python-decorators?color=green)](https://GitHub.com/LostInDarkMath/pedantic-python-decorators/pulls)
+
+This packages includes many decorators that will make you write cleaner Python code.
+
+## Getting Started
+This package requires Python 3.7 or later.
+Python 3.6 is only supported by `pedantic` 1.9.1 or lower.
+There are multiple options for installing this package.
+
+### Option 1: Installing with pip from [Pypi](https://pypi.org/)
+Run `pip install pedantic`.
+
+### Option 2: Installing with pip and git
+1. Install [Git](https://git-scm.com/downloads) if you don't have it already.
+2. Run `pip install git+https://github.com/LostInDarkMath/pedantic-python-decorators.git@master`
+
+### Option 3: Offline installation using wheel
+1. Download the [latest release here](https://github.com/LostInDarkMath/PythonHelpers/releases/latest) by clicking on `pedantic-python-decorators-x.y.z-py-none-any.whl`.
+2. Execute `pip install pedantic-python-decorators-x.y.z-py3-none-any.whl`.
+
+## The [@pedantic](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/method_decorators.html#pedantic.method_decorators.pedantic) decorator - Type checking at runtime
+The `@pedantic` decorator does the following things:
+- The decorated function can only be called by using keyword arguments. Positional arguments are not accepted.
+- The decorated function must have [type annotations](https://docs.python.org/3/library/typing.html).
+- Each time the decorated function is called, pedantic checks that the passed arguments and the return value of the function matches the given type annotations.
+As a consequence, the arguments are also checked for `None`, because `None` is only a valid argument, if it is annotated via `typing.Optional`.
+- If the decorated function has a docstring which lists the arguments, the docstring is parsed and compared with the type annotations. In other words, pedantic ensures that the docstring is everytime up-to-date.
+Currently, only docstrings in the [Google style](https://google.github.io/styleguide/pyguide.html) are supported. **Note:** you need install the [docstring-parser](https://github.com/rr-/docstring_parser) to make this work.
+
+In a nutshell:
+`@pedantic` raises an `PedanticException` if one of the following happened:
+- The decorated function is called with positional arguments.
+- The function has no type annotation for their return type or one or more parameters do not have type annotations.
+- A type annotation is incorrect.
+- A type annotation misses type arguments, e.g. `typing.List` instead of `typing.List[int]`.
+- The documented arguments do not match the argument list or their type annotations.
+
+### Minimal example
+```python
+from typing import Union, List
+from pedantic import pedantic, pedantic_class
+
+@pedantic
+def get_sum_of(values: List[Union[int, float]]) -> Union[int, float]:
+ return sum(values)
+
+@pedantic_class
+class MyClass:
+ def __init__(self, x: float, y: int) -> None:
+ self.x = x
+ self.y = y
+
+ def print_sum(self) -> None:
+ print(get_sum_of(values=[self.x, self.y]))
+
+m = MyClass(x=3.14, y=2)
+m.print_sum()
+```
+
+
+## The [@validate]() decorator
+As the name suggests, with `@validate` you are able to validate the values that are passed to the decorated function.
+That is done in a highly customizable way.
+But the highest benefit of this decorator is that it makes it extremely easy to write decoupled easy testable, maintainable and scalable code.
+The following example shows the decoupled implementation of a configurable algorithm with the help of `@validate`:
+```python
+import os
+from dataclasses import dataclass
+
+from pedantic import validate, ExternalParameter, overrides, Validator, Parameter, Min, ReturnAs
+
+
+@dataclass(frozen=True)
+class Configuration:
+ iterations: int
+ max_error: float
+
+
+class ConfigurationValidator(Validator):
+ @overrides(Validator)
+ def validate(self, value: Configuration) -> Configuration:
+ if value.iterations < 1 or value.max_error < 0:
+ self.raise_exception(msg=f'Invalid configuration: {value}', value=value)
+
+ return value
+
+
+class ConfigFromEnvVar(ExternalParameter):
+ """ Reads the configuration from environment variables. """
+
+ @overrides(ExternalParameter)
+ def has_value(self) -> bool:
+ return 'iterations' in os.environ and 'max_error' in os.environ
+
+ @overrides(ExternalParameter)
+ def load_value(self) -> Configuration:
+ return Configuration(
+ iterations=int(os.environ['iterations']),
+ max_error=float(os.environ['max_error']),
+ )
+
+
+class ConfigFromFile(ExternalParameter):
+ """ Reads the configuration from a config file. """
+
+ @overrides(ExternalParameter)
+ def has_value(self) -> bool:
+ return os.path.isfile('config.csv')
+
+ @overrides(ExternalParameter)
+ def load_value(self) -> Configuration:
+ with open(file='config.csv', mode='r') as file:
+ content = file.readlines()
+ return Configuration(
+ iterations=int(content[0].strip('\n')),
+ max_error=float(content[1]),
+ )
+
+
+# choose your configuration source here:
+@validate(ConfigFromEnvVar(name='config', validators=[ConfigurationValidator()]), strict=False, return_as=ReturnAs.KWARGS_WITH_NONE)
+# @validate(ConfigFromFile(name='config', validators=[ConfigurationValidator()]), strict=False)
+
+# with strict_mode = True (which is the default)
+# you need to pass a Parameter for each parameter of the decorated function
+# @validate(
+# Parameter(name='value', validators=[Min(5, include_boundary=False)]),
+# ConfigFromFile(name='config', validators=[ConfigurationValidator()]),
+# )
+def my_algorithm(value: float, config: Configuration) -> float:
+ """
+ This method calculates something that depends on the given value with considering the configuration.
+ Note how well this small piece of code is designed:
+ - Fhe function my_algorithm() need a Configuration but has no knowledge where this come from.
+ - Furthermore, it doesn't care about parameter validation.
+ - The ConfigurationValidator doesn't know anything about the creation of the data.
+ - The @validate decorator is the only you need to change, if you want a different configuration source.
+ """
+ print(value)
+ print(config)
+ return value
+
+
+if __name__ == '__main__':
+ # we can call the function with a config like there is no decorator.
+ # This makes testing extremely easy: no config files, no environment variables or stuff like that
+ print(my_algorithm(value=2, config=Configuration(iterations=3, max_error=4.4)))
+
+ os.environ['iterations'] = '12'
+ os.environ['max_error'] = '3.1415'
+
+ # but we also can omit the config and load it implicitly by our custom Parameters
+ print(my_algorithm(value=42.0))
+```
+
+## List of all decorators in this package
+- [@count_calls](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_count_calls.html)
+- [@deprecated](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_deprecated.html)
+- [@does_same_as_function](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_does_same_as_function.html)
+- [@frozen_dataclass](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/cls_deco_frozen_dataclass.html#pedantic.decorators.cls_deco_frozen_dataclass.frozen_dataclass)
+- [@frozen_type_safe_dataclass](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/cls_deco_frozen_dataclass.html#pedantic.decorators.cls_deco_frozen_dataclass.frozen_type_safe_dataclass)
+- [@for_all_methods](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/class_decorators.html#pedantic.decorators.class_decorators.for_all_methods)
+- [@in_subprocess](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_in_subprocess.html)
+- [@mock](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_mock.html)
+- [@overrides](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_overrides.html)
+- [@pedantic](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_pedantic.html#pedantic.decorators.fn_deco_pedantic.pedantic)
+- [@pedantic_require_docstring](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_pedantic.html#pedantic.decorators.fn_deco_pedantic.pedantic_require_docstring)
+- [@pedantic_class](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/class_decorators.html#pedantic.decorators.class_decorators.pedantic_class)
+- [@pedantic_class_require_docstring](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/class_decorators.html#pedantic.decorators.class_decorators.pedantic_class_require_docstring)
+- [@rename_kwargs](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_rename_kwargs.html)
+- [@require_kwargs](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_require_kwargs.html)
+- [@timer](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_timer.html)
+- [@timer_class](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/class_decorators.html#pedantic.decorators.class_decorators.timer_class)
+- [@trace](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_trace.html)
+- [@trace_class](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/class_decorators.html#pedantic.decorators.class_decorators.trace_class)
+- [@trace_if_returns](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_trace_if_returns.html)
+- [@unimplemented](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_unimplemented.html)
+- [@validate](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/decorators/fn_deco_validate/fn_deco_validate.html)
+
+## List of all mixins in this package
+- [GenericMixin](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic/mixins/generic_mixin.html)
+
+## Dependencies
+There are no hard dependencies. But if you want to use some advanced features you need to install the following packages:
+- [Docstring-Parser](https://github.com/rr-/docstring_parser) if you need to verify your docstrings.
+- [multiprocess](https://github.com/uqfoundation/multiprocess) if you want to use the `@in_subprocess` decorator
+- [flask](https://pypi.org/project/Flask/) if you want to you the request validators which are designed for `Flask` (see unit tests for examples):
+ - `FlaskParameter` (abstract class)
+ - `FlaskJsonParameter`
+ - `FlaskFormParameter`
+ - `FlaskPathParameter`
+ - `FlaskGetParameter`
+ - `FlaskHeaderParameter`
+ - `GenericFlaskDeserializer`
+
+## Contributing
+Feel free to contribute by submitting a pull request :)
+
+## Acknowledgments
+* [Rathaustreppe](https://github.com/rathaustreppe)
+* [Aran-Fey](https://stackoverflow.com/questions/55503673/how-do-i-check-if-a-value-matches-a-type-in-python/55504010#55504010)
+* [user395760](https://stackoverflow.com/questions/55503673/how-do-i-check-if-a-value-matches-a-type-in-python/55504010#55504010)
+
+## Risks and side effects
+The usage of decorators may affect the performance of your application.
+For this reason, I would highly recommend you to disable the decorators if your code runs in a productive environment.
+You can disable `pedantic` by set an environment variable:
+```
+export ENABLE_PEDANTIC=0
+```
+You can also disable or enable the environment variables in your project by calling a method:
+```python
+from pedantic import enable_pedantic, disable_pedantic
+enable_pedantic()
+```
+
+## Issues with compiled Python code
+This package is **not** compatible with compiled source code (e.g. with [Nuitka](https://github.com/Nuitka/Nuitka)).
+That's because it uses the `inspect` module from the standard library which will raise errors like `OSError: could not get source code` in case of compiled source code.
+
+
+Don't forget to check out the [documentation](https://lostindarkmath.github.io/pedantic-python-decorators/pedantic).
+Happy coding!
+
+
+%prep
+%autosetup -n pedantic-1.14.5
+
+%build
+%py3_build
+
+%install
+%py3_install
+install -d -m755 %{buildroot}/%{_pkgdocdir}
+if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi
+if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi
+if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi
+if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi
+pushd %{buildroot}
+if [ -d usr/lib ]; then
+ find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/lib64 ]; then
+ find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/bin ]; then
+ find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/sbin ]; then
+ find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+touch doclist.lst
+if [ -d usr/share/man ]; then
+ find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst
+fi
+popd
+mv %{buildroot}/filelist.lst .
+mv %{buildroot}/doclist.lst .
+
+%files -n python3-pedantic -f filelist.lst
+%dir %{python3_sitelib}/*
+
+%files help -f doclist.lst
+%{_docdir}/*
+
+%changelog
+* Wed May 10 2023 Python_Bot <Python_Bot@openeuler.org> - 1.14.5-1
+- Package Spec generated
diff --git a/sources b/sources
new file mode 100644
index 0000000..806cc53
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+552c179d466cf3e3a31e7d9055a266f3 pedantic-1.14.5.tar.gz