aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Stapleton <alexs@prol.etari.at>2015-01-03 10:17:57 +0000
committerAlex Stapleton <alexs@prol.etari.at>2015-01-03 10:17:57 +0000
commitb23a554dc5a6b71c3b543714d61a70fdf59c5ad1 (patch)
treefd3736d0403205effd0d0b6516f2da1992b07d01
parent5ffea405885710c6836d1318c00b67162cb4faf9 (diff)
parent75341e185b48100b9acda696d173990e6eb4624c (diff)
downloadcryptography-b23a554dc5a6b71c3b543714d61a70fdf59c5ad1.tar.gz
cryptography-b23a554dc5a6b71c3b543714d61a70fdf59c5ad1.tar.bz2
cryptography-b23a554dc5a6b71c3b543714d61a70fdf59c5ad1.zip
Merge pull request #1600 from alex/deprecated
Added a utility for deprecating a module attribute
-rw-r--r--src/cryptography/utils.py41
-rw-r--r--tests/test_warnings.py47
2 files changed, 84 insertions, 4 deletions
diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py
index ac2f787d..72f9a347 100644
--- a/src/cryptography/utils.py
+++ b/src/cryptography/utils.py
@@ -7,12 +7,17 @@ from __future__ import absolute_import, division, print_function
import abc
import inspect
import sys
+import warnings
# DeprecatedIn07 objects exist. This comment exists to remind developers to
# look for them when it's time for the ninth release cycle deprecation dance.
+def read_only_property(name):
+ return property(lambda self: getattr(self, name))
+
+
def register_interface(iface):
def register_decorator(klass):
verify_interface(iface, klass)
@@ -21,10 +26,6 @@ def register_interface(iface):
return register_decorator
-def read_only_property(name):
- return property(lambda self: getattr(self, name))
-
-
class InterfaceNotImplemented(Exception):
pass
@@ -55,3 +56,35 @@ if sys.version_info >= (2, 7):
else:
def bit_length(x):
return len(bin(x)) - (2 + (x <= 0))
+
+
+class _DeprecatedValue(object):
+ def __init__(self, value, message, warning_class):
+ self.value = value
+ self.message = message
+ self.warning_class = warning_class
+
+
+class _ModuleWithDeprecations(object):
+ def __init__(self, module):
+ self.__dict__["_module"] = module
+
+ def __getattr__(self, attr):
+ obj = getattr(self._module, attr)
+ if isinstance(obj, _DeprecatedValue):
+ warnings.warn(obj.message, obj.warning_class, stacklevel=2)
+ obj = obj.value
+ return obj
+
+ def __setattr__(self, attr, value):
+ setattr(self._module, attr, value)
+
+ def __dir__(self):
+ return ["_module"] + dir(self._module)
+
+
+def deprecated(value, module_name, message, warning_class):
+ module = sys.modules[module_name]
+ if not isinstance(module, _ModuleWithDeprecations):
+ sys.modules[module_name] = module = _ModuleWithDeprecations(module)
+ return _DeprecatedValue(value, message, warning_class)
diff --git a/tests/test_warnings.py b/tests/test_warnings.py
new file mode 100644
index 00000000..9946baa7
--- /dev/null
+++ b/tests/test_warnings.py
@@ -0,0 +1,47 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+
+from __future__ import absolute_import, division, print_function
+
+import sys
+import types
+import warnings
+
+from cryptography.utils import deprecated
+
+
+class TestDeprecated(object):
+ def test_deprecated(self, monkeypatch):
+ mod = types.ModuleType("TestDeprecated/test_deprecated")
+ monkeypatch.setitem(sys.modules, mod.__name__, mod)
+ mod.X = deprecated(
+ value=1,
+ module_name=mod.__name__,
+ message="deprecated message text",
+ warning_class=DeprecationWarning
+ )
+ mod.Y = deprecated(
+ value=2,
+ module_name=mod.__name__,
+ message="more deprecated text",
+ warning_class=PendingDeprecationWarning,
+ )
+ mod = sys.modules[mod.__name__]
+ mod.Z = 3
+
+ with warnings.catch_warnings(record=True) as log:
+ warnings.simplefilter("always", PendingDeprecationWarning)
+ warnings.simplefilter("always", DeprecationWarning)
+ assert mod.X == 1
+ assert mod.Y == 2
+ assert mod.Z == 3
+
+ [msg1, msg2] = log
+ assert msg1.category is DeprecationWarning
+ assert msg1.message.args == ("deprecated message text",)
+
+ assert msg2.category is PendingDeprecationWarning
+ assert msg2.message.args == ("more deprecated text",)
+
+ assert "Y" in dir(mod)