diff options
author | Larry Hastings <larry@hastings.org> | 2014-01-24 06:17:25 -0800 |
---|---|---|
committer | Larry Hastings <larry@hastings.org> | 2014-01-24 06:17:25 -0800 |
commit | 5c66189e88034ba807b10422a8750b0c71c4b62b (patch) | |
tree | 541626d6d627396acaccab565e936d35c3b99173 /Lib/test | |
parent | b3c0f4067d992fc2c0d8578e308cc7167dc98f32 (diff) | |
download | cpython-git-5c66189e88034ba807b10422a8750b0c71c4b62b.tar.gz |
Issue #20189: Four additional builtin types (PyTypeObject,
PyMethodDescr_Type, _PyMethodWrapper_Type, and PyWrapperDescr_Type)
have been modified to provide introspection information for builtins.
Also: many additional Lib, test suite, and Argument Clinic fixes.
Diffstat (limited to 'Lib/test')
-rw-r--r-- | Lib/test/test_capi.py | 6 | ||||
-rw-r--r-- | Lib/test/test_generators.py | 4 | ||||
-rw-r--r-- | Lib/test/test_genexps.py | 4 | ||||
-rw-r--r-- | Lib/test/test_inspect.py | 98 |
4 files changed, 75 insertions, 37 deletions
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 22c8eb0709..444feb6314 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -125,7 +125,7 @@ class CAPITest(unittest.TestCase): self.assertEqual(_testcapi.docstring_no_signature.__text_signature__, None) self.assertEqual(_testcapi.docstring_with_invalid_signature.__doc__, - "docstring_with_invalid_signature (boo)\n" + "docstring_with_invalid_signature (module, boo)\n" "\n" "This docstring has an invalid signature." ) @@ -133,12 +133,12 @@ class CAPITest(unittest.TestCase): self.assertEqual(_testcapi.docstring_with_signature.__doc__, "This docstring has a valid signature.") - self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "(sig)") + self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "(module, sig)") self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__doc__, "This docstring has a valid signature and some extra newlines.") self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__text_signature__, - "(parameter)") + "(module, parameter)") @unittest.skipUnless(threading, 'Threading required for this test.') diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index 4e921177a5..5b7424bcf8 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -436,8 +436,8 @@ From the Iterators list, about the types of these things. >>> [s for s in dir(i) if not s.startswith('_')] ['close', 'gi_code', 'gi_frame', 'gi_running', 'send', 'throw'] >>> from test.support import HAVE_DOCSTRINGS ->>> print(i.__next__.__doc__ if HAVE_DOCSTRINGS else 'x.__next__() <==> next(x)') -x.__next__() <==> next(x) +>>> print(i.__next__.__doc__ if HAVE_DOCSTRINGS else 'Implements next(self).') +Implements next(self). >>> iter(i) is i True >>> import types diff --git a/Lib/test/test_genexps.py b/Lib/test/test_genexps.py index 203b336fde..74957cb8f4 100644 --- a/Lib/test/test_genexps.py +++ b/Lib/test/test_genexps.py @@ -222,8 +222,8 @@ Check that generator attributes are present True >>> from test.support import HAVE_DOCSTRINGS - >>> print(g.__next__.__doc__ if HAVE_DOCSTRINGS else 'x.__next__() <==> next(x)') - x.__next__() <==> next(x) + >>> print(g.__next__.__doc__ if HAVE_DOCSTRINGS else 'Implements next(self).') + Implements next(self). >>> import types >>> isinstance(g, types.GeneratorType) True diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index 1bfe7246f7..028eeb9caa 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -1,21 +1,25 @@ -import re -import sys -import types -import unittest -import inspect -import linecache -import datetime +import _testcapi import collections -import os -import shutil +import datetime import functools import importlib +import inspect +import io +import linecache +import os from os.path import normcase +import _pickle +import re +import shutil +import sys +import types +import unicodedata +import unittest + try: from concurrent.futures import ThreadPoolExecutor except ImportError: ThreadPoolExecutor = None -import _testcapi from test.support import run_unittest, TESTFN, DirsOnSysPath from test.support import MISSING_C_DOCSTRINGS @@ -23,8 +27,6 @@ from test.script_helper import assert_python_ok, assert_python_failure from test import inspect_fodder as mod from test import inspect_fodder2 as mod2 -# C module for test_findsource_binary -import unicodedata # Functions tested in this suite: # ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode, @@ -1582,23 +1584,30 @@ class TestSignatureObject(unittest.TestCase): ...)) def test_signature_on_unsupported_builtins(self): - with self.assertRaisesRegex(ValueError, 'not supported by signature'): - inspect.signature(type) - with self.assertRaisesRegex(ValueError, 'not supported by signature'): - # support for 'wrapper_descriptor' - inspect.signature(type.__call__) - with self.assertRaisesRegex(ValueError, 'not supported by signature'): - # support for 'method-wrapper' - inspect.signature(min.__call__) + with self.assertRaisesRegex(ValueError, 'no signature found'): + # min simply doesn't have a signature (yet) + inspect.signature(min) @unittest.skipIf(MISSING_C_DOCSTRINGS, "Signature information for builtins requires docstrings") def test_signature_on_builtins(self): - # min doesn't have a signature (yet) - self.assertEqual(inspect.signature(min), None) - signature = inspect.signature(_testcapi.docstring_with_signature_with_defaults) - self.assertTrue(isinstance(signature, inspect.Signature)) + def test_unbound_method(o): + """Use this to test unbound methods (things that should have a self)""" + signature = inspect.signature(o) + self.assertTrue(isinstance(signature, inspect.Signature)) + self.assertEqual(list(signature.parameters.values())[0].name, 'self') + return signature + + def test_callable(o): + """Use this to test bound methods or normal callables (things that don't expect self)""" + signature = inspect.signature(o) + self.assertTrue(isinstance(signature, inspect.Signature)) + if signature.parameters: + self.assertNotEqual(list(signature.parameters.values())[0].name, 'self') + return signature + + signature = test_callable(_testcapi.docstring_with_signature_with_defaults) def p(name): return signature.parameters[name].default self.assertEqual(p('s'), 'avocado') self.assertEqual(p('b'), b'bytes') @@ -1611,6 +1620,41 @@ class TestSignatureObject(unittest.TestCase): self.assertEqual(p('sys'), sys.maxsize) self.assertEqual(p('exp'), sys.maxsize - 1) + test_callable(type) + test_callable(object) + + # normal method + # (PyMethodDescr_Type, "method_descriptor") + test_unbound_method(_pickle.Pickler.dump) + d = _pickle.Pickler(io.StringIO()) + test_callable(d.dump) + + # static method + test_callable(str.maketrans) + test_callable('abc'.maketrans) + + # class method + test_callable(dict.fromkeys) + test_callable({}.fromkeys) + + # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor") + test_unbound_method(type.__call__) + test_unbound_method(int.__add__) + test_callable((3).__add__) + + # _PyMethodWrapper_Type + # support for 'method-wrapper' + test_callable(min.__call__) + + class ThisWorksNow: + __call__ = type + test_callable(ThisWorksNow()) + + + def test_signature_on_builtins_no_signature(self): + with self.assertRaisesRegex(ValueError, 'no signature found for builtin'): + inspect.signature(_testcapi.docstring_no_signature) + def test_signature_on_non_function(self): with self.assertRaisesRegex(TypeError, 'is not a callable object'): inspect.signature(42) @@ -1985,12 +2029,6 @@ class TestSignatureObject(unittest.TestCase): ((('a', ..., ..., "positional_or_keyword"),), ...)) - class ToFail: - __call__ = type - with self.assertRaisesRegex(ValueError, "not supported by signature"): - inspect.signature(ToFail()) - - class Wrapped: pass Wrapped.__wrapped__ = lambda a: None |