Code Monkey home page Code Monkey logo

deprecation's People

Contributors

aakum03 avatar bdice avatar briancurtin avatar debosmit avatar domdfcoding avatar dotlambda avatar fl4m3ph03n1x avatar javierpena avatar kmuehlbauer avatar nicfit avatar nodakai avatar nsoranzo avatar radeklat avatar sbraz avatar toabctl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

deprecation's Issues

Allow removed_in to be a date

Depending on the versioning scheme used by a project, it can be difficult to tell in advance the version number at which code can be removed. Sometimes, though, it is easier to tell when it should be removed. Google Guava, for example, guarantees all methods marked deprecated will be kept around for two years post-deprecation.

It would be convenient to handle this by allowing a date (in some TBD format) to be passed for the removed_in argument.

Gentle plea for merging deprecation and deprecated packages

This just doesn’t make sense. Two tiny packages which do the same, both of them have to be packaged for all Linux/other distributions, all of them checked for security or whatever-else issues. Could you please guys join the effort?

Thank you.

Get proper versioning into docs

__version__ = "1.0" at the top of deprecation.py and the hardcoded 1.0 in the docs/conf.py file should be replaced with something that makes it nice.

2.1.0: test suite is usnig `unittest2`

unittest2 is no longer maintained anbd should not be used with python 3.x

+ /usr/bin/pytest -ra
=========================================================================== test session starts ============================================================================
platform linux -- Python 3.8.12, pytest-6.2.5, py-1.10.0, pluggy-0.13.1
benchmark: 3.4.1 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=0.000005 max_time=1.0 calibration_precision=10 warmup=False warmup_iterations=100000)
Using --randomly-seed=9223936
rootdir: /home/tkloczko/rpmbuild/BUILD/deprecation-2.1.0
plugins: forked-1.3.0, shutil-1.7.0, virtualenv-1.7.0, expect-1.1.0, flake8-1.0.7, timeout-1.4.2, betamax-0.8.1, freezegun-0.4.2, aspectlib-1.5.2, toolbox-0.5, rerunfailures-9.1.1, requests-mock-1.9.3, cov-2.12.1, flaky-3.7.0, benchmark-3.4.1, xdist-2.3.0, pylama-7.7.1, datadir-1.3.1, regressions-2.2.0, xprocess-0.18.1, black-0.3.12, asyncio-0.15.1, subtests-0.5.0, isort-2.0.0, hypothesis-6.14.6, mock-3.6.1, profiling-1.7.0, randomly-3.8.0, nose2pytest-1.0.8, pyfakefs-4.5.1, tornado-0.8.1, twisted-1.13.3, aiohttp-0.3.0, localserver-0.5.0, anyio-3.3.1, trio-0.7.0, cases-3.6.4, yagot-0.5.0, Faker-8.14.0
collected 0 items / 1 error

================================================================================== ERRORS ==================================================================================
________________________________________________________________ ERROR collecting tests/test_deprecation.py ________________________________________________________________
ImportError while importing test module '/home/tkloczko/rpmbuild/BUILD/deprecation-2.1.0/tests/test_deprecation.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/usr/lib64/python3.8/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
tests/test_deprecation.py:15: in <module>
    import unittest2
E   ModuleNotFoundError: No module named 'unittest2'
========================================================================= short test summary info ==========================================================================
ERROR tests/test_deprecation.py
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
============================================================================= 1 error in 0.28s =============================================================================
pytest-xprocess reminder::Be sure to terminate the started process by running 'pytest --xkill' if you have not explicitly done so in your fixture with 'xprocess.getinfo(<process_name>).terminate()'.

fail_if_not_removed decorator does not work for async methods

I am using anyio with asyncio. It seems to me that the decorator messes with the async frameworks and causes the test to be skipped.

Example 1: this test is ignored with "SKIPPED (async def function and no async plugin installed (see warnings))"

import deprecation
import pytest


@deprecation.fail_if_not_removed
@pytest.mark.anyio
async def test_async():
    assert True

Example 2: If I switch the decorators around, I see another message in addition: "coroutine 'test_async' was never awaited":

import deprecation
import pytest


@pytest.mark.anyio
@deprecation.fail_if_not_removed
async def test_async():
    assert True

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 1918: ordinal not in range(128)

When trying to package (RPM packaging) the deprecation module, I get:

[    5s] + '[' -d _build.python3 ']'
[    5s] + echo python3
[    5s] + /usr/bin/python3 setup.py build '--executable=/usr/bin/python3 -s'
[    5s] Traceback (most recent call last):
[    5s]   File "setup.py", line 17, in <module>
[    5s]     long_description=open("README.rst").read(),
[    5s]   File "/usr/lib64/python3.6/encodings/ascii.py", line 26, in decode
[    5s]     return codecs.ascii_decode(input, self.errors)[0]
[    5s] UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 1918: ordinal not in range(128)
[    5s] error: Bad exit status from /var/tmp/rpm-tmp.5z1jLX (%build)
[    5s] 

Deprecating classes with subclasses

