From 1815898ed1aee3ab0ff55dc26c2d46dada757e8e Mon Sep 17 00:00:00 2001 From: Alexey Stepanov Date: Thu, 6 Sep 2018 13:50:42 +0200 Subject: [PATCH 1/5] CI Update: port from threaded and do not use tox for travis * faster * pep257 -> pydocstyle Signed-off-by: Alexey Stepanov --- .travis.yml | 113 +++++++++++++++++++++++++++++++++++++------ logwrap/_log_wrap.py | 2 +- setup.cfg | 5 ++ tox.ini | 7 ++- 4 files changed, 109 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index 94638e2..7cc8162 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,46 +1,129 @@ sudo: false language: python os: linux -python: -- 3.5 -- 3.6 -- &mainstream_python 3.7-dev -- &pypy pypy3.5 install: - &upgrade_python_toolset pip install --upgrade pip setuptools wheel -- pip install tox-travis -- pip install coveralls -script: tox +- &install_test_deps pip install --upgrade pytest pytest-sugar +- &install_deps pip install -r CI_REQUIREMENTS.txt +- pip install --upgrade pytest-cov coveralls + +_helpers: +- &install_cython pip install Cython +- &build_package python setup.py bdist_wheel +- &install_built pip install logwrap --no-index -f dist +- &test_no_cov py.test -vv {posargs:test} +- &test_cythonized + install: + - *upgrade_python_toolset + - *install_test_deps + - *install_deps + - *install_cython + script: + - *build_package + - *install_built + - *test_no_cov + +script: +- py.test -vv --cov-config .coveragerc --cov-report term-missing --cov=logwrap test +- coverage report --fail-under 87 after_success: - coveralls jobs: fast_finish: true include: + - stage: test + name: "Python 3.5" + python: 3.5 + - stage: test + name: "Python 3.6" + python: 3.6 + - stage: test + name: "Python 3.7" + python: 3.7 + dist: xenial + sudo: true + - stage: test + name: "PyPy3" + python: pypy3.5 + - stage: Static analisys + name: "PyLint" python: 3.6 services: [] install: - *upgrade_python_toolset - - pip install tox + - *install_deps + - pip install --upgrade pylint >= 2.0 + script: + - pylint logwrap + after_success: skip + - stage: Static analisys + name: "Bandit" + python: 3.6 + services: [] + install: + - *upgrade_python_toolset + - pip install --upgrade bandit + script: + - bandit -r logwrap + after_success: skip + - stage: Static analisys + name: "MyPy" + python: 3.7 + dist: xenial + sudo: true + services: [] + install: + - *upgrade_python_toolset + - *install_deps + - pip install --upgrade mypy>=0.620 script: - - tox -e pylint,bandit,mypy + - mypy --strict logwrap + after_success: skip + + - stage: Test cythonized + name: "Python 3.5" + python: 3.5 + <<: *test_cythonized + after_success: skip + - stage: Test cythonized + name: "Python 3.6" + python: 3.6 + <<: *test_cythonized + after_success: skip + - stage: Test cythonized + name: "Python 3.7" + python: 3.7 + dist: xenial + sudo: true + <<: *test_cythonized after_success: skip - stage: Code style check - python: *mainstream_python - services: [] + name: "PEP8" + python: 3.6 + install: + - *upgrade_python_toolset + - pip install --upgrade flake8 + script: + - flake8 + after_success: skip + - stage: Code style check + name: "PEP257" + python: 3.6 install: - *upgrade_python_toolset - - pip install tox + - pip install --upgrade pydocstyle script: - - tox -e pep8,pep257 + - pydocstyle logwrap after_success: skip - stage: deploy # This prevents job from appearing in test plan unless commit is tagged: if: tag IS present - python: *pypy + # Run on pypy to build not cythonized wheel + python: pypy3.5 services: - docker install: diff --git a/logwrap/_log_wrap.py b/logwrap/_log_wrap.py index 9c13337..af2f866 100644 --- a/logwrap/_log_wrap.py +++ b/logwrap/_log_wrap.py @@ -425,7 +425,7 @@ def log_result_obj(self, val: bool) -> None: @property def _logger(self) -> logging.Logger: - """logger instance. + """Logger instance. :rtype: logging.Logger """ diff --git a/setup.cfg b/setup.cfg index 039d434..fb16d2d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -40,8 +40,13 @@ exclude = __init__.py, docs ignore = +show-pep8 = True show-source = True count = True +max-line-length = 120 + +[pydocstyle] +ignore = D401, D203, D213 [aliases] test=pytest diff --git a/tox.ini b/tox.ini index 0260c42..fbf59a1 100644 --- a/tox.ini +++ b/tox.ini @@ -65,9 +65,9 @@ commands = flake8 [testenv:pep257] deps = - pep257 + pydocstyle usedevelop = False -commands = pep257 logwrap +commands = pydocstyle logwrap [testenv:install] deps = @@ -98,6 +98,9 @@ show-source = True count = True max-line-length = 120 +[pydocstyle] +ignore = D401, D203, D213 + [testenv:docs] deps = sphinx From 56f5a46e31dbd1762ad5a111575615b90c89cf63 Mon Sep 17 00:00:00 2001 From: Alexey Stepanov Date: Thu, 6 Sep 2018 13:57:35 +0200 Subject: [PATCH 2/5] usedevelop Signed-off-by: Alexey Stepanov --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 7cc8162..34ee96b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,7 @@ _helpers: - *test_no_cov script: +- pip install -e . - py.test -vv --cov-config .coveragerc --cov-report term-missing --cov=logwrap test - coverage report --fail-under 87 after_success: From 662397517ab3a5c4d603a4fd506e521c5208ca3f Mon Sep 17 00:00:00 2001 From: Alexey Stepanov Date: Thu, 6 Sep 2018 14:09:30 +0200 Subject: [PATCH 3/5] quotes for shell Signed-off-by: Alexey Stepanov --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 34ee96b..91e7fcc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ install: - pip install --upgrade pytest-cov coveralls _helpers: -- &install_cython pip install Cython +- &install_cython pip install --upgrade Cython - &build_package python setup.py bdist_wheel - &install_built pip install logwrap --no-index -f dist - &test_no_cov py.test -vv {posargs:test} @@ -55,7 +55,7 @@ jobs: install: - *upgrade_python_toolset - *install_deps - - pip install --upgrade pylint >= 2.0 + - pip install --upgrade "pylint >= 2.0" script: - pylint logwrap after_success: skip @@ -78,7 +78,7 @@ jobs: install: - *upgrade_python_toolset - *install_deps - - pip install --upgrade mypy>=0.620 + - pip install --upgrade "mypy >= 0.620" script: - mypy --strict logwrap after_success: skip From 2480489c748d78647bd6efd4e2adb03e1625ace0 Mon Sep 17 00:00:00 2001 From: Alexey Stepanov Date: Thu, 6 Sep 2018 14:17:45 +0200 Subject: [PATCH 4/5] fix tox.ini copypaste Signed-off-by: Alexey Stepanov --- .travis.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 91e7fcc..3112564 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ _helpers: - &install_cython pip install --upgrade Cython - &build_package python setup.py bdist_wheel - &install_built pip install logwrap --no-index -f dist -- &test_no_cov py.test -vv {posargs:test} +- &test_no_cov py.test -vv test - &test_cythonized install: - *upgrade_python_toolset @@ -22,11 +22,12 @@ _helpers: - *build_package - *install_built - *test_no_cov + after_success: skip script: - pip install -e . -- py.test -vv --cov-config .coveragerc --cov-report term-missing --cov=logwrap test -- coverage report --fail-under 87 +- py.test -vv --cov-config .coveragerc --cov-report= --cov=logwrap test +- coverage report -m --fail-under 87 after_success: - coveralls @@ -87,19 +88,16 @@ jobs: name: "Python 3.5" python: 3.5 <<: *test_cythonized - after_success: skip - stage: Test cythonized name: "Python 3.6" python: 3.6 <<: *test_cythonized - after_success: skip - stage: Test cythonized name: "Python 3.7" python: 3.7 dist: xenial sudo: true <<: *test_cythonized - after_success: skip - stage: Code style check name: "PEP8" @@ -133,7 +131,7 @@ jobs: - ./tools/run_docker.sh "logwrap" before_deploy: - pip install -r build_requirements.txt - - python setup.py bdist_wheel + - *build_package deploy: - provider: pypi # `skip_cleanup: true` is required to preserve binary wheels, built From 823bda1520b79d96a82dbcf1a5e6ab3b81532078 Mon Sep 17 00:00:00 2001 From: Alexey Stepanov Date: Thu, 6 Sep 2018 16:42:24 +0200 Subject: [PATCH 5/5] Use pedantic docstrings validation Signed-off-by: Alexey Stepanov --- .pylintrc | 2 +- logwrap/_log_wrap.py | 14 ++++++++++++++ logwrap/_repr_utils.py | 31 ++++++++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/.pylintrc b/.pylintrc index 9e6d02f..15373de 100644 --- a/.pylintrc +++ b/.pylintrc @@ -16,7 +16,7 @@ persistent=yes # List of plugins (as comma separated values of python modules names) to load, # usually to register additional checkers. -load-plugins= +load-plugins=pylint.extensions.docparams # Use multiple processes to speed up Pylint. jobs=1 diff --git a/logwrap/_log_wrap.py b/logwrap/_log_wrap.py index af2f866..2a151a4 100644 --- a/logwrap/_log_wrap.py +++ b/logwrap/_log_wrap.py @@ -165,6 +165,10 @@ def bind_args_kwargs( :param sig: source signature :type sig: inspect.Signature + :param args: not keyworded arguments + :type args: tuple + :param kwargs: keyworded arguments + :type kwargs: dict :return: Iterator for bound parameters with all information about it :rtype: typing.Iterator[BoundParameter] @@ -366,7 +370,9 @@ def log_call_args(self) -> bool: def log_call_args(self, val: bool) -> None: """Flag: log call arguments before call. + :param val: Enable flag :type val: bool + :raises TypeError: Value is not bool """ if not isinstance(val, bool): raise TypeError( @@ -389,7 +395,9 @@ def log_call_args_on_exc(self) -> bool: def log_call_args_on_exc(self, val: bool) -> None: """Flag: log call arguments on exception. + :param val: Enable flag :type val: bool + :raises TypeError: Value is not bool """ if not isinstance(val, bool): raise TypeError( @@ -412,7 +420,9 @@ def log_result_obj(self) -> bool: def log_result_obj(self, val: bool) -> None: """Flag: log result object. + :param val: Enable flag :type val: bool + :raises TypeError: Value is not bool """ if not isinstance(val, bool): raise TypeError( @@ -506,9 +516,13 @@ def _get_func_args_repr( ) -> str: """Internal helper for reducing complexity of decorator code. + :param sig: function signature :type sig: inspect.Signature + :param args: not keyworded arguments :type args: tuple + :param kwargs: keyworded arguments :type kwargs: dict + :return: repr over function arguments :rtype: str .. versionchanged:: 3.3.0 Use pre- and post- processing of params during execution diff --git a/logwrap/_repr_utils.py b/logwrap/_repr_utils.py index ca66a3d..828f6cf 100644 --- a/logwrap/_repr_utils.py +++ b/logwrap/_repr_utils.py @@ -121,7 +121,9 @@ def _prepare_repr( ) -> typing.Iterator[ReprParameter]: """Get arguments lists with defaults. + :param func: Callable object to process :type func: typing.Union[types.FunctionType, types.MethodType] + :return: repr of callable parameter from signature :rtype: typing.Iterator[ReprParameter] """ isfunction = isinstance(func, types.FunctionType) @@ -192,6 +194,7 @@ def next_indent(self, indent: int, multiplier: int = 1) -> int: :type indent: int :param multiplier: step multiplier :type multiplier: int + :return: next indentation value :rtype: int """ return indent + multiplier * self.indent_step @@ -204,8 +207,11 @@ def _repr_callable( ) -> str: """Repr callable object (function or method). + :param src: Callable to process :type src: typing.Union[types.FunctionType, types.MethodType] + :param indent: start indentation :type indent: int + :return: Repr of function or method with signature. :rtype: str """ raise NotImplementedError() # pragma: no cover @@ -219,9 +225,13 @@ def _repr_simple( ) -> str: """Repr object without iteration. + :param src: Source object :type src: typing.Any + :param indent: start indentation :type indent: int + :param no_indent_start: ignore indent :type no_indent_start: bool + :return: simple repr() over object :rtype: str """ raise NotImplementedError() # pragma: no cover @@ -280,6 +290,7 @@ def _repr_iterable_items( :type src: typing.Iterable :param indent: start indentation :type indent: int + :return: repr of element in iterable item :rtype: typing.Iterator[str] """ for elem in src: @@ -427,9 +438,13 @@ def _repr_simple( ) -> str: """Repr object without iteration. + :param src: Source object :type src: typing.Any + :param indent: start indentation :type indent: int + :param no_indent_start: ignore indent :type no_indent_start: bool + :return: simple repr() over object, except strings (add prefix) and set (uniform py2/py3) :rtype: str """ indent = 0 if no_indent_start else indent @@ -458,6 +473,7 @@ def _repr_dict_items( :type src: dict :param indent: start indentation :type indent: int + :return: repr of key/value pair from dict :rtype: typing.Iterator[str] """ max_len = max((len(repr(key)) for key in src)) if src else 0 @@ -481,8 +497,11 @@ def _repr_callable( ) -> str: """Repr callable object (function or method). + :param src: Callable to process :type src: typing.Union[types.FunctionType, types.MethodType] + :param indent: start indentation :type indent: int + :return: Repr of function or method with signature. :rtype: str """ param_str = "" @@ -545,6 +564,7 @@ def _repr_iterable_item( :type result: str :param suffix: suffix :type suffix: str + :return: formatted repr of "result" with prefix and suffix to explain type. :rtype: str """ return ( @@ -600,9 +620,13 @@ def _repr_simple( ) -> str: """Repr object without iteration. + :param src: Source object :type src: typing.Any + :param indent: start indentation :type indent: int + :param no_indent_start: ignore indent :type no_indent_start: bool + :return: simple repr() over object, except strings (decode) and set (uniform py2/py3) :rtype: str """ indent = 0 if no_indent_start else indent @@ -631,7 +655,8 @@ def _repr_dict_items( :type src: dict :param indent: start indentation :type indent: int - :rtype: typing.Generator[str] + :return: repr of key/value pair from dict + :rtype: typing.Iterator[str] """ max_len = max((len(str(key)) for key in src)) if src else 0 for key, val in src.items(): @@ -654,8 +679,11 @@ def _repr_callable( ) -> str: """Repr callable object (function or method). + :param src: Callable to process :type src: typing.Union[types.FunctionType, types.MethodType] + :param indent: start indentation :type indent: int + :return: Repr of function or method with signature. :rtype: str """ param_str = "" @@ -718,6 +746,7 @@ def _repr_iterable_item( :type result: str :param suffix: suffix :type suffix: str + :return: formatted repr of "result" with prefix and suffix to explain type. :rtype: str """ return (