• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import builtins
2import collections
3import datetime
4import functools
5import importlib
6import inspect
7import io
8import linecache
9import os
10from os.path import normcase
11import _pickle
12import pickle
13import shutil
14import sys
15import types
16import textwrap
17import unicodedata
18import unittest
19import unittest.mock
20import warnings
21
22try:
23    from concurrent.futures import ThreadPoolExecutor
24except ImportError:
25    ThreadPoolExecutor = None
26
27from test.support import cpython_only
28from test.support import MISSING_C_DOCSTRINGS, ALWAYS_EQ
29from test.support.import_helper import DirsOnSysPath
30from test.support.os_helper import TESTFN
31from test.support.script_helper import assert_python_ok, assert_python_failure
32from test import inspect_fodder as mod
33from test import inspect_fodder2 as mod2
34from test import support
35from test import inspect_stock_annotations
36from test import inspect_stringized_annotations
37from test import inspect_stringized_annotations_2
38
39from test.test_import import _ready_to_import
40
41
42# Functions tested in this suite:
43# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
44# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
45# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
46# getclasstree, getargvalues, formatargspec, formatargvalues,
47# currentframe, stack, trace, isdatadescriptor
48
49# NOTE: There are some additional tests relating to interaction with
50#       zipimport in the test_zipimport_support test module.
51
52modfile = mod.__file__
53if modfile.endswith(('c', 'o')):
54    modfile = modfile[:-1]
55
56# Normalize file names: on Windows, the case of file names of compiled
57# modules depends on the path used to start the python executable.
58modfile = normcase(modfile)
59
60def revise(filename, *args):
61    return (normcase(filename),) + args
62
63git = mod.StupidGit()
64
65
66def signatures_with_lexicographic_keyword_only_parameters():
67    """
68    Yields a whole bunch of functions with only keyword-only parameters,
69    where those parameters are always in lexicographically sorted order.
70    """
71    parameters = ['a', 'bar', 'c', 'delta', 'ephraim', 'magical', 'yoyo', 'z']
72    for i in range(1, 2**len(parameters)):
73        p = []
74        bit = 1
75        for j in range(len(parameters)):
76            if i & (bit << j):
77                p.append(parameters[j])
78        fn_text = "def foo(*, " + ", ".join(p) + "): pass"
79        symbols = {}
80        exec(fn_text, symbols, symbols)
81        yield symbols['foo']
82
83
84def unsorted_keyword_only_parameters_fn(*, throw, out, the, baby, with_,
85                                        the_, bathwater):
86    pass
87
88unsorted_keyword_only_parameters = 'throw out the baby with_ the_ bathwater'.split()
89
90class IsTestBase(unittest.TestCase):
91    predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
92                      inspect.isframe, inspect.isfunction, inspect.ismethod,
93                      inspect.ismodule, inspect.istraceback,
94                      inspect.isgenerator, inspect.isgeneratorfunction,
95                      inspect.iscoroutine, inspect.iscoroutinefunction,
96                      inspect.isasyncgen, inspect.isasyncgenfunction])
97
98    def istest(self, predicate, exp):
99        obj = eval(exp)
100        self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
101
102        for other in self.predicates - set([predicate]):
103            if (predicate == inspect.isgeneratorfunction or \
104               predicate == inspect.isasyncgenfunction or \
105               predicate == inspect.iscoroutinefunction) and \
106               other == inspect.isfunction:
107                continue
108            self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
109
110def generator_function_example(self):
111    for i in range(2):
112        yield i
113
114async def async_generator_function_example(self):
115    async for i in range(2):
116        yield i
117
118async def coroutine_function_example(self):
119    return 'spam'
120
121@types.coroutine
122def gen_coroutine_function_example(self):
123    yield
124    return 'spam'
125
126class TestPredicates(IsTestBase):
127
128    def test_excluding_predicates(self):
129        global tb
130        self.istest(inspect.isbuiltin, 'sys.exit')
131        self.istest(inspect.isbuiltin, '[].append')
132        self.istest(inspect.iscode, 'mod.spam.__code__')
133        try:
134            1/0
135        except Exception as e:
136            tb = e.__traceback__
137            self.istest(inspect.isframe, 'tb.tb_frame')
138            self.istest(inspect.istraceback, 'tb')
139            if hasattr(types, 'GetSetDescriptorType'):
140                self.istest(inspect.isgetsetdescriptor,
141                            'type(tb.tb_frame).f_locals')
142            else:
143                self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
144        finally:
145            # Clear traceback and all the frames and local variables hanging to it.
146            tb = None
147        self.istest(inspect.isfunction, 'mod.spam')
148        self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
149        self.istest(inspect.ismethod, 'git.argue')
150        self.istest(inspect.ismethod, 'mod.custom_method')
151        self.istest(inspect.ismodule, 'mod')
152        self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
153        self.istest(inspect.isgenerator, '(x for x in range(2))')
154        self.istest(inspect.isgeneratorfunction, 'generator_function_example')
155        self.istest(inspect.isasyncgen,
156                    'async_generator_function_example(1)')
157        self.istest(inspect.isasyncgenfunction,
158                    'async_generator_function_example')
159
160        with warnings.catch_warnings():
161            warnings.simplefilter("ignore")
162            self.istest(inspect.iscoroutine, 'coroutine_function_example(1)')
163            self.istest(inspect.iscoroutinefunction, 'coroutine_function_example')
164
165        if hasattr(types, 'MemberDescriptorType'):
166            self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
167        else:
168            self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
169
170    def test_iscoroutine(self):
171        async_gen_coro = async_generator_function_example(1)
172        gen_coro = gen_coroutine_function_example(1)
173        coro = coroutine_function_example(1)
174
175        self.assertFalse(
176            inspect.iscoroutinefunction(gen_coroutine_function_example))
177        self.assertFalse(
178            inspect.iscoroutinefunction(
179                functools.partial(functools.partial(
180                    gen_coroutine_function_example))))
181        self.assertFalse(inspect.iscoroutine(gen_coro))
182
183        self.assertTrue(
184            inspect.isgeneratorfunction(gen_coroutine_function_example))
185        self.assertTrue(
186            inspect.isgeneratorfunction(
187                functools.partial(functools.partial(
188                    gen_coroutine_function_example))))
189        self.assertTrue(inspect.isgenerator(gen_coro))
190
191        self.assertTrue(
192            inspect.iscoroutinefunction(coroutine_function_example))
193        self.assertTrue(
194            inspect.iscoroutinefunction(
195                functools.partial(functools.partial(
196                    coroutine_function_example))))
197        self.assertTrue(inspect.iscoroutine(coro))
198
199        self.assertFalse(
200            inspect.isgeneratorfunction(coroutine_function_example))
201        self.assertFalse(
202            inspect.isgeneratorfunction(
203                functools.partial(functools.partial(
204                    coroutine_function_example))))
205        self.assertFalse(inspect.isgenerator(coro))
206
207        self.assertTrue(
208            inspect.isasyncgenfunction(async_generator_function_example))
209        self.assertTrue(
210            inspect.isasyncgenfunction(
211                functools.partial(functools.partial(
212                    async_generator_function_example))))
213        self.assertTrue(inspect.isasyncgen(async_gen_coro))
214
215        coro.close(); gen_coro.close(); # silence warnings
216
217    def test_isawaitable(self):
218        def gen(): yield
219        self.assertFalse(inspect.isawaitable(gen()))
220
221        coro = coroutine_function_example(1)
222        gen_coro = gen_coroutine_function_example(1)
223
224        self.assertTrue(inspect.isawaitable(coro))
225        self.assertTrue(inspect.isawaitable(gen_coro))
226
227        class Future:
228            def __await__():
229                pass
230        self.assertTrue(inspect.isawaitable(Future()))
231        self.assertFalse(inspect.isawaitable(Future))
232
233        class NotFuture: pass
234        not_fut = NotFuture()
235        not_fut.__await__ = lambda: None
236        self.assertFalse(inspect.isawaitable(not_fut))
237
238        coro.close(); gen_coro.close() # silence warnings
239
240    def test_isroutine(self):
241        self.assertTrue(inspect.isroutine(mod.spam))
242        self.assertTrue(inspect.isroutine([].count))
243
244    def test_isclass(self):
245        self.istest(inspect.isclass, 'mod.StupidGit')
246        self.assertTrue(inspect.isclass(list))
247
248        class CustomGetattr(object):
249            def __getattr__(self, attr):
250                return None
251        self.assertFalse(inspect.isclass(CustomGetattr()))
252
253    def test_get_slot_members(self):
254        class C(object):
255            __slots__ = ("a", "b")
256        x = C()
257        x.a = 42
258        members = dict(inspect.getmembers(x))
259        self.assertIn('a', members)
260        self.assertNotIn('b', members)
261
262    def test_isabstract(self):
263        from abc import ABCMeta, abstractmethod
264
265        class AbstractClassExample(metaclass=ABCMeta):
266
267            @abstractmethod
268            def foo(self):
269                pass
270
271        class ClassExample(AbstractClassExample):
272            def foo(self):
273                pass
274
275        a = ClassExample()
276
277        # Test general behaviour.
278        self.assertTrue(inspect.isabstract(AbstractClassExample))
279        self.assertFalse(inspect.isabstract(ClassExample))
280        self.assertFalse(inspect.isabstract(a))
281        self.assertFalse(inspect.isabstract(int))
282        self.assertFalse(inspect.isabstract(5))
283
284    def test_isabstract_during_init_subclass(self):
285        from abc import ABCMeta, abstractmethod
286        isabstract_checks = []
287        class AbstractChecker(metaclass=ABCMeta):
288            def __init_subclass__(cls):
289                isabstract_checks.append(inspect.isabstract(cls))
290        class AbstractClassExample(AbstractChecker):
291            @abstractmethod
292            def foo(self):
293                pass
294        class ClassExample(AbstractClassExample):
295            def foo(self):
296                pass
297        self.assertEqual(isabstract_checks, [True, False])
298
299        isabstract_checks.clear()
300        class AbstractChild(AbstractClassExample):
301            pass
302        class AbstractGrandchild(AbstractChild):
303            pass
304        class ConcreteGrandchild(ClassExample):
305            pass
306        self.assertEqual(isabstract_checks, [True, True, False])
307
308
309class TestInterpreterStack(IsTestBase):
310    def __init__(self, *args, **kwargs):
311        unittest.TestCase.__init__(self, *args, **kwargs)
312
313        git.abuse(7, 8, 9)
314
315    def test_abuse_done(self):
316        self.istest(inspect.istraceback, 'git.ex[2]')
317        self.istest(inspect.isframe, 'mod.fr')
318
319    def test_stack(self):
320        self.assertTrue(len(mod.st) >= 5)
321        self.assertEqual(revise(*mod.st[0][1:]),
322             (modfile, 16, 'eggs', ['    st = inspect.stack()\n'], 0))
323        self.assertEqual(revise(*mod.st[1][1:]),
324             (modfile, 9, 'spam', ['    eggs(b + d, c + f)\n'], 0))
325        self.assertEqual(revise(*mod.st[2][1:]),
326             (modfile, 43, 'argue', ['            spam(a, b, c)\n'], 0))
327        self.assertEqual(revise(*mod.st[3][1:]),
328             (modfile, 39, 'abuse', ['        self.argue(a, b, c)\n'], 0))
329        # Test named tuple fields
330        record = mod.st[0]
331        self.assertIs(record.frame, mod.fr)
332        self.assertEqual(record.lineno, 16)
333        self.assertEqual(record.filename, mod.__file__)
334        self.assertEqual(record.function, 'eggs')
335        self.assertIn('inspect.stack()', record.code_context[0])
336        self.assertEqual(record.index, 0)
337
338    def test_trace(self):
339        self.assertEqual(len(git.tr), 3)
340        self.assertEqual(revise(*git.tr[0][1:]),
341             (modfile, 43, 'argue', ['            spam(a, b, c)\n'], 0))
342        self.assertEqual(revise(*git.tr[1][1:]),
343             (modfile, 9, 'spam', ['    eggs(b + d, c + f)\n'], 0))
344        self.assertEqual(revise(*git.tr[2][1:]),
345             (modfile, 18, 'eggs', ['    q = y / 0\n'], 0))
346
347    def test_frame(self):
348        args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
349        self.assertEqual(args, ['x', 'y'])
350        self.assertEqual(varargs, None)
351        self.assertEqual(varkw, None)
352        self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
353        self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
354                         '(x=11, y=14)')
355
356    def test_previous_frame(self):
357        args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
358        self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
359        self.assertEqual(varargs, 'g')
360        self.assertEqual(varkw, 'h')
361        self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
362             '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
363
364class GetSourceBase(unittest.TestCase):
365    # Subclasses must override.
366    fodderModule = None
367
368    def setUp(self):
369        with open(inspect.getsourcefile(self.fodderModule), encoding="utf-8") as fp:
370            self.source = fp.read()
371
372    def sourcerange(self, top, bottom):
373        lines = self.source.split("\n")
374        return "\n".join(lines[top-1:bottom]) + ("\n" if bottom else "")
375
376    def assertSourceEqual(self, obj, top, bottom):
377        self.assertEqual(inspect.getsource(obj),
378                         self.sourcerange(top, bottom))
379
380class SlotUser:
381    'Docstrings for __slots__'
382    __slots__ = {'power': 'measured in kilowatts',
383                 'distance': 'measured in kilometers'}
384
385class TestRetrievingSourceCode(GetSourceBase):
386    fodderModule = mod
387
388    def test_getclasses(self):
389        classes = inspect.getmembers(mod, inspect.isclass)
390        self.assertEqual(classes,
391                         [('FesteringGob', mod.FesteringGob),
392                          ('MalodorousPervert', mod.MalodorousPervert),
393                          ('ParrotDroppings', mod.ParrotDroppings),
394                          ('StupidGit', mod.StupidGit),
395                          ('Tit', mod.MalodorousPervert),
396                          ('WhichComments', mod.WhichComments),
397                         ])
398        tree = inspect.getclasstree([cls[1] for cls in classes])
399        self.assertEqual(tree,
400                         [(object, ()),
401                          [(mod.ParrotDroppings, (object,)),
402                           [(mod.FesteringGob, (mod.MalodorousPervert,
403                                                   mod.ParrotDroppings))
404                            ],
405                           (mod.StupidGit, (object,)),
406                           [(mod.MalodorousPervert, (mod.StupidGit,)),
407                            [(mod.FesteringGob, (mod.MalodorousPervert,
408                                                    mod.ParrotDroppings))
409                             ]
410                            ],
411                            (mod.WhichComments, (object,),)
412                           ]
413                          ])
414        tree = inspect.getclasstree([cls[1] for cls in classes], True)
415        self.assertEqual(tree,
416                         [(object, ()),
417                          [(mod.ParrotDroppings, (object,)),
418                           (mod.StupidGit, (object,)),
419                           [(mod.MalodorousPervert, (mod.StupidGit,)),
420                            [(mod.FesteringGob, (mod.MalodorousPervert,
421                                                    mod.ParrotDroppings))
422                             ]
423                            ],
424                            (mod.WhichComments, (object,),)
425                           ]
426                          ])
427
428    def test_getfunctions(self):
429        functions = inspect.getmembers(mod, inspect.isfunction)
430        self.assertEqual(functions, [('eggs', mod.eggs),
431                                     ('lobbest', mod.lobbest),
432                                     ('spam', mod.spam)])
433
434    @unittest.skipIf(sys.flags.optimize >= 2,
435                     "Docstrings are omitted with -O2 and above")
436    def test_getdoc(self):
437        self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
438        self.assertEqual(inspect.getdoc(mod.StupidGit),
439                         'A longer,\n\nindented\n\ndocstring.')
440        self.assertEqual(inspect.getdoc(git.abuse),
441                         'Another\n\ndocstring\n\ncontaining\n\ntabs')
442        self.assertEqual(inspect.getdoc(SlotUser.power),
443                         'measured in kilowatts')
444        self.assertEqual(inspect.getdoc(SlotUser.distance),
445                         'measured in kilometers')
446
447    @unittest.skipIf(sys.flags.optimize >= 2,
448                     "Docstrings are omitted with -O2 and above")
449    def test_getdoc_inherited(self):
450        self.assertEqual(inspect.getdoc(mod.FesteringGob),
451                         'A longer,\n\nindented\n\ndocstring.')
452        self.assertEqual(inspect.getdoc(mod.FesteringGob.abuse),
453                         'Another\n\ndocstring\n\ncontaining\n\ntabs')
454        self.assertEqual(inspect.getdoc(mod.FesteringGob().abuse),
455                         'Another\n\ndocstring\n\ncontaining\n\ntabs')
456        self.assertEqual(inspect.getdoc(mod.FesteringGob.contradiction),
457                         'The automatic gainsaying.')
458
459    @unittest.skipIf(MISSING_C_DOCSTRINGS, "test requires docstrings")
460    def test_finddoc(self):
461        finddoc = inspect._finddoc
462        self.assertEqual(finddoc(int), int.__doc__)
463        self.assertEqual(finddoc(int.to_bytes), int.to_bytes.__doc__)
464        self.assertEqual(finddoc(int().to_bytes), int.to_bytes.__doc__)
465        self.assertEqual(finddoc(int.from_bytes), int.from_bytes.__doc__)
466        self.assertEqual(finddoc(int.real), int.real.__doc__)
467
468    def test_cleandoc(self):
469        self.assertEqual(inspect.cleandoc('An\n    indented\n    docstring.'),
470                         'An\nindented\ndocstring.')
471
472    def test_getcomments(self):
473        self.assertEqual(inspect.getcomments(mod), '# line 1\n')
474        self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
475        self.assertEqual(inspect.getcomments(mod2.cls160), '# line 159\n')
476        # If the object source file is not available, return None.
477        co = compile('x=1', '_non_existing_filename.py', 'exec')
478        self.assertIsNone(inspect.getcomments(co))
479        # If the object has been defined in C, return None.
480        self.assertIsNone(inspect.getcomments(list))
481
482    def test_getmodule(self):
483        # Check actual module
484        self.assertEqual(inspect.getmodule(mod), mod)
485        # Check class (uses __module__ attribute)
486        self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
487        # Check a method (no __module__ attribute, falls back to filename)
488        self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
489        # Do it again (check the caching isn't broken)
490        self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
491        # Check a builtin
492        self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
493        # Check filename override
494        self.assertEqual(inspect.getmodule(None, modfile), mod)
495
496    def test_getmodule_file_not_found(self):
497        # See bpo-45406
498        def _getabsfile(obj, _filename):
499            raise FileNotFoundError('bad file')
500        with unittest.mock.patch('inspect.getabsfile', _getabsfile):
501            f = inspect.currentframe()
502            self.assertIsNone(inspect.getmodule(f))
503            inspect.getouterframes(f)  # smoke test
504
505    def test_getframeinfo_get_first_line(self):
506        frame_info = inspect.getframeinfo(self.fodderModule.fr, 50)
507        self.assertEqual(frame_info.code_context[0], "# line 1\n")
508        self.assertEqual(frame_info.code_context[1], "'A module docstring.'\n")
509
510    def test_getsource(self):
511        self.assertSourceEqual(git.abuse, 29, 39)
512        self.assertSourceEqual(mod.StupidGit, 21, 51)
513        self.assertSourceEqual(mod.lobbest, 75, 76)
514
515    def test_getsourcefile(self):
516        self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
517        self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
518        fn = "_non_existing_filename_used_for_sourcefile_test.py"
519        co = compile("x=1", fn, "exec")
520        self.assertEqual(inspect.getsourcefile(co), None)
521        linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
522        try:
523            self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
524        finally:
525            del linecache.cache[co.co_filename]
526
527    def test_getfile(self):
528        self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
529
530    def test_getfile_builtin_module(self):
531        with self.assertRaises(TypeError) as e:
532            inspect.getfile(sys)
533        self.assertTrue(str(e.exception).startswith('<module'))
534
535    def test_getfile_builtin_class(self):
536        with self.assertRaises(TypeError) as e:
537            inspect.getfile(int)
538        self.assertTrue(str(e.exception).startswith('<class'))
539
540    def test_getfile_builtin_function_or_method(self):
541        with self.assertRaises(TypeError) as e_abs:
542            inspect.getfile(abs)
543        self.assertIn('expected, got', str(e_abs.exception))
544        with self.assertRaises(TypeError) as e_append:
545            inspect.getfile(list.append)
546        self.assertIn('expected, got', str(e_append.exception))
547
548    def test_getfile_class_without_module(self):
549        class CM(type):
550            @property
551            def __module__(cls):
552                raise AttributeError
553        class C(metaclass=CM):
554            pass
555        with self.assertRaises(TypeError):
556            inspect.getfile(C)
557
558    def test_getfile_broken_repr(self):
559        class ErrorRepr:
560            def __repr__(self):
561                raise Exception('xyz')
562        er = ErrorRepr()
563        with self.assertRaises(TypeError):
564            inspect.getfile(er)
565
566    def test_getmodule_recursion(self):
567        from types import ModuleType
568        name = '__inspect_dummy'
569        m = sys.modules[name] = ModuleType(name)
570        m.__file__ = "<string>" # hopefully not a real filename...
571        m.__loader__ = "dummy"  # pretend the filename is understood by a loader
572        exec("def x(): pass", m.__dict__)
573        self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
574        del sys.modules[name]
575        inspect.getmodule(compile('a=10','','single'))
576
577    def test_proceed_with_fake_filename(self):
578        '''doctest monkeypatches linecache to enable inspection'''
579        fn, source = '<test>', 'def x(): pass\n'
580        getlines = linecache.getlines
581        def monkey(filename, module_globals=None):
582            if filename == fn:
583                return source.splitlines(keepends=True)
584            else:
585                return getlines(filename, module_globals)
586        linecache.getlines = monkey
587        try:
588            ns = {}
589            exec(compile(source, fn, 'single'), ns)
590            inspect.getsource(ns["x"])
591        finally:
592            linecache.getlines = getlines
593
594    def test_getsource_on_code_object(self):
595        self.assertSourceEqual(mod.eggs.__code__, 12, 18)
596
597class TestGetsourceInteractive(unittest.TestCase):
598    def test_getclasses_interactive(self):
599        # bpo-44648: simulate a REPL session;
600        # there is no `__file__` in the __main__ module
601        code = "import sys, inspect; \
602                assert not hasattr(sys.modules['__main__'], '__file__'); \
603                A = type('A', (), {}); \
604                inspect.getsource(A)"
605        _, _, stderr = assert_python_failure("-c", code, __isolated=True)
606        self.assertIn(b'OSError: source code not available', stderr)
607
608class TestGettingSourceOfToplevelFrames(GetSourceBase):
609    fodderModule = mod
610
611    def test_range_toplevel_frame(self):
612        self.maxDiff = None
613        self.assertSourceEqual(mod.currentframe, 1, None)
614
615    def test_range_traceback_toplevel_frame(self):
616        self.assertSourceEqual(mod.tb, 1, None)
617
618class TestDecorators(GetSourceBase):
619    fodderModule = mod2
620
621    def test_wrapped_decorator(self):
622        self.assertSourceEqual(mod2.wrapped, 14, 17)
623
624    def test_replacing_decorator(self):
625        self.assertSourceEqual(mod2.gone, 9, 10)
626
627    def test_getsource_unwrap(self):
628        self.assertSourceEqual(mod2.real, 130, 132)
629
630    def test_decorator_with_lambda(self):
631        self.assertSourceEqual(mod2.func114, 113, 115)
632
633class TestOneliners(GetSourceBase):
634    fodderModule = mod2
635    def test_oneline_lambda(self):
636        # Test inspect.getsource with a one-line lambda function.
637        self.assertSourceEqual(mod2.oll, 25, 25)
638
639    def test_threeline_lambda(self):
640        # Test inspect.getsource with a three-line lambda function,
641        # where the second and third lines are _not_ indented.
642        self.assertSourceEqual(mod2.tll, 28, 30)
643
644    def test_twoline_indented_lambda(self):
645        # Test inspect.getsource with a two-line lambda function,
646        # where the second line _is_ indented.
647        self.assertSourceEqual(mod2.tlli, 33, 34)
648
649    def test_onelinefunc(self):
650        # Test inspect.getsource with a regular one-line function.
651        self.assertSourceEqual(mod2.onelinefunc, 37, 37)
652
653    def test_manyargs(self):
654        # Test inspect.getsource with a regular function where
655        # the arguments are on two lines and _not_ indented and
656        # the body on the second line with the last arguments.
657        self.assertSourceEqual(mod2.manyargs, 40, 41)
658
659    def test_twolinefunc(self):
660        # Test inspect.getsource with a regular function where
661        # the body is on two lines, following the argument list and
662        # continued on the next line by a \\.
663        self.assertSourceEqual(mod2.twolinefunc, 44, 45)
664
665    def test_lambda_in_list(self):
666        # Test inspect.getsource with a one-line lambda function
667        # defined in a list, indented.
668        self.assertSourceEqual(mod2.a[1], 49, 49)
669
670    def test_anonymous(self):
671        # Test inspect.getsource with a lambda function defined
672        # as argument to another function.
673        self.assertSourceEqual(mod2.anonymous, 55, 55)
674
675class TestBlockComments(GetSourceBase):
676    fodderModule = mod
677
678    def test_toplevel_class(self):
679        self.assertSourceEqual(mod.WhichComments, 96, 114)
680
681    def test_class_method(self):
682        self.assertSourceEqual(mod.WhichComments.f, 99, 104)
683
684    def test_class_async_method(self):
685        self.assertSourceEqual(mod.WhichComments.asyncf, 109, 112)
686
687class TestBuggyCases(GetSourceBase):
688    fodderModule = mod2
689
690    def test_with_comment(self):
691        self.assertSourceEqual(mod2.with_comment, 58, 59)
692
693    def test_multiline_sig(self):
694        self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
695
696    def test_nested_class(self):
697        self.assertSourceEqual(mod2.func69().func71, 71, 72)
698
699    def test_one_liner_followed_by_non_name(self):
700        self.assertSourceEqual(mod2.func77, 77, 77)
701
702    def test_one_liner_dedent_non_name(self):
703        self.assertSourceEqual(mod2.cls82.func83, 83, 83)
704
705    def test_with_comment_instead_of_docstring(self):
706        self.assertSourceEqual(mod2.func88, 88, 90)
707
708    def test_method_in_dynamic_class(self):
709        self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
710
711    # This should not skip for CPython, but might on a repackaged python where
712    # unicodedata is not an external module, or on pypy.
713    @unittest.skipIf(not hasattr(unicodedata, '__file__') or
714                                 unicodedata.__file__.endswith('.py'),
715                     "unicodedata is not an external binary module")
716    def test_findsource_binary(self):
717        self.assertRaises(OSError, inspect.getsource, unicodedata)
718        self.assertRaises(OSError, inspect.findsource, unicodedata)
719
720    def test_findsource_code_in_linecache(self):
721        lines = ["x=1"]
722        co = compile(lines[0], "_dynamically_created_file", "exec")
723        self.assertRaises(OSError, inspect.findsource, co)
724        self.assertRaises(OSError, inspect.getsource, co)
725        linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
726        try:
727            self.assertEqual(inspect.findsource(co), (lines,0))
728            self.assertEqual(inspect.getsource(co), lines[0])
729        finally:
730            del linecache.cache[co.co_filename]
731
732    def test_findsource_without_filename(self):
733        for fname in ['', '<string>']:
734            co = compile('x=1', fname, "exec")
735            self.assertRaises(IOError, inspect.findsource, co)
736            self.assertRaises(IOError, inspect.getsource, co)
737
738    def test_findsource_with_out_of_bounds_lineno(self):
739        mod_len = len(inspect.getsource(mod))
740        src = '\n' * 2* mod_len + "def f(): pass"
741        co = compile(src, mod.__file__, "exec")
742        g, l = {}, {}
743        eval(co, g, l)
744        func = l['f']
745        self.assertEqual(func.__code__.co_firstlineno, 1+2*mod_len)
746        with self.assertRaisesRegex(IOError, "lineno is out of bounds"):
747            inspect.findsource(func)
748
749    def test_getsource_on_method(self):
750        self.assertSourceEqual(mod2.ClassWithMethod.method, 118, 119)
751
752    def test_nested_func(self):
753        self.assertSourceEqual(mod2.cls135.func136, 136, 139)
754
755    def test_class_definition_in_multiline_string_definition(self):
756        self.assertSourceEqual(mod2.cls149, 149, 152)
757
758    def test_class_definition_in_multiline_comment(self):
759        self.assertSourceEqual(mod2.cls160, 160, 163)
760
761    def test_nested_class_definition_indented_string(self):
762        self.assertSourceEqual(mod2.cls173.cls175, 175, 176)
763
764    def test_nested_class_definition(self):
765        self.assertSourceEqual(mod2.cls183, 183, 188)
766        self.assertSourceEqual(mod2.cls183.cls185, 185, 188)
767
768    def test_class_decorator(self):
769        self.assertSourceEqual(mod2.cls196, 194, 201)
770        self.assertSourceEqual(mod2.cls196.cls200, 198, 201)
771
772    def test_class_inside_conditional(self):
773        self.assertSourceEqual(mod2.cls238, 238, 240)
774        self.assertSourceEqual(mod2.cls238.cls239, 239, 240)
775
776    def test_multiple_children_classes(self):
777        self.assertSourceEqual(mod2.cls203, 203, 209)
778        self.assertSourceEqual(mod2.cls203.cls204, 204, 206)
779        self.assertSourceEqual(mod2.cls203.cls204.cls205, 205, 206)
780        self.assertSourceEqual(mod2.cls203.cls207, 207, 209)
781        self.assertSourceEqual(mod2.cls203.cls207.cls205, 208, 209)
782
783    def test_nested_class_definition_inside_function(self):
784        self.assertSourceEqual(mod2.func212(), 213, 214)
785        self.assertSourceEqual(mod2.cls213, 218, 222)
786        self.assertSourceEqual(mod2.cls213().func219(), 220, 221)
787
788    def test_nested_class_definition_inside_async_function(self):
789        import asyncio
790        self.addCleanup(asyncio.set_event_loop_policy, None)
791        self.assertSourceEqual(asyncio.run(mod2.func225()), 226, 227)
792        self.assertSourceEqual(mod2.cls226, 231, 235)
793        self.assertSourceEqual(asyncio.run(mod2.cls226().func232()), 233, 234)
794
795class TestNoEOL(GetSourceBase):
796    def setUp(self):
797        self.tempdir = TESTFN + '_dir'
798        os.mkdir(self.tempdir)
799        with open(os.path.join(self.tempdir, 'inspect_fodder3%spy' % os.extsep),
800                  'w', encoding='utf-8') as f:
801            f.write("class X:\n    pass # No EOL")
802        with DirsOnSysPath(self.tempdir):
803            import inspect_fodder3 as mod3
804        self.fodderModule = mod3
805        super().setUp()
806
807    def tearDown(self):
808        shutil.rmtree(self.tempdir)
809
810    def test_class(self):
811        self.assertSourceEqual(self.fodderModule.X, 1, 2)
812
813
814class _BrokenDataDescriptor(object):
815    """
816    A broken data descriptor. See bug #1785.
817    """
818    def __get__(*args):
819        raise AttributeError("broken data descriptor")
820
821    def __set__(*args):
822        raise RuntimeError
823
824    def __getattr__(*args):
825        raise AttributeError("broken data descriptor")
826
827
828class _BrokenMethodDescriptor(object):
829    """
830    A broken method descriptor. See bug #1785.
831    """
832    def __get__(*args):
833        raise AttributeError("broken method descriptor")
834
835    def __getattr__(*args):
836        raise AttributeError("broken method descriptor")
837
838
839# Helper for testing classify_class_attrs.
840def attrs_wo_objs(cls):
841    return [t[:3] for t in inspect.classify_class_attrs(cls)]
842
843
844class TestClassesAndFunctions(unittest.TestCase):
845    def test_newstyle_mro(self):
846        # The same w/ new-class MRO.
847        class A(object):    pass
848        class B(A): pass
849        class C(A): pass
850        class D(B, C): pass
851
852        expected = (D, B, C, A, object)
853        got = inspect.getmro(D)
854        self.assertEqual(expected, got)
855
856    def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
857                            varkw_e=None, defaults_e=None, formatted=None):
858        with self.assertWarns(DeprecationWarning):
859            args, varargs, varkw, defaults = inspect.getargspec(routine)
860        self.assertEqual(args, args_e)
861        self.assertEqual(varargs, varargs_e)
862        self.assertEqual(varkw, varkw_e)
863        self.assertEqual(defaults, defaults_e)
864        if formatted is not None:
865            with self.assertWarns(DeprecationWarning):
866                self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
867                                 formatted)
868
869    def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
870                                    varkw_e=None, defaults_e=None,
871                                    posonlyargs_e=[], kwonlyargs_e=[],
872                                    kwonlydefaults_e=None,
873                                    ann_e={}, formatted=None):
874        args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
875            inspect.getfullargspec(routine)
876        self.assertEqual(args, args_e)
877        self.assertEqual(varargs, varargs_e)
878        self.assertEqual(varkw, varkw_e)
879        self.assertEqual(defaults, defaults_e)
880        self.assertEqual(kwonlyargs, kwonlyargs_e)
881        self.assertEqual(kwonlydefaults, kwonlydefaults_e)
882        self.assertEqual(ann, ann_e)
883        if formatted is not None:
884            with self.assertWarns(DeprecationWarning):
885                self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults,
886                                                       kwonlyargs, kwonlydefaults, ann),
887                                 formatted)
888
889    def test_getargspec(self):
890        self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
891
892        self.assertArgSpecEquals(mod.spam,
893                                 ['a', 'b', 'c', 'd', 'e', 'f'],
894                                 'g', 'h', (3, 4, 5),
895                                 '(a, b, c, d=3, e=4, f=5, *g, **h)')
896
897        self.assertRaises(ValueError, self.assertArgSpecEquals,
898                          mod2.keyworded, [])
899
900        self.assertRaises(ValueError, self.assertArgSpecEquals,
901                          mod2.annotated, [])
902        self.assertRaises(ValueError, self.assertArgSpecEquals,
903                          mod2.keyword_only_arg, [])
904
905
906    def test_getfullargspec(self):
907        self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
908                                     kwonlyargs_e=['arg2'],
909                                     kwonlydefaults_e={'arg2':1},
910                                     formatted='(*arg1, arg2=1)')
911
912        self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
913                                     ann_e={'arg1' : list},
914                                     formatted='(arg1: list)')
915        self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
916                                     kwonlyargs_e=['arg'],
917                                     formatted='(*, arg)')
918
919        self.assertFullArgSpecEquals(mod2.all_markers, ['a', 'b', 'c', 'd'],
920                                     kwonlyargs_e=['e', 'f'],
921                                     formatted='(a, b, c, d, *, e, f)')
922
923        self.assertFullArgSpecEquals(mod2.all_markers_with_args_and_kwargs,
924                                     ['a', 'b', 'c', 'd'],
925                                     varargs_e='args',
926                                     varkw_e='kwargs',
927                                     kwonlyargs_e=['e', 'f'],
928                                     formatted='(a, b, c, d, *args, e, f, **kwargs)')
929
930        self.assertFullArgSpecEquals(mod2.all_markers_with_defaults, ['a', 'b', 'c', 'd'],
931                                     defaults_e=(1,2,3),
932                                     kwonlyargs_e=['e', 'f'],
933                                     kwonlydefaults_e={'e': 4, 'f': 5},
934                                     formatted='(a, b=1, c=2, d=3, *, e=4, f=5)')
935
936    def test_argspec_api_ignores_wrapped(self):
937        # Issue 20684: low level introspection API must ignore __wrapped__
938        @functools.wraps(mod.spam)
939        def ham(x, y):
940            pass
941        # Basic check
942        self.assertArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
943        self.assertFullArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
944        self.assertFullArgSpecEquals(functools.partial(ham),
945                                     ['x', 'y'], formatted='(x, y)')
946        # Other variants
947        def check_method(f):
948            self.assertArgSpecEquals(f, ['self', 'x', 'y'],
949                                        formatted='(self, x, y)')
950        class C:
951            @functools.wraps(mod.spam)
952            def ham(self, x, y):
953                pass
954            pham = functools.partialmethod(ham)
955            @functools.wraps(mod.spam)
956            def __call__(self, x, y):
957                pass
958        check_method(C())
959        check_method(C.ham)
960        check_method(C().ham)
961        check_method(C.pham)
962        check_method(C().pham)
963
964        class C_new:
965            @functools.wraps(mod.spam)
966            def __new__(self, x, y):
967                pass
968        check_method(C_new)
969
970        class C_init:
971            @functools.wraps(mod.spam)
972            def __init__(self, x, y):
973                pass
974        check_method(C_init)
975
976    def test_getfullargspec_signature_attr(self):
977        def test():
978            pass
979        spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY)
980        test.__signature__ = inspect.Signature(parameters=(spam_param,))
981
982        self.assertFullArgSpecEquals(test, ['spam'], formatted='(spam)')
983
984    def test_getfullargspec_signature_annos(self):
985        def test(a:'spam') -> 'ham': pass
986        spec = inspect.getfullargspec(test)
987        self.assertEqual(test.__annotations__, spec.annotations)
988
989        def test(): pass
990        spec = inspect.getfullargspec(test)
991        self.assertEqual(test.__annotations__, spec.annotations)
992
993    @unittest.skipIf(MISSING_C_DOCSTRINGS,
994                     "Signature information for builtins requires docstrings")
995    def test_getfullargspec_builtin_methods(self):
996        self.assertFullArgSpecEquals(_pickle.Pickler.dump, ['self', 'obj'],
997                                     formatted='(self, obj)')
998
999        self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump, ['self', 'obj'],
1000                                     formatted='(self, obj)')
1001
1002        self.assertFullArgSpecEquals(
1003             os.stat,
1004             args_e=['path'],
1005             kwonlyargs_e=['dir_fd', 'follow_symlinks'],
1006             kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True},
1007             formatted='(path, *, dir_fd=None, follow_symlinks=True)')
1008
1009    @cpython_only
1010    @unittest.skipIf(MISSING_C_DOCSTRINGS,
1011                     "Signature information for builtins requires docstrings")
1012    def test_getfullargspec_builtin_func(self):
1013        import _testcapi
1014        builtin = _testcapi.docstring_with_signature_with_defaults
1015        spec = inspect.getfullargspec(builtin)
1016        self.assertEqual(spec.defaults[0], 'avocado')
1017
1018    @cpython_only
1019    @unittest.skipIf(MISSING_C_DOCSTRINGS,
1020                     "Signature information for builtins requires docstrings")
1021    def test_getfullargspec_builtin_func_no_signature(self):
1022        import _testcapi
1023        builtin = _testcapi.docstring_no_signature
1024        with self.assertRaises(TypeError):
1025            inspect.getfullargspec(builtin)
1026
1027    def test_getfullargspec_definition_order_preserved_on_kwonly(self):
1028        for fn in signatures_with_lexicographic_keyword_only_parameters():
1029            signature = inspect.getfullargspec(fn)
1030            l = list(signature.kwonlyargs)
1031            sorted_l = sorted(l)
1032            self.assertTrue(l)
1033            self.assertEqual(l, sorted_l)
1034        signature = inspect.getfullargspec(unsorted_keyword_only_parameters_fn)
1035        l = list(signature.kwonlyargs)
1036        self.assertEqual(l, unsorted_keyword_only_parameters)
1037
1038    def test_getargspec_method(self):
1039        class A(object):
1040            def m(self):
1041                pass
1042        self.assertArgSpecEquals(A.m, ['self'])
1043
1044    def test_classify_newstyle(self):
1045        class A(object):
1046
1047            def s(): pass
1048            s = staticmethod(s)
1049
1050            def c(cls): pass
1051            c = classmethod(c)
1052
1053            def getp(self): pass
1054            p = property(getp)
1055
1056            def m(self): pass
1057
1058            def m1(self): pass
1059
1060            datablob = '1'
1061
1062            dd = _BrokenDataDescriptor()
1063            md = _BrokenMethodDescriptor()
1064
1065        attrs = attrs_wo_objs(A)
1066
1067        self.assertIn(('__new__', 'static method', object), attrs,
1068                      'missing __new__')
1069        self.assertIn(('__init__', 'method', object), attrs, 'missing __init__')
1070
1071        self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1072        self.assertIn(('c', 'class method', A), attrs, 'missing class method')
1073        self.assertIn(('p', 'property', A), attrs, 'missing property')
1074        self.assertIn(('m', 'method', A), attrs,
1075                      'missing plain method: %r' % attrs)
1076        self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
1077        self.assertIn(('datablob', 'data', A), attrs, 'missing data')
1078        self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1079        self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
1080
1081        class B(A):
1082
1083            def m(self): pass
1084
1085        attrs = attrs_wo_objs(B)
1086        self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1087        self.assertIn(('c', 'class method', A), attrs, 'missing class method')
1088        self.assertIn(('p', 'property', A), attrs, 'missing property')
1089        self.assertIn(('m', 'method', B), attrs, 'missing plain method')
1090        self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
1091        self.assertIn(('datablob', 'data', A), attrs, 'missing data')
1092        self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1093        self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
1094
1095
1096        class C(A):
1097
1098            def m(self): pass
1099            def c(self): pass
1100
1101        attrs = attrs_wo_objs(C)
1102        self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1103        self.assertIn(('c', 'method', C), attrs, 'missing plain method')
1104        self.assertIn(('p', 'property', A), attrs, 'missing property')
1105        self.assertIn(('m', 'method', C), attrs, 'missing plain method')
1106        self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
1107        self.assertIn(('datablob', 'data', A), attrs, 'missing data')
1108        self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1109        self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
1110
1111        class D(B, C):
1112
1113            def m1(self): pass
1114
1115        attrs = attrs_wo_objs(D)
1116        self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1117        self.assertIn(('c', 'method', C), attrs, 'missing plain method')
1118        self.assertIn(('p', 'property', A), attrs, 'missing property')
1119        self.assertIn(('m', 'method', B), attrs, 'missing plain method')
1120        self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
1121        self.assertIn(('datablob', 'data', A), attrs, 'missing data')
1122        self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1123        self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
1124
1125    def test_classify_builtin_types(self):
1126        # Simple sanity check that all built-in types can have their
1127        # attributes classified.
1128        for name in dir(__builtins__):
1129            builtin = getattr(__builtins__, name)
1130            if isinstance(builtin, type):
1131                inspect.classify_class_attrs(builtin)
1132
1133        attrs = attrs_wo_objs(bool)
1134        self.assertIn(('__new__', 'static method', bool), attrs,
1135                      'missing __new__')
1136        self.assertIn(('from_bytes', 'class method', int), attrs,
1137                      'missing class method')
1138        self.assertIn(('to_bytes', 'method', int), attrs,
1139                      'missing plain method')
1140        self.assertIn(('__add__', 'method', int), attrs,
1141                      'missing plain method')
1142        self.assertIn(('__and__', 'method', bool), attrs,
1143                      'missing plain method')
1144
1145    def test_classify_DynamicClassAttribute(self):
1146        class Meta(type):
1147            def __getattr__(self, name):
1148                if name == 'ham':
1149                    return 'spam'
1150                return super().__getattr__(name)
1151        class VA(metaclass=Meta):
1152            @types.DynamicClassAttribute
1153            def ham(self):
1154                return 'eggs'
1155        should_find_dca = inspect.Attribute('ham', 'data', VA, VA.__dict__['ham'])
1156        self.assertIn(should_find_dca, inspect.classify_class_attrs(VA))
1157        should_find_ga = inspect.Attribute('ham', 'data', Meta, 'spam')
1158        self.assertIn(should_find_ga, inspect.classify_class_attrs(VA))
1159
1160    def test_classify_overrides_bool(self):
1161        class NoBool(object):
1162            def __eq__(self, other):
1163                return NoBool()
1164
1165            def __bool__(self):
1166                raise NotImplementedError(
1167                    "This object does not specify a boolean value")
1168
1169        class HasNB(object):
1170            dd = NoBool()
1171
1172        should_find_attr = inspect.Attribute('dd', 'data', HasNB, HasNB.dd)
1173        self.assertIn(should_find_attr, inspect.classify_class_attrs(HasNB))
1174
1175    def test_classify_metaclass_class_attribute(self):
1176        class Meta(type):
1177            fish = 'slap'
1178            def __dir__(self):
1179                return ['__class__', '__module__', '__name__', 'fish']
1180        class Class(metaclass=Meta):
1181            pass
1182        should_find = inspect.Attribute('fish', 'data', Meta, 'slap')
1183        self.assertIn(should_find, inspect.classify_class_attrs(Class))
1184
1185    def test_classify_VirtualAttribute(self):
1186        class Meta(type):
1187            def __dir__(cls):
1188                return ['__class__', '__module__', '__name__', 'BOOM']
1189            def __getattr__(self, name):
1190                if name =='BOOM':
1191                    return 42
1192                return super().__getattr(name)
1193        class Class(metaclass=Meta):
1194            pass
1195        should_find = inspect.Attribute('BOOM', 'data', Meta, 42)
1196        self.assertIn(should_find, inspect.classify_class_attrs(Class))
1197
1198    def test_classify_VirtualAttribute_multi_classes(self):
1199        class Meta1(type):
1200            def __dir__(cls):
1201                return ['__class__', '__module__', '__name__', 'one']
1202            def __getattr__(self, name):
1203                if name =='one':
1204                    return 1
1205                return super().__getattr__(name)
1206        class Meta2(type):
1207            def __dir__(cls):
1208                return ['__class__', '__module__', '__name__', 'two']
1209            def __getattr__(self, name):
1210                if name =='two':
1211                    return 2
1212                return super().__getattr__(name)
1213        class Meta3(Meta1, Meta2):
1214            def __dir__(cls):
1215                return list(sorted(set(['__class__', '__module__', '__name__', 'three'] +
1216                    Meta1.__dir__(cls) + Meta2.__dir__(cls))))
1217            def __getattr__(self, name):
1218                if name =='three':
1219                    return 3
1220                return super().__getattr__(name)
1221        class Class1(metaclass=Meta1):
1222            pass
1223        class Class2(Class1, metaclass=Meta3):
1224            pass
1225
1226        should_find1 = inspect.Attribute('one', 'data', Meta1, 1)
1227        should_find2 = inspect.Attribute('two', 'data', Meta2, 2)
1228        should_find3 = inspect.Attribute('three', 'data', Meta3, 3)
1229        cca = inspect.classify_class_attrs(Class2)
1230        for sf in (should_find1, should_find2, should_find3):
1231            self.assertIn(sf, cca)
1232
1233    def test_classify_class_attrs_with_buggy_dir(self):
1234        class M(type):
1235            def __dir__(cls):
1236                return ['__class__', '__name__', 'missing']
1237        class C(metaclass=M):
1238            pass
1239        attrs = [a[0] for a in inspect.classify_class_attrs(C)]
1240        self.assertNotIn('missing', attrs)
1241
1242    def test_getmembers_descriptors(self):
1243        class A(object):
1244            dd = _BrokenDataDescriptor()
1245            md = _BrokenMethodDescriptor()
1246
1247        def pred_wrapper(pred):
1248            # A quick'n'dirty way to discard standard attributes of new-style
1249            # classes.
1250            class Empty(object):
1251                pass
1252            def wrapped(x):
1253                if '__name__' in dir(x) and hasattr(Empty, x.__name__):
1254                    return False
1255                return pred(x)
1256            return wrapped
1257
1258        ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
1259        isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
1260
1261        self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
1262            [('md', A.__dict__['md'])])
1263        self.assertEqual(inspect.getmembers(A, isdatadescriptor),
1264            [('dd', A.__dict__['dd'])])
1265
1266        class B(A):
1267            pass
1268
1269        self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
1270            [('md', A.__dict__['md'])])
1271        self.assertEqual(inspect.getmembers(B, isdatadescriptor),
1272            [('dd', A.__dict__['dd'])])
1273
1274    def test_getmembers_method(self):
1275        class B:
1276            def f(self):
1277                pass
1278
1279        self.assertIn(('f', B.f), inspect.getmembers(B))
1280        self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
1281        b = B()
1282        self.assertIn(('f', b.f), inspect.getmembers(b))
1283        self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
1284
1285    def test_getmembers_VirtualAttribute(self):
1286        class M(type):
1287            def __getattr__(cls, name):
1288                if name == 'eggs':
1289                    return 'scrambled'
1290                return super().__getattr__(name)
1291        class A(metaclass=M):
1292            @types.DynamicClassAttribute
1293            def eggs(self):
1294                return 'spam'
1295        self.assertIn(('eggs', 'scrambled'), inspect.getmembers(A))
1296        self.assertIn(('eggs', 'spam'), inspect.getmembers(A()))
1297
1298    def test_getmembers_with_buggy_dir(self):
1299        class M(type):
1300            def __dir__(cls):
1301                return ['__class__', '__name__', 'missing']
1302        class C(metaclass=M):
1303            pass
1304        attrs = [a[0] for a in inspect.getmembers(C)]
1305        self.assertNotIn('missing', attrs)
1306
1307    def test_get_annotations_with_stock_annotations(self):
1308        def foo(a:int, b:str): pass
1309        self.assertEqual(inspect.get_annotations(foo), {'a': int, 'b': str})
1310
1311        foo.__annotations__ = {'a': 'foo', 'b':'str'}
1312        self.assertEqual(inspect.get_annotations(foo), {'a': 'foo', 'b': 'str'})
1313
1314        self.assertEqual(inspect.get_annotations(foo, eval_str=True, locals=locals()), {'a': foo, 'b': str})
1315        self.assertEqual(inspect.get_annotations(foo, eval_str=True, globals=locals()), {'a': foo, 'b': str})
1316
1317        isa = inspect_stock_annotations
1318        self.assertEqual(inspect.get_annotations(isa), {'a': int, 'b': str})
1319        self.assertEqual(inspect.get_annotations(isa.MyClass), {'a': int, 'b': str})
1320        self.assertEqual(inspect.get_annotations(isa.function), {'a': int, 'b': str, 'return': isa.MyClass})
1321        self.assertEqual(inspect.get_annotations(isa.function2), {'a': int, 'b': 'str', 'c': isa.MyClass, 'return': isa.MyClass})
1322        self.assertEqual(inspect.get_annotations(isa.function3), {'a': 'int', 'b': 'str', 'c': 'MyClass'})
1323        self.assertEqual(inspect.get_annotations(inspect), {}) # inspect module has no annotations
1324        self.assertEqual(inspect.get_annotations(isa.UnannotatedClass), {})
1325        self.assertEqual(inspect.get_annotations(isa.unannotated_function), {})
1326
1327        self.assertEqual(inspect.get_annotations(isa, eval_str=True), {'a': int, 'b': str})
1328        self.assertEqual(inspect.get_annotations(isa.MyClass, eval_str=True), {'a': int, 'b': str})
1329        self.assertEqual(inspect.get_annotations(isa.function, eval_str=True), {'a': int, 'b': str, 'return': isa.MyClass})
1330        self.assertEqual(inspect.get_annotations(isa.function2, eval_str=True), {'a': int, 'b': str, 'c': isa.MyClass, 'return': isa.MyClass})
1331        self.assertEqual(inspect.get_annotations(isa.function3, eval_str=True), {'a': int, 'b': str, 'c': isa.MyClass})
1332        self.assertEqual(inspect.get_annotations(inspect, eval_str=True), {})
1333        self.assertEqual(inspect.get_annotations(isa.UnannotatedClass, eval_str=True), {})
1334        self.assertEqual(inspect.get_annotations(isa.unannotated_function, eval_str=True), {})
1335
1336        self.assertEqual(inspect.get_annotations(isa, eval_str=False), {'a': int, 'b': str})
1337        self.assertEqual(inspect.get_annotations(isa.MyClass, eval_str=False), {'a': int, 'b': str})
1338        self.assertEqual(inspect.get_annotations(isa.function, eval_str=False), {'a': int, 'b': str, 'return': isa.MyClass})
1339        self.assertEqual(inspect.get_annotations(isa.function2, eval_str=False), {'a': int, 'b': 'str', 'c': isa.MyClass, 'return': isa.MyClass})
1340        self.assertEqual(inspect.get_annotations(isa.function3, eval_str=False), {'a': 'int', 'b': 'str', 'c': 'MyClass'})
1341        self.assertEqual(inspect.get_annotations(inspect, eval_str=False), {})
1342        self.assertEqual(inspect.get_annotations(isa.UnannotatedClass, eval_str=False), {})
1343        self.assertEqual(inspect.get_annotations(isa.unannotated_function, eval_str=False), {})
1344
1345        def times_three(fn):
1346            @functools.wraps(fn)
1347            def wrapper(a, b):
1348                return fn(a*3, b*3)
1349            return wrapper
1350
1351        wrapped = times_three(isa.function)
1352        self.assertEqual(wrapped(1, 'x'), isa.MyClass(3, 'xxx'))
1353        self.assertIsNot(wrapped.__globals__, isa.function.__globals__)
1354        self.assertEqual(inspect.get_annotations(wrapped), {'a': int, 'b': str, 'return': isa.MyClass})
1355        self.assertEqual(inspect.get_annotations(wrapped, eval_str=True), {'a': int, 'b': str, 'return': isa.MyClass})
1356        self.assertEqual(inspect.get_annotations(wrapped, eval_str=False), {'a': int, 'b': str, 'return': isa.MyClass})
1357
1358    def test_get_annotations_with_stringized_annotations(self):
1359        isa = inspect_stringized_annotations
1360        self.assertEqual(inspect.get_annotations(isa), {'a': 'int', 'b': 'str'})
1361        self.assertEqual(inspect.get_annotations(isa.MyClass), {'a': 'int', 'b': 'str'})
1362        self.assertEqual(inspect.get_annotations(isa.function), {'a': 'int', 'b': 'str', 'return': 'MyClass'})
1363        self.assertEqual(inspect.get_annotations(isa.function2), {'a': 'int', 'b': "'str'", 'c': 'MyClass', 'return': 'MyClass'})
1364        self.assertEqual(inspect.get_annotations(isa.function3), {'a': "'int'", 'b': "'str'", 'c': "'MyClass'"})
1365        self.assertEqual(inspect.get_annotations(isa.UnannotatedClass), {})
1366        self.assertEqual(inspect.get_annotations(isa.unannotated_function), {})
1367
1368        self.assertEqual(inspect.get_annotations(isa, eval_str=True), {'a': int, 'b': str})
1369        self.assertEqual(inspect.get_annotations(isa.MyClass, eval_str=True), {'a': int, 'b': str})
1370        self.assertEqual(inspect.get_annotations(isa.function, eval_str=True), {'a': int, 'b': str, 'return': isa.MyClass})
1371        self.assertEqual(inspect.get_annotations(isa.function2, eval_str=True), {'a': int, 'b': 'str', 'c': isa.MyClass, 'return': isa.MyClass})
1372        self.assertEqual(inspect.get_annotations(isa.function3, eval_str=True), {'a': 'int', 'b': 'str', 'c': 'MyClass'})
1373        self.assertEqual(inspect.get_annotations(isa.UnannotatedClass, eval_str=True), {})
1374        self.assertEqual(inspect.get_annotations(isa.unannotated_function, eval_str=True), {})
1375
1376        self.assertEqual(inspect.get_annotations(isa, eval_str=False), {'a': 'int', 'b': 'str'})
1377        self.assertEqual(inspect.get_annotations(isa.MyClass, eval_str=False), {'a': 'int', 'b': 'str'})
1378        self.assertEqual(inspect.get_annotations(isa.function, eval_str=False), {'a': 'int', 'b': 'str', 'return': 'MyClass'})
1379        self.assertEqual(inspect.get_annotations(isa.function2, eval_str=False), {'a': 'int', 'b': "'str'", 'c': 'MyClass', 'return': 'MyClass'})
1380        self.assertEqual(inspect.get_annotations(isa.function3, eval_str=False), {'a': "'int'", 'b': "'str'", 'c': "'MyClass'"})
1381        self.assertEqual(inspect.get_annotations(isa.UnannotatedClass, eval_str=False), {})
1382        self.assertEqual(inspect.get_annotations(isa.unannotated_function, eval_str=False), {})
1383
1384        isa2 = inspect_stringized_annotations_2
1385        self.assertEqual(inspect.get_annotations(isa2), {})
1386        self.assertEqual(inspect.get_annotations(isa2, eval_str=True), {})
1387        self.assertEqual(inspect.get_annotations(isa2, eval_str=False), {})
1388
1389        def times_three(fn):
1390            @functools.wraps(fn)
1391            def wrapper(a, b):
1392                return fn(a*3, b*3)
1393            return wrapper
1394
1395        wrapped = times_three(isa.function)
1396        self.assertEqual(wrapped(1, 'x'), isa.MyClass(3, 'xxx'))
1397        self.assertIsNot(wrapped.__globals__, isa.function.__globals__)
1398        self.assertEqual(inspect.get_annotations(wrapped), {'a': 'int', 'b': 'str', 'return': 'MyClass'})
1399        self.assertEqual(inspect.get_annotations(wrapped, eval_str=True), {'a': int, 'b': str, 'return': isa.MyClass})
1400        self.assertEqual(inspect.get_annotations(wrapped, eval_str=False), {'a': 'int', 'b': 'str', 'return': 'MyClass'})
1401
1402        # test that local namespace lookups work
1403        self.assertEqual(inspect.get_annotations(isa.MyClassWithLocalAnnotations), {'x': 'mytype'})
1404        self.assertEqual(inspect.get_annotations(isa.MyClassWithLocalAnnotations, eval_str=True), {'x': int})
1405
1406
1407class TestIsDataDescriptor(unittest.TestCase):
1408
1409    def test_custom_descriptors(self):
1410        class NonDataDescriptor:
1411            def __get__(self, value, type=None): pass
1412        class DataDescriptor0:
1413            def __set__(self, name, value): pass
1414        class DataDescriptor1:
1415            def __delete__(self, name): pass
1416        class DataDescriptor2:
1417            __set__ = None
1418        self.assertFalse(inspect.isdatadescriptor(NonDataDescriptor()),
1419                         'class with only __get__ not a data descriptor')
1420        self.assertTrue(inspect.isdatadescriptor(DataDescriptor0()),
1421                        'class with __set__ is a data descriptor')
1422        self.assertTrue(inspect.isdatadescriptor(DataDescriptor1()),
1423                        'class with __delete__ is a data descriptor')
1424        self.assertTrue(inspect.isdatadescriptor(DataDescriptor2()),
1425                        'class with __set__ = None is a data descriptor')
1426
1427    def test_slot(self):
1428        class Slotted:
1429            __slots__ = 'foo',
1430        self.assertTrue(inspect.isdatadescriptor(Slotted.foo),
1431                        'a slot is a data descriptor')
1432
1433    def test_property(self):
1434        class Propertied:
1435            @property
1436            def a_property(self):
1437                pass
1438        self.assertTrue(inspect.isdatadescriptor(Propertied.a_property),
1439                        'a property is a data descriptor')
1440
1441    def test_functions(self):
1442        class Test(object):
1443            def instance_method(self): pass
1444            @classmethod
1445            def class_method(cls): pass
1446            @staticmethod
1447            def static_method(): pass
1448        def function():
1449            pass
1450        a_lambda = lambda: None
1451        self.assertFalse(inspect.isdatadescriptor(Test().instance_method),
1452                         'a instance method is not a data descriptor')
1453        self.assertFalse(inspect.isdatadescriptor(Test().class_method),
1454                         'a class method is not a data descriptor')
1455        self.assertFalse(inspect.isdatadescriptor(Test().static_method),
1456                         'a static method is not a data descriptor')
1457        self.assertFalse(inspect.isdatadescriptor(function),
1458                         'a function is not a data descriptor')
1459        self.assertFalse(inspect.isdatadescriptor(a_lambda),
1460                         'a lambda is not a data descriptor')
1461
1462
1463_global_ref = object()
1464class TestGetClosureVars(unittest.TestCase):
1465
1466    def test_name_resolution(self):
1467        # Basic test of the 4 different resolution mechanisms
1468        def f(nonlocal_ref):
1469            def g(local_ref):
1470                print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1471            return g
1472        _arg = object()
1473        nonlocal_vars = {"nonlocal_ref": _arg}
1474        global_vars = {"_global_ref": _global_ref}
1475        builtin_vars = {"print": print}
1476        unbound_names = {"unbound_ref"}
1477        expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1478                                       builtin_vars, unbound_names)
1479        self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1480
1481    def test_generator_closure(self):
1482        def f(nonlocal_ref):
1483            def g(local_ref):
1484                print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1485                yield
1486            return g
1487        _arg = object()
1488        nonlocal_vars = {"nonlocal_ref": _arg}
1489        global_vars = {"_global_ref": _global_ref}
1490        builtin_vars = {"print": print}
1491        unbound_names = {"unbound_ref"}
1492        expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1493                                       builtin_vars, unbound_names)
1494        self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
1495
1496    def test_method_closure(self):
1497        class C:
1498            def f(self, nonlocal_ref):
1499                def g(local_ref):
1500                    print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
1501                return g
1502        _arg = object()
1503        nonlocal_vars = {"nonlocal_ref": _arg}
1504        global_vars = {"_global_ref": _global_ref}
1505        builtin_vars = {"print": print}
1506        unbound_names = {"unbound_ref"}
1507        expected = inspect.ClosureVars(nonlocal_vars, global_vars,
1508                                       builtin_vars, unbound_names)
1509        self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
1510
1511    def test_nonlocal_vars(self):
1512        # More complex tests of nonlocal resolution
1513        def _nonlocal_vars(f):
1514            return inspect.getclosurevars(f).nonlocals
1515
1516        def make_adder(x):
1517            def add(y):
1518                return x + y
1519            return add
1520
1521        def curry(func, arg1):
1522            return lambda arg2: func(arg1, arg2)
1523
1524        def less_than(a, b):
1525            return a < b
1526
1527        # The infamous Y combinator.
1528        def Y(le):
1529            def g(f):
1530                return le(lambda x: f(f)(x))
1531            Y.g_ref = g
1532            return g(g)
1533
1534        def check_y_combinator(func):
1535            self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
1536
1537        inc = make_adder(1)
1538        add_two = make_adder(2)
1539        greater_than_five = curry(less_than, 5)
1540
1541        self.assertEqual(_nonlocal_vars(inc), {'x': 1})
1542        self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
1543        self.assertEqual(_nonlocal_vars(greater_than_five),
1544                         {'arg1': 5, 'func': less_than})
1545        self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
1546                         {'x': 3})
1547        Y(check_y_combinator)
1548
1549    def test_getclosurevars_empty(self):
1550        def foo(): pass
1551        _empty = inspect.ClosureVars({}, {}, {}, set())
1552        self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
1553        self.assertEqual(inspect.getclosurevars(foo), _empty)
1554
1555    def test_getclosurevars_error(self):
1556        class T: pass
1557        self.assertRaises(TypeError, inspect.getclosurevars, 1)
1558        self.assertRaises(TypeError, inspect.getclosurevars, list)
1559        self.assertRaises(TypeError, inspect.getclosurevars, {})
1560
1561    def _private_globals(self):
1562        code = """def f(): print(path)"""
1563        ns = {}
1564        exec(code, ns)
1565        return ns["f"], ns
1566
1567    def test_builtins_fallback(self):
1568        f, ns = self._private_globals()
1569        ns.pop("__builtins__", None)
1570        expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
1571        self.assertEqual(inspect.getclosurevars(f), expected)
1572
1573    def test_builtins_as_dict(self):
1574        f, ns = self._private_globals()
1575        ns["__builtins__"] = {"path":1}
1576        expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
1577        self.assertEqual(inspect.getclosurevars(f), expected)
1578
1579    def test_builtins_as_module(self):
1580        f, ns = self._private_globals()
1581        ns["__builtins__"] = os
1582        expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
1583        self.assertEqual(inspect.getclosurevars(f), expected)
1584
1585
1586class TestGetcallargsFunctions(unittest.TestCase):
1587
1588    def assertEqualCallArgs(self, func, call_params_string, locs=None):
1589        locs = dict(locs or {}, func=func)
1590        r1 = eval('func(%s)' % call_params_string, None, locs)
1591        r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
1592                  locs)
1593        self.assertEqual(r1, r2)
1594
1595    def assertEqualException(self, func, call_param_string, locs=None):
1596        locs = dict(locs or {}, func=func)
1597        try:
1598            eval('func(%s)' % call_param_string, None, locs)
1599        except Exception as e:
1600            ex1 = e
1601        else:
1602            self.fail('Exception not raised')
1603        try:
1604            eval('inspect.getcallargs(func, %s)' % call_param_string, None,
1605                 locs)
1606        except Exception as e:
1607            ex2 = e
1608        else:
1609            self.fail('Exception not raised')
1610        self.assertIs(type(ex1), type(ex2))
1611        self.assertEqual(str(ex1), str(ex2))
1612        del ex1, ex2
1613
1614    def makeCallable(self, signature):
1615        """Create a function that returns its locals()"""
1616        code = "lambda %s: locals()"
1617        return eval(code % signature)
1618
1619    def test_plain(self):
1620        f = self.makeCallable('a, b=1')
1621        self.assertEqualCallArgs(f, '2')
1622        self.assertEqualCallArgs(f, '2, 3')
1623        self.assertEqualCallArgs(f, 'a=2')
1624        self.assertEqualCallArgs(f, 'b=3, a=2')
1625        self.assertEqualCallArgs(f, '2, b=3')
1626        # expand *iterable / **mapping
1627        self.assertEqualCallArgs(f, '*(2,)')
1628        self.assertEqualCallArgs(f, '*[2]')
1629        self.assertEqualCallArgs(f, '*(2, 3)')
1630        self.assertEqualCallArgs(f, '*[2, 3]')
1631        self.assertEqualCallArgs(f, '**{"a":2}')
1632        self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
1633        self.assertEqualCallArgs(f, '2, **{"b":3}')
1634        self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
1635        # expand UserList / UserDict
1636        self.assertEqualCallArgs(f, '*collections.UserList([2])')
1637        self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
1638        self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
1639        self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
1640        self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
1641
1642    def test_varargs(self):
1643        f = self.makeCallable('a, b=1, *c')
1644        self.assertEqualCallArgs(f, '2')
1645        self.assertEqualCallArgs(f, '2, 3')
1646        self.assertEqualCallArgs(f, '2, 3, 4')
1647        self.assertEqualCallArgs(f, '*(2,3,4)')
1648        self.assertEqualCallArgs(f, '2, *[3,4]')
1649        self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
1650
1651    def test_varkw(self):
1652        f = self.makeCallable('a, b=1, **c')
1653        self.assertEqualCallArgs(f, 'a=2')
1654        self.assertEqualCallArgs(f, '2, b=3, c=4')
1655        self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
1656        self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
1657        self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
1658        self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
1659        self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
1660        self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
1661        self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
1662
1663    def test_varkw_only(self):
1664        # issue11256:
1665        f = self.makeCallable('**c')
1666        self.assertEqualCallArgs(f, '')
1667        self.assertEqualCallArgs(f, 'a=1')
1668        self.assertEqualCallArgs(f, 'a=1, b=2')
1669        self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
1670        self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
1671        self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
1672
1673    def test_keyword_only(self):
1674        f = self.makeCallable('a=3, *, c, d=2')
1675        self.assertEqualCallArgs(f, 'c=3')
1676        self.assertEqualCallArgs(f, 'c=3, a=3')
1677        self.assertEqualCallArgs(f, 'a=2, c=4')
1678        self.assertEqualCallArgs(f, '4, c=4')
1679        self.assertEqualException(f, '')
1680        self.assertEqualException(f, '3')
1681        self.assertEqualException(f, 'a=3')
1682        self.assertEqualException(f, 'd=4')
1683
1684        f = self.makeCallable('*, c, d=2')
1685        self.assertEqualCallArgs(f, 'c=3')
1686        self.assertEqualCallArgs(f, 'c=3, d=4')
1687        self.assertEqualCallArgs(f, 'd=4, c=3')
1688
1689    def test_multiple_features(self):
1690        f = self.makeCallable('a, b=2, *f, **g')
1691        self.assertEqualCallArgs(f, '2, 3, 7')
1692        self.assertEqualCallArgs(f, '2, 3, x=8')
1693        self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1694        self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
1695        self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
1696        self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1697                                 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
1698        self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1699                                 '(4,[5,6])]), **collections.UserDict('
1700                                 'y=9, z=10)')
1701
1702        f = self.makeCallable('a, b=2, *f, x, y=99, **g')
1703        self.assertEqualCallArgs(f, '2, 3, x=8')
1704        self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
1705        self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
1706        self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
1707        self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
1708                                 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
1709        self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
1710                                 '(4,[5,6])]), q=0, **collections.UserDict('
1711                                 'y=9, z=10)')
1712
1713    def test_errors(self):
1714        f0 = self.makeCallable('')
1715        f1 = self.makeCallable('a, b')
1716        f2 = self.makeCallable('a, b=1')
1717        # f0 takes no arguments
1718        self.assertEqualException(f0, '1')
1719        self.assertEqualException(f0, 'x=1')
1720        self.assertEqualException(f0, '1,x=1')
1721        # f1 takes exactly 2 arguments
1722        self.assertEqualException(f1, '')
1723        self.assertEqualException(f1, '1')
1724        self.assertEqualException(f1, 'a=2')
1725        self.assertEqualException(f1, 'b=3')
1726        # f2 takes at least 1 argument
1727        self.assertEqualException(f2, '')
1728        self.assertEqualException(f2, 'b=3')
1729        for f in f1, f2:
1730            # f1/f2 takes exactly/at most 2 arguments
1731            self.assertEqualException(f, '2, 3, 4')
1732            self.assertEqualException(f, '1, 2, 3, a=1')
1733            self.assertEqualException(f, '2, 3, 4, c=5')
1734            # XXX: success of this one depends on dict order
1735            ## self.assertEqualException(f, '2, 3, 4, a=1, c=5')
1736            # f got an unexpected keyword argument
1737            self.assertEqualException(f, 'c=2')
1738            self.assertEqualException(f, '2, c=3')
1739            self.assertEqualException(f, '2, 3, c=4')
1740            self.assertEqualException(f, '2, c=4, b=3')
1741            self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
1742            # f got multiple values for keyword argument
1743            self.assertEqualException(f, '1, a=2')
1744            self.assertEqualException(f, '1, **{"a":2}')
1745            self.assertEqualException(f, '1, 2, b=3')
1746            # XXX: Python inconsistency
1747            # - for functions and bound methods: unexpected keyword 'c'
1748            # - for unbound methods: multiple values for keyword 'a'
1749            #self.assertEqualException(f, '1, c=3, a=2')
1750        # issue11256:
1751        f3 = self.makeCallable('**c')
1752        self.assertEqualException(f3, '1, 2')
1753        self.assertEqualException(f3, '1, 2, a=1, b=2')
1754        f4 = self.makeCallable('*, a, b=0')
1755        self.assertEqualException(f3, '1, 2')
1756        self.assertEqualException(f3, '1, 2, a=1, b=2')
1757
1758        # issue #20816: getcallargs() fails to iterate over non-existent
1759        # kwonlydefaults and raises a wrong TypeError
1760        def f5(*, a): pass
1761        with self.assertRaisesRegex(TypeError,
1762                                    'missing 1 required keyword-only'):
1763            inspect.getcallargs(f5)
1764
1765
1766        # issue20817:
1767        def f6(a, b, c):
1768            pass
1769        with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"):
1770            inspect.getcallargs(f6)
1771
1772        # bpo-33197
1773        with self.assertRaisesRegex(ValueError,
1774                                    'variadic keyword parameters cannot'
1775                                    ' have default values'):
1776            inspect.Parameter("foo", kind=inspect.Parameter.VAR_KEYWORD,
1777                              default=42)
1778        with self.assertRaisesRegex(ValueError,
1779                                    "value 5 is not a valid Parameter.kind"):
1780            inspect.Parameter("bar", kind=5, default=42)
1781
1782        with self.assertRaisesRegex(TypeError,
1783                                   'name must be a str, not a int'):
1784            inspect.Parameter(123, kind=4)
1785
1786class TestGetcallargsMethods(TestGetcallargsFunctions):
1787
1788    def setUp(self):
1789        class Foo(object):
1790            pass
1791        self.cls = Foo
1792        self.inst = Foo()
1793
1794    def makeCallable(self, signature):
1795        assert 'self' not in signature
1796        mk = super(TestGetcallargsMethods, self).makeCallable
1797        self.cls.method = mk('self, ' + signature)
1798        return self.inst.method
1799
1800class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
1801
1802    def makeCallable(self, signature):
1803        super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
1804        return self.cls.method
1805
1806    def assertEqualCallArgs(self, func, call_params_string, locs=None):
1807        return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
1808            *self._getAssertEqualParams(func, call_params_string, locs))
1809
1810    def assertEqualException(self, func, call_params_string, locs=None):
1811        return super(TestGetcallargsUnboundMethods, self).assertEqualException(
1812            *self._getAssertEqualParams(func, call_params_string, locs))
1813
1814    def _getAssertEqualParams(self, func, call_params_string, locs=None):
1815        assert 'inst' not in call_params_string
1816        locs = dict(locs or {}, inst=self.inst)
1817        return (func, 'inst,' + call_params_string, locs)
1818
1819
1820class TestGetattrStatic(unittest.TestCase):
1821
1822    def test_basic(self):
1823        class Thing(object):
1824            x = object()
1825
1826        thing = Thing()
1827        self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1828        self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
1829        with self.assertRaises(AttributeError):
1830            inspect.getattr_static(thing, 'y')
1831
1832        self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
1833
1834    def test_inherited(self):
1835        class Thing(object):
1836            x = object()
1837        class OtherThing(Thing):
1838            pass
1839
1840        something = OtherThing()
1841        self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
1842
1843    def test_instance_attr(self):
1844        class Thing(object):
1845            x = 2
1846            def __init__(self, x):
1847                self.x = x
1848        thing = Thing(3)
1849        self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
1850        del thing.x
1851        self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
1852
1853    def test_property(self):
1854        class Thing(object):
1855            @property
1856            def x(self):
1857                raise AttributeError("I'm pretending not to exist")
1858        thing = Thing()
1859        self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1860
1861    def test_descriptor_raises_AttributeError(self):
1862        class descriptor(object):
1863            def __get__(*_):
1864                raise AttributeError("I'm pretending not to exist")
1865        desc = descriptor()
1866        class Thing(object):
1867            x = desc
1868        thing = Thing()
1869        self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
1870
1871    def test_classAttribute(self):
1872        class Thing(object):
1873            x = object()
1874
1875        self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
1876
1877    def test_classVirtualAttribute(self):
1878        class Thing(object):
1879            @types.DynamicClassAttribute
1880            def x(self):
1881                return self._x
1882            _x = object()
1883
1884        self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.__dict__['x'])
1885
1886    def test_inherited_classattribute(self):
1887        class Thing(object):
1888            x = object()
1889        class OtherThing(Thing):
1890            pass
1891
1892        self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
1893
1894    def test_slots(self):
1895        class Thing(object):
1896            y = 'bar'
1897            __slots__ = ['x']
1898            def __init__(self):
1899                self.x = 'foo'
1900        thing = Thing()
1901        self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1902        self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
1903
1904        del thing.x
1905        self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
1906
1907    def test_metaclass(self):
1908        class meta(type):
1909            attr = 'foo'
1910        class Thing(object, metaclass=meta):
1911            pass
1912        self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
1913
1914        class sub(meta):
1915            pass
1916        class OtherThing(object, metaclass=sub):
1917            x = 3
1918        self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
1919
1920        class OtherOtherThing(OtherThing):
1921            pass
1922        # this test is odd, but it was added as it exposed a bug
1923        self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
1924
1925    def test_no_dict_no_slots(self):
1926        self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
1927        self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
1928
1929    def test_no_dict_no_slots_instance_member(self):
1930        # returns descriptor
1931        with open(__file__, encoding='utf-8') as handle:
1932            self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
1933
1934    def test_inherited_slots(self):
1935        # returns descriptor
1936        class Thing(object):
1937            __slots__ = ['x']
1938            def __init__(self):
1939                self.x = 'foo'
1940
1941        class OtherThing(Thing):
1942            pass
1943        # it would be nice if this worked...
1944        # we get the descriptor instead of the instance attribute
1945        self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
1946
1947    def test_descriptor(self):
1948        class descriptor(object):
1949            def __get__(self, instance, owner):
1950                return 3
1951        class Foo(object):
1952            d = descriptor()
1953
1954        foo = Foo()
1955
1956        # for a non data descriptor we return the instance attribute
1957        foo.__dict__['d'] = 1
1958        self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
1959
1960        # if the descriptor is a data-descriptor we should return the
1961        # descriptor
1962        descriptor.__set__ = lambda s, i, v: None
1963        self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
1964
1965
1966    def test_metaclass_with_descriptor(self):
1967        class descriptor(object):
1968            def __get__(self, instance, owner):
1969                return 3
1970        class meta(type):
1971            d = descriptor()
1972        class Thing(object, metaclass=meta):
1973            pass
1974        self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
1975
1976
1977    def test_class_as_property(self):
1978        class Base(object):
1979            foo = 3
1980
1981        class Something(Base):
1982            executed = False
1983            @property
1984            def __class__(self):
1985                self.executed = True
1986                return object
1987
1988        instance = Something()
1989        self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
1990        self.assertFalse(instance.executed)
1991        self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
1992
1993    def test_mro_as_property(self):
1994        class Meta(type):
1995            @property
1996            def __mro__(self):
1997                return (object,)
1998
1999        class Base(object):
2000            foo = 3
2001
2002        class Something(Base, metaclass=Meta):
2003            pass
2004
2005        self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
2006        self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
2007
2008    def test_dict_as_property(self):
2009        test = self
2010        test.called = False
2011
2012        class Foo(dict):
2013            a = 3
2014            @property
2015            def __dict__(self):
2016                test.called = True
2017                return {}
2018
2019        foo = Foo()
2020        foo.a = 4
2021        self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
2022        self.assertFalse(test.called)
2023
2024    def test_custom_object_dict(self):
2025        test = self
2026        test.called = False
2027
2028        class Custom(dict):
2029            def get(self, key, default=None):
2030                test.called = True
2031                super().get(key, default)
2032
2033        class Foo(object):
2034            a = 3
2035        foo = Foo()
2036        foo.__dict__ = Custom()
2037        self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
2038        self.assertFalse(test.called)
2039
2040    def test_metaclass_dict_as_property(self):
2041        class Meta(type):
2042            @property
2043            def __dict__(self):
2044                self.executed = True
2045
2046        class Thing(metaclass=Meta):
2047            executed = False
2048
2049            def __init__(self):
2050                self.spam = 42
2051
2052        instance = Thing()
2053        self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
2054        self.assertFalse(Thing.executed)
2055
2056    def test_module(self):
2057        sentinel = object()
2058        self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
2059                         sentinel)
2060
2061    def test_metaclass_with_metaclass_with_dict_as_property(self):
2062        class MetaMeta(type):
2063            @property
2064            def __dict__(self):
2065                self.executed = True
2066                return dict(spam=42)
2067
2068        class Meta(type, metaclass=MetaMeta):
2069            executed = False
2070
2071        class Thing(metaclass=Meta):
2072            pass
2073
2074        with self.assertRaises(AttributeError):
2075            inspect.getattr_static(Thing, "spam")
2076        self.assertFalse(Thing.executed)
2077
2078class TestGetGeneratorState(unittest.TestCase):
2079
2080    def setUp(self):
2081        def number_generator():
2082            for number in range(5):
2083                yield number
2084        self.generator = number_generator()
2085
2086    def _generatorstate(self):
2087        return inspect.getgeneratorstate(self.generator)
2088
2089    def test_created(self):
2090        self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
2091
2092    def test_suspended(self):
2093        next(self.generator)
2094        self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
2095
2096    def test_closed_after_exhaustion(self):
2097        for i in self.generator:
2098            pass
2099        self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
2100
2101    def test_closed_after_immediate_exception(self):
2102        with self.assertRaises(RuntimeError):
2103            self.generator.throw(RuntimeError)
2104        self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
2105
2106    def test_running(self):
2107        # As mentioned on issue #10220, checking for the RUNNING state only
2108        # makes sense inside the generator itself.
2109        # The following generator checks for this by using the closure's
2110        # reference to self and the generator state checking helper method
2111        def running_check_generator():
2112            for number in range(5):
2113                self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
2114                yield number
2115                self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
2116        self.generator = running_check_generator()
2117        # Running up to the first yield
2118        next(self.generator)
2119        # Running after the first yield
2120        next(self.generator)
2121
2122    def test_easy_debugging(self):
2123        # repr() and str() of a generator state should contain the state name
2124        names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
2125        for name in names:
2126            state = getattr(inspect, name)
2127            self.assertIn(name, repr(state))
2128            self.assertIn(name, str(state))
2129
2130    def test_getgeneratorlocals(self):
2131        def each(lst, a=None):
2132            b=(1, 2, 3)
2133            for v in lst:
2134                if v == 3:
2135                    c = 12
2136                yield v
2137
2138        numbers = each([1, 2, 3])
2139        self.assertEqual(inspect.getgeneratorlocals(numbers),
2140                         {'a': None, 'lst': [1, 2, 3]})
2141        next(numbers)
2142        self.assertEqual(inspect.getgeneratorlocals(numbers),
2143                         {'a': None, 'lst': [1, 2, 3], 'v': 1,
2144                          'b': (1, 2, 3)})
2145        next(numbers)
2146        self.assertEqual(inspect.getgeneratorlocals(numbers),
2147                         {'a': None, 'lst': [1, 2, 3], 'v': 2,
2148                          'b': (1, 2, 3)})
2149        next(numbers)
2150        self.assertEqual(inspect.getgeneratorlocals(numbers),
2151                         {'a': None, 'lst': [1, 2, 3], 'v': 3,
2152                          'b': (1, 2, 3), 'c': 12})
2153        try:
2154            next(numbers)
2155        except StopIteration:
2156            pass
2157        self.assertEqual(inspect.getgeneratorlocals(numbers), {})
2158
2159    def test_getgeneratorlocals_empty(self):
2160        def yield_one():
2161            yield 1
2162        one = yield_one()
2163        self.assertEqual(inspect.getgeneratorlocals(one), {})
2164        try:
2165            next(one)
2166        except StopIteration:
2167            pass
2168        self.assertEqual(inspect.getgeneratorlocals(one), {})
2169
2170    def test_getgeneratorlocals_error(self):
2171        self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
2172        self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
2173        self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
2174        self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
2175
2176
2177class TestGetCoroutineState(unittest.TestCase):
2178
2179    def setUp(self):
2180        @types.coroutine
2181        def number_coroutine():
2182            for number in range(5):
2183                yield number
2184        async def coroutine():
2185            await number_coroutine()
2186        self.coroutine = coroutine()
2187
2188    def tearDown(self):
2189        self.coroutine.close()
2190
2191    def _coroutinestate(self):
2192        return inspect.getcoroutinestate(self.coroutine)
2193
2194    def test_created(self):
2195        self.assertEqual(self._coroutinestate(), inspect.CORO_CREATED)
2196
2197    def test_suspended(self):
2198        self.coroutine.send(None)
2199        self.assertEqual(self._coroutinestate(), inspect.CORO_SUSPENDED)
2200
2201    def test_closed_after_exhaustion(self):
2202        while True:
2203            try:
2204                self.coroutine.send(None)
2205            except StopIteration:
2206                break
2207
2208        self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
2209
2210    def test_closed_after_immediate_exception(self):
2211        with self.assertRaises(RuntimeError):
2212            self.coroutine.throw(RuntimeError)
2213        self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
2214
2215    def test_easy_debugging(self):
2216        # repr() and str() of a coroutine state should contain the state name
2217        names = 'CORO_CREATED CORO_RUNNING CORO_SUSPENDED CORO_CLOSED'.split()
2218        for name in names:
2219            state = getattr(inspect, name)
2220            self.assertIn(name, repr(state))
2221            self.assertIn(name, str(state))
2222
2223    def test_getcoroutinelocals(self):
2224        @types.coroutine
2225        def gencoro():
2226            yield
2227
2228        gencoro = gencoro()
2229        async def func(a=None):
2230            b = 'spam'
2231            await gencoro
2232
2233        coro = func()
2234        self.assertEqual(inspect.getcoroutinelocals(coro),
2235                         {'a': None, 'gencoro': gencoro})
2236        coro.send(None)
2237        self.assertEqual(inspect.getcoroutinelocals(coro),
2238                         {'a': None, 'gencoro': gencoro, 'b': 'spam'})
2239
2240
2241class MySignature(inspect.Signature):
2242    # Top-level to make it picklable;
2243    # used in test_signature_object_pickle
2244    pass
2245
2246class MyParameter(inspect.Parameter):
2247    # Top-level to make it picklable;
2248    # used in test_signature_object_pickle
2249    pass
2250
2251
2252
2253class TestSignatureObject(unittest.TestCase):
2254    @staticmethod
2255    def signature(func, **kw):
2256        sig = inspect.signature(func, **kw)
2257        return (tuple((param.name,
2258                       (... if param.default is param.empty else param.default),
2259                       (... if param.annotation is param.empty
2260                                                        else param.annotation),
2261                       str(param.kind).lower())
2262                                    for param in sig.parameters.values()),
2263                (... if sig.return_annotation is sig.empty
2264                                            else sig.return_annotation))
2265
2266    def test_signature_object(self):
2267        S = inspect.Signature
2268        P = inspect.Parameter
2269
2270        self.assertEqual(str(S()), '()')
2271        self.assertEqual(repr(S().parameters), 'mappingproxy(OrderedDict())')
2272
2273        def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs):
2274            pass
2275        sig = inspect.signature(test)
2276        po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY)
2277        pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY)
2278        pk = sig.parameters['pk']
2279        pkd = sig.parameters['pkd']
2280        args = sig.parameters['args']
2281        ko = sig.parameters['ko']
2282        kwargs = sig.parameters['kwargs']
2283
2284        S((po, pk, args, ko, kwargs))
2285
2286        with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
2287            S((pk, po, args, ko, kwargs))
2288
2289        with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
2290            S((po, args, pk, ko, kwargs))
2291
2292        with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
2293            S((args, po, pk, ko, kwargs))
2294
2295        with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
2296            S((po, pk, args, kwargs, ko))
2297
2298        kwargs2 = kwargs.replace(name='args')
2299        with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
2300            S((po, pk, args, kwargs2, ko))
2301
2302        with self.assertRaisesRegex(ValueError, 'follows default argument'):
2303            S((pod, po))
2304
2305        with self.assertRaisesRegex(ValueError, 'follows default argument'):
2306            S((po, pkd, pk))
2307
2308        with self.assertRaisesRegex(ValueError, 'follows default argument'):
2309            S((pkd, pk))
2310
2311        self.assertTrue(repr(sig).startswith('<Signature'))
2312        self.assertTrue('(po, pk' in repr(sig))
2313
2314    def test_signature_object_pickle(self):
2315        def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
2316        foo_partial = functools.partial(foo, a=1)
2317
2318        sig = inspect.signature(foo_partial)
2319
2320        for ver in range(pickle.HIGHEST_PROTOCOL + 1):
2321            with self.subTest(pickle_ver=ver, subclass=False):
2322                sig_pickled = pickle.loads(pickle.dumps(sig, ver))
2323                self.assertEqual(sig, sig_pickled)
2324
2325        # Test that basic sub-classing works
2326        sig = inspect.signature(foo)
2327        myparam = MyParameter(name='z', kind=inspect.Parameter.POSITIONAL_ONLY)
2328        myparams = collections.OrderedDict(sig.parameters, a=myparam)
2329        mysig = MySignature().replace(parameters=myparams.values(),
2330                                      return_annotation=sig.return_annotation)
2331        self.assertTrue(isinstance(mysig, MySignature))
2332        self.assertTrue(isinstance(mysig.parameters['z'], MyParameter))
2333
2334        for ver in range(pickle.HIGHEST_PROTOCOL + 1):
2335            with self.subTest(pickle_ver=ver, subclass=True):
2336                sig_pickled = pickle.loads(pickle.dumps(mysig, ver))
2337                self.assertEqual(mysig, sig_pickled)
2338                self.assertTrue(isinstance(sig_pickled, MySignature))
2339                self.assertTrue(isinstance(sig_pickled.parameters['z'],
2340                                           MyParameter))
2341
2342    def test_signature_immutability(self):
2343        def test(a):
2344            pass
2345        sig = inspect.signature(test)
2346
2347        with self.assertRaises(AttributeError):
2348            sig.foo = 'bar'
2349
2350        with self.assertRaises(TypeError):
2351            sig.parameters['a'] = None
2352
2353    def test_signature_on_noarg(self):
2354        def test():
2355            pass
2356        self.assertEqual(self.signature(test), ((), ...))
2357
2358    def test_signature_on_wargs(self):
2359        def test(a, b:'foo') -> 123:
2360            pass
2361        self.assertEqual(self.signature(test),
2362                         ((('a', ..., ..., "positional_or_keyword"),
2363                           ('b', ..., 'foo', "positional_or_keyword")),
2364                          123))
2365
2366    def test_signature_on_wkwonly(self):
2367        def test(*, a:float, b:str) -> int:
2368            pass
2369        self.assertEqual(self.signature(test),
2370                         ((('a', ..., float, "keyword_only"),
2371                           ('b', ..., str, "keyword_only")),
2372                           int))
2373
2374    def test_signature_on_complex_args(self):
2375        def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
2376            pass
2377        self.assertEqual(self.signature(test),
2378                         ((('a', ..., ..., "positional_or_keyword"),
2379                           ('b', 10, 'foo', "positional_or_keyword"),
2380                           ('args', ..., 'bar', "var_positional"),
2381                           ('spam', ..., 'baz', "keyword_only"),
2382                           ('ham', 123, ..., "keyword_only"),
2383                           ('kwargs', ..., int, "var_keyword")),
2384                          ...))
2385
2386    def test_signature_without_self(self):
2387        def test_args_only(*args):  # NOQA
2388            pass
2389
2390        def test_args_kwargs_only(*args, **kwargs):  # NOQA
2391            pass
2392
2393        class A:
2394            @classmethod
2395            def test_classmethod(*args):  # NOQA
2396                pass
2397
2398            @staticmethod
2399            def test_staticmethod(*args):  # NOQA
2400                pass
2401
2402            f1 = functools.partialmethod((test_classmethod), 1)
2403            f2 = functools.partialmethod((test_args_only), 1)
2404            f3 = functools.partialmethod((test_staticmethod), 1)
2405            f4 = functools.partialmethod((test_args_kwargs_only),1)
2406
2407        self.assertEqual(self.signature(test_args_only),
2408                         ((('args', ..., ..., 'var_positional'),), ...))
2409        self.assertEqual(self.signature(test_args_kwargs_only),
2410                         ((('args', ..., ..., 'var_positional'),
2411                           ('kwargs', ..., ..., 'var_keyword')), ...))
2412        self.assertEqual(self.signature(A.f1),
2413                         ((('args', ..., ..., 'var_positional'),), ...))
2414        self.assertEqual(self.signature(A.f2),
2415                         ((('args', ..., ..., 'var_positional'),), ...))
2416        self.assertEqual(self.signature(A.f3),
2417                         ((('args', ..., ..., 'var_positional'),), ...))
2418        self.assertEqual(self.signature(A.f4),
2419                         ((('args', ..., ..., 'var_positional'),
2420                            ('kwargs', ..., ..., 'var_keyword')), ...))
2421    @cpython_only
2422    @unittest.skipIf(MISSING_C_DOCSTRINGS,
2423                     "Signature information for builtins requires docstrings")
2424    def test_signature_on_builtins(self):
2425        import _testcapi
2426
2427        def test_unbound_method(o):
2428            """Use this to test unbound methods (things that should have a self)"""
2429            signature = inspect.signature(o)
2430            self.assertTrue(isinstance(signature, inspect.Signature))
2431            self.assertEqual(list(signature.parameters.values())[0].name, 'self')
2432            return signature
2433
2434        def test_callable(o):
2435            """Use this to test bound methods or normal callables (things that don't expect self)"""
2436            signature = inspect.signature(o)
2437            self.assertTrue(isinstance(signature, inspect.Signature))
2438            if signature.parameters:
2439                self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
2440            return signature
2441
2442        signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
2443        def p(name): return signature.parameters[name].default
2444        self.assertEqual(p('s'), 'avocado')
2445        self.assertEqual(p('b'), b'bytes')
2446        self.assertEqual(p('d'), 3.14)
2447        self.assertEqual(p('i'), 35)
2448        self.assertEqual(p('n'), None)
2449        self.assertEqual(p('t'), True)
2450        self.assertEqual(p('f'), False)
2451        self.assertEqual(p('local'), 3)
2452        self.assertEqual(p('sys'), sys.maxsize)
2453        self.assertNotIn('exp', signature.parameters)
2454
2455        test_callable(object)
2456
2457        # normal method
2458        # (PyMethodDescr_Type, "method_descriptor")
2459        test_unbound_method(_pickle.Pickler.dump)
2460        d = _pickle.Pickler(io.StringIO())
2461        test_callable(d.dump)
2462
2463        # static method
2464        test_callable(bytes.maketrans)
2465        test_callable(b'abc'.maketrans)
2466
2467        # class method
2468        test_callable(dict.fromkeys)
2469        test_callable({}.fromkeys)
2470
2471        # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
2472        test_unbound_method(type.__call__)
2473        test_unbound_method(int.__add__)
2474        test_callable((3).__add__)
2475
2476        # _PyMethodWrapper_Type
2477        # support for 'method-wrapper'
2478        test_callable(min.__call__)
2479
2480        # This doesn't work now.
2481        # (We don't have a valid signature for "type" in 3.4)
2482        with self.assertRaisesRegex(ValueError, "no signature found"):
2483            class ThisWorksNow:
2484                __call__ = type
2485            test_callable(ThisWorksNow())
2486
2487        # Regression test for issue #20786
2488        test_unbound_method(dict.__delitem__)
2489        test_unbound_method(property.__delete__)
2490
2491        # Regression test for issue #20586
2492        test_callable(_testcapi.docstring_with_signature_but_no_doc)
2493
2494    @cpython_only
2495    @unittest.skipIf(MISSING_C_DOCSTRINGS,
2496                     "Signature information for builtins requires docstrings")
2497    def test_signature_on_decorated_builtins(self):
2498        import _testcapi
2499        func = _testcapi.docstring_with_signature_with_defaults
2500
2501        def decorator(func):
2502            @functools.wraps(func)
2503            def wrapper(*args, **kwargs) -> int:
2504                return func(*args, **kwargs)
2505            return wrapper
2506
2507        decorated_func = decorator(func)
2508
2509        self.assertEqual(inspect.signature(func),
2510                         inspect.signature(decorated_func))
2511
2512        def wrapper_like(*args, **kwargs) -> int: pass
2513        self.assertEqual(inspect.signature(decorated_func,
2514                                           follow_wrapped=False),
2515                         inspect.signature(wrapper_like))
2516
2517    @cpython_only
2518    def test_signature_on_builtins_no_signature(self):
2519        import _testcapi
2520        with self.assertRaisesRegex(ValueError,
2521                                    'no signature found for builtin'):
2522            inspect.signature(_testcapi.docstring_no_signature)
2523
2524        with self.assertRaisesRegex(ValueError,
2525                                    'no signature found for builtin'):
2526            inspect.signature(str)
2527
2528    def test_signature_on_non_function(self):
2529        with self.assertRaisesRegex(TypeError, 'is not a callable object'):
2530            inspect.signature(42)
2531
2532    def test_signature_from_functionlike_object(self):
2533        def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2534            pass
2535
2536        class funclike:
2537            # Has to be callable, and have correct
2538            # __code__, __annotations__, __defaults__, __name__,
2539            # and __kwdefaults__ attributes
2540
2541            def __init__(self, func):
2542                self.__name__ = func.__name__
2543                self.__code__ = func.__code__
2544                self.__annotations__ = func.__annotations__
2545                self.__defaults__ = func.__defaults__
2546                self.__kwdefaults__ = func.__kwdefaults__
2547                self.func = func
2548
2549            def __call__(self, *args, **kwargs):
2550                return self.func(*args, **kwargs)
2551
2552        sig_func = inspect.Signature.from_callable(func)
2553
2554        sig_funclike = inspect.Signature.from_callable(funclike(func))
2555        self.assertEqual(sig_funclike, sig_func)
2556
2557        sig_funclike = inspect.signature(funclike(func))
2558        self.assertEqual(sig_funclike, sig_func)
2559
2560        # If object is not a duck type of function, then
2561        # signature will try to get a signature for its '__call__'
2562        # method
2563        fl = funclike(func)
2564        del fl.__defaults__
2565        self.assertEqual(self.signature(fl),
2566                         ((('args', ..., ..., "var_positional"),
2567                           ('kwargs', ..., ..., "var_keyword")),
2568                           ...))
2569
2570        # Test with cython-like builtins:
2571        _orig_isdesc = inspect.ismethoddescriptor
2572        def _isdesc(obj):
2573            if hasattr(obj, '_builtinmock'):
2574                return True
2575            return _orig_isdesc(obj)
2576
2577        with unittest.mock.patch('inspect.ismethoddescriptor', _isdesc):
2578            builtin_func = funclike(func)
2579            # Make sure that our mock setup is working
2580            self.assertFalse(inspect.ismethoddescriptor(builtin_func))
2581            builtin_func._builtinmock = True
2582            self.assertTrue(inspect.ismethoddescriptor(builtin_func))
2583            self.assertEqual(inspect.signature(builtin_func), sig_func)
2584
2585    def test_signature_functionlike_class(self):
2586        # We only want to duck type function-like objects,
2587        # not classes.
2588
2589        def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
2590            pass
2591
2592        class funclike:
2593            def __init__(self, marker):
2594                pass
2595
2596            __name__ = func.__name__
2597            __code__ = func.__code__
2598            __annotations__ = func.__annotations__
2599            __defaults__ = func.__defaults__
2600            __kwdefaults__ = func.__kwdefaults__
2601
2602        self.assertEqual(str(inspect.signature(funclike)), '(marker)')
2603
2604    def test_signature_on_method(self):
2605        class Test:
2606            def __init__(*args):
2607                pass
2608            def m1(self, arg1, arg2=1) -> int:
2609                pass
2610            def m2(*args):
2611                pass
2612            def __call__(*, a):
2613                pass
2614
2615        self.assertEqual(self.signature(Test().m1),
2616                         ((('arg1', ..., ..., "positional_or_keyword"),
2617                           ('arg2', 1, ..., "positional_or_keyword")),
2618                          int))
2619
2620        self.assertEqual(self.signature(Test().m2),
2621                         ((('args', ..., ..., "var_positional"),),
2622                          ...))
2623
2624        self.assertEqual(self.signature(Test),
2625                         ((('args', ..., ..., "var_positional"),),
2626                          ...))
2627
2628        with self.assertRaisesRegex(ValueError, 'invalid method signature'):
2629            self.signature(Test())
2630
2631    def test_signature_wrapped_bound_method(self):
2632        # Issue 24298
2633        class Test:
2634            def m1(self, arg1, arg2=1) -> int:
2635                pass
2636        @functools.wraps(Test().m1)
2637        def m1d(*args, **kwargs):
2638            pass
2639        self.assertEqual(self.signature(m1d),
2640                         ((('arg1', ..., ..., "positional_or_keyword"),
2641                           ('arg2', 1, ..., "positional_or_keyword")),
2642                          int))
2643
2644    def test_signature_on_classmethod(self):
2645        class Test:
2646            @classmethod
2647            def foo(cls, arg1, *, arg2=1):
2648                pass
2649
2650        meth = Test().foo
2651        self.assertEqual(self.signature(meth),
2652                         ((('arg1', ..., ..., "positional_or_keyword"),
2653                           ('arg2', 1, ..., "keyword_only")),
2654                          ...))
2655
2656        meth = Test.foo
2657        self.assertEqual(self.signature(meth),
2658                         ((('arg1', ..., ..., "positional_or_keyword"),
2659                           ('arg2', 1, ..., "keyword_only")),
2660                          ...))
2661
2662    def test_signature_on_staticmethod(self):
2663        class Test:
2664            @staticmethod
2665            def foo(cls, *, arg):
2666                pass
2667
2668        meth = Test().foo
2669        self.assertEqual(self.signature(meth),
2670                         ((('cls', ..., ..., "positional_or_keyword"),
2671                           ('arg', ..., ..., "keyword_only")),
2672                          ...))
2673
2674        meth = Test.foo
2675        self.assertEqual(self.signature(meth),
2676                         ((('cls', ..., ..., "positional_or_keyword"),
2677                           ('arg', ..., ..., "keyword_only")),
2678                          ...))
2679
2680    def test_signature_on_partial(self):
2681        from functools import partial
2682
2683        Parameter = inspect.Parameter
2684
2685        def test():
2686            pass
2687
2688        self.assertEqual(self.signature(partial(test)), ((), ...))
2689
2690        with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2691            inspect.signature(partial(test, 1))
2692
2693        with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2694            inspect.signature(partial(test, a=1))
2695
2696        def test(a, b, *, c, d):
2697            pass
2698
2699        self.assertEqual(self.signature(partial(test)),
2700                         ((('a', ..., ..., "positional_or_keyword"),
2701                           ('b', ..., ..., "positional_or_keyword"),
2702                           ('c', ..., ..., "keyword_only"),
2703                           ('d', ..., ..., "keyword_only")),
2704                          ...))
2705
2706        self.assertEqual(self.signature(partial(test, 1)),
2707                         ((('b', ..., ..., "positional_or_keyword"),
2708                           ('c', ..., ..., "keyword_only"),
2709                           ('d', ..., ..., "keyword_only")),
2710                          ...))
2711
2712        self.assertEqual(self.signature(partial(test, 1, c=2)),
2713                         ((('b', ..., ..., "positional_or_keyword"),
2714                           ('c', 2, ..., "keyword_only"),
2715                           ('d', ..., ..., "keyword_only")),
2716                          ...))
2717
2718        self.assertEqual(self.signature(partial(test, b=1, c=2)),
2719                         ((('a', ..., ..., "positional_or_keyword"),
2720                           ('b', 1, ..., "keyword_only"),
2721                           ('c', 2, ..., "keyword_only"),
2722                           ('d', ..., ..., "keyword_only")),
2723                          ...))
2724
2725        self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
2726                         ((('b', 1, ..., "keyword_only"),
2727                           ('c', 2, ..., "keyword_only"),
2728                           ('d', ..., ..., "keyword_only")),
2729                          ...))
2730
2731        self.assertEqual(self.signature(partial(test, a=1)),
2732                         ((('a', 1, ..., "keyword_only"),
2733                           ('b', ..., ..., "keyword_only"),
2734                           ('c', ..., ..., "keyword_only"),
2735                           ('d', ..., ..., "keyword_only")),
2736                          ...))
2737
2738        def test(a, *args, b, **kwargs):
2739            pass
2740
2741        self.assertEqual(self.signature(partial(test, 1)),
2742                         ((('args', ..., ..., "var_positional"),
2743                           ('b', ..., ..., "keyword_only"),
2744                           ('kwargs', ..., ..., "var_keyword")),
2745                          ...))
2746
2747        self.assertEqual(self.signature(partial(test, a=1)),
2748                         ((('a', 1, ..., "keyword_only"),
2749                           ('b', ..., ..., "keyword_only"),
2750                           ('kwargs', ..., ..., "var_keyword")),
2751                          ...))
2752
2753        self.assertEqual(self.signature(partial(test, 1, 2, 3)),
2754                         ((('args', ..., ..., "var_positional"),
2755                           ('b', ..., ..., "keyword_only"),
2756                           ('kwargs', ..., ..., "var_keyword")),
2757                          ...))
2758
2759        self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
2760                         ((('args', ..., ..., "var_positional"),
2761                           ('b', ..., ..., "keyword_only"),
2762                           ('kwargs', ..., ..., "var_keyword")),
2763                          ...))
2764
2765        self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
2766                         ((('args', ..., ..., "var_positional"),
2767                           ('b', 0, ..., "keyword_only"),
2768                           ('kwargs', ..., ..., "var_keyword")),
2769                          ...))
2770
2771        self.assertEqual(self.signature(partial(test, b=0)),
2772                         ((('a', ..., ..., "positional_or_keyword"),
2773                           ('args', ..., ..., "var_positional"),
2774                           ('b', 0, ..., "keyword_only"),
2775                           ('kwargs', ..., ..., "var_keyword")),
2776                          ...))
2777
2778        self.assertEqual(self.signature(partial(test, b=0, test=1)),
2779                         ((('a', ..., ..., "positional_or_keyword"),
2780                           ('args', ..., ..., "var_positional"),
2781                           ('b', 0, ..., "keyword_only"),
2782                           ('kwargs', ..., ..., "var_keyword")),
2783                          ...))
2784
2785        def test(a, b, c:int) -> 42:
2786            pass
2787
2788        sig = test.__signature__ = inspect.signature(test)
2789
2790        self.assertEqual(self.signature(partial(partial(test, 1))),
2791                         ((('b', ..., ..., "positional_or_keyword"),
2792                           ('c', ..., int, "positional_or_keyword")),
2793                          42))
2794
2795        self.assertEqual(self.signature(partial(partial(test, 1), 2)),
2796                         ((('c', ..., int, "positional_or_keyword"),),
2797                          42))
2798
2799        psig = inspect.signature(partial(partial(test, 1), 2))
2800
2801        def foo(a):
2802            return a
2803        _foo = partial(partial(foo, a=10), a=20)
2804        self.assertEqual(self.signature(_foo),
2805                         ((('a', 20, ..., "keyword_only"),),
2806                          ...))
2807        # check that we don't have any side-effects in signature(),
2808        # and the partial object is still functioning
2809        self.assertEqual(_foo(), 20)
2810
2811        def foo(a, b, c):
2812            return a, b, c
2813        _foo = partial(partial(foo, 1, b=20), b=30)
2814
2815        self.assertEqual(self.signature(_foo),
2816                         ((('b', 30, ..., "keyword_only"),
2817                           ('c', ..., ..., "keyword_only")),
2818                          ...))
2819        self.assertEqual(_foo(c=10), (1, 30, 10))
2820
2821        def foo(a, b, c, *, d):
2822            return a, b, c, d
2823        _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
2824        self.assertEqual(self.signature(_foo),
2825                         ((('a', ..., ..., "positional_or_keyword"),
2826                           ('b', 10, ..., "keyword_only"),
2827                           ('c', 20, ..., "keyword_only"),
2828                           ('d', 30, ..., "keyword_only"),
2829                           ),
2830                          ...))
2831        ba = inspect.signature(_foo).bind(a=200, b=11)
2832        self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
2833
2834        def foo(a=1, b=2, c=3):
2835            return a, b, c
2836        _foo = partial(foo, c=13) # (a=1, b=2, *, c=13)
2837
2838        ba = inspect.signature(_foo).bind(a=11)
2839        self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
2840
2841        ba = inspect.signature(_foo).bind(11, 12)
2842        self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
2843
2844        ba = inspect.signature(_foo).bind(11, b=12)
2845        self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
2846
2847        ba = inspect.signature(_foo).bind(b=12)
2848        self.assertEqual(_foo(*ba.args, **ba.kwargs), (1, 12, 13))
2849
2850        _foo = partial(_foo, b=10, c=20)
2851        ba = inspect.signature(_foo).bind(12)
2852        self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 10, 20))
2853
2854
2855        def foo(a, b, c, d, **kwargs):
2856            pass
2857        sig = inspect.signature(foo)
2858        params = sig.parameters.copy()
2859        params['a'] = params['a'].replace(kind=Parameter.POSITIONAL_ONLY)
2860        params['b'] = params['b'].replace(kind=Parameter.POSITIONAL_ONLY)
2861        foo.__signature__ = inspect.Signature(params.values())
2862        sig = inspect.signature(foo)
2863        self.assertEqual(str(sig), '(a, b, /, c, d, **kwargs)')
2864
2865        self.assertEqual(self.signature(partial(foo, 1)),
2866                         ((('b', ..., ..., 'positional_only'),
2867                           ('c', ..., ..., 'positional_or_keyword'),
2868                           ('d', ..., ..., 'positional_or_keyword'),
2869                           ('kwargs', ..., ..., 'var_keyword')),
2870                         ...))
2871
2872        self.assertEqual(self.signature(partial(foo, 1, 2)),
2873                         ((('c', ..., ..., 'positional_or_keyword'),
2874                           ('d', ..., ..., 'positional_or_keyword'),
2875                           ('kwargs', ..., ..., 'var_keyword')),
2876                         ...))
2877
2878        self.assertEqual(self.signature(partial(foo, 1, 2, 3)),
2879                         ((('d', ..., ..., 'positional_or_keyword'),
2880                           ('kwargs', ..., ..., 'var_keyword')),
2881                         ...))
2882
2883        self.assertEqual(self.signature(partial(foo, 1, 2, c=3)),
2884                         ((('c', 3, ..., 'keyword_only'),
2885                           ('d', ..., ..., 'keyword_only'),
2886                           ('kwargs', ..., ..., 'var_keyword')),
2887                         ...))
2888
2889        self.assertEqual(self.signature(partial(foo, 1, c=3)),
2890                         ((('b', ..., ..., 'positional_only'),
2891                           ('c', 3, ..., 'keyword_only'),
2892                           ('d', ..., ..., 'keyword_only'),
2893                           ('kwargs', ..., ..., 'var_keyword')),
2894                         ...))
2895
2896    def test_signature_on_partialmethod(self):
2897        from functools import partialmethod
2898
2899        class Spam:
2900            def test():
2901                pass
2902            ham = partialmethod(test)
2903
2904        with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
2905            inspect.signature(Spam.ham)
2906
2907        class Spam:
2908            def test(it, a, *, c) -> 'spam':
2909                pass
2910            ham = partialmethod(test, c=1)
2911
2912        self.assertEqual(self.signature(Spam.ham, eval_str=False),
2913                         ((('it', ..., ..., 'positional_or_keyword'),
2914                           ('a', ..., ..., 'positional_or_keyword'),
2915                           ('c', 1, ..., 'keyword_only')),
2916                          'spam'))
2917
2918        self.assertEqual(self.signature(Spam().ham, eval_str=False),
2919                         ((('a', ..., ..., 'positional_or_keyword'),
2920                           ('c', 1, ..., 'keyword_only')),
2921                          'spam'))
2922
2923        class Spam:
2924            def test(self: 'anno', x):
2925                pass
2926
2927            g = partialmethod(test, 1)
2928
2929        self.assertEqual(self.signature(Spam.g, eval_str=False),
2930                         ((('self', ..., 'anno', 'positional_or_keyword'),),
2931                          ...))
2932
2933    def test_signature_on_fake_partialmethod(self):
2934        def foo(a): pass
2935        foo._partialmethod = 'spam'
2936        self.assertEqual(str(inspect.signature(foo)), '(a)')
2937
2938    def test_signature_on_decorated(self):
2939        import functools
2940
2941        def decorator(func):
2942            @functools.wraps(func)
2943            def wrapper(*args, **kwargs) -> int:
2944                return func(*args, **kwargs)
2945            return wrapper
2946
2947        class Foo:
2948            @decorator
2949            def bar(self, a, b):
2950                pass
2951
2952        self.assertEqual(self.signature(Foo.bar),
2953                         ((('self', ..., ..., "positional_or_keyword"),
2954                           ('a', ..., ..., "positional_or_keyword"),
2955                           ('b', ..., ..., "positional_or_keyword")),
2956                          ...))
2957
2958        self.assertEqual(self.signature(Foo().bar),
2959                         ((('a', ..., ..., "positional_or_keyword"),
2960                           ('b', ..., ..., "positional_or_keyword")),
2961                          ...))
2962
2963        self.assertEqual(self.signature(Foo.bar, follow_wrapped=False),
2964                         ((('args', ..., ..., "var_positional"),
2965                           ('kwargs', ..., ..., "var_keyword")),
2966                          ...)) # functools.wraps will copy __annotations__
2967                                # from "func" to "wrapper", hence no
2968                                # return_annotation
2969
2970        # Test that we handle method wrappers correctly
2971        def decorator(func):
2972            @functools.wraps(func)
2973            def wrapper(*args, **kwargs) -> int:
2974                return func(42, *args, **kwargs)
2975            sig = inspect.signature(func)
2976            new_params = tuple(sig.parameters.values())[1:]
2977            wrapper.__signature__ = sig.replace(parameters=new_params)
2978            return wrapper
2979
2980        class Foo:
2981            @decorator
2982            def __call__(self, a, b):
2983                pass
2984
2985        self.assertEqual(self.signature(Foo.__call__),
2986                         ((('a', ..., ..., "positional_or_keyword"),
2987                           ('b', ..., ..., "positional_or_keyword")),
2988                          ...))
2989
2990        self.assertEqual(self.signature(Foo().__call__),
2991                         ((('b', ..., ..., "positional_or_keyword"),),
2992                          ...))
2993
2994        # Test we handle __signature__ partway down the wrapper stack
2995        def wrapped_foo_call():
2996            pass
2997        wrapped_foo_call.__wrapped__ = Foo.__call__
2998
2999        self.assertEqual(self.signature(wrapped_foo_call),
3000                         ((('a', ..., ..., "positional_or_keyword"),
3001                           ('b', ..., ..., "positional_or_keyword")),
3002                          ...))
3003
3004
3005    def test_signature_on_class(self):
3006        class C:
3007            def __init__(self, a):
3008                pass
3009
3010        self.assertEqual(self.signature(C),
3011                         ((('a', ..., ..., "positional_or_keyword"),),
3012                          ...))
3013
3014        class CM(type):
3015            def __call__(cls, a):
3016                pass
3017        class C(metaclass=CM):
3018            def __init__(self, b):
3019                pass
3020
3021        self.assertEqual(self.signature(C),
3022                         ((('a', ..., ..., "positional_or_keyword"),),
3023                          ...))
3024
3025        class CM(type):
3026            def __new__(mcls, name, bases, dct, *, foo=1):
3027                return super().__new__(mcls, name, bases, dct)
3028        class C(metaclass=CM):
3029            def __init__(self, b):
3030                pass
3031
3032        self.assertEqual(self.signature(C),
3033                         ((('b', ..., ..., "positional_or_keyword"),),
3034                          ...))
3035
3036        self.assertEqual(self.signature(CM),
3037                         ((('name', ..., ..., "positional_or_keyword"),
3038                           ('bases', ..., ..., "positional_or_keyword"),
3039                           ('dct', ..., ..., "positional_or_keyword"),
3040                           ('foo', 1, ..., "keyword_only")),
3041                          ...))
3042
3043        class CMM(type):
3044            def __new__(mcls, name, bases, dct, *, foo=1):
3045                return super().__new__(mcls, name, bases, dct)
3046            def __call__(cls, nm, bs, dt):
3047                return type(nm, bs, dt)
3048        class CM(type, metaclass=CMM):
3049            def __new__(mcls, name, bases, dct, *, bar=2):
3050                return super().__new__(mcls, name, bases, dct)
3051        class C(metaclass=CM):
3052            def __init__(self, b):
3053                pass
3054
3055        self.assertEqual(self.signature(CMM),
3056                         ((('name', ..., ..., "positional_or_keyword"),
3057                           ('bases', ..., ..., "positional_or_keyword"),
3058                           ('dct', ..., ..., "positional_or_keyword"),
3059                           ('foo', 1, ..., "keyword_only")),
3060                          ...))
3061
3062        self.assertEqual(self.signature(CM),
3063                         ((('nm', ..., ..., "positional_or_keyword"),
3064                           ('bs', ..., ..., "positional_or_keyword"),
3065                           ('dt', ..., ..., "positional_or_keyword")),
3066                          ...))
3067
3068        self.assertEqual(self.signature(C),
3069                         ((('b', ..., ..., "positional_or_keyword"),),
3070                          ...))
3071
3072        class CM(type):
3073            def __init__(cls, name, bases, dct, *, bar=2):
3074                return super().__init__(name, bases, dct)
3075        class C(metaclass=CM):
3076            def __init__(self, b):
3077                pass
3078
3079        self.assertEqual(self.signature(CM),
3080                         ((('name', ..., ..., "positional_or_keyword"),
3081                           ('bases', ..., ..., "positional_or_keyword"),
3082                           ('dct', ..., ..., "positional_or_keyword"),
3083                           ('bar', 2, ..., "keyword_only")),
3084                          ...))
3085
3086    def test_signature_on_subclass(self):
3087        class A:
3088            def __new__(cls, a=1, *args, **kwargs):
3089                return object.__new__(cls)
3090        class B(A):
3091            def __init__(self, b):
3092                pass
3093        class C(A):
3094            def __new__(cls, a=1, b=2, *args, **kwargs):
3095                return object.__new__(cls)
3096        class D(A):
3097            pass
3098
3099        self.assertEqual(self.signature(B),
3100                         ((('b', ..., ..., "positional_or_keyword"),),
3101                          ...))
3102        self.assertEqual(self.signature(C),
3103                         ((('a', 1, ..., 'positional_or_keyword'),
3104                           ('b', 2, ..., 'positional_or_keyword'),
3105                           ('args', ..., ..., 'var_positional'),
3106                           ('kwargs', ..., ..., 'var_keyword')),
3107                          ...))
3108        self.assertEqual(self.signature(D),
3109                         ((('a', 1, ..., 'positional_or_keyword'),
3110                           ('args', ..., ..., 'var_positional'),
3111                           ('kwargs', ..., ..., 'var_keyword')),
3112                          ...))
3113
3114    def test_signature_on_generic_subclass(self):
3115        from typing import Generic, TypeVar
3116
3117        T = TypeVar('T')
3118
3119        class A(Generic[T]):
3120            def __init__(self, *, a: int) -> None:
3121                pass
3122
3123        self.assertEqual(self.signature(A),
3124                         ((('a', ..., int, 'keyword_only'),),
3125                          None))
3126
3127    @unittest.skipIf(MISSING_C_DOCSTRINGS,
3128                     "Signature information for builtins requires docstrings")
3129    def test_signature_on_class_without_init(self):
3130        # Test classes without user-defined __init__ or __new__
3131        class C: pass
3132        self.assertEqual(str(inspect.signature(C)), '()')
3133        class D(C): pass
3134        self.assertEqual(str(inspect.signature(D)), '()')
3135
3136        # Test meta-classes without user-defined __init__ or __new__
3137        class C(type): pass
3138        class D(C): pass
3139        with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
3140            self.assertEqual(inspect.signature(C), None)
3141        with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
3142            self.assertEqual(inspect.signature(D), None)
3143
3144    @unittest.skipIf(MISSING_C_DOCSTRINGS,
3145                     "Signature information for builtins requires docstrings")
3146    def test_signature_on_builtin_class(self):
3147        expected = ('(file, protocol=None, fix_imports=True, '
3148                    'buffer_callback=None)')
3149        self.assertEqual(str(inspect.signature(_pickle.Pickler)), expected)
3150
3151        class P(_pickle.Pickler): pass
3152        class EmptyTrait: pass
3153        class P2(EmptyTrait, P): pass
3154        self.assertEqual(str(inspect.signature(P)), expected)
3155        self.assertEqual(str(inspect.signature(P2)), expected)
3156
3157        class P3(P2):
3158            def __init__(self, spam):
3159                pass
3160        self.assertEqual(str(inspect.signature(P3)), '(spam)')
3161
3162        class MetaP(type):
3163            def __call__(cls, foo, bar):
3164                pass
3165        class P4(P2, metaclass=MetaP):
3166            pass
3167        self.assertEqual(str(inspect.signature(P4)), '(foo, bar)')
3168
3169    def test_signature_on_callable_objects(self):
3170        class Foo:
3171            def __call__(self, a):
3172                pass
3173
3174        self.assertEqual(self.signature(Foo()),
3175                         ((('a', ..., ..., "positional_or_keyword"),),
3176                          ...))
3177
3178        class Spam:
3179            pass
3180        with self.assertRaisesRegex(TypeError, "is not a callable object"):
3181            inspect.signature(Spam())
3182
3183        class Bar(Spam, Foo):
3184            pass
3185
3186        self.assertEqual(self.signature(Bar()),
3187                         ((('a', ..., ..., "positional_or_keyword"),),
3188                          ...))
3189
3190        class Wrapped:
3191            pass
3192        Wrapped.__wrapped__ = lambda a: None
3193        self.assertEqual(self.signature(Wrapped),
3194                         ((('a', ..., ..., "positional_or_keyword"),),
3195                          ...))
3196        # wrapper loop:
3197        Wrapped.__wrapped__ = Wrapped
3198        with self.assertRaisesRegex(ValueError, 'wrapper loop'):
3199            self.signature(Wrapped)
3200
3201    def test_signature_on_lambdas(self):
3202        self.assertEqual(self.signature((lambda a=10: a)),
3203                         ((('a', 10, ..., "positional_or_keyword"),),
3204                          ...))
3205
3206    def test_signature_equality(self):
3207        def foo(a, *, b:int) -> float: pass
3208        self.assertFalse(inspect.signature(foo) == 42)
3209        self.assertTrue(inspect.signature(foo) != 42)
3210        self.assertTrue(inspect.signature(foo) == ALWAYS_EQ)
3211        self.assertFalse(inspect.signature(foo) != ALWAYS_EQ)
3212
3213        def bar(a, *, b:int) -> float: pass
3214        self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3215        self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
3216        self.assertEqual(
3217            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
3218
3219        def bar(a, *, b:int) -> int: pass
3220        self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3221        self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
3222        self.assertNotEqual(
3223            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
3224
3225        def bar(a, *, b:int): pass
3226        self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3227        self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
3228        self.assertNotEqual(
3229            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
3230
3231        def bar(a, *, b:int=42) -> float: pass
3232        self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3233        self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
3234        self.assertNotEqual(
3235            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
3236
3237        def bar(a, *, c) -> float: pass
3238        self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3239        self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
3240        self.assertNotEqual(
3241            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
3242
3243        def bar(a, b:int) -> float: pass
3244        self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3245        self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
3246        self.assertNotEqual(
3247            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
3248        def spam(b:int, a) -> float: pass
3249        self.assertFalse(inspect.signature(spam) == inspect.signature(bar))
3250        self.assertTrue(inspect.signature(spam) != inspect.signature(bar))
3251        self.assertNotEqual(
3252            hash(inspect.signature(spam)), hash(inspect.signature(bar)))
3253
3254        def foo(*, a, b, c): pass
3255        def bar(*, c, b, a): pass
3256        self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3257        self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
3258        self.assertEqual(
3259            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
3260
3261        def foo(*, a=1, b, c): pass
3262        def bar(*, c, b, a=1): pass
3263        self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3264        self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
3265        self.assertEqual(
3266            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
3267
3268        def foo(pos, *, a=1, b, c): pass
3269        def bar(pos, *, c, b, a=1): pass
3270        self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3271        self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
3272        self.assertEqual(
3273            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
3274
3275        def foo(pos, *, a, b, c): pass
3276        def bar(pos, *, c, b, a=1): pass
3277        self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
3278        self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
3279        self.assertNotEqual(
3280            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
3281
3282        def foo(pos, *args, a=42, b, c, **kwargs:int): pass
3283        def bar(pos, *args, c, b, a=42, **kwargs:int): pass
3284        self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
3285        self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
3286        self.assertEqual(
3287            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
3288
3289    def test_signature_hashable(self):
3290        S = inspect.Signature
3291        P = inspect.Parameter
3292
3293        def foo(a): pass
3294        foo_sig = inspect.signature(foo)
3295
3296        manual_sig = S(parameters=[P('a', P.POSITIONAL_OR_KEYWORD)])
3297
3298        self.assertEqual(hash(foo_sig), hash(manual_sig))
3299        self.assertNotEqual(hash(foo_sig),
3300                            hash(manual_sig.replace(return_annotation='spam')))
3301
3302        def bar(a) -> 1: pass
3303        self.assertNotEqual(hash(foo_sig), hash(inspect.signature(bar)))
3304
3305        def foo(a={}): pass
3306        with self.assertRaisesRegex(TypeError, 'unhashable type'):
3307            hash(inspect.signature(foo))
3308
3309        def foo(a) -> {}: pass
3310        with self.assertRaisesRegex(TypeError, 'unhashable type'):
3311            hash(inspect.signature(foo))
3312
3313    def test_signature_str(self):
3314        def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
3315            pass
3316        self.assertEqual(str(inspect.signature(foo)),
3317                         '(a: int = 1, *, b, c=None, **kwargs) -> 42')
3318
3319        def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
3320            pass
3321        self.assertEqual(str(inspect.signature(foo)),
3322                         '(a: int = 1, *args, b, c=None, **kwargs) -> 42')
3323
3324        def foo():
3325            pass
3326        self.assertEqual(str(inspect.signature(foo)), '()')
3327
3328        def foo(a: list[str]) -> tuple[str, float]:
3329            pass
3330        self.assertEqual(str(inspect.signature(foo)),
3331                         '(a: list[str]) -> tuple[str, float]')
3332
3333        from typing import Tuple
3334        def foo(a: list[str]) -> Tuple[str, float]:
3335            pass
3336        self.assertEqual(str(inspect.signature(foo)),
3337                         '(a: list[str]) -> Tuple[str, float]')
3338
3339    def test_signature_str_positional_only(self):
3340        P = inspect.Parameter
3341        S = inspect.Signature
3342
3343        def test(a_po, *, b, **kwargs):
3344            return a_po, kwargs
3345
3346        sig = inspect.signature(test)
3347        new_params = list(sig.parameters.values())
3348        new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY)
3349        test.__signature__ = sig.replace(parameters=new_params)
3350
3351        self.assertEqual(str(inspect.signature(test)),
3352                         '(a_po, /, *, b, **kwargs)')
3353
3354        self.assertEqual(str(S(parameters=[P('foo', P.POSITIONAL_ONLY)])),
3355                         '(foo, /)')
3356
3357        self.assertEqual(str(S(parameters=[
3358                                P('foo', P.POSITIONAL_ONLY),
3359                                P('bar', P.VAR_KEYWORD)])),
3360                         '(foo, /, **bar)')
3361
3362        self.assertEqual(str(S(parameters=[
3363                                P('foo', P.POSITIONAL_ONLY),
3364                                P('bar', P.VAR_POSITIONAL)])),
3365                         '(foo, /, *bar)')
3366
3367    def test_signature_replace_anno(self):
3368        def test() -> 42:
3369            pass
3370
3371        sig = inspect.signature(test)
3372        sig = sig.replace(return_annotation=None)
3373        self.assertIs(sig.return_annotation, None)
3374        sig = sig.replace(return_annotation=sig.empty)
3375        self.assertIs(sig.return_annotation, sig.empty)
3376        sig = sig.replace(return_annotation=42)
3377        self.assertEqual(sig.return_annotation, 42)
3378        self.assertEqual(sig, inspect.signature(test))
3379
3380    def test_signature_on_mangled_parameters(self):
3381        class Spam:
3382            def foo(self, __p1:1=2, *, __p2:2=3):
3383                pass
3384        class Ham(Spam):
3385            pass
3386
3387        self.assertEqual(self.signature(Spam.foo),
3388                         ((('self', ..., ..., "positional_or_keyword"),
3389                           ('_Spam__p1', 2, 1, "positional_or_keyword"),
3390                           ('_Spam__p2', 3, 2, "keyword_only")),
3391                          ...))
3392
3393        self.assertEqual(self.signature(Spam.foo),
3394                         self.signature(Ham.foo))
3395
3396    def test_signature_from_callable_python_obj(self):
3397        class MySignature(inspect.Signature): pass
3398        def foo(a, *, b:1): pass
3399        foo_sig = MySignature.from_callable(foo)
3400        self.assertIsInstance(foo_sig, MySignature)
3401
3402    def test_signature_from_callable_class(self):
3403        # A regression test for a class inheriting its signature from `object`.
3404        class MySignature(inspect.Signature): pass
3405        class foo: pass
3406        foo_sig = MySignature.from_callable(foo)
3407        self.assertIsInstance(foo_sig, MySignature)
3408
3409    @unittest.skipIf(MISSING_C_DOCSTRINGS,
3410                     "Signature information for builtins requires docstrings")
3411    def test_signature_from_callable_builtin_obj(self):
3412        class MySignature(inspect.Signature): pass
3413        sig = MySignature.from_callable(_pickle.Pickler)
3414        self.assertIsInstance(sig, MySignature)
3415
3416    def test_signature_definition_order_preserved_on_kwonly(self):
3417        for fn in signatures_with_lexicographic_keyword_only_parameters():
3418            signature = inspect.signature(fn)
3419            l = list(signature.parameters)
3420            sorted_l = sorted(l)
3421            self.assertTrue(l)
3422            self.assertEqual(l, sorted_l)
3423        signature = inspect.signature(unsorted_keyword_only_parameters_fn)
3424        l = list(signature.parameters)
3425        self.assertEqual(l, unsorted_keyword_only_parameters)
3426
3427    def test_signater_parameters_is_ordered(self):
3428        p1 = inspect.signature(lambda x, y: None).parameters
3429        p2 = inspect.signature(lambda y, x: None).parameters
3430        self.assertNotEqual(p1, p2)
3431
3432    def test_signature_annotations_with_local_namespaces(self):
3433        class Foo: ...
3434        def func(foo: Foo) -> int: pass
3435        def func2(foo: Foo, bar: 'Bar') -> int: pass
3436
3437        for signature_func in (inspect.signature, inspect.Signature.from_callable):
3438            with self.subTest(signature_func = signature_func):
3439                sig1 = signature_func(func)
3440                self.assertEqual(sig1.return_annotation, int)
3441                self.assertEqual(sig1.parameters['foo'].annotation, Foo)
3442
3443                sig2 = signature_func(func, locals=locals())
3444                self.assertEqual(sig2.return_annotation, int)
3445                self.assertEqual(sig2.parameters['foo'].annotation, Foo)
3446
3447                sig3 = signature_func(func2, globals={'Bar': int}, locals=locals())
3448                self.assertEqual(sig3.return_annotation, int)
3449                self.assertEqual(sig3.parameters['foo'].annotation, Foo)
3450                self.assertEqual(sig3.parameters['bar'].annotation, 'Bar')
3451
3452    def test_signature_eval_str(self):
3453        isa = inspect_stringized_annotations
3454        sig = inspect.Signature
3455        par = inspect.Parameter
3456        PORK = inspect.Parameter.POSITIONAL_OR_KEYWORD
3457        for signature_func in (inspect.signature, inspect.Signature.from_callable):
3458            with self.subTest(signature_func = signature_func):
3459                self.assertEqual(
3460                    signature_func(isa.MyClass),
3461                    sig(
3462                        parameters=(
3463                            par('a', PORK),
3464                            par('b', PORK),
3465                        )))
3466                self.assertEqual(
3467                    signature_func(isa.function),
3468                    sig(
3469                        return_annotation='MyClass',
3470                        parameters=(
3471                            par('a', PORK, annotation='int'),
3472                            par('b', PORK, annotation='str'),
3473                        )))
3474                self.assertEqual(
3475                    signature_func(isa.function2),
3476                    sig(
3477                        return_annotation='MyClass',
3478                        parameters=(
3479                            par('a', PORK, annotation='int'),
3480                            par('b', PORK, annotation="'str'"),
3481                            par('c', PORK, annotation="MyClass"),
3482                        )))
3483                self.assertEqual(
3484                    signature_func(isa.function3),
3485                    sig(
3486                        parameters=(
3487                            par('a', PORK, annotation="'int'"),
3488                            par('b', PORK, annotation="'str'"),
3489                            par('c', PORK, annotation="'MyClass'"),
3490                        )))
3491
3492                self.assertEqual(signature_func(isa.UnannotatedClass), sig())
3493                self.assertEqual(signature_func(isa.unannotated_function),
3494                    sig(
3495                        parameters=(
3496                            par('a', PORK),
3497                            par('b', PORK),
3498                            par('c', PORK),
3499                        )))
3500
3501                self.assertEqual(
3502                    signature_func(isa.MyClass, eval_str=True),
3503                    sig(
3504                        parameters=(
3505                            par('a', PORK),
3506                            par('b', PORK),
3507                        )))
3508                self.assertEqual(
3509                    signature_func(isa.function, eval_str=True),
3510                    sig(
3511                        return_annotation=isa.MyClass,
3512                        parameters=(
3513                            par('a', PORK, annotation=int),
3514                            par('b', PORK, annotation=str),
3515                        )))
3516                self.assertEqual(
3517                    signature_func(isa.function2, eval_str=True),
3518                    sig(
3519                        return_annotation=isa.MyClass,
3520                        parameters=(
3521                            par('a', PORK, annotation=int),
3522                            par('b', PORK, annotation='str'),
3523                            par('c', PORK, annotation=isa.MyClass),
3524                        )))
3525                self.assertEqual(
3526                    signature_func(isa.function3, eval_str=True),
3527                    sig(
3528                        parameters=(
3529                            par('a', PORK, annotation='int'),
3530                            par('b', PORK, annotation='str'),
3531                            par('c', PORK, annotation='MyClass'),
3532                        )))
3533
3534                globalns = {'int': float, 'str': complex}
3535                localns = {'str': tuple, 'MyClass': dict}
3536                with self.assertRaises(NameError):
3537                    signature_func(isa.function, eval_str=True, globals=globalns)
3538
3539                self.assertEqual(
3540                    signature_func(isa.function, eval_str=True, locals=localns),
3541                    sig(
3542                        return_annotation=dict,
3543                        parameters=(
3544                            par('a', PORK, annotation=int),
3545                            par('b', PORK, annotation=tuple),
3546                        )))
3547
3548                self.assertEqual(
3549                    signature_func(isa.function, eval_str=True, globals=globalns, locals=localns),
3550                    sig(
3551                        return_annotation=dict,
3552                        parameters=(
3553                            par('a', PORK, annotation=float),
3554                            par('b', PORK, annotation=tuple),
3555                        )))
3556
3557    def test_signature_none_annotation(self):
3558        class funclike:
3559            # Has to be callable, and have correct
3560            # __code__, __annotations__, __defaults__, __name__,
3561            # and __kwdefaults__ attributes
3562
3563            def __init__(self, func):
3564                self.__name__ = func.__name__
3565                self.__code__ = func.__code__
3566                self.__annotations__ = func.__annotations__
3567                self.__defaults__ = func.__defaults__
3568                self.__kwdefaults__ = func.__kwdefaults__
3569                self.func = func
3570
3571            def __call__(self, *args, **kwargs):
3572                return self.func(*args, **kwargs)
3573
3574        def foo(): pass
3575        foo = funclike(foo)
3576        foo.__annotations__ = None
3577        for signature_func in (inspect.signature, inspect.Signature.from_callable):
3578            with self.subTest(signature_func = signature_func):
3579                self.assertEqual(signature_func(foo), inspect.Signature())
3580        self.assertEqual(inspect.get_annotations(foo), {})
3581
3582
3583class TestParameterObject(unittest.TestCase):
3584    def test_signature_parameter_kinds(self):
3585        P = inspect.Parameter
3586        self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
3587                        P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
3588
3589        self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
3590        self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
3591
3592    def test_signature_parameter_object(self):
3593        p = inspect.Parameter('foo', default=10,
3594                              kind=inspect.Parameter.POSITIONAL_ONLY)
3595        self.assertEqual(p.name, 'foo')
3596        self.assertEqual(p.default, 10)
3597        self.assertIs(p.annotation, p.empty)
3598        self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
3599
3600        with self.assertRaisesRegex(ValueError, "value '123' is "
3601                                    "not a valid Parameter.kind"):
3602            inspect.Parameter('foo', default=10, kind='123')
3603
3604        with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
3605            inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
3606
3607        with self.assertRaisesRegex(TypeError, 'name must be a str'):
3608            inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
3609
3610        with self.assertRaisesRegex(ValueError,
3611                                    'is not a valid parameter name'):
3612            inspect.Parameter('$', kind=inspect.Parameter.VAR_KEYWORD)
3613
3614        with self.assertRaisesRegex(ValueError,
3615                                    'is not a valid parameter name'):
3616            inspect.Parameter('.a', kind=inspect.Parameter.VAR_KEYWORD)
3617
3618        with self.assertRaisesRegex(ValueError, 'cannot have default values'):
3619            inspect.Parameter('a', default=42,
3620                              kind=inspect.Parameter.VAR_KEYWORD)
3621
3622        with self.assertRaisesRegex(ValueError, 'cannot have default values'):
3623            inspect.Parameter('a', default=42,
3624                              kind=inspect.Parameter.VAR_POSITIONAL)
3625
3626        p = inspect.Parameter('a', default=42,
3627                              kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
3628        with self.assertRaisesRegex(ValueError, 'cannot have default values'):
3629            p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
3630
3631        self.assertTrue(repr(p).startswith('<Parameter'))
3632        self.assertTrue('"a=42"' in repr(p))
3633
3634    def test_signature_parameter_hashable(self):
3635        P = inspect.Parameter
3636        foo = P('foo', kind=P.POSITIONAL_ONLY)
3637        self.assertEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY)))
3638        self.assertNotEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY,
3639                                              default=42)))
3640        self.assertNotEqual(hash(foo),
3641                            hash(foo.replace(kind=P.VAR_POSITIONAL)))
3642
3643    def test_signature_parameter_equality(self):
3644        P = inspect.Parameter
3645        p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
3646
3647        self.assertTrue(p == p)
3648        self.assertFalse(p != p)
3649        self.assertFalse(p == 42)
3650        self.assertTrue(p != 42)
3651        self.assertTrue(p == ALWAYS_EQ)
3652        self.assertFalse(p != ALWAYS_EQ)
3653
3654        self.assertTrue(p == P('foo', default=42,
3655                               kind=inspect.Parameter.KEYWORD_ONLY))
3656        self.assertFalse(p != P('foo', default=42,
3657                                kind=inspect.Parameter.KEYWORD_ONLY))
3658
3659    def test_signature_parameter_replace(self):
3660        p = inspect.Parameter('foo', default=42,
3661                              kind=inspect.Parameter.KEYWORD_ONLY)
3662
3663        self.assertIsNot(p, p.replace())
3664        self.assertEqual(p, p.replace())
3665
3666        p2 = p.replace(annotation=1)
3667        self.assertEqual(p2.annotation, 1)
3668        p2 = p2.replace(annotation=p2.empty)
3669        self.assertEqual(p, p2)
3670
3671        p2 = p2.replace(name='bar')
3672        self.assertEqual(p2.name, 'bar')
3673        self.assertNotEqual(p2, p)
3674
3675        with self.assertRaisesRegex(ValueError,
3676                                    'name is a required attribute'):
3677            p2 = p2.replace(name=p2.empty)
3678
3679        p2 = p2.replace(name='foo', default=None)
3680        self.assertIs(p2.default, None)
3681        self.assertNotEqual(p2, p)
3682
3683        p2 = p2.replace(name='foo', default=p2.empty)
3684        self.assertIs(p2.default, p2.empty)
3685
3686
3687        p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
3688        self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
3689        self.assertNotEqual(p2, p)
3690
3691        with self.assertRaisesRegex(ValueError,
3692                                    "value <class 'inspect._empty'> "
3693                                    "is not a valid Parameter.kind"):
3694            p2 = p2.replace(kind=p2.empty)
3695
3696        p2 = p2.replace(kind=p2.KEYWORD_ONLY)
3697        self.assertEqual(p2, p)
3698
3699    def test_signature_parameter_positional_only(self):
3700        with self.assertRaisesRegex(TypeError, 'name must be a str'):
3701            inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
3702
3703    @cpython_only
3704    def test_signature_parameter_implicit(self):
3705        with self.assertRaisesRegex(ValueError,
3706                                    'implicit arguments must be passed as '
3707                                    'positional or keyword arguments, '
3708                                    'not positional-only'):
3709            inspect.Parameter('.0', kind=inspect.Parameter.POSITIONAL_ONLY)
3710
3711        param = inspect.Parameter(
3712            '.0', kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
3713        self.assertEqual(param.kind, inspect.Parameter.POSITIONAL_ONLY)
3714        self.assertEqual(param.name, 'implicit0')
3715
3716    def test_signature_parameter_immutability(self):
3717        p = inspect.Parameter('spam', kind=inspect.Parameter.KEYWORD_ONLY)
3718
3719        with self.assertRaises(AttributeError):
3720            p.foo = 'bar'
3721
3722        with self.assertRaises(AttributeError):
3723            p.kind = 123
3724
3725
3726class TestSignatureBind(unittest.TestCase):
3727    @staticmethod
3728    def call(func, *args, **kwargs):
3729        sig = inspect.signature(func)
3730        ba = sig.bind(*args, **kwargs)
3731        return func(*ba.args, **ba.kwargs)
3732
3733    def test_signature_bind_empty(self):
3734        def test():
3735            return 42
3736
3737        self.assertEqual(self.call(test), 42)
3738        with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
3739            self.call(test, 1)
3740        with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
3741            self.call(test, 1, spam=10)
3742        with self.assertRaisesRegex(
3743            TypeError, "got an unexpected keyword argument 'spam'"):
3744
3745            self.call(test, spam=1)
3746
3747    def test_signature_bind_var(self):
3748        def test(*args, **kwargs):
3749            return args, kwargs
3750
3751        self.assertEqual(self.call(test), ((), {}))
3752        self.assertEqual(self.call(test, 1), ((1,), {}))
3753        self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
3754        self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
3755        self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
3756        self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
3757        self.assertEqual(self.call(test, 1, 2, foo='bar'),
3758                         ((1, 2), {'foo': 'bar'}))
3759
3760    def test_signature_bind_just_args(self):
3761        def test(a, b, c):
3762            return a, b, c
3763
3764        self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3765
3766        with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
3767            self.call(test, 1, 2, 3, 4)
3768
3769        with self.assertRaisesRegex(TypeError,
3770                                    "missing a required argument: 'b'"):
3771            self.call(test, 1)
3772
3773        with self.assertRaisesRegex(TypeError,
3774                                    "missing a required argument: 'a'"):
3775            self.call(test)
3776
3777        def test(a, b, c=10):
3778            return a, b, c
3779        self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3780        self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
3781
3782        def test(a=1, b=2, c=3):
3783            return a, b, c
3784        self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
3785        self.assertEqual(self.call(test, a=10), (10, 2, 3))
3786        self.assertEqual(self.call(test, b=10), (1, 10, 3))
3787
3788    def test_signature_bind_varargs_order(self):
3789        def test(*args):
3790            return args
3791
3792        self.assertEqual(self.call(test), ())
3793        self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
3794
3795    def test_signature_bind_args_and_varargs(self):
3796        def test(a, b, c=3, *args):
3797            return a, b, c, args
3798
3799        self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
3800        self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
3801        self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
3802        self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
3803
3804        with self.assertRaisesRegex(TypeError,
3805                                     "multiple values for argument 'c'"):
3806            self.call(test, 1, 2, 3, c=4)
3807
3808    def test_signature_bind_just_kwargs(self):
3809        def test(**kwargs):
3810            return kwargs
3811
3812        self.assertEqual(self.call(test), {})
3813        self.assertEqual(self.call(test, foo='bar', spam='ham'),
3814                         {'foo': 'bar', 'spam': 'ham'})
3815
3816    def test_signature_bind_args_and_kwargs(self):
3817        def test(a, b, c=3, **kwargs):
3818            return a, b, c, kwargs
3819
3820        self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
3821        self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
3822                         (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3823        self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
3824                         (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3825        self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
3826                         (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3827        self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
3828                         (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
3829        self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
3830                         (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
3831        self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
3832                         (1, 2, 4, {'foo': 'bar'}))
3833        self.assertEqual(self.call(test, c=5, a=4, b=3),
3834                         (4, 3, 5, {}))
3835
3836    def test_signature_bind_kwonly(self):
3837        def test(*, foo):
3838            return foo
3839        with self.assertRaisesRegex(TypeError,
3840                                     'too many positional arguments'):
3841            self.call(test, 1)
3842        self.assertEqual(self.call(test, foo=1), 1)
3843
3844        def test(a, *, foo=1, bar):
3845            return foo
3846        with self.assertRaisesRegex(TypeError,
3847                                     "missing a required argument: 'bar'"):
3848            self.call(test, 1)
3849
3850        def test(foo, *, bar):
3851            return foo, bar
3852        self.assertEqual(self.call(test, 1, bar=2), (1, 2))
3853        self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
3854
3855        with self.assertRaisesRegex(
3856            TypeError, "got an unexpected keyword argument 'spam'"):
3857
3858            self.call(test, bar=2, foo=1, spam=10)
3859
3860        with self.assertRaisesRegex(TypeError,
3861                                     'too many positional arguments'):
3862            self.call(test, 1, 2)
3863
3864        with self.assertRaisesRegex(TypeError,
3865                                     'too many positional arguments'):
3866            self.call(test, 1, 2, bar=2)
3867
3868        with self.assertRaisesRegex(
3869            TypeError, "got an unexpected keyword argument 'spam'"):
3870
3871            self.call(test, 1, bar=2, spam='ham')
3872
3873        with self.assertRaisesRegex(TypeError,
3874                                     "missing a required argument: 'bar'"):
3875            self.call(test, 1)
3876
3877        def test(foo, *, bar, **bin):
3878            return foo, bar, bin
3879        self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
3880        self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
3881        self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
3882                         (1, 2, {'spam': 'ham'}))
3883        self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
3884                         (1, 2, {'spam': 'ham'}))
3885        with self.assertRaisesRegex(TypeError,
3886                                    "missing a required argument: 'foo'"):
3887            self.call(test, spam='ham', bar=2)
3888        self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
3889                         (1, 2, {'bin': 1, 'spam': 10}))
3890
3891    def test_signature_bind_arguments(self):
3892        def test(a, *args, b, z=100, **kwargs):
3893            pass
3894        sig = inspect.signature(test)
3895        ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
3896        # we won't have 'z' argument in the bound arguments object, as we didn't
3897        # pass it to the 'bind'
3898        self.assertEqual(tuple(ba.arguments.items()),
3899                         (('a', 10), ('args', (20,)), ('b', 30),
3900                          ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
3901        self.assertEqual(ba.kwargs,
3902                         {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
3903        self.assertEqual(ba.args, (10, 20))
3904
3905    def test_signature_bind_positional_only(self):
3906        P = inspect.Parameter
3907
3908        def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs):
3909            return a_po, b_po, c_po, foo, bar, kwargs
3910
3911        sig = inspect.signature(test)
3912        new_params = collections.OrderedDict(tuple(sig.parameters.items()))
3913        for name in ('a_po', 'b_po', 'c_po'):
3914            new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY)
3915        new_sig = sig.replace(parameters=new_params.values())
3916        test.__signature__ = new_sig
3917
3918        self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
3919                         (1, 2, 4, 5, 6, {}))
3920
3921        self.assertEqual(self.call(test, 1, 2),
3922                         (1, 2, 3, 42, 50, {}))
3923
3924        self.assertEqual(self.call(test, 1, 2, foo=4, bar=5),
3925                         (1, 2, 3, 4, 5, {}))
3926
3927        with self.assertRaisesRegex(TypeError, "but was passed as a keyword"):
3928            self.call(test, 1, 2, foo=4, bar=5, c_po=10)
3929
3930        with self.assertRaisesRegex(TypeError, "parameter is positional only"):
3931            self.call(test, 1, 2, c_po=4)
3932
3933        with self.assertRaisesRegex(TypeError, "parameter is positional only"):
3934            self.call(test, a_po=1, b_po=2)
3935
3936    def test_signature_bind_with_self_arg(self):
3937        # Issue #17071: one of the parameters is named "self
3938        def test(a, self, b):
3939            pass
3940        sig = inspect.signature(test)
3941        ba = sig.bind(1, 2, 3)
3942        self.assertEqual(ba.args, (1, 2, 3))
3943        ba = sig.bind(1, self=2, b=3)
3944        self.assertEqual(ba.args, (1, 2, 3))
3945
3946    def test_signature_bind_vararg_name(self):
3947        def test(a, *args):
3948            return a, args
3949        sig = inspect.signature(test)
3950
3951        with self.assertRaisesRegex(
3952            TypeError, "got an unexpected keyword argument 'args'"):
3953
3954            sig.bind(a=0, args=1)
3955
3956        def test(*args, **kwargs):
3957            return args, kwargs
3958        self.assertEqual(self.call(test, args=1), ((), {'args': 1}))
3959
3960        sig = inspect.signature(test)
3961        ba = sig.bind(args=1)
3962        self.assertEqual(ba.arguments, {'kwargs': {'args': 1}})
3963
3964    @cpython_only
3965    def test_signature_bind_implicit_arg(self):
3966        # Issue #19611: getcallargs should work with set comprehensions
3967        def make_set():
3968            return {z * z for z in range(5)}
3969        setcomp_code = make_set.__code__.co_consts[1]
3970        setcomp_func = types.FunctionType(setcomp_code, {})
3971
3972        iterator = iter(range(5))
3973        self.assertEqual(self.call(setcomp_func, iterator), {0, 1, 4, 9, 16})
3974
3975    def test_signature_bind_posonly_kwargs(self):
3976        def foo(bar, /, **kwargs):
3977            return bar, kwargs.get(bar)
3978
3979        sig = inspect.signature(foo)
3980        result = sig.bind("pos-only", bar="keyword")
3981
3982        self.assertEqual(result.kwargs, {"bar": "keyword"})
3983        self.assertIn(("bar", "pos-only"), result.arguments.items())
3984
3985
3986class TestBoundArguments(unittest.TestCase):
3987    def test_signature_bound_arguments_unhashable(self):
3988        def foo(a): pass
3989        ba = inspect.signature(foo).bind(1)
3990
3991        with self.assertRaisesRegex(TypeError, 'unhashable type'):
3992            hash(ba)
3993
3994    def test_signature_bound_arguments_equality(self):
3995        def foo(a): pass
3996        ba = inspect.signature(foo).bind(1)
3997        self.assertTrue(ba == ba)
3998        self.assertFalse(ba != ba)
3999        self.assertTrue(ba == ALWAYS_EQ)
4000        self.assertFalse(ba != ALWAYS_EQ)
4001
4002        ba2 = inspect.signature(foo).bind(1)
4003        self.assertTrue(ba == ba2)
4004        self.assertFalse(ba != ba2)
4005
4006        ba3 = inspect.signature(foo).bind(2)
4007        self.assertFalse(ba == ba3)
4008        self.assertTrue(ba != ba3)
4009        ba3.arguments['a'] = 1
4010        self.assertTrue(ba == ba3)
4011        self.assertFalse(ba != ba3)
4012
4013        def bar(b): pass
4014        ba4 = inspect.signature(bar).bind(1)
4015        self.assertFalse(ba == ba4)
4016        self.assertTrue(ba != ba4)
4017
4018        def foo(*, a, b): pass
4019        sig = inspect.signature(foo)
4020        ba1 = sig.bind(a=1, b=2)
4021        ba2 = sig.bind(b=2, a=1)
4022        self.assertTrue(ba1 == ba2)
4023        self.assertFalse(ba1 != ba2)
4024
4025    def test_signature_bound_arguments_pickle(self):
4026        def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
4027        sig = inspect.signature(foo)
4028        ba = sig.bind(20, 30, z={})
4029
4030        for ver in range(pickle.HIGHEST_PROTOCOL + 1):
4031            with self.subTest(pickle_ver=ver):
4032                ba_pickled = pickle.loads(pickle.dumps(ba, ver))
4033                self.assertEqual(ba, ba_pickled)
4034
4035    def test_signature_bound_arguments_repr(self):
4036        def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
4037        sig = inspect.signature(foo)
4038        ba = sig.bind(20, 30, z={})
4039        self.assertRegex(repr(ba), r'<BoundArguments \(a=20,.*\}\}\)>')
4040
4041    def test_signature_bound_arguments_apply_defaults(self):
4042        def foo(a, b=1, *args, c:1={}, **kw): pass
4043        sig = inspect.signature(foo)
4044
4045        ba = sig.bind(20)
4046        ba.apply_defaults()
4047        self.assertEqual(
4048            list(ba.arguments.items()),
4049            [('a', 20), ('b', 1), ('args', ()), ('c', {}), ('kw', {})])
4050
4051        # Make sure that we preserve the order:
4052        # i.e. 'c' should be *before* 'kw'.
4053        ba = sig.bind(10, 20, 30, d=1)
4054        ba.apply_defaults()
4055        self.assertEqual(
4056            list(ba.arguments.items()),
4057            [('a', 10), ('b', 20), ('args', (30,)), ('c', {}), ('kw', {'d':1})])
4058
4059        # Make sure that BoundArguments produced by bind_partial()
4060        # are supported.
4061        def foo(a, b): pass
4062        sig = inspect.signature(foo)
4063        ba = sig.bind_partial(20)
4064        ba.apply_defaults()
4065        self.assertEqual(
4066            list(ba.arguments.items()),
4067            [('a', 20)])
4068
4069        # Test no args
4070        def foo(): pass
4071        sig = inspect.signature(foo)
4072        ba = sig.bind()
4073        ba.apply_defaults()
4074        self.assertEqual(list(ba.arguments.items()), [])
4075
4076        # Make sure a no-args binding still acquires proper defaults.
4077        def foo(a='spam'): pass
4078        sig = inspect.signature(foo)
4079        ba = sig.bind()
4080        ba.apply_defaults()
4081        self.assertEqual(list(ba.arguments.items()), [('a', 'spam')])
4082
4083    def test_signature_bound_arguments_arguments_type(self):
4084        def foo(a): pass
4085        ba = inspect.signature(foo).bind(1)
4086        self.assertIs(type(ba.arguments), dict)
4087
4088class TestSignaturePrivateHelpers(unittest.TestCase):
4089    def test_signature_get_bound_param(self):
4090        getter = inspect._signature_get_bound_param
4091
4092        self.assertEqual(getter('($self)'), 'self')
4093        self.assertEqual(getter('($self, obj)'), 'self')
4094        self.assertEqual(getter('($cls, /, obj)'), 'cls')
4095
4096    def _strip_non_python_syntax(self, input,
4097        clean_signature, self_parameter, last_positional_only):
4098        computed_clean_signature, \
4099            computed_self_parameter, \
4100            computed_last_positional_only = \
4101            inspect._signature_strip_non_python_syntax(input)
4102        self.assertEqual(computed_clean_signature, clean_signature)
4103        self.assertEqual(computed_self_parameter, self_parameter)
4104        self.assertEqual(computed_last_positional_only, last_positional_only)
4105
4106    def test_signature_strip_non_python_syntax(self):
4107        self._strip_non_python_syntax(
4108            "($module, /, path, mode, *, dir_fd=None, " +
4109                "effective_ids=False,\n       follow_symlinks=True)",
4110            "(module, path, mode, *, dir_fd=None, " +
4111                "effective_ids=False, follow_symlinks=True)",
4112            0,
4113            0)
4114
4115        self._strip_non_python_syntax(
4116            "($module, word, salt, /)",
4117            "(module, word, salt)",
4118            0,
4119            2)
4120
4121        self._strip_non_python_syntax(
4122            "(x, y=None, z=None, /)",
4123            "(x, y=None, z=None)",
4124            None,
4125            2)
4126
4127        self._strip_non_python_syntax(
4128            "(x, y=None, z=None)",
4129            "(x, y=None, z=None)",
4130            None,
4131            None)
4132
4133        self._strip_non_python_syntax(
4134            "(x,\n    y=None,\n      z = None  )",
4135            "(x, y=None, z=None)",
4136            None,
4137            None)
4138
4139        self._strip_non_python_syntax(
4140            "",
4141            "",
4142            None,
4143            None)
4144
4145        self._strip_non_python_syntax(
4146            None,
4147            None,
4148            None,
4149            None)
4150
4151class TestSignatureDefinitions(unittest.TestCase):
4152    # This test case provides a home for checking that particular APIs
4153    # have signatures available for introspection
4154
4155    @cpython_only
4156    @unittest.skipIf(MISSING_C_DOCSTRINGS,
4157                     "Signature information for builtins requires docstrings")
4158    def test_builtins_have_signatures(self):
4159        # This checks all builtin callables in CPython have signatures
4160        # A few have signatures Signature can't yet handle, so we skip those
4161        # since they will have to wait until PEP 457 adds the required
4162        # introspection support to the inspect module
4163        # Some others also haven't been converted yet for various other
4164        # reasons, so we also skip those for the time being, but design
4165        # the test to fail in order to indicate when it needs to be
4166        # updated.
4167        no_signature = set()
4168        # These need PEP 457 groups
4169        needs_groups = {"range", "slice", "dir", "getattr",
4170                        "next", "iter", "vars"}
4171        no_signature |= needs_groups
4172        # These have unrepresentable parameter default values of NULL
4173        needs_null = {"anext"}
4174        no_signature |= needs_null
4175        # These need PEP 457 groups or a signature change to accept None
4176        needs_semantic_update = {"round"}
4177        no_signature |= needs_semantic_update
4178        # These need *args support in Argument Clinic
4179        needs_varargs = {"breakpoint", "min", "max", "print",
4180                         "__build_class__"}
4181        no_signature |= needs_varargs
4182        # These simply weren't covered in the initial AC conversion
4183        # for builtin callables
4184        not_converted_yet = {"open", "__import__"}
4185        no_signature |= not_converted_yet
4186        # These builtin types are expected to provide introspection info
4187        types_with_signatures = set()
4188        # Check the signatures we expect to be there
4189        ns = vars(builtins)
4190        for name, obj in sorted(ns.items()):
4191            if not callable(obj):
4192                continue
4193            # The builtin types haven't been converted to AC yet
4194            if isinstance(obj, type) and (name not in types_with_signatures):
4195                # Note that this also skips all the exception types
4196                no_signature.add(name)
4197            if (name in no_signature):
4198                # Not yet converted
4199                continue
4200            with self.subTest(builtin=name):
4201                self.assertIsNotNone(inspect.signature(obj))
4202        # Check callables that haven't been converted don't claim a signature
4203        # This ensures this test will start failing as more signatures are
4204        # added, so the affected items can be moved into the scope of the
4205        # regression test above
4206        for name in no_signature:
4207            with self.subTest(builtin=name):
4208                self.assertIsNone(obj.__text_signature__)
4209
4210    def test_python_function_override_signature(self):
4211        def func(*args, **kwargs):
4212            pass
4213        func.__text_signature__ = '($self, a, b=1, *args, c, d=2, **kwargs)'
4214        sig = inspect.signature(func)
4215        self.assertIsNotNone(sig)
4216        self.assertEqual(str(sig), '(self, /, a, b=1, *args, c, d=2, **kwargs)')
4217        func.__text_signature__ = '($self, a, b=1, /, *args, c, d=2, **kwargs)'
4218        sig = inspect.signature(func)
4219        self.assertEqual(str(sig), '(self, a, b=1, /, *args, c, d=2, **kwargs)')
4220
4221    def test_base_class_have_text_signature(self):
4222        # see issue 43118
4223        from test.ann_module7 import BufferedReader
4224        class MyBufferedReader(BufferedReader):
4225            """buffer reader class."""
4226
4227        text_signature = BufferedReader.__text_signature__
4228        self.assertEqual(text_signature, '(raw, buffer_size=DEFAULT_BUFFER_SIZE)')
4229        sig = inspect.signature(MyBufferedReader)
4230        self.assertEqual(str(sig), '(raw, buffer_size=8192)')
4231
4232
4233class NTimesUnwrappable:
4234    def __init__(self, n):
4235        self.n = n
4236        self._next = None
4237
4238    @property
4239    def __wrapped__(self):
4240        if self.n <= 0:
4241            raise Exception("Unwrapped too many times")
4242        if self._next is None:
4243            self._next = NTimesUnwrappable(self.n - 1)
4244        return self._next
4245
4246class TestUnwrap(unittest.TestCase):
4247
4248    def test_unwrap_one(self):
4249        def func(a, b):
4250            return a + b
4251        wrapper = functools.lru_cache(maxsize=20)(func)
4252        self.assertIs(inspect.unwrap(wrapper), func)
4253
4254    def test_unwrap_several(self):
4255        def func(a, b):
4256            return a + b
4257        wrapper = func
4258        for __ in range(10):
4259            @functools.wraps(wrapper)
4260            def wrapper():
4261                pass
4262        self.assertIsNot(wrapper.__wrapped__, func)
4263        self.assertIs(inspect.unwrap(wrapper), func)
4264
4265    def test_stop(self):
4266        def func1(a, b):
4267            return a + b
4268        @functools.wraps(func1)
4269        def func2():
4270            pass
4271        @functools.wraps(func2)
4272        def wrapper():
4273            pass
4274        func2.stop_here = 1
4275        unwrapped = inspect.unwrap(wrapper,
4276                                   stop=(lambda f: hasattr(f, "stop_here")))
4277        self.assertIs(unwrapped, func2)
4278
4279    def test_cycle(self):
4280        def func1(): pass
4281        func1.__wrapped__ = func1
4282        with self.assertRaisesRegex(ValueError, 'wrapper loop'):
4283            inspect.unwrap(func1)
4284
4285        def func2(): pass
4286        func2.__wrapped__ = func1
4287        func1.__wrapped__ = func2
4288        with self.assertRaisesRegex(ValueError, 'wrapper loop'):
4289            inspect.unwrap(func1)
4290        with self.assertRaisesRegex(ValueError, 'wrapper loop'):
4291            inspect.unwrap(func2)
4292
4293    def test_unhashable(self):
4294        def func(): pass
4295        func.__wrapped__ = None
4296        class C:
4297            __hash__ = None
4298            __wrapped__ = func
4299        self.assertIsNone(inspect.unwrap(C()))
4300
4301    def test_recursion_limit(self):
4302        obj = NTimesUnwrappable(sys.getrecursionlimit() + 1)
4303        with self.assertRaisesRegex(ValueError, 'wrapper loop'):
4304            inspect.unwrap(obj)
4305
4306class TestMain(unittest.TestCase):
4307    def test_only_source(self):
4308        module = importlib.import_module('unittest')
4309        rc, out, err = assert_python_ok('-m', 'inspect',
4310                                        'unittest')
4311        lines = out.decode().splitlines()
4312        # ignore the final newline
4313        self.assertEqual(lines[:-1], inspect.getsource(module).splitlines())
4314        self.assertEqual(err, b'')
4315
4316    def test_custom_getattr(self):
4317        def foo():
4318            pass
4319        foo.__signature__ = 42
4320        with self.assertRaises(TypeError):
4321            inspect.signature(foo)
4322
4323    @unittest.skipIf(ThreadPoolExecutor is None,
4324            'threads required to test __qualname__ for source files')
4325    def test_qualname_source(self):
4326        rc, out, err = assert_python_ok('-m', 'inspect',
4327                                     'concurrent.futures:ThreadPoolExecutor')
4328        lines = out.decode().splitlines()
4329        # ignore the final newline
4330        self.assertEqual(lines[:-1],
4331                         inspect.getsource(ThreadPoolExecutor).splitlines())
4332        self.assertEqual(err, b'')
4333
4334    def test_builtins(self):
4335        module = importlib.import_module('unittest')
4336        _, out, err = assert_python_failure('-m', 'inspect',
4337                                            'sys')
4338        lines = err.decode().splitlines()
4339        self.assertEqual(lines, ["Can't get info for builtin modules."])
4340
4341    def test_details(self):
4342        module = importlib.import_module('unittest')
4343        args = support.optim_args_from_interpreter_flags()
4344        rc, out, err = assert_python_ok(*args, '-m', 'inspect',
4345                                        'unittest', '--details')
4346        output = out.decode()
4347        # Just a quick sanity check on the output
4348        self.assertIn(module.__name__, output)
4349        self.assertIn(module.__file__, output)
4350        self.assertIn(module.__cached__, output)
4351        self.assertEqual(err, b'')
4352
4353
4354class TestReload(unittest.TestCase):
4355
4356    src_before = textwrap.dedent("""\
4357def foo():
4358    print("Bla")
4359    """)
4360
4361    src_after = textwrap.dedent("""\
4362def foo():
4363    print("Oh no!")
4364    """)
4365
4366    def assertInspectEqual(self, path, source):
4367        inspected_src = inspect.getsource(source)
4368        with open(path, encoding='utf-8') as src:
4369            self.assertEqual(
4370                src.read().splitlines(True),
4371                inspected_src.splitlines(True)
4372            )
4373
4374    def test_getsource_reload(self):
4375        # see issue 1218234
4376        with _ready_to_import('reload_bug', self.src_before) as (name, path):
4377            module = importlib.import_module(name)
4378            self.assertInspectEqual(path, module)
4379            with open(path, 'w', encoding='utf-8') as src:
4380                src.write(self.src_after)
4381            self.assertInspectEqual(path, module)
4382
4383
4384if __name__ == "__main__":
4385    unittest.main()
4386