Deprecation decorator doesn't work on classes if the class being deprecated has a subclass that inherits from it, even if all the subclasses are marked deprecated as well.

Pip install not working and PyPi info data not loading when whl file uploaded to artifactory.

When I load other libraries (see my attached chardet-3.0.4-py2.py3-none-any.whl example) into artifactory and then click on the PyPi info I see what is shown in the attachment, valid PyPi information. I am then able to pip install the file from our internal artifactory server.
When I load deprecation version 2.0 everything works fine (see attachment).
But when I load deprecation versions after 2.0 (2.0.1 and 2.0.2) I don't get the PyPi information when clicking on the tab in artifactory (see attachment) and I am unable to access it from pip install.
pypi-chardet-example
pypi-deprecation-2 0-example
pypi-deprecation-2 0 2-example

Support deprecation of (module level) variables

Hi. I just hit and interesting use case that I was not able to solve with this library. There is a module level variable and it's name has changed. Since is is not a function, I cannot decorate it with @deprecated(...).

I searched for possible solutions and found a couple of them in here: https://stackoverflow.com/questions/922550/how-to-mark-a-global-as-deprecated-in-python I liked the second solution with the Deprecated class, becasue it is similar to @deprecated(...) and would allow to have the same interface.

I'm considering making a pull request but would like to check first if there would be an appetite for that.

Add support for nose to tox/travis configs

#30 mentions a situation where the test decorator doesn't work properly with nose. We should support nose in tox and travis so that this fix doesn't end up being a regression later on if someone changes that name or refactors it. This should be done in addition to the current setup that uses unittest discovery.

deprecation_note brakes docstring processing

While joining the function.__doc__-string with the deprecation_note-string the indentation isn't handled properly. Let's look at this example:

@deprecated(deprecated_in="0.0.3", removed_in="0.1.0",
            current_version="0.0.4",
            details="Do not use this function any more.")
def testfunc():
    """Test function.

    Returns
    -------
    name : str
        Some string
    """
    return "Teststring"

def newfunc():
    """Test function.

    Returns
    -------
    name : str
        Some string
    """
    return "Teststring"

Output of help(testfunc) (broken):

testfunc()
    Test function.
    
        Returns
        -------
        name : str
            Some string
        
    
    *Deprecated in 0.0.3, to be removed in 0.1.0. Do not use this function any more.*

Output of help(newfunc) (correct):

newfunc()
    Test function.
    
    Returns
    -------
    name : str
        Some string

The indentation of the function (numpy-style) docstring has been broken by the addition of the deprecation_note. While this might seem like a minor cosmetic issue, this breaks proper docstring processing in eg. sphinx.

Feature: Issue DeprecationWarnings/DeprecationErrors when calling API changes

Here I would like to discuss the possibility to extend the functionality of this package to notice about forthcoming API changes and the like.

In many cases functions/classes/methods (you name it) are not deprecated but a change in the API will take place. So it would be useful to warn the user about forthcoming changes with a special decorator.

We used this in the past in our package but would like to see it added here, where it belongs (IMHO). Please have a look at possible use cases here.

The current code would naturally need quite bit of lifting to adapt it to this packages style.

Thoughts?

"deprecation" package name is taken

There's currently an issue that https://pypi.python.org/pypi/deprecation is taken on PyPI, but it was done by a developer who seems like they started a project and then dropped it. There's one release you can see from the PyPI simple index that is effectively a NotImplementedError package to reserve the name.

I've reached out to that person to see if I can use the package name, and eventually something like PEP 541 could be helpful here.

fail_if_not_removed interferes with pytest fixtures

Decorating a test with fail_if_not_removed when the test expects a pytest fixture causes a TypeError due to a missing argument.

For example:

@deprecation.fail_if_not_removed
def test_get_pt_bounds(peak):
    peak.get_pt_bounds()

Results in:

../../../../.local/lib/python3.6/site-packages/deprecation.py:264 (test_get_pt_bounds)
args = (), kwargs = {}, caught_warnings = []

    def test_inner(*args, **kwargs):
        with warnings.catch_warnings(record=True) as caught_warnings:
            warnings.simplefilter("always")
>           rv = method(*args, **kwargs)
E           TypeError: test_get_pt_bounds() missing 1 required positional argument: 'peak'

/home/domdf/.local/lib/python3.6/site-packages/deprecation.py:268: TypeError

From the documentation I can't see an alternative way to pass the fixture to the test

Allow wrapping `.. deprecated::` directive in admonitions

I'd like the ability to wrap deprecation warnings within another sphinx admonition such as info or warning. My idea is to have an admonition argument in deprecated() which defaults to None but optionally takes the name of an admonition. The results would be as follows:

@deprecated(deprecated_in="1.0", details="This function is deprecated")
def my_func():
    """Docstring for the function"""

# leads to the following docstring:
"""Docstring for the function

.. deprecated::1.0
    This function is deprecated
"""

# versus
@deprecated(deprecated_in="1.0", details="This function is deprecated", admonition='warning')
def my_func():
    """Docstring for the function"""

# leads to the following docstring:
"""Docstring for the function

.. warning::
  .. deprecated::1.0
      This function is deprecated
"""

