Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-Deprecated for openSUSE:Factory checked in at 2021-04-19 21:06:14 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-Deprecated (Old) and /work/SRC/openSUSE:Factory/.python-Deprecated.new.12324 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-Deprecated" Mon Apr 19 21:06:14 2021 rev:6 rq:886600 version:1.2.12 Changes: -------- --- /work/SRC/openSUSE:Factory/python-Deprecated/python-Deprecated.changes 2020-07-09 13:21:00.605581088 +0200 +++ /work/SRC/openSUSE:Factory/.python-Deprecated.new.12324/python-Deprecated.changes 2021-04-19 21:06:39.336088402 +0200 @@ -1,0 +2,18 @@ +Sun Apr 18 13:29:45 UTC 2021 - Ben Greiner <c...@bnavigator.de> + +- Update to 1.2.12 + * Avoid "Explicit markup ends without a blank line" when the + decorated function has no docstring. + * Fix #40: 'version' argument is required in Sphinx directives. + * Fix #41: deprecated.sphinx: strip Sphinx cross-referencing + syntax from warning message. +- Release 1.2.11 + * Fix packit configuration: use upstream_tag_template: v{version}. + * Fix #33: Change the class ~deprecated.sphinx.SphinxAdapter: add + the line_length keyword argument to the constructor to specify + the max line length of the directive text. Sphinx decorators + also accept the line_length argument. + * Fix #34: versionadded and versionchanged decorators don't emit + DeprecationWarning anymore on decorated classes. + +------------------------------------------------------------------- Old: ---- Deprecated-1.2.10.tar.gz New: ---- Deprecated-1.2.12.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-Deprecated.spec ++++++ --- /var/tmp/diff_new_pack.13o0lb/_old 2021-04-19 21:06:39.768089051 +0200 +++ /var/tmp/diff_new_pack.13o0lb/_new 2021-04-19 21:06:39.772089056 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-Deprecated # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2021 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,7 +18,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-Deprecated -Version: 1.2.10 +Version: 1.2.12 Release: 0 Summary: Python @deprecated decorator License: MIT ++++++ Deprecated-1.2.10.tar.gz -> Deprecated-1.2.12.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/.bumpversion.cfg new/Deprecated-1.2.12/.bumpversion.cfg --- old/Deprecated-1.2.10/.bumpversion.cfg 2020-05-13 22:20:55.000000000 +0200 +++ new/Deprecated-1.2.12/.bumpversion.cfg 2021-01-17 10:57:45.000000000 +0100 @@ -1,5 +1,5 @@ [bumpversion] -current_version = 1.2.10 +current_version = 1.2.12 commit = True tag = False message = Prepare next version {new_version} (unreleased) @@ -19,3 +19,4 @@ [bumpversion:file:python-deprecated.spec] search = (?<=Version:\s+){current_version} replace = {new_version} + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/.github/workflows/python-package.yml new/Deprecated-1.2.12/.github/workflows/python-package.yml --- old/Deprecated-1.2.10/.github/workflows/python-package.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/Deprecated-1.2.12/.github/workflows/python-package.yml 2021-01-03 21:38:43.000000000 +0100 @@ -0,0 +1,57 @@ +# This workflow will install Python dependencies, run tests and lint with a variety of Python versions +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions + +name: Python package + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + pytest-py27-p35: + runs-on: ${{ matrix.platform }} + + strategy: + matrix: + platform: [ ubuntu-latest, macos-latest, windows-latest ] + python-version: [ 2.7, 3.5 ] + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade 'pip < 21' + python -m pip install 'PyTest < 5' + python -m pip install -e . + - name: Test with pytest + run: | + pytest tests/ + + pytest-py36-py39: + runs-on: ${{ matrix.platform }} + + strategy: + matrix: + platform: [ ubuntu-latest, macos-latest, windows-latest ] + python-version: [ 3.6, 3.7, 3.8, 3.9 ] + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python -m pip install 'PyTest' + python -m pip install -e . + - name: Test with pytest + run: | + pytest tests/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/.packit.yml new/Deprecated-1.2.12/.packit.yml --- old/Deprecated-1.2.10/.packit.yml 2020-04-10 09:54:34.000000000 +0200 +++ new/Deprecated-1.2.12/.packit.yml 2020-12-17 18:54:01.000000000 +0100 @@ -1,32 +1,17 @@ -specfile_path: python-deprecated.spec synced_files: - python-deprecated.spec - .packit.yml -upstream_project_name: Deprecated +upstream_package_name: Deprecated +upstream_tag_template: v{version} downstream_package_name: python-deprecated -create_pr: false jobs: - - job: propose_downstream - trigger: release - metadata: - dist-git-branch: master - - job: propose_downstream - trigger: release - metadata: - dist-git-branch: fedora-all - - job: propose_downstream - trigger: release - metadata: - dist-git-branch: f30 - - job: propose_downstream - trigger: release - metadata: - dist-git-branch: f29 - - job: copr_build - trigger: pull_request - metadata: - targets: - - fedora-all - - fedora-30-x86_64 - - fedora-29-x86_64 - - fedora-rawhide-x86_64 +- job: propose_downstream + trigger: release + metadata: + dist_git_branches: + - fedora-all +- job: copr_build + trigger: pull_request + metadata: + targets: + - fedora-all diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/.travis.yml new/Deprecated-1.2.12/.travis.yml --- old/Deprecated-1.2.10/.travis.yml 2020-05-13 22:20:55.000000000 +0200 +++ new/Deprecated-1.2.12/.travis.yml 2021-01-18 13:36:18.000000000 +0100 @@ -1,3 +1,6 @@ +arch: + - amd64 + - ppc64le language: python python: - "2.7" @@ -5,12 +8,24 @@ - "3.6" - "3.7" - "3.8" - - "3.9-dev" # 3.9 development branch + - "3.9" + - "3.10-dev" # 3.10 development branch - "pypy" - "pypy3" jobs: - allow_failures: - - python: "3.9-dev" + exclude: + - arch: ppc64le + python: "2.7" + - arch: ppc64le + python: "pypy" + - arch: ppc64le + python: "pypy3" + - arch: amd64 + python: "pypy" + +allow_failures: + - python: "3.10-dev" + install: - pip install coveralls tox-travis script: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/CHANGELOG.rst new/Deprecated-1.2.12/CHANGELOG.rst --- old/Deprecated-1.2.10/CHANGELOG.rst 2020-05-13 22:43:10.000000000 +0200 +++ new/Deprecated-1.2.12/CHANGELOG.rst 2021-03-13 14:59:20.000000000 +0100 @@ -18,6 +18,59 @@ (only in comment or documentation). +v1.2.12 (2020-03-13) +==================== + +Bug fix release + +Fix +--- + +- Avoid "Explicit markup ends without a blank line" when the decorated function has no docstring. + +- Fix #40: 'version' argument is required in Sphinx directives. + +- Fix #41: :mod:`deprecated.sphinx`: strip Sphinx cross-referencing syntax from warning message. + + +Other +----- + +- Change in Tox and Travis CI configurations: enable unit testing on Python 3.10. + + +v1.2.11 (2021-01-17) +==================== + +Bug fix release + +Fix +--- + +- Fix packit configuration: use ``upstream_tag_template: v{version}``. + +- Fix #33: Change the class :class:`~deprecated.sphinx.SphinxAdapter`: + add the ``line_length`` keyword argument to the constructor to specify the max line length of the directive text. + Sphinx decorators also accept the ``line_length`` argument. + +- Fix #34: ``versionadded`` and ``versionchanged`` decorators don't emit ``DeprecationWarning`` + anymore on decorated classes. + + +Other +----- + +- Change the Tox configuration to run tests on Python 2.7, Python 3.4 and above (and PyPy 2.7 & 3.6). + +- Update the classifiers in ``setup.py``. + +- Replace ``bumpversion`` by `bump2version <https://pypi.org/project/bump2version/>`_ in ``setup.py`` and documentation. + +- Update configuration for Black and iSort. + +- Fix the development requirement versions in ``setup.py`` for Python 2.7 EOL. + + v1.2.10 (2020-05-13) ==================== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/Deprecated.egg-info/PKG-INFO new/Deprecated-1.2.12/Deprecated.egg-info/PKG-INFO --- old/Deprecated-1.2.10/Deprecated.egg-info/PKG-INFO 2020-05-13 22:43:41.000000000 +0200 +++ new/Deprecated-1.2.12/Deprecated.egg-info/PKG-INFO 2021-03-13 15:07:08.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Deprecated -Version: 1.2.10 +Version: 1.2.12 Summary: Python @deprecated decorator to deprecate old python classes, functions or methods. Home-page: https://github.com/tantale/deprecated Author: Laurent LAPORTE @@ -163,6 +163,8 @@ Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 Classifier: Topic :: Software Development :: Libraries :: Python Modules Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* Description-Content-Type: text/x-rst diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/Deprecated.egg-info/SOURCES.txt new/Deprecated-1.2.12/Deprecated.egg-info/SOURCES.txt --- old/Deprecated-1.2.10/Deprecated.egg-info/SOURCES.txt 2020-05-13 22:43:41.000000000 +0200 +++ new/Deprecated-1.2.12/Deprecated.egg-info/SOURCES.txt 2021-03-13 15:07:08.000000000 +0100 @@ -9,6 +9,7 @@ Makefile README.md appveyor.yml +pyproject.toml python-deprecated.spec setup.cfg setup.py @@ -16,6 +17,7 @@ .github/CODE_OF_CONDUCT.md .github/ISSUE_TEMPLATE.md .github/PULL_REQUEST_TEMPLATE.md +.github/workflows/python-package.yml Deprecated.egg-info/PKG-INFO Deprecated.egg-info/SOURCES.txt Deprecated.egg-info/dependency_links.txt @@ -63,5 +65,6 @@ tests/test_deprecated_class.py tests/test_deprecated_metaclass.py tests/test_sphinx.py +tests/test_sphinx_adapter.py tests/test_sphinx_class.py tests/test_sphinx_metaclass.py \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/Deprecated.egg-info/requires.txt new/Deprecated-1.2.12/Deprecated.egg-info/requires.txt --- old/Deprecated-1.2.10/Deprecated.egg-info/requires.txt 2020-05-13 22:43:41.000000000 +0200 +++ new/Deprecated-1.2.12/Deprecated.egg-info/requires.txt 2021-03-13 15:07:08.000000000 +0100 @@ -2,10 +2,17 @@ [dev] tox -bumpversion<1 +bump2version<1 sphinx<2 [dev:python_version < "3"] +importlib-metadata<3 +importlib-resources<4 +configparser<5 +sphinxcontrib-websupport<2 +zipp<2 + +[dev:python_version < "3.6"] PyTest<5 PyTest-Cov<2.6 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/PKG-INFO new/Deprecated-1.2.12/PKG-INFO --- old/Deprecated-1.2.10/PKG-INFO 2020-05-13 22:43:41.000000000 +0200 +++ new/Deprecated-1.2.12/PKG-INFO 2021-03-13 15:07:08.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Deprecated -Version: 1.2.10 +Version: 1.2.12 Summary: Python @deprecated decorator to deprecate old python classes, functions or methods. Home-page: https://github.com/tantale/deprecated Author: Laurent LAPORTE @@ -163,6 +163,8 @@ Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 Classifier: Topic :: Software Development :: Libraries :: Python Modules Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* Description-Content-Type: text/x-rst diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/deprecated/__init__.py new/Deprecated-1.2.12/deprecated/__init__.py --- old/Deprecated-1.2.10/deprecated/__init__.py 2020-05-13 22:20:55.000000000 +0200 +++ new/Deprecated-1.2.12/deprecated/__init__.py 2021-03-13 14:59:20.000000000 +0100 @@ -7,7 +7,9 @@ """ -#: Module Version Number, see `PEP 396 <https://www.python.org/dev/peps/pep-0396/>`_. -__version__ = "1.2.10" +__version__ = "1.2.12" +__author__ = u"Laurent LAPORTE <tantale.soluti...@gmail.com>" +__date__ = "2020-03-13" +__credits__ = "(c) Laurent LAPORTE" from deprecated.classic import deprecated diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/deprecated/classic.py new/Deprecated-1.2.12/deprecated/classic.py --- old/Deprecated-1.2.10/deprecated/classic.py 2020-05-13 22:22:53.000000000 +0200 +++ new/Deprecated-1.2.12/deprecated/classic.py 2021-01-31 19:16:19.000000000 +0100 @@ -9,8 +9,8 @@ """ import functools import inspect -import warnings import platform +import warnings import wrapt @@ -226,7 +226,7 @@ return x + y The *category* keyword argument allow you to specify the deprecation warning class of your choice. - By default, :exc:`DeprecationWarning` is ued but you can choose :exc:`FutureWarning`, + By default, :exc:`DeprecationWarning` is used but you can choose :exc:`FutureWarning`, :exc:`PendingDeprecationWarning` or a custom subclass. .. code-block:: python diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/deprecated/sphinx.py new/Deprecated-1.2.12/deprecated/sphinx.py --- old/Deprecated-1.2.10/deprecated/sphinx.py 2020-02-23 07:15:14.000000000 +0100 +++ new/Deprecated-1.2.12/deprecated/sphinx.py 2021-03-13 11:56:07.000000000 +0100 @@ -19,6 +19,7 @@ Of course, the ``@deprecated`` decorator will emit a deprecation warning when the function/method is called or the class is constructed. """ +import re import textwrap import wrapt @@ -40,7 +41,15 @@ - The reason message is obviously added in the directive block if not empty. """ - def __init__(self, directive, reason="", version="", action=None, category=DeprecationWarning): + def __init__( + self, + directive, + reason="", + version="", + action=None, + category=DeprecationWarning, + line_length=70, + ): """ Construct a wrapper adapter. @@ -70,8 +79,16 @@ The warning category to use for the deprecation warning. By default, the category class is :class:`~DeprecationWarning`, you can inherit this class to define your own deprecation warning category. + + :type line_length: int + :param line_length: + Max line length of the directive text. If non nul, a long text is wrapped in several lines. """ + if not version: + # https://github.com/tantale/deprecated/issues/40 + raise ValueError("'version' argument is required in Sphinx directives") self.directive = directive + self.line_length = line_length super(SphinxAdapter, self).__init__(reason=reason, version=version, action=action, category=category) def __call__(self, wrapped): @@ -82,24 +99,64 @@ :return: the decorated class or function. """ + # -- build the directive division + fmt = ".. {directive}:: {version}" if self.version else ".. {directive}::" + div_lines = [fmt.format(directive=self.directive, version=self.version)] + width = self.line_length - 3 if self.line_length > 3 else 2 ** 16 reason = textwrap.dedent(self.reason).strip() - reason = '\n'.join( - textwrap.fill(line, width=70, initial_indent=' ', subsequent_indent=' ') for line in reason.splitlines() - ).strip() + for paragraph in reason.splitlines(): + if paragraph: + div_lines.extend( + textwrap.fill( + paragraph, + width=width, + initial_indent=" ", + subsequent_indent=" ", + ).splitlines() + ) + else: + div_lines.append("") + + # -- get the docstring, normalize the trailing newlines docstring = textwrap.dedent(wrapped.__doc__ or "") if docstring: - docstring += "\n\n" - if self.version: - docstring += ".. {directive}:: {version}\n".format(directive=self.directive, version=self.version) + # An empty line must separate the original docstring and the directive. + docstring = re.sub(r"\n+$", "", docstring, flags=re.DOTALL) + "\n\n" else: - docstring += ".. {directive}::\n".format(directive=self.directive) - if reason: - docstring += " {reason}\n".format(reason=reason) + # Avoid "Explicit markup ends without a blank line" when the decorated function has no docstring + docstring = "\n" + + # -- append the directive division to the docstring + docstring += "".join("{}\n".format(line) for line in div_lines) + wrapped.__doc__ = docstring + if self.directive in {"versionadded", "versionchanged"}: + return wrapped return super(SphinxAdapter, self).__call__(wrapped) + def get_deprecated_msg(self, wrapped, instance): + """ + Get the deprecation warning message (without Sphinx cross-referencing syntax) for the user. + + :param wrapped: Wrapped class or function. + + :param instance: The object to which the wrapped function was bound when it was called. -def versionadded(reason="", version=""): + :return: The warning message. + + .. versionadded:: 1.2.12 + Strip Sphinx cross-referencing syntax from warning message. + + """ + msg = super(SphinxAdapter, self).get_deprecated_msg(wrapped, instance) + # Strip Sphinx cross reference syntax (like ":function:", ":py:func:" and ":py:meth:") + # Possible values are ":role:`foo`", ":domain:role:`foo`" + # where ``role`` and ``domain`` should match "[a-zA-Z]+" + msg = re.sub(r"(?: : [a-zA-Z]+ )? : [a-zA-Z]+ : (`[^`]*`)", r"\1", msg, flags=re.X) + return msg + + +def versionadded(reason="", version="", line_length=70): """ This decorator can be used to insert a "versionadded" directive in your function/class docstring in order to documents the @@ -114,9 +171,18 @@ the version number has the format "MAJOR.MINOR.PATCH", and, in the case of a new functionality, the "PATCH" component should be "0". + :type line_length: int + :param line_length: + Max line length of the directive text. If non nul, a long text is wrapped in several lines. + :return: the decorated function. """ - adapter = SphinxAdapter('versionadded', reason=reason, version=version) + adapter = SphinxAdapter( + 'versionadded', + reason=reason, + version=version, + line_length=line_length, + ) # noinspection PyUnusedLocal @wrapt.decorator(adapter=adapter) @@ -126,7 +192,7 @@ return wrapper -def versionchanged(reason="", version=""): +def versionchanged(reason="", version="", line_length=70): """ This decorator can be used to insert a "versionchanged" directive in your function/class docstring in order to documents the @@ -140,9 +206,18 @@ If you follow the `Semantic Versioning <https://semver.org/>`_, the version number has the format "MAJOR.MINOR.PATCH". + :type line_length: int + :param line_length: + Max line length of the directive text. If non nul, a long text is wrapped in several lines. + :return: the decorated function. """ - adapter = SphinxAdapter('versionchanged', reason=reason, version=version) + adapter = SphinxAdapter( + 'versionchanged', + reason=reason, + version=version, + line_length=line_length, + ) # noinspection PyUnusedLocal @wrapt.decorator(adapter=adapter) @@ -178,6 +253,9 @@ By default, the category class is :class:`~DeprecationWarning`, you can inherit this class to define your own deprecation warning category. + - "line_length": + Max line length of the directive text. If non nul, a long text is wrapped in several lines. + :return: the decorated function. """ directive = kwargs.pop('directive', 'deprecated') Binary files old/Deprecated-1.2.10/docs/source/_static/banner.png and new/Deprecated-1.2.12/docs/source/_static/banner.png differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/docs/source/conf.py new/Deprecated-1.2.12/docs/source/conf.py --- old/Deprecated-1.2.10/docs/source/conf.py 2020-05-13 22:20:55.000000000 +0200 +++ new/Deprecated-1.2.12/docs/source/conf.py 2021-01-17 10:57:45.000000000 +0100 @@ -61,7 +61,7 @@ # built documents. # # The full version, including alpha/beta/rc tags. -release = "1.2.10" +release = "1.2.12" # The short X.Y version. version = release.rpartition('.')[0] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/docs/source/installation.rst new/Deprecated-1.2.12/docs/source/installation.rst --- old/Deprecated-1.2.10/docs/source/installation.rst 2020-05-13 22:20:55.000000000 +0200 +++ new/Deprecated-1.2.12/docs/source/installation.rst 2020-12-18 13:36:37.000000000 +0100 @@ -28,7 +28,7 @@ * `pytest-cov`_ is a `pytest`_ plugin used to produce coverage reports. * `tox`_ aims to automate and standardize testing in Python. It is part of a larger vision of easing the packaging, testing and release process of Python software??? -* `bumpversion`_ is a small command line tool to simplify releasing software +* `bump2version`_ is a small command line tool to simplify releasing software by updating all version strings in your source code by the correct increment. Also creates commits and tags??? * `sphinx`_ is a tool that makes it easy to create intelligent and beautiful documentation. @@ -36,7 +36,7 @@ .. _pytest: https://docs.pytest.org/en/latest/ .. _pytest-cov: http://pytest-cov.readthedocs.io/en/latest/ .. _tox: https://tox.readthedocs.io/en/latest/ -.. _bumpversion: https://github.com/peritus/bumpversion +.. _bump2version: https://github.com/c4urself/bump2version .. _sphinx: http://www.sphinx-doc.org/en/stable/index.html diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/docs/source/sphinx/calc_mean.py new/Deprecated-1.2.12/docs/source/sphinx/calc_mean.py --- old/Deprecated-1.2.10/docs/source/sphinx/calc_mean.py 2020-04-05 22:17:11.000000000 +0200 +++ new/Deprecated-1.2.12/docs/source/sphinx/calc_mean.py 2020-12-18 13:28:10.000000000 +0100 @@ -2,7 +2,7 @@ """ Compute the arithmetic mean (???average???) of values. - :type values: list[float] + :type values: typing.List[float] :param values: List of floats :return: Mean of values. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/docs/source/sphinx/calc_mean_deco.py new/Deprecated-1.2.12/docs/source/sphinx/calc_mean_deco.py --- old/Deprecated-1.2.10/docs/source/sphinx/calc_mean_deco.py 2020-04-05 22:17:11.000000000 +0200 +++ new/Deprecated-1.2.12/docs/source/sphinx/calc_mean_deco.py 2020-12-18 13:28:10.000000000 +0100 @@ -9,7 +9,7 @@ """ Compute the arithmetic mean (???average???) of values. - :type values: list[float] + :type values: typing.List[float] :param values: List of floats :return: Mean of values. """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/docs/source/sphinx_deco.rst new/Deprecated-1.2.12/docs/source/sphinx_deco.rst --- old/Deprecated-1.2.10/docs/source/sphinx_deco.rst 2020-04-05 22:31:25.000000000 +0200 +++ new/Deprecated-1.2.12/docs/source/sphinx_deco.rst 2021-02-04 14:56:28.000000000 +0100 @@ -61,7 +61,7 @@ Compute the arithmetic mean (???average???) of values. - :type values: list[float] + :type values: typing.List[float] :param values: List of floats :return: Mean of values. @@ -151,6 +151,10 @@ commands = sphinx-build -b html -d {envtmpdir}/doctrees docs/source/ {envtmpdir}/html +.. hint:: + + You can see a sample implementation of Sphinx directives in the demo project + `Deprecated-Demo.Sphinx <https://github.com/tantale/deprecated-demo.sphinx>`_. .. rubric:: Footnotes diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/pyproject.toml new/Deprecated-1.2.12/pyproject.toml --- old/Deprecated-1.2.10/pyproject.toml 1970-01-01 01:00:00.000000000 +0100 +++ new/Deprecated-1.2.12/pyproject.toml 2020-12-18 15:05:04.000000000 +0100 @@ -0,0 +1,9 @@ +[tool.black] +line-length = 120 +skip-string-normalization = true +target-version = ['py27', 'py34', 'py35', 'py36', 'py37', 'py38'] +include = '\.pyi?$' + +[tool.isort] +line_length = 120 +force_single_line = true diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/python-deprecated.spec new/Deprecated-1.2.12/python-deprecated.spec --- old/Deprecated-1.2.10/python-deprecated.spec 2020-05-13 22:20:55.000000000 +0200 +++ new/Deprecated-1.2.12/python-deprecated.spec 2021-01-17 10:57:45.000000000 +0100 @@ -2,12 +2,12 @@ %global pkgname deprecated Name: python-%{pkgname} -Version: 1.2.10 +Version: 1.2.12 Release: 2%{?dist} Summary: Python decorator to deprecate old python classes, functions or methods License: MIT URL: https://github.com/tantale/%{pkgname} -Source0: https://files.pythonhosted.org/packages/source/D/%{srcname}/%{srcname}-%{version}.tar.gz +Source0: %{pypi_source} BuildArch: noarch %description @@ -38,7 +38,7 @@ %license LICENSE.rst %doc README.md %{python3_sitelib}/%{pkgname}/ -%{python3_sitelib}/%{srcname}-%{version}-*.egg-info/ +%{python3_sitelib}/%{srcname}-*.egg-info/ %changelog diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/setup.py new/Deprecated-1.2.12/setup.py --- old/Deprecated-1.2.10/setup.py 2020-05-13 22:20:55.000000000 +0200 +++ new/Deprecated-1.2.12/setup.py 2021-01-18 14:03:16.000000000 +0100 @@ -143,7 +143,7 @@ setup( name='Deprecated', - version='1.2.10', + version='1.2.12', url='https://github.com/tantale/deprecated', project_urls={ "Documentation": "https://deprecated.readthedocs.io/en/latest/", @@ -176,17 +176,26 @@ 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + # 'Programming Language :: Python :: 3.10', # scheduled on 2021-10-04 'Topic :: Software Development :: Libraries :: Python Modules', ], extras_require={ 'dev': [ 'tox', 'PyTest ; python_version >= "3.6"', - 'PyTest < 5 ; python_version < "3"', + 'PyTest < 5 ; python_version < "3.6"', 'PyTest-Cov ; python_version >= "3.6"', - 'PyTest-Cov < 2.6 ; python_version < "3"', - 'bumpversion < 1', + 'PyTest-Cov < 2.6 ; python_version < "3.6"', + 'bump2version < 1', 'sphinx < 2', + # Python 2.7 EOL: + 'importlib-metadata < 3 ; python_version < "3"', + 'importlib-resources < 4 ; python_version < "3"', + 'configparser < 5 ; python_version < "3"', + 'sphinxcontrib-websupport < 2 ; python_version < "3"', + 'zipp < 2 ; python_version < "3"', ] }, python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/tests/test_deprecated.py new/Deprecated-1.2.12/tests/test_deprecated.py --- old/Deprecated-1.2.10/tests/test_deprecated.py 2020-05-13 22:22:53.000000000 +0200 +++ new/Deprecated-1.2.12/tests/test_deprecated.py 2020-12-17 18:47:12.000000000 +0100 @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +import sys import warnings import pytest @@ -184,7 +185,10 @@ assert len(warns) == 1 warn = warns[0] assert issubclass(warn.category, DeprecationWarning) - assert "deprecated function (or staticmethod)" in str(warn.message) + if sys.version_info >= (3, 9): + assert "deprecated class method" in str(warn.message) + else: + assert "deprecated function (or staticmethod)" in str(warn.message) assert warn.filename == __file__, 'Incorrect warning stackLevel' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/tests/test_sphinx.py new/Deprecated-1.2.12/tests/test_sphinx.py --- old/Deprecated-1.2.10/tests/test_sphinx.py 2019-10-27 16:13:42.000000000 +0100 +++ new/Deprecated-1.2.12/tests/test_sphinx.py 2021-03-13 11:54:58.000000000 +0100 @@ -24,6 +24,7 @@ :return: sum = *x* + *y* """, ], + ids=["no_docstring", "short_docstring", "long_docstring"], ) def docstring(request): return request.param @@ -43,9 +44,9 @@ '1.2.0', textwrap.dedent( """\ - .. {directive}:: {version} - {reason} - """ + .. {directive}:: {version} + {reason} + """ ), ), ( @@ -53,21 +54,12 @@ '1.2.0', textwrap.dedent( """\ - .. {directive}:: {version} - """ - ), - ), - ( - 'A good reason', - None, - textwrap.dedent( - """\ - .. {directive}:: - {reason} - """ + .. {directive}:: {version} + """ ), ), ], + ids=["reason&version", "version"], ) def test_has_sphinx_docstring(docstring, directive, reason, version, expected): # The function: @@ -88,10 +80,23 @@ current = textwrap.dedent(foo.__doc__) assert current.endswith(expected) - # An empty line must separate the original docstring and the directive. current = current.replace(expected, '') - if current: + if docstring: + # An empty line must separate the original docstring and the directive. assert re.search("\n[ ]*\n$", current, flags=re.DOTALL) + else: + # Avoid "Explicit markup ends without a blank line" when the decorated function has no docstring + assert current == "\n" + + with warnings.catch_warnings(record=True) as warns: + foo(1, 2) + + if directive in {'versionadded', 'versionchanged'}: + # don't emit DeprecationWarning + assert len(warns) == 0 + else: + # emit DeprecationWarning + assert len(warns) == 1 # noinspection PyShadowingNames @@ -106,9 +111,9 @@ '1.2.0', textwrap.dedent( """\ - .. {directive}:: {version} - {reason} - """ + .. {directive}:: {version} + {reason} + """ ), ), ( @@ -116,21 +121,12 @@ '1.2.0', textwrap.dedent( """\ - .. {directive}:: {version} - """ - ), - ), - ( - 'A good reason', - None, - textwrap.dedent( - """\ - .. {directive}:: - {reason} - """ + .. {directive}:: {version} + """ ), ), ], + ids=["reason&version", "version"], ) def test_cls_has_sphinx_docstring(docstring, directive, reason, version, expected): # The class: @@ -151,10 +147,23 @@ current = textwrap.dedent(Foo.__doc__) assert current.endswith(expected) - # An empty line must separate the original docstring and the directive. current = current.replace(expected, '') - if current: + if docstring: + # An empty line must separate the original docstring and the directive. assert re.search("\n[ ]*\n$", current, flags=re.DOTALL) + else: + # Avoid "Explicit markup ends without a blank line" when the decorated function has no docstring + assert current == "\n" + + with warnings.catch_warnings(record=True) as warns: + Foo() + + if directive in {'versionadded', 'versionchanged'}: + # don't emit DeprecationWarning + assert len(warns) == 0 + else: + # emit DeprecationWarning + assert len(warns) == 1 class MyDeprecationWarning(DeprecationWarning): @@ -162,119 +171,71 @@ _PARAMS = [ - None, - ((), {}), - (('Good reason',), {}), - ((), {'reason': 'Good reason'}), - ((), {'version': '1.2.3'}), - ((), {'action': 'once'}), - ((), {'category': MyDeprecationWarning}), + {'version': '1.2.3'}, + {'version': '1.2.3', 'reason': 'Good reason'}, + {'version': '1.2.3', 'action': 'once'}, + {'version': '1.2.3', 'category': MyDeprecationWarning}, ] @pytest.fixture(scope="module", params=_PARAMS) def sphinx_deprecated_function(request): - if request.param is None: - - @deprecated.sphinx.deprecated - def foo1(): - pass + kwargs = request.param - return foo1 - else: - args, kwargs = request.param - - @deprecated.sphinx.deprecated(*args, **kwargs) - def foo1(): - pass + @deprecated.sphinx.deprecated(**kwargs) + def foo1(): + pass - return foo1 + return foo1 @pytest.fixture(scope="module", params=_PARAMS) def sphinx_deprecated_class(request): - if request.param is None: - - @deprecated.sphinx.deprecated - class Foo2(object): - pass - - return Foo2 - else: - args, kwargs = request.param + kwargs = request.param - @deprecated.sphinx.deprecated(*args, **kwargs) - class Foo2(object): - pass + @deprecated.sphinx.deprecated(**kwargs) + class Foo2(object): + pass - return Foo2 + return Foo2 @pytest.fixture(scope="module", params=_PARAMS) def sphinx_deprecated_method(request): - if request.param is None: - - class Foo3(object): - @deprecated.sphinx.deprecated - def foo3(self): - pass - - return Foo3 - else: - args, kwargs = request.param + kwargs = request.param - class Foo3(object): - @deprecated.sphinx.deprecated(*args, **kwargs) - def foo3(self): - pass + class Foo3(object): + @deprecated.sphinx.deprecated(**kwargs) + def foo3(self): + pass - return Foo3 + return Foo3 @pytest.fixture(scope="module", params=_PARAMS) def sphinx_deprecated_static_method(request): - if request.param is None: - - class Foo4(object): - @staticmethod - @deprecated.sphinx.deprecated - def foo4(): - pass - - return Foo4.foo4 - else: - args, kwargs = request.param + kwargs = request.param - class Foo4(object): - @staticmethod - @deprecated.sphinx.deprecated(*args, **kwargs) - def foo4(): - pass + class Foo4(object): + @staticmethod + @deprecated.sphinx.deprecated(**kwargs) + def foo4(): + pass - return Foo4.foo4 + return Foo4.foo4 @pytest.fixture(scope="module", params=_PARAMS) def sphinx_deprecated_class_method(request): - if request.param is None: - - class Foo5(object): - @classmethod - @deprecated.sphinx.deprecated - def foo5(cls): - pass - - return Foo5 - else: - args, kwargs = request.param + kwargs = request.param - class Foo5(object): - @classmethod - @deprecated.sphinx.deprecated(*args, **kwargs) - def foo5(cls): - pass + class Foo5(object): + @classmethod + @deprecated.sphinx.deprecated(**kwargs) + def foo5(cls): + pass - return Foo5 + return Foo5 # noinspection PyShadowingNames @@ -334,7 +295,10 @@ assert len(warns) == 1 warn = warns[0] assert issubclass(warn.category, DeprecationWarning) - assert "deprecated function (or staticmethod)" in str(warn.message) + if sys.version_info >= (3, 9): + assert "deprecated class method" in str(warn.message) + else: + assert "deprecated function (or staticmethod)" in str(warn.message) def test_should_raise_type_error(): @@ -348,7 +312,7 @@ def test_warning_msg_has_reason(): reason = "Good reason" - @deprecated.sphinx.deprecated(reason=reason) + @deprecated.sphinx.deprecated(version="4.5.6", reason=reason) def foo(): pass @@ -372,7 +336,7 @@ def test_warning_is_ignored(): - @deprecated.sphinx.deprecated(action='ignore') + @deprecated.sphinx.deprecated(version="4.5.6", action='ignore') def foo(): pass @@ -382,7 +346,7 @@ def test_specific_warning_cls_is_used(): - @deprecated.sphinx.deprecated(category=MyDeprecationWarning) + @deprecated.sphinx.deprecated(version="4.5.6", category=MyDeprecationWarning) def foo(): pass @@ -397,3 +361,55 @@ warnings.simplefilter("always") warnings.warn("A message in a bottle", category=DeprecationWarning, stacklevel=2) assert len(warns) == 1 + + +@pytest.mark.parametrize( + ["reason", "expected"], + [ + ("Use :function:`bar` instead", "Use `bar` instead"), + ("Use :py:func:`bar` instead", "Use `bar` instead"), + ], +) +def test_sphinx_syntax_trimming(reason, expected): + @deprecated.sphinx.deprecated(version="4.5.6", reason=reason) + def foo(): + pass + + with warnings.catch_warnings(record=True) as warns: + foo() + warn = warns[0] + assert expected in str(warn.message) + + +# noinspection SpellCheckingInspection +@pytest.mark.parametrize( + "reason, expected", + [ + # classic examples using the default domain (Python) + ("Use :func:`bar` instead", "Use `bar` instead"), + ("Use :function:`bar` instead", "Use `bar` instead"), + ("Use :class:`Baz` instead", "Use `Baz` instead"), + ("Use :exc:`Baz` instead", "Use `Baz` instead"), + ("Use :exception:`Baz` instead", "Use `Baz` instead"), + ("Use :meth:`Baz.bar` instead", "Use `Baz.bar` instead"), + ("Use :method:`Baz.bar` instead", "Use `Baz.bar` instead"), + # other examples using a domain : + ("Use :py:func:`bar` instead", "Use `bar` instead"), + ("Use :cpp:func:`bar` instead", "Use `bar` instead"), + ("Use :js:func:`bar` instead", "Use `bar` instead"), + # the reference can have special characters: + ("Use :func:`~pkg.mod.bar` instead", "Use `~pkg.mod.bar` instead"), + # edge cases: + ("Use :r:`` instead", "Use `` instead"), + ("Use :d:r:`` instead", "Use `` instead"), + ("Use :r:`foo` instead", "Use `foo` instead"), + ("Use :d:r:`foo` instead", "Use `foo` instead"), + ("Use r:`bad` instead", "Use r:`bad` instead"), + ("Use ::`bad` instead", "Use ::`bad` instead"), + ("Use :::`bad` instead", "Use :::`bad` instead"), + ], +) +def test_get_deprecated_msg(reason, expected): + adapter = deprecated.sphinx.SphinxAdapter("deprecated", reason=reason, version="1") + actual = adapter.get_deprecated_msg(lambda: None, None) + assert expected in actual diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/tests/test_sphinx_adapter.py new/Deprecated-1.2.12/tests/test_sphinx_adapter.py --- old/Deprecated-1.2.10/tests/test_sphinx_adapter.py 1970-01-01 01:00:00.000000000 +0100 +++ new/Deprecated-1.2.12/tests/test_sphinx_adapter.py 2021-02-04 14:56:28.000000000 +0100 @@ -0,0 +1,128 @@ +# coding: utf-8 +import textwrap + +import pytest + +from deprecated.sphinx import SphinxAdapter +from deprecated.sphinx import deprecated +from deprecated.sphinx import versionadded +from deprecated.sphinx import versionchanged + + +@pytest.mark.parametrize( + "line_length, expected", + [ + ( + 50, + textwrap.dedent( + """ + Description of foo + + :return: nothing + + .. {directive}:: 1.2.3 + foo has changed in this version + + bar bar bar bar bar bar bar bar bar bar bar + bar bar bar bar bar bar bar bar bar bar bar + bar + """ + ), + ), + ( + 0, + textwrap.dedent( + """ + Description of foo + + :return: nothing + + .. {directive}:: 1.2.3 + foo has changed in this version + + bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar bar + """ + ), + ), + ], + ids=["wrapped", "long"], +) +@pytest.mark.parametrize("directive", ["versionchanged", "versionadded", "deprecated"]) +def test_sphinx_adapter(directive, line_length, expected): + lines = [ + "foo has changed in this version", + "", # newline + "bar " * 23, # long line + "", # trailing newline + ] + reason = "\n".join(lines) + adapter = SphinxAdapter(directive, reason=reason, version="1.2.3", line_length=line_length) + + def foo(): + """ + Description of foo + + :return: nothing + """ + + wrapped = adapter.__call__(foo) + expected = expected.format(directive=directive) + assert wrapped.__doc__ == expected + + +@pytest.mark.parametrize("directive", ["versionchanged", "versionadded", "deprecated"]) +def test_sphinx_adapter__empty_docstring(directive): + lines = [ + "foo has changed in this version", + "", # newline + "bar " * 23, # long line + "", # trailing newline + ] + reason = "\n".join(lines) + adapter = SphinxAdapter(directive, reason=reason, version="1.2.3", line_length=50) + + def foo(): + pass + + wrapped = adapter.__call__(foo) + expected = textwrap.dedent( + """ + .. {directive}:: 1.2.3 + foo has changed in this version + + bar bar bar bar bar bar bar bar bar bar bar + bar bar bar bar bar bar bar bar bar bar bar + bar + """ + ) + expected = expected.format(directive=directive) + assert wrapped.__doc__ == expected + + +@pytest.mark.parametrize( + "decorator_factory, directive", + [ + (versionadded, "versionadded"), + (versionchanged, "versionchanged"), + (deprecated, "deprecated"), + ], +) +def test_decorator_accept_line_length(decorator_factory, directive): + reason = "bar " * 30 + decorator = decorator_factory(reason=reason, version="1.2.3", line_length=50) + + def foo(): + pass + + foo = decorator(foo) + + expected = textwrap.dedent( + """ + .. {directive}:: 1.2.3 + bar bar bar bar bar bar bar bar bar bar bar + bar bar bar bar bar bar bar bar bar bar bar + bar bar bar bar bar bar bar bar + """ + ) + expected = expected.format(directive=directive) + assert foo.__doc__ == expected diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/tests/test_sphinx_class.py new/Deprecated-1.2.12/tests/test_sphinx_class.py --- old/Deprecated-1.2.10/tests/test_sphinx_class.py 2019-10-27 16:35:43.000000000 +0100 +++ new/Deprecated-1.2.12/tests/test_sphinx_class.py 2021-02-04 15:13:27.000000000 +0100 @@ -45,7 +45,7 @@ sys.version_info < (3, 3), reason="Classes should have mutable docstrings -- resolved in python 3.3" ) def test_class_deprecation_using_deprecated_decorator(): - @deprecated.sphinx.deprecated + @deprecated.sphinx.deprecated(version="7.8.9") class MyBaseClass(object): pass @@ -66,11 +66,11 @@ sys.version_info < (3, 3), reason="Classes should have mutable docstrings -- resolved in python 3.3" ) def test_subclass_deprecation_using_deprecated_decorator(): - @deprecated.sphinx.deprecated + @deprecated.sphinx.deprecated(version="7.8.9") class MyBaseClass(object): pass - @deprecated.sphinx.deprecated + @deprecated.sphinx.deprecated(version="7.8.9") class MySubClass(MyBaseClass): pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Deprecated-1.2.10/tox.ini new/Deprecated-1.2.12/tox.ini --- old/Deprecated-1.2.10/tox.ini 2020-05-13 22:33:49.000000000 +0200 +++ new/Deprecated-1.2.12/tox.ini 2021-01-18 13:36:18.000000000 +0100 @@ -11,18 +11,18 @@ # - /usr/local/bin/pypy -> /opt/pypy2.7-v7.3.0-osx64/bin/pypy # - /usr/local/bin/pypy3 -> /opt/pypy3.6-v7.3.0-osx64/bin/pypy3 envlist = - py{27,35,36,37,38,39}-wrapt{1.10,1.11,1.12} + py{27,34,35,36,37,38,39,310}-wrapt{1.10,1.11,1.12} pypy, pypy3 docs [testenv] commands = pytest --cov-report term-missing --cov=deprecated tests/ deps = - py27,py35: pip >= 9.0.3, < 19.2 - py27: PyTest < 5 - py35,py36,py37,py38,pypy,pypy3: PyTest - py27: PyTest-Cov < 2.6 - py35,py36,py37,py38,py39,pypy,pypy3: PyTest-Cov + py27,py34,py35: pip >= 9.0.3, < 19.2 + py27,py34: PyTest < 5 + py35,py36,py37,py38,py39,pypy,pypy3: PyTest + py27,py34: PyTest-Cov < 2.6 + py35,py36,py37,py38,py39,py310,pypy,pypy3: PyTest-Cov wrapt1.10: wrapt ~= 1.10.0 wrapt1.11: wrapt ~= 1.11.0 wrapt1.12: wrapt ~= 1.12.0