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