I already have clone with this implemented, the patch is very straightforward. If you agree to implement this I can make a PR.

Happy to change the name of the argument if you prefer as well.

Installed version "2.0.2", but the loaded package said "1.0"

[kimyentruong@sage-mac0045:~/Documents/synapsePythonClient] $python
Python 3.6.2 (default, Jul 17 2017, 16:44:45) 
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import deprecation
>>> deprecation.__version__
'1.0'
[kimyentruong@sage-mac0045:~/Documents/synapsePythonClient] $pip3 show deprecation
Name: deprecation
Version: 2.0.2
Summary: A library to handle automated deprecations
Home-page: http://deprecation.readthedocs.io/
Author: Brian Curtin
Author-email: [email protected]
License: Apache 2
Location: /usr/local/lib/python3.6/site-packages
Requires: packaging
Required-by: 

Allow decorating without argument list

Minor usability issue, should be easy to fix.

Tried using it today and got a weird error.

Traceback (most recent call last):
  ...
  File "/home/.../lib/python3.7/site-packages/deprecation.py", line 232, in _function_wrapper
    function.__doc__ = "".join(string_list)
AttributeError: 'list' object attribute '__doc__' is read-only

This was easily resolved by changing the decorating line from @deprecated to @deprecated(), but expected behavior for most decorators (ime) is to behave identically if arguments were given or not.

If you're fine with this @briancurtin I'll make a PR.

args not set on warning

>>> warn = deprecation.DeprecatedWarning("depricated", 1, 2)
>>> warn.args
()

currently warnings generated through this module do not set the args property. This is making the library incomparable with the latest release of pytest-xdist since they are using those args as a way of recreating the warning on the manager thread.

DeprecatedWarning.__str__ should handle None arguments better

DeprecatedWarning.__str__doesn't play nicely with None values, such as what happens when you call deprecation.deprecated() with no arguments. This ends up showing up in the interpreter messages when run with python -Wd, though it doesn't affect docstrings.

/.../deprecation.py:183: DeprecatedWarning: fn is deprecated as of None and will be removed in None. 
  warnings.warn(the_warning)

Feature: Specify what replaces an API call...

This looks quite interesting; however, it'd be highly beneficial to be able to optionally specify what is replacing the call.

import deprecation

@deprecation.deprecated(deprecated_in="1.0", removed_in="2.0",
                        current_version=__version__,
                        details="Reasoning for change", replaced_by=bar)
def foo():
    """Do some stuff"""
    return bar()

def bar():
    """Do some stuff using new API"""
    return 1

details could probably be used more for reasoning behind the change while replaced_by could be used to explicitly note the new method if it was provided.

NOTE: replaced_by could either be an object or a string. If an object then the string could be formed via '.'.join([replaced_by.__module__, replaced_by.__name__]).

Output text related to replaced_by should simply be:

Please update usage of "foo" to "bar".

Reasoning: By calling out explicitly this way some uniformity is provided in the messaging to users.
Yes, this could be achieved by details but then the calling project would have to implement a standard on how to write out details in a way that clearly communicates the change to the user. By reserving details for more detailed reasoning (ex: foo had a security issue and needed to go away because X) and taking in replaced_by type argument the updated API can be consistently and reliably communicated.

NOTE: This might be one aspect of #17, but it probably stands on its own since (a) it could be achieved without #17 and (b) #17 would only enhance the capability.

fail_if_not_removed hides tests from nose runner

Unit tests marked with the fail_if_not_removed decorator are not discovered by nose, because the test methods are renamed by the decorator to _inner and that does not match the default nose pattern.

Tested solution:
In fail_if_not_removed, return test_inner instead of _inner.

Choking on version strings from setuptools_scm

When a project uses the setuptools_scm package to create version number strings fromSCM automatically, the version strings look like: 0.11.2.dev208+g1e95728.d20171223. Using these version strings with the deprecation module causes things to fail:

tests/block/test_block.py:1: in <module>
    import lz4.block
.tox/py/lib/python3.6/site-packages/lz4/__init__.py:14: in <module>
    details="Use the lz4.library_version_number function instead")
.tox/py/lib/python3.6/site-packages/deprecation.py:131: in deprecated
    current_version = version.StrictVersion(current_version)
/usr/lib64/python3.6/distutils/version.py:40: in __init__
    self.parse(vstring)
/usr/lib64/python3.6/distutils/version.py:137: in parse
    raise ValueError("invalid version number '%s'" % vstring)
E   ValueError: invalid version number '0.11.2.dev208+g1e95728.d20171223'

This is caused by this piece of code:

@deprecated(deprecated_in="0.14", removed_in="1.0",
            current_version=VERSION,
            details="Use the lz4.library_version_number function instead")

Removing the current_version argument resolves the problem but of course then you lose the ability to raise exceptions when a function hasn't been removed.

It would probably be better to use packaging.version.parse for version string comparisons, which is the standard used by setuptools, I think.

Support for Python >= 3.8

I see in pypi that this library is not supported in Python >= 3.8
Is there a reason for this?
What can be done to change it?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.