mirror of
https://github.com/python/cpython.git
synced 2025-09-27 02:39:58 +00:00
Issue #23883: Add test.support.check__all__() and test gettext.__all__
Patches by Jacek Kołodziej.
This commit is contained in:
parent
63c1ebb67b
commit
d226d308a3
5 changed files with 132 additions and 0 deletions
|
@ -580,6 +580,48 @@ The :mod:`test.support` module defines the following functions:
|
||||||
.. versionadded:: 3.5
|
.. versionadded:: 3.5
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: check__all__(test_case, module, name_of_module=None, extra=(), blacklist=())
|
||||||
|
|
||||||
|
Assert that the ``__all__`` variable of *module* contains all public names.
|
||||||
|
|
||||||
|
The module's public names (its API) are detected automatically
|
||||||
|
based on whether they match the public name convention and were defined in
|
||||||
|
*module*.
|
||||||
|
|
||||||
|
The *name_of_module* argument can specify (as a string or tuple thereof) what
|
||||||
|
module(s) an API could be defined in in order to be detected as a public
|
||||||
|
API. One case for this is when *module* imports part of its public API from
|
||||||
|
other modules, possibly a C backend (like ``csv`` and its ``_csv``).
|
||||||
|
|
||||||
|
The *extra* argument can be a set of names that wouldn't otherwise be automatically
|
||||||
|
detected as "public", like objects without a proper ``__module__``
|
||||||
|
attribute. If provided, it will be added to the automatically detected ones.
|
||||||
|
|
||||||
|
The *blacklist* argument can be a set of names that must not be treated as part of
|
||||||
|
the public API even though their names indicate otherwise.
|
||||||
|
|
||||||
|
Example use::
|
||||||
|
|
||||||
|
import bar
|
||||||
|
import foo
|
||||||
|
import unittest
|
||||||
|
from test import support
|
||||||
|
|
||||||
|
class MiscTestCase(unittest.TestCase):
|
||||||
|
def test__all__(self):
|
||||||
|
support.check__all__(self, foo)
|
||||||
|
|
||||||
|
class OtherTestCase(unittest.TestCase):
|
||||||
|
def test__all__(self):
|
||||||
|
extra = {'BAR_CONST', 'FOO_CONST'}
|
||||||
|
blacklist = {'baz'} # Undocumented name.
|
||||||
|
# bar imports part of its API from _bar.
|
||||||
|
support.check__all__(self, bar, ('bar', '_bar'),
|
||||||
|
extra=extra, blacklist=blacklist)
|
||||||
|
|
||||||
|
.. versionadded:: 3.6
|
||||||
|
|
||||||
|
|
||||||
The :mod:`test.support` module defines the following classes:
|
The :mod:`test.support` module defines the following classes:
|
||||||
|
|
||||||
.. class:: TransientResource(exc, **kwargs)
|
.. class:: TransientResource(exc, **kwargs)
|
||||||
|
|
|
@ -26,6 +26,7 @@ import sys
|
||||||
import sysconfig
|
import sysconfig
|
||||||
import tempfile
|
import tempfile
|
||||||
import time
|
import time
|
||||||
|
import types
|
||||||
import unittest
|
import unittest
|
||||||
import urllib.error
|
import urllib.error
|
||||||
import warnings
|
import warnings
|
||||||
|
@ -89,6 +90,7 @@ __all__ = [
|
||||||
"bigmemtest", "bigaddrspacetest", "cpython_only", "get_attribute",
|
"bigmemtest", "bigaddrspacetest", "cpython_only", "get_attribute",
|
||||||
"requires_IEEE_754", "skip_unless_xattr", "requires_zlib",
|
"requires_IEEE_754", "skip_unless_xattr", "requires_zlib",
|
||||||
"anticipate_failure", "load_package_tests", "detect_api_mismatch",
|
"anticipate_failure", "load_package_tests", "detect_api_mismatch",
|
||||||
|
"check__all__",
|
||||||
# sys
|
# sys
|
||||||
"is_jython", "check_impl_detail",
|
"is_jython", "check_impl_detail",
|
||||||
# network
|
# network
|
||||||
|
@ -2199,6 +2201,65 @@ def detect_api_mismatch(ref_api, other_api, *, ignore=()):
|
||||||
return missing_items
|
return missing_items
|
||||||
|
|
||||||
|
|
||||||
|
def check__all__(test_case, module, name_of_module=None, extra=(),
|
||||||
|
blacklist=()):
|
||||||
|
"""Assert that the __all__ variable of 'module' contains all public names.
|
||||||
|
|
||||||
|
The module's public names (its API) are detected automatically based on
|
||||||
|
whether they match the public name convention and were defined in
|
||||||
|
'module'.
|
||||||
|
|
||||||
|
The 'name_of_module' argument can specify (as a string or tuple thereof)
|
||||||
|
what module(s) an API could be defined in in order to be detected as a
|
||||||
|
public API. One case for this is when 'module' imports part of its public
|
||||||
|
API from other modules, possibly a C backend (like 'csv' and its '_csv').
|
||||||
|
|
||||||
|
The 'extra' argument can be a set of names that wouldn't otherwise be
|
||||||
|
automatically detected as "public", like objects without a proper
|
||||||
|
'__module__' attriubute. If provided, it will be added to the
|
||||||
|
automatically detected ones.
|
||||||
|
|
||||||
|
The 'blacklist' argument can be a set of names that must not be treated
|
||||||
|
as part of the public API even though their names indicate otherwise.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
import bar
|
||||||
|
import foo
|
||||||
|
import unittest
|
||||||
|
from test import support
|
||||||
|
|
||||||
|
class MiscTestCase(unittest.TestCase):
|
||||||
|
def test__all__(self):
|
||||||
|
support.check__all__(self, foo)
|
||||||
|
|
||||||
|
class OtherTestCase(unittest.TestCase):
|
||||||
|
def test__all__(self):
|
||||||
|
extra = {'BAR_CONST', 'FOO_CONST'}
|
||||||
|
blacklist = {'baz'} # Undocumented name.
|
||||||
|
# bar imports part of its API from _bar.
|
||||||
|
support.check__all__(self, bar, ('bar', '_bar'),
|
||||||
|
extra=extra, blacklist=blacklist)
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
if name_of_module is None:
|
||||||
|
name_of_module = (module.__name__, )
|
||||||
|
elif isinstance(name_of_module, str):
|
||||||
|
name_of_module = (name_of_module, )
|
||||||
|
|
||||||
|
expected = set(extra)
|
||||||
|
|
||||||
|
for name in dir(module):
|
||||||
|
if name.startswith('_') or name in blacklist:
|
||||||
|
continue
|
||||||
|
obj = getattr(module, name)
|
||||||
|
if (getattr(obj, '__module__', None) in name_of_module or
|
||||||
|
(not hasattr(obj, '__module__') and
|
||||||
|
not isinstance(obj, types.ModuleType))):
|
||||||
|
expected.add(name)
|
||||||
|
test_case.assertCountEqual(module.__all__, expected)
|
||||||
|
|
||||||
|
|
||||||
class SuppressCrashReport:
|
class SuppressCrashReport:
|
||||||
"""Try to prevent a crash report from popping up.
|
"""Try to prevent a crash report from popping up.
|
||||||
|
|
||||||
|
|
|
@ -440,6 +440,12 @@ class GettextCacheTestCase(GettextBaseTest):
|
||||||
self.assertEqual(t.__class__, DummyGNUTranslations)
|
self.assertEqual(t.__class__, DummyGNUTranslations)
|
||||||
|
|
||||||
|
|
||||||
|
class MiscTestCase(unittest.TestCase):
|
||||||
|
def test__all__(self):
|
||||||
|
blacklist = {'c2py', 'ENOENT'}
|
||||||
|
support.check__all__(self, gettext, blacklist=blacklist)
|
||||||
|
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
support.run_unittest(__name__)
|
support.run_unittest(__name__)
|
||||||
|
|
||||||
|
|
|
@ -312,6 +312,28 @@ class TestSupport(unittest.TestCase):
|
||||||
self.OtherClass, self.RefClass, ignore=ignore)
|
self.OtherClass, self.RefClass, ignore=ignore)
|
||||||
self.assertEqual(set(), missing_items)
|
self.assertEqual(set(), missing_items)
|
||||||
|
|
||||||
|
def test_check__all__(self):
|
||||||
|
extra = {'tempdir'}
|
||||||
|
blacklist = {'template'}
|
||||||
|
support.check__all__(self,
|
||||||
|
tempfile,
|
||||||
|
extra=extra,
|
||||||
|
blacklist=blacklist)
|
||||||
|
|
||||||
|
extra = {'TextTestResult', 'installHandler'}
|
||||||
|
blacklist = {'load_tests', "TestProgram", "BaseTestSuite"}
|
||||||
|
|
||||||
|
support.check__all__(self,
|
||||||
|
unittest,
|
||||||
|
("unittest.result", "unittest.case",
|
||||||
|
"unittest.suite", "unittest.loader",
|
||||||
|
"unittest.main", "unittest.runner",
|
||||||
|
"unittest.signals"),
|
||||||
|
extra=extra,
|
||||||
|
blacklist=blacklist)
|
||||||
|
|
||||||
|
self.assertRaises(AssertionError, support.check__all__, self, unittest)
|
||||||
|
|
||||||
# XXX -follows a list of untested API
|
# XXX -follows a list of untested API
|
||||||
# make_legacy_pyc
|
# make_legacy_pyc
|
||||||
# is_resource_enabled
|
# is_resource_enabled
|
||||||
|
|
|
@ -765,6 +765,7 @@ Damon Kohler
|
||||||
Marko Kohtala
|
Marko Kohtala
|
||||||
Vajrasky Kok
|
Vajrasky Kok
|
||||||
Guido Kollerie
|
Guido Kollerie
|
||||||
|
Jacek Kołodziej
|
||||||
Jacek Konieczny
|
Jacek Konieczny
|
||||||
Марк Коренберг
|
Марк Коренберг
|
||||||
Arkady Koplyarov
|
Arkady Koplyarov
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue