summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorGregory P. Smith <greg@krypto.org>2015-04-14 19:56:53 (GMT)
committerGregory P. Smith <greg@krypto.org>2015-04-14 19:56:53 (GMT)
commite334e3ff714502a25c3270bd4cb4d9a699076deb (patch)
tree6320908ce22dea096f84d2d11a02ff5f1a829405 /Lib
parenta8b120641bd286bb0be663c5486077e2e61863ba (diff)
downloadcpython-e334e3ff714502a25c3270bd4cb4d9a699076deb.zip
cpython-e334e3ff714502a25c3270bd4cb4d9a699076deb.tar.gz
cpython-e334e3ff714502a25c3270bd4cb4d9a699076deb.tar.bz2
issue9859: Adds a test.support.detect_api_mismatch function useful to
compare the public APIs of two modules or classes.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/support/__init__.py17
-rw-r--r--Lib/test/test_support.py42
2 files changed, 58 insertions, 1 deletions
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index 1d0f11f..b9fda11 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -88,7 +88,7 @@ __all__ = [
"skip_unless_symlink", "requires_gzip", "requires_bz2", "requires_lzma",
"bigmemtest", "bigaddrspacetest", "cpython_only", "get_attribute",
"requires_IEEE_754", "skip_unless_xattr", "requires_zlib",
- "anticipate_failure", "load_package_tests",
+ "anticipate_failure", "load_package_tests", "detect_api_mismatch",
# sys
"is_jython", "check_impl_detail",
# network
@@ -2184,6 +2184,21 @@ def fs_is_case_insensitive(directory):
return False
+def detect_api_mismatch(ref_api, other_api, *, ignore=None):
+ """Returns the set of items in ref_api not in other_api, except for a
+ defined list of items to be ignored in this check.
+
+ By default this skips private attributes beginning with '_' but
+ includes all magic methods, i.e. those starting and ending in '__'.
+ """
+ missing_items = set(dir(ref_api)) - set(dir(other_api))
+ if ignore:
+ missing_items -= set(ignore)
+ missing_items = set(m for m in missing_items
+ if not m.startswith('_') or m.endswith('__'))
+ return missing_items
+
+
class SuppressCrashReport:
"""Try to prevent a crash report from popping up.
diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py
index a02d2f4..4a27c44 100644
--- a/Lib/test/test_support.py
+++ b/Lib/test/test_support.py
@@ -280,6 +280,48 @@ class TestSupport(unittest.TestCase):
self.assertEqual(D["item"], 5)
self.assertEqual(D["item"], 1)
+ def test_detect_api_mismatch(self):
+ class RefClass:
+ attribute1 = None
+ attribute2 = None
+ _hidden_attribute1 = None
+ __magic_1__ = None
+
+ class OtherClass:
+ attribute2 = None
+ attribute3 = None
+ __magic_1__ = None
+ __magic_2__ = None
+
+ missing_items = support.detect_api_mismatch(RefClass, OtherClass)
+ self.assertEqual({'attribute1'}, missing_items)
+
+ missing_items = support.detect_api_mismatch(OtherClass, RefClass)
+ self.assertEqual({'attribute3', '__magic_2__'}, missing_items)
+
+ def test_detect_api_mismatch__ignore(self):
+ class RefClass:
+ attribute1 = None
+ attribute2 = None
+ _hidden_attribute1 = None
+ __magic_1__ = None
+
+ class OtherClass:
+ attribute2 = None
+ attribute3 = None
+ __magic_1__ = None
+ __magic_2__ = None
+
+ ignore = ['attribute1', 'attribute3', '__magic_2__', 'not_in_either']
+
+ missing_items = support.detect_api_mismatch(RefClass, OtherClass,
+ ignore=ignore)
+ self.assertEqual(set(), missing_items)
+
+ missing_items = support.detect_api_mismatch(OtherClass, RefClass,
+ ignore=ignore)
+ self.assertEqual(set(), missing_items)
+
# XXX -follows a list of untested API
# make_legacy_pyc
# is_resource_enabled