• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import asyncio
2import builtins
3import collections
4import copy
5import datetime
6import functools
7import gc
8import importlib
9import inspect
10import io
11import linecache
12import os
13import dis
14from os.path import normcase
15import _pickle
16import pickle
17import shutil
18import stat
19import sys
20import subprocess
21import time
22import types
23import tempfile
24import textwrap
25from typing import Unpack
26import unicodedata
27import unittest
28import unittest.mock
29import warnings
30import weakref
31
32
33try:
34    from concurrent.futures import ThreadPoolExecutor
35except ImportError:
36    ThreadPoolExecutor = None
37
38from test.support import cpython_only, import_helper, suppress_immortalization
39from test.support import MISSING_C_DOCSTRINGS, ALWAYS_EQ
40from test.support.import_helper import DirsOnSysPath, ready_to_import
41from test.support.os_helper import TESTFN, temp_cwd
42from test.support.script_helper import assert_python_ok, assert_python_failure, kill_python
43from test.support import has_subprocess_support, SuppressCrashReport
44from test import support
45
46from test.test_inspect import inspect_fodder as mod
47from test.test_inspect import inspect_fodder2 as mod2
48from test.test_inspect import inspect_stock_annotations
49from test.test_inspect import inspect_stringized_annotations
50from test.test_inspect import inspect_stringized_annotations_2
51from test.test_inspect import inspect_stringized_annotations_pep695
52
53
54# Functions tested in this suite:
55# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
56# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
57# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
58# getclasstree, getargvalues, formatargvalues, currentframe,
59# stack, trace, ismethoddescriptor, isdatadescriptor, ismethodwrapper
60
61# NOTE: There are some additional tests relating to interaction with
62#       zipimport in the test_zipimport_support test module.
63
64modfile = mod.__file__
65if modfile.endswith(('c', 'o')):
66    modfile = modfile[:-1]
67
68# Normalize file names: on Windows, the case of file names of compiled
69# modules depends on the path used to start the python executable.
70modfile = normcase(modfile)
71
72def revise(filename, *args):
73    return (normcase(filename),) + args
74
75git = mod.StupidGit()
76
77
78def tearDownModule():
79    if support.has_socket_support:
80        asyncio.set_event_loop_policy(None)
81
82
83def signatures_with_lexicographic_keyword_only_parameters():
84    """
85    Yields a whole bunch of functions with only keyword-only parameters,
86    where those parameters are always in lexicographically sorted order.
87    """
88    parameters = ['a', 'bar', 'c', 'delta', 'ephraim', 'magical', 'yoyo', 'z']
89    for i in range(1, 2**len(parameters)):
90        p = []
91        bit = 1
92        for j in range(len(parameters)):
93            if i & (bit << j):
94                p.append(parameters[j])
95        fn_text = "def foo(*, " + ", ".join(p) + "): pass"
96        symbols = {}
97        exec(fn_text, symbols, symbols)
98        yield symbols['foo']
99
100
101def unsorted_keyword_only_parameters_fn(*, throw, out, the, baby, with_,
102                                        the_, bathwater):
103    pass
104
105unsorted_keyword_only_parameters = 'throw out the baby with_ the_ bathwater'.split()
106
107class IsTestBase(unittest.TestCase):
108    predicates = set([inspect.isbuiltin, inspect.isclass, inspect.iscode,
109                      inspect.isframe, inspect.isfunction, inspect.ismethod,
110                      inspect.ismodule, inspect.istraceback,
111                      inspect.isgenerator, inspect.isgeneratorfunction,
112                      inspect.iscoroutine, inspect.iscoroutinefunction,
113                      inspect.isasyncgen, inspect.isasyncgenfunction,
114                      inspect.ismethodwrapper])
115
116    def istest(self, predicate, exp):
117        obj = eval(exp)
118        self.assertTrue(predicate(obj), '%s(%s)' % (predicate.__name__, exp))
119
120        for other in self.predicates - set([predicate]):
121            if (predicate == inspect.isgeneratorfunction or \
122               predicate == inspect.isasyncgenfunction or \
123               predicate == inspect.iscoroutinefunction) and \
124               other == inspect.isfunction:
125                continue
126            self.assertFalse(other(obj), 'not %s(%s)' % (other.__name__, exp))
127
128    def test__all__(self):
129        support.check__all__(self, inspect, not_exported=("modulesbyfile",))
130
131def generator_function_example(self):
132    for i in range(2):
133        yield i
134
135async def async_generator_function_example(self):
136    async for i in range(2):
137        yield i
138
139async def coroutine_function_example(self):
140    return 'spam'
141
142@types.coroutine
143def gen_coroutine_function_example(self):
144    yield
145    return 'spam'
146
147def meth_noargs(): pass
148def meth_o(object, /): pass
149def meth_self_noargs(self, /): pass
150def meth_self_o(self, object, /): pass
151def meth_type_noargs(type, /): pass
152def meth_type_o(type, object, /): pass
153
154
155class TestPredicates(IsTestBase):
156
157    def test_excluding_predicates(self):
158        global tb
159        self.istest(inspect.isbuiltin, 'sys.exit')
160        self.istest(inspect.isbuiltin, '[].append')
161        self.istest(inspect.iscode, 'mod.spam.__code__')
162        try:
163            1/0
164        except Exception as e:
165            tb = e.__traceback__
166            self.istest(inspect.isframe, 'tb.tb_frame')
167            self.istest(inspect.istraceback, 'tb')
168            if hasattr(types, 'GetSetDescriptorType'):
169                self.istest(inspect.isgetsetdescriptor,
170                            'type(tb.tb_frame).f_locals')
171            else:
172                self.assertFalse(inspect.isgetsetdescriptor(type(tb.tb_frame).f_locals))
173        finally:
174            # Clear traceback and all the frames and local variables hanging to it.
175            tb = None
176        self.istest(inspect.isfunction, 'mod.spam')
177        self.istest(inspect.isfunction, 'mod.StupidGit.abuse')
178        self.istest(inspect.ismethod, 'git.argue')
179        self.istest(inspect.ismethod, 'mod.custom_method')
180        self.istest(inspect.ismodule, 'mod')
181        self.istest(inspect.ismethoddescriptor, 'int.__add__')
182        self.istest(inspect.isdatadescriptor, 'collections.defaultdict.default_factory')
183        self.istest(inspect.isgenerator, '(x for x in range(2))')
184        self.istest(inspect.isgeneratorfunction, 'generator_function_example')
185        self.istest(inspect.isasyncgen,
186                    'async_generator_function_example(1)')
187        self.istest(inspect.isasyncgenfunction,
188                    'async_generator_function_example')
189
190        with warnings.catch_warnings():
191            warnings.simplefilter("ignore")
192            self.istest(inspect.iscoroutine, 'coroutine_function_example(1)')
193            self.istest(inspect.iscoroutinefunction, 'coroutine_function_example')
194
195        if hasattr(types, 'MemberDescriptorType'):
196            self.istest(inspect.ismemberdescriptor, 'datetime.timedelta.days')
197        else:
198            self.assertFalse(inspect.ismemberdescriptor(datetime.timedelta.days))
199        self.istest(inspect.ismethodwrapper, "object().__str__")
200        self.istest(inspect.ismethodwrapper, "object().__eq__")
201        self.istest(inspect.ismethodwrapper, "object().__repr__")
202        self.assertFalse(inspect.ismethodwrapper(type))
203        self.assertFalse(inspect.ismethodwrapper(int))
204        self.assertFalse(inspect.ismethodwrapper(type("AnyClass", (), {})))
205
206
207
208    def test_iscoroutine(self):
209        async_gen_coro = async_generator_function_example(1)
210        gen_coro = gen_coroutine_function_example(1)
211        coro = coroutine_function_example(1)
212
213        class PMClass:
214            async_generator_partialmethod_example = functools.partialmethod(
215                async_generator_function_example)
216            coroutine_partialmethod_example = functools.partialmethod(
217                coroutine_function_example)
218            gen_coroutine_partialmethod_example = functools.partialmethod(
219                gen_coroutine_function_example)
220
221        # partialmethods on the class, bound to an instance
222        pm_instance = PMClass()
223        async_gen_coro_pmi = pm_instance.async_generator_partialmethod_example
224        gen_coro_pmi = pm_instance.gen_coroutine_partialmethod_example
225        coro_pmi = pm_instance.coroutine_partialmethod_example
226
227        # partialmethods on the class, unbound but accessed via the class
228        async_gen_coro_pmc = PMClass.async_generator_partialmethod_example
229        gen_coro_pmc = PMClass.gen_coroutine_partialmethod_example
230        coro_pmc = PMClass.coroutine_partialmethod_example
231
232        self.assertFalse(
233            inspect.iscoroutinefunction(gen_coroutine_function_example))
234        self.assertFalse(
235            inspect.iscoroutinefunction(
236                functools.partial(functools.partial(
237                    gen_coroutine_function_example))))
238        self.assertFalse(inspect.iscoroutinefunction(gen_coro_pmi))
239        self.assertFalse(inspect.iscoroutinefunction(gen_coro_pmc))
240        self.assertFalse(inspect.iscoroutinefunction(inspect))
241        self.assertFalse(inspect.iscoroutine(gen_coro))
242
243        self.assertTrue(
244            inspect.isgeneratorfunction(gen_coroutine_function_example))
245        self.assertTrue(
246            inspect.isgeneratorfunction(
247                functools.partial(functools.partial(
248                    gen_coroutine_function_example))))
249        self.assertTrue(inspect.isgeneratorfunction(gen_coro_pmi))
250        self.assertTrue(inspect.isgeneratorfunction(gen_coro_pmc))
251        self.assertTrue(inspect.isgenerator(gen_coro))
252
253        async def _fn3():
254            pass
255
256        @inspect.markcoroutinefunction
257        def fn3():
258            return _fn3()
259
260        self.assertTrue(inspect.iscoroutinefunction(fn3))
261        self.assertTrue(
262            inspect.iscoroutinefunction(
263                inspect.markcoroutinefunction(lambda: _fn3())
264            )
265        )
266
267        class Cl:
268            async def __call__(self):
269                pass
270
271        self.assertFalse(inspect.iscoroutinefunction(Cl))
272        # instances with async def __call__ are NOT recognised.
273        self.assertFalse(inspect.iscoroutinefunction(Cl()))
274        # unless explicitly marked.
275        self.assertTrue(inspect.iscoroutinefunction(
276            inspect.markcoroutinefunction(Cl())
277        ))
278
279        class Cl2:
280            @inspect.markcoroutinefunction
281            def __call__(self):
282                pass
283
284        self.assertFalse(inspect.iscoroutinefunction(Cl2))
285        # instances with marked __call__ are NOT recognised.
286        self.assertFalse(inspect.iscoroutinefunction(Cl2()))
287        # unless explicitly marked.
288        self.assertTrue(inspect.iscoroutinefunction(
289            inspect.markcoroutinefunction(Cl2())
290        ))
291
292        class Cl3:
293            @inspect.markcoroutinefunction
294            @classmethod
295            def do_something_classy(cls):
296                pass
297
298            @inspect.markcoroutinefunction
299            @staticmethod
300            def do_something_static():
301                pass
302
303        self.assertTrue(inspect.iscoroutinefunction(Cl3.do_something_classy))
304        self.assertTrue(inspect.iscoroutinefunction(Cl3.do_something_static))
305
306        self.assertFalse(
307            inspect.iscoroutinefunction(unittest.mock.Mock()))
308        self.assertTrue(
309            inspect.iscoroutinefunction(unittest.mock.AsyncMock()))
310        self.assertTrue(
311            inspect.iscoroutinefunction(coroutine_function_example))
312        self.assertTrue(
313            inspect.iscoroutinefunction(
314                functools.partial(functools.partial(
315                    coroutine_function_example))))
316        self.assertTrue(inspect.iscoroutinefunction(coro_pmi))
317        self.assertTrue(inspect.iscoroutinefunction(coro_pmc))
318        self.assertTrue(inspect.iscoroutine(coro))
319
320        self.assertFalse(
321            inspect.isgeneratorfunction(unittest.mock.Mock()))
322        self.assertFalse(
323            inspect.isgeneratorfunction(unittest.mock.AsyncMock()))
324        self.assertFalse(
325            inspect.isgeneratorfunction(coroutine_function_example))
326        self.assertFalse(
327            inspect.isgeneratorfunction(
328                functools.partial(functools.partial(
329                    coroutine_function_example))))
330        self.assertFalse(inspect.isgeneratorfunction(coro_pmi))
331        self.assertFalse(inspect.isgeneratorfunction(coro_pmc))
332        self.assertFalse(inspect.isgenerator(coro))
333
334        self.assertFalse(
335            inspect.isasyncgenfunction(unittest.mock.Mock()))
336        self.assertFalse(
337            inspect.isasyncgenfunction(unittest.mock.AsyncMock()))
338        self.assertFalse(
339            inspect.isasyncgenfunction(coroutine_function_example))
340        self.assertTrue(
341            inspect.isasyncgenfunction(async_generator_function_example))
342        self.assertTrue(
343            inspect.isasyncgenfunction(
344                functools.partial(functools.partial(
345                    async_generator_function_example))))
346        self.assertTrue(inspect.isasyncgenfunction(async_gen_coro_pmi))
347        self.assertTrue(inspect.isasyncgenfunction(async_gen_coro_pmc))
348        self.assertTrue(inspect.isasyncgen(async_gen_coro))
349
350        coro.close(); gen_coro.close(); # silence warnings
351
352    def test_isawaitable(self):
353        def gen(): yield
354        self.assertFalse(inspect.isawaitable(gen()))
355
356        coro = coroutine_function_example(1)
357        gen_coro = gen_coroutine_function_example(1)
358
359        self.assertTrue(inspect.isawaitable(coro))
360        self.assertTrue(inspect.isawaitable(gen_coro))
361
362        class Future:
363            def __await__():
364                pass
365        self.assertTrue(inspect.isawaitable(Future()))
366        self.assertFalse(inspect.isawaitable(Future))
367
368        class NotFuture: pass
369        not_fut = NotFuture()
370        not_fut.__await__ = lambda: None
371        self.assertFalse(inspect.isawaitable(not_fut))
372
373        coro.close(); gen_coro.close() # silence warnings
374
375    def test_isroutine(self):
376        # method
377        self.assertTrue(inspect.isroutine(git.argue))
378        self.assertTrue(inspect.isroutine(mod.custom_method))
379        self.assertTrue(inspect.isroutine([].count))
380        # function
381        self.assertTrue(inspect.isroutine(mod.spam))
382        self.assertTrue(inspect.isroutine(mod.StupidGit.abuse))
383        # slot-wrapper
384        self.assertTrue(inspect.isroutine(object.__init__))
385        self.assertTrue(inspect.isroutine(object.__str__))
386        self.assertTrue(inspect.isroutine(object.__lt__))
387        self.assertTrue(inspect.isroutine(int.__lt__))
388        # method-wrapper
389        self.assertTrue(inspect.isroutine(object().__init__))
390        self.assertTrue(inspect.isroutine(object().__str__))
391        self.assertTrue(inspect.isroutine(object().__lt__))
392        self.assertTrue(inspect.isroutine((42).__lt__))
393        # method-descriptor
394        self.assertTrue(inspect.isroutine(str.join))
395        self.assertTrue(inspect.isroutine(list.append))
396        self.assertTrue(inspect.isroutine(''.join))
397        self.assertTrue(inspect.isroutine([].append))
398        # object
399        self.assertFalse(inspect.isroutine(object))
400        self.assertFalse(inspect.isroutine(object()))
401        self.assertFalse(inspect.isroutine(str()))
402        # module
403        self.assertFalse(inspect.isroutine(mod))
404        # type
405        self.assertFalse(inspect.isroutine(type))
406        self.assertFalse(inspect.isroutine(int))
407        self.assertFalse(inspect.isroutine(type('some_class', (), {})))
408        # partial
409        self.assertFalse(inspect.isroutine(functools.partial(mod.spam)))
410
411    def test_isclass(self):
412        self.istest(inspect.isclass, 'mod.StupidGit')
413        self.assertTrue(inspect.isclass(list))
414
415        class CustomGetattr(object):
416            def __getattr__(self, attr):
417                return None
418        self.assertFalse(inspect.isclass(CustomGetattr()))
419
420    def test_get_slot_members(self):
421        class C(object):
422            __slots__ = ("a", "b")
423        x = C()
424        x.a = 42
425        members = dict(inspect.getmembers(x))
426        self.assertIn('a', members)
427        self.assertNotIn('b', members)
428
429    def test_isabstract(self):
430        from abc import ABCMeta, abstractmethod
431
432        class AbstractClassExample(metaclass=ABCMeta):
433
434            @abstractmethod
435            def foo(self):
436                pass
437
438        class ClassExample(AbstractClassExample):
439            def foo(self):
440                pass
441
442        a = ClassExample()
443
444        # Test general behaviour.
445        self.assertTrue(inspect.isabstract(AbstractClassExample))
446        self.assertFalse(inspect.isabstract(ClassExample))
447        self.assertFalse(inspect.isabstract(a))
448        self.assertFalse(inspect.isabstract(int))
449        self.assertFalse(inspect.isabstract(5))
450
451    def test_isabstract_during_init_subclass(self):
452        from abc import ABCMeta, abstractmethod
453        isabstract_checks = []
454        class AbstractChecker(metaclass=ABCMeta):
455            def __init_subclass__(cls):
456                isabstract_checks.append(inspect.isabstract(cls))
457        class AbstractClassExample(AbstractChecker):
458            @abstractmethod
459            def foo(self):
460                pass
461        class ClassExample(AbstractClassExample):
462            def foo(self):
463                pass
464        self.assertEqual(isabstract_checks, [True, False])
465
466        isabstract_checks.clear()
467        class AbstractChild(AbstractClassExample):
468            pass
469        class AbstractGrandchild(AbstractChild):
470            pass
471        class ConcreteGrandchild(ClassExample):
472            pass
473        self.assertEqual(isabstract_checks, [True, True, False])
474
475
476class TestInterpreterStack(IsTestBase):
477    def __init__(self, *args, **kwargs):
478        unittest.TestCase.__init__(self, *args, **kwargs)
479
480        git.abuse(7, 8, 9)
481
482    def test_abuse_done(self):
483        self.istest(inspect.istraceback, 'git.ex.__traceback__')
484        self.istest(inspect.isframe, 'mod.fr')
485
486    def test_stack(self):
487        self.assertTrue(len(mod.st) >= 5)
488        frame1, frame2, frame3, frame4, *_ = mod.st
489        frameinfo = revise(*frame1[1:])
490        self.assertEqual(frameinfo,
491             (modfile, 16, 'eggs', ['    st = inspect.stack()\n'], 0))
492        self.assertEqual(frame1.positions, dis.Positions(16, 16, 9, 24))
493        frameinfo = revise(*frame2[1:])
494        self.assertEqual(frameinfo,
495             (modfile, 9, 'spam', ['    eggs(b + d, c + f)\n'], 0))
496        self.assertEqual(frame2.positions, dis.Positions(9, 9, 4, 22))
497        frameinfo = revise(*frame3[1:])
498        self.assertEqual(frameinfo,
499             (modfile, 43, 'argue', ['            spam(a, b, c)\n'], 0))
500        self.assertEqual(frame3.positions, dis.Positions(43, 43, 12, 25))
501        frameinfo = revise(*frame4[1:])
502        self.assertEqual(frameinfo,
503             (modfile, 39, 'abuse', ['        self.argue(a, b, c)\n'], 0))
504        self.assertEqual(frame4.positions, dis.Positions(39, 39, 8, 27))
505        # Test named tuple fields
506        record = mod.st[0]
507        self.assertIs(record.frame, mod.fr)
508        self.assertEqual(record.lineno, 16)
509        self.assertEqual(record.filename, mod.__file__)
510        self.assertEqual(record.function, 'eggs')
511        self.assertIn('inspect.stack()', record.code_context[0])
512        self.assertEqual(record.index, 0)
513
514    def test_trace(self):
515        self.assertEqual(len(git.tr), 3)
516        frame1, frame2, frame3, = git.tr
517        self.assertEqual(revise(*frame1[1:]),
518             (modfile, 43, 'argue', ['            spam(a, b, c)\n'], 0))
519        self.assertEqual(frame1.positions, dis.Positions(43, 43, 12, 25))
520        self.assertEqual(revise(*frame2[1:]),
521             (modfile, 9, 'spam', ['    eggs(b + d, c + f)\n'], 0))
522        self.assertEqual(frame2.positions, dis.Positions(9, 9, 4, 22))
523        self.assertEqual(revise(*frame3[1:]),
524             (modfile, 18, 'eggs', ['    q = y / 0\n'], 0))
525        self.assertEqual(frame3.positions, dis.Positions(18, 18, 8, 13))
526
527    def test_frame(self):
528        args, varargs, varkw, locals = inspect.getargvalues(mod.fr)
529        self.assertEqual(args, ['x', 'y'])
530        self.assertEqual(varargs, None)
531        self.assertEqual(varkw, None)
532        self.assertEqual(locals, {'x': 11, 'p': 11, 'y': 14})
533        self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
534                         '(x=11, y=14)')
535
536    def test_previous_frame(self):
537        args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back)
538        self.assertEqual(args, ['a', 'b', 'c', 'd', 'e', 'f'])
539        self.assertEqual(varargs, 'g')
540        self.assertEqual(varkw, 'h')
541        self.assertEqual(inspect.formatargvalues(args, varargs, varkw, locals),
542             '(a=7, b=8, c=9, d=3, e=4, f=5, *g=(), **h={})')
543
544class GetSourceBase(unittest.TestCase):
545    # Subclasses must override.
546    fodderModule = None
547
548    def setUp(self):
549        with open(inspect.getsourcefile(self.fodderModule), encoding="utf-8") as fp:
550            self.source = fp.read()
551
552    def sourcerange(self, top, bottom):
553        lines = self.source.split("\n")
554        return "\n".join(lines[top-1:bottom]) + ("\n" if bottom else "")
555
556    def assertSourceEqual(self, obj, top, bottom):
557        self.assertEqual(inspect.getsource(obj),
558                         self.sourcerange(top, bottom))
559
560class SlotUser:
561    'Docstrings for __slots__'
562    __slots__ = {'power': 'measured in kilowatts',
563                 'distance': 'measured in kilometers'}
564
565class TestRetrievingSourceCode(GetSourceBase):
566    fodderModule = mod
567
568    def test_getclasses(self):
569        classes = inspect.getmembers(mod, inspect.isclass)
570        self.assertEqual(classes,
571                         [('FesteringGob', mod.FesteringGob),
572                          ('MalodorousPervert', mod.MalodorousPervert),
573                          ('ParrotDroppings', mod.ParrotDroppings),
574                          ('StupidGit', mod.StupidGit),
575                          ('Tit', mod.MalodorousPervert),
576                          ('WhichComments', mod.WhichComments),
577                         ])
578        tree = inspect.getclasstree([cls[1] for cls in classes])
579        self.assertEqual(tree,
580                         [(object, ()),
581                          [(mod.ParrotDroppings, (object,)),
582                           [(mod.FesteringGob, (mod.MalodorousPervert,
583                                                   mod.ParrotDroppings))
584                            ],
585                           (mod.StupidGit, (object,)),
586                           [(mod.MalodorousPervert, (mod.StupidGit,)),
587                            [(mod.FesteringGob, (mod.MalodorousPervert,
588                                                    mod.ParrotDroppings))
589                             ]
590                            ],
591                            (mod.WhichComments, (object,),)
592                           ]
593                          ])
594        tree = inspect.getclasstree([cls[1] for cls in classes], True)
595        self.assertEqual(tree,
596                         [(object, ()),
597                          [(mod.ParrotDroppings, (object,)),
598                           (mod.StupidGit, (object,)),
599                           [(mod.MalodorousPervert, (mod.StupidGit,)),
600                            [(mod.FesteringGob, (mod.MalodorousPervert,
601                                                    mod.ParrotDroppings))
602                             ]
603                            ],
604                            (mod.WhichComments, (object,),)
605                           ]
606                          ])
607
608    def test_getfunctions(self):
609        functions = inspect.getmembers(mod, inspect.isfunction)
610        self.assertEqual(functions, [('after_closing', mod.after_closing),
611                                     ('eggs', mod.eggs),
612                                     ('lobbest', mod.lobbest),
613                                     ('spam', mod.spam)])
614
615    @unittest.skipIf(sys.flags.optimize >= 2,
616                     "Docstrings are omitted with -O2 and above")
617    def test_getdoc(self):
618        self.assertEqual(inspect.getdoc(mod), 'A module docstring.')
619        self.assertEqual(inspect.getdoc(mod.StupidGit),
620                         'A longer,\n\nindented\n\ndocstring.')
621        self.assertEqual(inspect.getdoc(git.abuse),
622                         'Another\n\ndocstring\n\ncontaining\n\ntabs')
623        self.assertEqual(inspect.getdoc(SlotUser.power),
624                         'measured in kilowatts')
625        self.assertEqual(inspect.getdoc(SlotUser.distance),
626                         'measured in kilometers')
627
628    @unittest.skipIf(sys.flags.optimize >= 2,
629                     "Docstrings are omitted with -O2 and above")
630    def test_getdoc_inherited(self):
631        self.assertEqual(inspect.getdoc(mod.FesteringGob),
632                         'A longer,\n\nindented\n\ndocstring.')
633        self.assertEqual(inspect.getdoc(mod.FesteringGob.abuse),
634                         'Another\n\ndocstring\n\ncontaining\n\ntabs')
635        self.assertEqual(inspect.getdoc(mod.FesteringGob().abuse),
636                         'Another\n\ndocstring\n\ncontaining\n\ntabs')
637        self.assertEqual(inspect.getdoc(mod.FesteringGob.contradiction),
638                         'The automatic gainsaying.')
639
640    @unittest.skipIf(MISSING_C_DOCSTRINGS, "test requires docstrings")
641    def test_finddoc(self):
642        finddoc = inspect._finddoc
643        self.assertEqual(finddoc(int), int.__doc__)
644        self.assertEqual(finddoc(int.to_bytes), int.to_bytes.__doc__)
645        self.assertEqual(finddoc(int().to_bytes), int.to_bytes.__doc__)
646        self.assertEqual(finddoc(int.from_bytes), int.from_bytes.__doc__)
647        self.assertEqual(finddoc(int.real), int.real.__doc__)
648
649    cleandoc_testdata = [
650        # first line should have different margin
651        (' An\n  indented\n   docstring.', 'An\nindented\n docstring.'),
652        # trailing whitespace are not removed.
653        (' An \n   \n  indented \n   docstring. ',
654         'An \n \nindented \n docstring. '),
655        # NUL is not termination.
656        ('doc\0string\n\n  second\0line\n  third\0line\0',
657         'doc\0string\n\nsecond\0line\nthird\0line\0'),
658        # first line is lstrip()-ped. other lines are kept when no margin.[w:
659        ('   ', ''),
660        # compiler.cleandoc() doesn't strip leading/trailing newlines
661        # to keep maximum backward compatibility.
662        # inspect.cleandoc() removes them.
663        ('\n\n\n  first paragraph\n\n   second paragraph\n\n',
664         '\n\n\nfirst paragraph\n\n second paragraph\n\n'),
665        ('   \n \n  \n   ', '\n \n  \n   '),
666    ]
667
668    def test_cleandoc(self):
669        func = inspect.cleandoc
670        for i, (input, expected) in enumerate(self.cleandoc_testdata):
671            # only inspect.cleandoc() strip \n
672            expected = expected.strip('\n')
673            with self.subTest(i=i):
674                self.assertEqual(func(input), expected)
675
676    @cpython_only
677    def test_c_cleandoc(self):
678        try:
679            import _testinternalcapi
680        except ImportError:
681            return unittest.skip("requires _testinternalcapi")
682        func = _testinternalcapi.compiler_cleandoc
683        for i, (input, expected) in enumerate(self.cleandoc_testdata):
684            with self.subTest(i=i):
685                self.assertEqual(func(input), expected)
686
687    def test_getcomments(self):
688        self.assertEqual(inspect.getcomments(mod), '# line 1\n')
689        self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n')
690        self.assertEqual(inspect.getcomments(mod2.cls160), '# line 159\n')
691        # If the object source file is not available, return None.
692        co = compile('x=1', '_non_existing_filename.py', 'exec')
693        self.assertIsNone(inspect.getcomments(co))
694        # If the object has been defined in C, return None.
695        self.assertIsNone(inspect.getcomments(list))
696
697    def test_getmodule(self):
698        # Check actual module
699        self.assertEqual(inspect.getmodule(mod), mod)
700        # Check class (uses __module__ attribute)
701        self.assertEqual(inspect.getmodule(mod.StupidGit), mod)
702        # Check a method (no __module__ attribute, falls back to filename)
703        self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
704        # Do it again (check the caching isn't broken)
705        self.assertEqual(inspect.getmodule(mod.StupidGit.abuse), mod)
706        # Check a builtin
707        self.assertEqual(inspect.getmodule(str), sys.modules["builtins"])
708        # Check filename override
709        self.assertEqual(inspect.getmodule(None, modfile), mod)
710
711    def test_getmodule_file_not_found(self):
712        # See bpo-45406
713        def _getabsfile(obj, _filename):
714            raise FileNotFoundError('bad file')
715        with unittest.mock.patch('inspect.getabsfile', _getabsfile):
716            f = inspect.currentframe()
717            self.assertIsNone(inspect.getmodule(f))
718            inspect.getouterframes(f)  # smoke test
719
720    def test_getframeinfo_get_first_line(self):
721        frame_info = inspect.getframeinfo(self.fodderModule.fr, 50)
722        self.assertEqual(frame_info.code_context[0], "# line 1\n")
723        self.assertEqual(frame_info.code_context[1], "'A module docstring.'\n")
724
725    def test_getsource(self):
726        self.assertSourceEqual(git.abuse, 29, 39)
727        self.assertSourceEqual(mod.StupidGit, 21, 51)
728        self.assertSourceEqual(mod.lobbest, 75, 76)
729        self.assertSourceEqual(mod.after_closing, 120, 120)
730
731    def test_getsourcefile(self):
732        self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile)
733        self.assertEqual(normcase(inspect.getsourcefile(git.abuse)), modfile)
734        fn = "_non_existing_filename_used_for_sourcefile_test.py"
735        co = compile("x=1", fn, "exec")
736        self.assertEqual(inspect.getsourcefile(co), None)
737        linecache.cache[co.co_filename] = (1, None, "None", co.co_filename)
738        try:
739            self.assertEqual(normcase(inspect.getsourcefile(co)), fn)
740        finally:
741            del linecache.cache[co.co_filename]
742
743    def test_getsource_empty_file(self):
744        with temp_cwd() as cwd:
745            with open('empty_file.py', 'w'):
746                pass
747            sys.path.insert(0, cwd)
748            try:
749                import empty_file
750                self.assertEqual(inspect.getsource(empty_file), '\n')
751                self.assertEqual(inspect.getsourcelines(empty_file), (['\n'], 0))
752            finally:
753                sys.path.remove(cwd)
754
755    def test_getfile(self):
756        self.assertEqual(inspect.getfile(mod.StupidGit), mod.__file__)
757
758    def test_getfile_builtin_module(self):
759        with self.assertRaises(TypeError) as e:
760            inspect.getfile(sys)
761        self.assertTrue(str(e.exception).startswith('<module'))
762
763    def test_getfile_builtin_class(self):
764        with self.assertRaises(TypeError) as e:
765            inspect.getfile(int)
766        self.assertTrue(str(e.exception).startswith('<class'))
767
768    def test_getfile_builtin_function_or_method(self):
769        with self.assertRaises(TypeError) as e_abs:
770            inspect.getfile(abs)
771        self.assertIn('expected, got', str(e_abs.exception))
772        with self.assertRaises(TypeError) as e_append:
773            inspect.getfile(list.append)
774        self.assertIn('expected, got', str(e_append.exception))
775
776    @suppress_immortalization()
777    def test_getfile_class_without_module(self):
778        class CM(type):
779            @property
780            def __module__(cls):
781                raise AttributeError
782        class C(metaclass=CM):
783            pass
784        with self.assertRaises(TypeError):
785            inspect.getfile(C)
786
787    def test_getfile_broken_repr(self):
788        class ErrorRepr:
789            def __repr__(self):
790                raise Exception('xyz')
791        er = ErrorRepr()
792        with self.assertRaises(TypeError):
793            inspect.getfile(er)
794
795    def test_getmodule_recursion(self):
796        from types import ModuleType
797        name = '__inspect_dummy'
798        m = sys.modules[name] = ModuleType(name)
799        m.__file__ = "<string>" # hopefully not a real filename...
800        m.__loader__ = "dummy"  # pretend the filename is understood by a loader
801        exec("def x(): pass", m.__dict__)
802        self.assertEqual(inspect.getsourcefile(m.x.__code__), '<string>')
803        del sys.modules[name]
804        inspect.getmodule(compile('a=10','','single'))
805
806    def test_proceed_with_fake_filename(self):
807        '''doctest monkeypatches linecache to enable inspection'''
808        fn, source = '<test>', 'def x(): pass\n'
809        getlines = linecache.getlines
810        def monkey(filename, module_globals=None):
811            if filename == fn:
812                return source.splitlines(keepends=True)
813            else:
814                return getlines(filename, module_globals)
815        linecache.getlines = monkey
816        try:
817            ns = {}
818            exec(compile(source, fn, 'single'), ns)
819            inspect.getsource(ns["x"])
820        finally:
821            linecache.getlines = getlines
822
823    def test_getsource_on_code_object(self):
824        self.assertSourceEqual(mod.eggs.__code__, 12, 18)
825
826    def test_getsource_on_generated_class(self):
827        A = type('A', (unittest.TestCase,), {})
828        self.assertEqual(inspect.getsourcefile(A), __file__)
829        self.assertEqual(inspect.getfile(A), __file__)
830        self.assertIs(inspect.getmodule(A), sys.modules[__name__])
831        self.assertRaises(OSError, inspect.getsource, A)
832        self.assertRaises(OSError, inspect.getsourcelines, A)
833        self.assertIsNone(inspect.getcomments(A))
834
835    def test_getsource_on_class_without_firstlineno(self):
836        __firstlineno__ = 1
837        class C:
838            nonlocal __firstlineno__
839        self.assertRaises(OSError, inspect.getsource, C)
840
841class TestGetsourceStdlib(unittest.TestCase):
842    # Test Python implementations of the stdlib modules
843
844    def test_getsource_stdlib_collections_abc(self):
845        import collections.abc
846        lines, lineno = inspect.getsourcelines(collections.abc.Sequence)
847        self.assertEqual(lines[0], 'class Sequence(Reversible, Collection):\n')
848        src = inspect.getsource(collections.abc.Sequence)
849        self.assertEqual(src.splitlines(True), lines)
850
851    def test_getsource_stdlib_tomllib(self):
852        import tomllib
853        self.assertRaises(OSError, inspect.getsource, tomllib.TOMLDecodeError)
854        self.assertRaises(OSError, inspect.getsourcelines, tomllib.TOMLDecodeError)
855
856    def test_getsource_stdlib_abc(self):
857        # Pure Python implementation
858        abc = import_helper.import_fresh_module('abc', blocked=['_abc'])
859        with support.swap_item(sys.modules, 'abc', abc):
860            self.assertRaises(OSError, inspect.getsource, abc.ABCMeta)
861            self.assertRaises(OSError, inspect.getsourcelines, abc.ABCMeta)
862        # With C acceleration
863        import abc
864        try:
865            src = inspect.getsource(abc.ABCMeta)
866            lines, lineno = inspect.getsourcelines(abc.ABCMeta)
867        except OSError:
868            pass
869        else:
870            self.assertEqual(lines[0], '    class ABCMeta(type):\n')
871            self.assertEqual(src.splitlines(True), lines)
872
873    def test_getsource_stdlib_decimal(self):
874        # Pure Python implementation
875        decimal = import_helper.import_fresh_module('decimal', blocked=['_decimal'])
876        with support.swap_item(sys.modules, 'decimal', decimal):
877            src = inspect.getsource(decimal.Decimal)
878            lines, lineno = inspect.getsourcelines(decimal.Decimal)
879        self.assertEqual(lines[0], 'class Decimal(object):\n')
880        self.assertEqual(src.splitlines(True), lines)
881
882class TestGetsourceInteractive(unittest.TestCase):
883    def test_getclasses_interactive(self):
884        # bpo-44648: simulate a REPL session;
885        # there is no `__file__` in the __main__ module
886        code = "import sys, inspect; \
887                assert not hasattr(sys.modules['__main__'], '__file__'); \
888                A = type('A', (), {}); \
889                inspect.getsource(A)"
890        _, _, stderr = assert_python_failure("-c", code, __isolated=True)
891        self.assertIn(b'OSError: source code not available', stderr)
892
893class TestGettingSourceOfToplevelFrames(GetSourceBase):
894    fodderModule = mod
895
896    def test_range_toplevel_frame(self):
897        self.maxDiff = None
898        self.assertSourceEqual(mod.currentframe, 1, None)
899
900    def test_range_traceback_toplevel_frame(self):
901        self.assertSourceEqual(mod.tb, 1, None)
902
903class TestDecorators(GetSourceBase):
904    fodderModule = mod2
905
906    def test_wrapped_decorator(self):
907        self.assertSourceEqual(mod2.wrapped, 14, 17)
908
909    def test_replacing_decorator(self):
910        self.assertSourceEqual(mod2.gone, 9, 10)
911
912    def test_getsource_unwrap(self):
913        self.assertSourceEqual(mod2.real, 130, 132)
914
915    def test_decorator_with_lambda(self):
916        self.assertSourceEqual(mod2.func114, 113, 115)
917
918class TestOneliners(GetSourceBase):
919    fodderModule = mod2
920    def test_oneline_lambda(self):
921        # Test inspect.getsource with a one-line lambda function.
922        self.assertSourceEqual(mod2.oll, 25, 25)
923
924    def test_threeline_lambda(self):
925        # Test inspect.getsource with a three-line lambda function,
926        # where the second and third lines are _not_ indented.
927        self.assertSourceEqual(mod2.tll, 28, 30)
928
929    def test_twoline_indented_lambda(self):
930        # Test inspect.getsource with a two-line lambda function,
931        # where the second line _is_ indented.
932        self.assertSourceEqual(mod2.tlli, 33, 34)
933
934    def test_parenthesized_multiline_lambda(self):
935        # Test inspect.getsource with a parenthesized multi-line lambda
936        # function.
937        self.assertSourceEqual(mod2.parenthesized_lambda, 279, 279)
938        self.assertSourceEqual(mod2.parenthesized_lambda2, 281, 281)
939        self.assertSourceEqual(mod2.parenthesized_lambda3, 283, 283)
940
941    def test_post_line_parenthesized_lambda(self):
942        # Test inspect.getsource with a parenthesized multi-line lambda
943        # function.
944        self.assertSourceEqual(mod2.post_line_parenthesized_lambda1, 286, 287)
945
946    def test_nested_lambda(self):
947        # Test inspect.getsource with a nested lambda function.
948        self.assertSourceEqual(mod2.nested_lambda, 291, 292)
949
950    def test_onelinefunc(self):
951        # Test inspect.getsource with a regular one-line function.
952        self.assertSourceEqual(mod2.onelinefunc, 37, 37)
953
954    def test_manyargs(self):
955        # Test inspect.getsource with a regular function where
956        # the arguments are on two lines and _not_ indented and
957        # the body on the second line with the last arguments.
958        self.assertSourceEqual(mod2.manyargs, 40, 41)
959
960    def test_twolinefunc(self):
961        # Test inspect.getsource with a regular function where
962        # the body is on two lines, following the argument list and
963        # continued on the next line by a \\.
964        self.assertSourceEqual(mod2.twolinefunc, 44, 45)
965
966    def test_lambda_in_list(self):
967        # Test inspect.getsource with a one-line lambda function
968        # defined in a list, indented.
969        self.assertSourceEqual(mod2.a[1], 49, 49)
970
971    def test_anonymous(self):
972        # Test inspect.getsource with a lambda function defined
973        # as argument to another function.
974        self.assertSourceEqual(mod2.anonymous, 55, 55)
975
976    def test_enum(self):
977        self.assertSourceEqual(mod2.enum322, 322, 323)
978        self.assertSourceEqual(mod2.enum326, 326, 327)
979        self.assertSourceEqual(mod2.flag330, 330, 331)
980        self.assertSourceEqual(mod2.flag334, 334, 335)
981        self.assertRaises(OSError, inspect.getsource, mod2.simple_enum338)
982        self.assertRaises(OSError, inspect.getsource, mod2.simple_enum339)
983        self.assertRaises(OSError, inspect.getsource, mod2.simple_flag340)
984        self.assertRaises(OSError, inspect.getsource, mod2.simple_flag341)
985
986    def test_namedtuple(self):
987        self.assertSourceEqual(mod2.nt346, 346, 348)
988        self.assertRaises(OSError, inspect.getsource, mod2.nt351)
989
990    def test_typeddict(self):
991        self.assertSourceEqual(mod2.td354, 354, 356)
992        self.assertRaises(OSError, inspect.getsource, mod2.td359)
993
994    def test_dataclass(self):
995        self.assertSourceEqual(mod2.dc364, 364, 367)
996        self.assertRaises(OSError, inspect.getsource, mod2.dc370)
997        self.assertRaises(OSError, inspect.getsource, mod2.dc371)
998
999class TestBlockComments(GetSourceBase):
1000    fodderModule = mod
1001
1002    def test_toplevel_class(self):
1003        self.assertSourceEqual(mod.WhichComments, 96, 114)
1004
1005    def test_class_method(self):
1006        self.assertSourceEqual(mod.WhichComments.f, 99, 104)
1007
1008    def test_class_async_method(self):
1009        self.assertSourceEqual(mod.WhichComments.asyncf, 109, 112)
1010
1011class TestBuggyCases(GetSourceBase):
1012    fodderModule = mod2
1013
1014    def test_with_comment(self):
1015        self.assertSourceEqual(mod2.with_comment, 58, 59)
1016
1017    def test_multiline_sig(self):
1018        self.assertSourceEqual(mod2.multiline_sig[0], 63, 64)
1019
1020    def test_nested_class(self):
1021        self.assertSourceEqual(mod2.func69().func71, 71, 72)
1022
1023    def test_one_liner_followed_by_non_name(self):
1024        self.assertSourceEqual(mod2.func77, 77, 77)
1025
1026    def test_one_liner_dedent_non_name(self):
1027        self.assertSourceEqual(mod2.cls82.func83, 83, 83)
1028
1029    def test_with_comment_instead_of_docstring(self):
1030        self.assertSourceEqual(mod2.func88, 88, 90)
1031
1032    def test_method_in_dynamic_class(self):
1033        self.assertSourceEqual(mod2.method_in_dynamic_class, 95, 97)
1034
1035    # This should not skip for CPython, but might on a repackaged python where
1036    # unicodedata is not an external module, or on pypy.
1037    @unittest.skipIf(not hasattr(unicodedata, '__file__') or
1038                                 unicodedata.__file__.endswith('.py'),
1039                     "unicodedata is not an external binary module")
1040    def test_findsource_binary(self):
1041        self.assertRaises(OSError, inspect.getsource, unicodedata)
1042        self.assertRaises(OSError, inspect.findsource, unicodedata)
1043
1044    def test_findsource_code_in_linecache(self):
1045        lines = ["x=1"]
1046        co = compile(lines[0], "_dynamically_created_file", "exec")
1047        self.assertRaises(OSError, inspect.findsource, co)
1048        self.assertRaises(OSError, inspect.getsource, co)
1049        linecache.cache[co.co_filename] = (1, None, lines, co.co_filename)
1050        try:
1051            self.assertEqual(inspect.findsource(co), (lines,0))
1052            self.assertEqual(inspect.getsource(co), lines[0])
1053        finally:
1054            del linecache.cache[co.co_filename]
1055
1056    def test_findsource_without_filename(self):
1057        for fname in ['', '<string>']:
1058            co = compile('x=1', fname, "exec")
1059            self.assertRaises(IOError, inspect.findsource, co)
1060            self.assertRaises(IOError, inspect.getsource, co)
1061
1062    def test_findsource_on_func_with_out_of_bounds_lineno(self):
1063        mod_len = len(inspect.getsource(mod))
1064        src = '\n' * 2* mod_len + "def f(): pass"
1065        co = compile(src, mod.__file__, "exec")
1066        g, l = {}, {}
1067        eval(co, g, l)
1068        func = l['f']
1069        self.assertEqual(func.__code__.co_firstlineno, 1+2*mod_len)
1070        with self.assertRaisesRegex(OSError, "lineno is out of bounds"):
1071            inspect.findsource(func)
1072
1073    def test_findsource_on_class_with_out_of_bounds_lineno(self):
1074        mod_len = len(inspect.getsource(mod))
1075        src = '\n' * 2* mod_len + "class A: pass"
1076        co = compile(src, mod.__file__, "exec")
1077        g, l = {'__name__': mod.__name__}, {}
1078        eval(co, g, l)
1079        cls = l['A']
1080        self.assertEqual(cls.__firstlineno__, 1+2*mod_len)
1081        with self.assertRaisesRegex(OSError, "lineno is out of bounds"):
1082            inspect.findsource(cls)
1083
1084    def test_getsource_on_method(self):
1085        self.assertSourceEqual(mod2.ClassWithMethod.method, 118, 119)
1086
1087    def test_getsource_on_class_code_object(self):
1088        self.assertSourceEqual(mod2.ClassWithCodeObject.code, 315, 317)
1089
1090    def test_nested_func(self):
1091        self.assertSourceEqual(mod2.cls135.func136, 136, 139)
1092
1093    def test_class_definition_in_multiline_string_definition(self):
1094        self.assertSourceEqual(mod2.cls149, 149, 152)
1095
1096    def test_class_definition_in_multiline_comment(self):
1097        self.assertSourceEqual(mod2.cls160, 160, 163)
1098
1099    def test_nested_class_definition_indented_string(self):
1100        self.assertSourceEqual(mod2.cls173.cls175, 175, 176)
1101
1102    def test_nested_class_definition(self):
1103        self.assertSourceEqual(mod2.cls183, 183, 188)
1104        self.assertSourceEqual(mod2.cls183.cls185, 185, 188)
1105
1106    def test_class_decorator(self):
1107        self.assertSourceEqual(mod2.cls196, 194, 201)
1108        self.assertSourceEqual(mod2.cls196.cls200, 198, 201)
1109
1110    @support.requires_docstrings
1111    def test_class_inside_conditional(self):
1112        # We skip this test when docstrings are not present,
1113        # because docstrings are one of the main factors of
1114        # finding the correct class in the source code.
1115        self.assertSourceEqual(mod2.cls238.cls239, 239, 240)
1116
1117    def test_multiple_children_classes(self):
1118        self.assertSourceEqual(mod2.cls203, 203, 209)
1119        self.assertSourceEqual(mod2.cls203.cls204, 204, 206)
1120        self.assertSourceEqual(mod2.cls203.cls204.cls205, 205, 206)
1121        self.assertSourceEqual(mod2.cls203.cls207, 207, 209)
1122        self.assertSourceEqual(mod2.cls203.cls207.cls205, 208, 209)
1123
1124    def test_nested_class_definition_inside_function(self):
1125        self.assertSourceEqual(mod2.func212(), 213, 214)
1126        self.assertSourceEqual(mod2.cls213, 218, 222)
1127        self.assertSourceEqual(mod2.cls213().func219(), 220, 221)
1128
1129    def test_class_with_method_from_other_module(self):
1130        with tempfile.TemporaryDirectory() as tempdir:
1131            with open(os.path.join(tempdir, 'inspect_actual%spy' % os.extsep),
1132                      'w', encoding='utf-8') as f:
1133                f.write(textwrap.dedent("""
1134                    import inspect_other
1135                    class A:
1136                        def f(self):
1137                            pass
1138                    class A:
1139                        def f(self):
1140                            pass  # correct one
1141                    A.f = inspect_other.A.f
1142                    """))
1143
1144            with open(os.path.join(tempdir, 'inspect_other%spy' % os.extsep),
1145                      'w', encoding='utf-8') as f:
1146                f.write(textwrap.dedent("""
1147                    class A:
1148                        def f(self):
1149                            pass
1150                    """))
1151
1152            with DirsOnSysPath(tempdir):
1153                import inspect_actual
1154                self.assertIn("correct", inspect.getsource(inspect_actual.A))
1155                # Remove the module from sys.modules to force it to be reloaded.
1156                # This is necessary when the test is run multiple times.
1157                sys.modules.pop("inspect_actual")
1158
1159    @unittest.skipIf(
1160        support.is_emscripten or support.is_wasi,
1161        "socket.accept is broken"
1162    )
1163    def test_nested_class_definition_inside_async_function(self):
1164        import asyncio
1165        self.addCleanup(asyncio.set_event_loop_policy, None)
1166        self.assertSourceEqual(asyncio.run(mod2.func225()), 226, 227)
1167        self.assertSourceEqual(mod2.cls226, 231, 235)
1168        self.assertSourceEqual(asyncio.run(mod2.cls226().func232()), 233, 234)
1169
1170    def test_class_definition_same_name_diff_methods(self):
1171        self.assertSourceEqual(mod2.cls296, 296, 298)
1172        self.assertSourceEqual(mod2.cls310, 310, 312)
1173
1174class TestNoEOL(GetSourceBase):
1175    def setUp(self):
1176        self.tempdir = TESTFN + '_dir'
1177        os.mkdir(self.tempdir)
1178        with open(os.path.join(self.tempdir, 'inspect_fodder3%spy' % os.extsep),
1179                  'w', encoding='utf-8') as f:
1180            f.write("class X:\n    pass # No EOL")
1181        with DirsOnSysPath(self.tempdir):
1182            import inspect_fodder3 as mod3
1183        self.fodderModule = mod3
1184        super().setUp()
1185
1186    def tearDown(self):
1187        shutil.rmtree(self.tempdir)
1188
1189    def test_class(self):
1190        self.assertSourceEqual(self.fodderModule.X, 1, 2)
1191
1192
1193class TestComplexDecorator(GetSourceBase):
1194    fodderModule = mod2
1195
1196    def test_parens_in_decorator(self):
1197        self.assertSourceEqual(self.fodderModule.complex_decorated, 273, 275)
1198
1199class _BrokenDataDescriptor(object):
1200    """
1201    A broken data descriptor. See bug #1785.
1202    """
1203    def __get__(*args):
1204        raise AttributeError("broken data descriptor")
1205
1206    def __set__(*args):
1207        raise RuntimeError
1208
1209    def __getattr__(*args):
1210        raise AttributeError("broken data descriptor")
1211
1212
1213class _BrokenMethodDescriptor(object):
1214    """
1215    A broken method descriptor. See bug #1785.
1216    """
1217    def __get__(*args):
1218        raise AttributeError("broken method descriptor")
1219
1220    def __getattr__(*args):
1221        raise AttributeError("broken method descriptor")
1222
1223
1224# Helper for testing classify_class_attrs.
1225def attrs_wo_objs(cls):
1226    return [t[:3] for t in inspect.classify_class_attrs(cls)]
1227
1228
1229class TestClassesAndFunctions(unittest.TestCase):
1230    def test_newstyle_mro(self):
1231        # The same w/ new-class MRO.
1232        class A(object):    pass
1233        class B(A): pass
1234        class C(A): pass
1235        class D(B, C): pass
1236
1237        expected = (D, B, C, A, object)
1238        got = inspect.getmro(D)
1239        self.assertEqual(expected, got)
1240
1241    def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
1242                                    varkw_e=None, defaults_e=None,
1243                                    posonlyargs_e=[], kwonlyargs_e=[],
1244                                    kwonlydefaults_e=None,
1245                                    ann_e={}):
1246        args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = \
1247            inspect.getfullargspec(routine)
1248        self.assertEqual(args, args_e)
1249        self.assertEqual(varargs, varargs_e)
1250        self.assertEqual(varkw, varkw_e)
1251        self.assertEqual(defaults, defaults_e)
1252        self.assertEqual(kwonlyargs, kwonlyargs_e)
1253        self.assertEqual(kwonlydefaults, kwonlydefaults_e)
1254        self.assertEqual(ann, ann_e)
1255
1256    def test_getfullargspec(self):
1257        self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
1258                                     kwonlyargs_e=['arg2'],
1259                                     kwonlydefaults_e={'arg2':1})
1260
1261        self.assertFullArgSpecEquals(mod2.annotated, ['arg1'],
1262                                     ann_e={'arg1' : list})
1263        self.assertFullArgSpecEquals(mod2.keyword_only_arg, [],
1264                                     kwonlyargs_e=['arg'])
1265
1266        self.assertFullArgSpecEquals(mod2.all_markers, ['a', 'b', 'c', 'd'],
1267                                     kwonlyargs_e=['e', 'f'])
1268
1269        self.assertFullArgSpecEquals(mod2.all_markers_with_args_and_kwargs,
1270                                     ['a', 'b', 'c', 'd'],
1271                                     varargs_e='args',
1272                                     varkw_e='kwargs',
1273                                     kwonlyargs_e=['e', 'f'])
1274
1275        self.assertFullArgSpecEquals(mod2.all_markers_with_defaults, ['a', 'b', 'c', 'd'],
1276                                     defaults_e=(1,2,3),
1277                                     kwonlyargs_e=['e', 'f'],
1278                                     kwonlydefaults_e={'e': 4, 'f': 5})
1279
1280    def test_argspec_api_ignores_wrapped(self):
1281        # Issue 20684: low level introspection API must ignore __wrapped__
1282        @functools.wraps(mod.spam)
1283        def ham(x, y):
1284            pass
1285        # Basic check
1286        self.assertFullArgSpecEquals(ham, ['x', 'y'])
1287        self.assertFullArgSpecEquals(functools.partial(ham),
1288                                     ['x', 'y'])
1289
1290    def test_getfullargspec_signature_attr(self):
1291        def test():
1292            pass
1293        spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY)
1294        test.__signature__ = inspect.Signature(parameters=(spam_param,))
1295
1296        self.assertFullArgSpecEquals(test, ['spam'])
1297
1298    def test_getfullargspec_signature_annos(self):
1299        def test(a:'spam') -> 'ham': pass
1300        spec = inspect.getfullargspec(test)
1301        self.assertEqual(test.__annotations__, spec.annotations)
1302
1303        def test(): pass
1304        spec = inspect.getfullargspec(test)
1305        self.assertEqual(test.__annotations__, spec.annotations)
1306
1307    @unittest.skipIf(MISSING_C_DOCSTRINGS,
1308                     "Signature information for builtins requires docstrings")
1309    def test_getfullargspec_builtin_methods(self):
1310        self.assertFullArgSpecEquals(_pickle.Pickler.dump, ['self', 'obj'])
1311
1312        self.assertFullArgSpecEquals(_pickle.Pickler(io.BytesIO()).dump, ['self', 'obj'])
1313
1314        self.assertFullArgSpecEquals(
1315             os.stat,
1316             args_e=['path'],
1317             kwonlyargs_e=['dir_fd', 'follow_symlinks'],
1318             kwonlydefaults_e={'dir_fd': None, 'follow_symlinks': True})
1319
1320    @cpython_only
1321    @unittest.skipIf(MISSING_C_DOCSTRINGS,
1322                     "Signature information for builtins requires docstrings")
1323    def test_getfullargspec_builtin_func(self):
1324        _testcapi = import_helper.import_module("_testcapi")
1325        builtin = _testcapi.docstring_with_signature_with_defaults
1326        spec = inspect.getfullargspec(builtin)
1327        self.assertEqual(spec.defaults[0], 'avocado')
1328
1329    @cpython_only
1330    @unittest.skipIf(MISSING_C_DOCSTRINGS,
1331                     "Signature information for builtins requires docstrings")
1332    def test_getfullargspec_builtin_func_no_signature(self):
1333        _testcapi = import_helper.import_module("_testcapi")
1334        builtin = _testcapi.docstring_no_signature
1335        with self.assertRaises(TypeError):
1336            inspect.getfullargspec(builtin)
1337
1338        cls = _testcapi.DocStringNoSignatureTest
1339        obj = _testcapi.DocStringNoSignatureTest()
1340        tests = [
1341            (_testcapi.docstring_no_signature_noargs, meth_noargs),
1342            (_testcapi.docstring_no_signature_o, meth_o),
1343            (cls.meth_noargs, meth_self_noargs),
1344            (cls.meth_o, meth_self_o),
1345            (obj.meth_noargs, meth_self_noargs),
1346            (obj.meth_o, meth_self_o),
1347            (cls.meth_noargs_class, meth_type_noargs),
1348            (cls.meth_o_class, meth_type_o),
1349            (cls.meth_noargs_static, meth_noargs),
1350            (cls.meth_o_static, meth_o),
1351            (cls.meth_noargs_coexist, meth_self_noargs),
1352            (cls.meth_o_coexist, meth_self_o),
1353
1354            (time.time, meth_noargs),
1355            (str.lower, meth_self_noargs),
1356            (''.lower, meth_self_noargs),
1357            (set.add, meth_self_o),
1358            (set().add, meth_self_o),
1359            (set.__contains__, meth_self_o),
1360            (set().__contains__, meth_self_o),
1361            (datetime.datetime.__dict__['utcnow'], meth_type_noargs),
1362            (datetime.datetime.utcnow, meth_type_noargs),
1363            (dict.__dict__['__class_getitem__'], meth_type_o),
1364            (dict.__class_getitem__, meth_type_o),
1365        ]
1366        try:
1367            import _stat
1368        except ImportError:
1369            # if the _stat extension is not available, stat.S_IMODE() is
1370            # implemented in Python, not in C
1371            pass
1372        else:
1373            tests.append((stat.S_IMODE, meth_o))
1374        for builtin, template in tests:
1375            with self.subTest(builtin):
1376                self.assertEqual(inspect.getfullargspec(builtin),
1377                                 inspect.getfullargspec(template))
1378
1379    def test_getfullargspec_definition_order_preserved_on_kwonly(self):
1380        for fn in signatures_with_lexicographic_keyword_only_parameters():
1381            signature = inspect.getfullargspec(fn)
1382            l = list(signature.kwonlyargs)
1383            sorted_l = sorted(l)
1384            self.assertTrue(l)
1385            self.assertEqual(l, sorted_l)
1386        signature = inspect.getfullargspec(unsorted_keyword_only_parameters_fn)
1387        l = list(signature.kwonlyargs)
1388        self.assertEqual(l, unsorted_keyword_only_parameters)
1389
1390    def test_classify_newstyle(self):
1391        class A(object):
1392
1393            def s(): pass
1394            s = staticmethod(s)
1395
1396            def c(cls): pass
1397            c = classmethod(c)
1398
1399            def getp(self): pass
1400            p = property(getp)
1401
1402            def m(self): pass
1403
1404            def m1(self): pass
1405
1406            datablob = '1'
1407
1408            dd = _BrokenDataDescriptor()
1409            md = _BrokenMethodDescriptor()
1410
1411        attrs = attrs_wo_objs(A)
1412
1413        self.assertIn(('__new__', 'static method', object), attrs,
1414                      'missing __new__')
1415        self.assertIn(('__init__', 'method', object), attrs, 'missing __init__')
1416
1417        self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1418        self.assertIn(('c', 'class method', A), attrs, 'missing class method')
1419        self.assertIn(('p', 'property', A), attrs, 'missing property')
1420        self.assertIn(('m', 'method', A), attrs,
1421                      'missing plain method: %r' % attrs)
1422        self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
1423        self.assertIn(('datablob', 'data', A), attrs, 'missing data')
1424        self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1425        self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
1426
1427        class B(A):
1428
1429            def m(self): pass
1430
1431        attrs = attrs_wo_objs(B)
1432        self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1433        self.assertIn(('c', 'class method', A), attrs, 'missing class method')
1434        self.assertIn(('p', 'property', A), attrs, 'missing property')
1435        self.assertIn(('m', 'method', B), attrs, 'missing plain method')
1436        self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
1437        self.assertIn(('datablob', 'data', A), attrs, 'missing data')
1438        self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1439        self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
1440
1441
1442        class C(A):
1443
1444            def m(self): pass
1445            def c(self): pass
1446
1447        attrs = attrs_wo_objs(C)
1448        self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1449        self.assertIn(('c', 'method', C), attrs, 'missing plain method')
1450        self.assertIn(('p', 'property', A), attrs, 'missing property')
1451        self.assertIn(('m', 'method', C), attrs, 'missing plain method')
1452        self.assertIn(('m1', 'method', A), attrs, 'missing plain method')
1453        self.assertIn(('datablob', 'data', A), attrs, 'missing data')
1454        self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1455        self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
1456
1457        class D(B, C):
1458
1459            def m1(self): pass
1460
1461        attrs = attrs_wo_objs(D)
1462        self.assertIn(('s', 'static method', A), attrs, 'missing static method')
1463        self.assertIn(('c', 'method', C), attrs, 'missing plain method')
1464        self.assertIn(('p', 'property', A), attrs, 'missing property')
1465        self.assertIn(('m', 'method', B), attrs, 'missing plain method')
1466        self.assertIn(('m1', 'method', D), attrs, 'missing plain method')
1467        self.assertIn(('datablob', 'data', A), attrs, 'missing data')
1468        self.assertIn(('md', 'method', A), attrs, 'missing method descriptor')
1469        self.assertIn(('dd', 'data', A), attrs, 'missing data descriptor')
1470
1471    def test_classify_builtin_types(self):
1472        # Simple sanity check that all built-in types can have their
1473        # attributes classified.
1474        for name in dir(__builtins__):
1475            builtin = getattr(__builtins__, name)
1476            if isinstance(builtin, type):
1477                inspect.classify_class_attrs(builtin)
1478
1479        attrs = attrs_wo_objs(bool)
1480        self.assertIn(('__new__', 'static method', bool), attrs,
1481                      'missing __new__')
1482        self.assertIn(('from_bytes', 'class method', int), attrs,
1483                      'missing class method')
1484        self.assertIn(('to_bytes', 'method', int), attrs,
1485                      'missing plain method')
1486        self.assertIn(('__add__', 'method', int), attrs,
1487                      'missing plain method')
1488        self.assertIn(('__and__', 'method', bool), attrs,
1489                      'missing plain method')
1490
1491    def test_classify_DynamicClassAttribute(self):
1492        class Meta(type):
1493            def __getattr__(self, name):
1494                if name == 'ham':
1495                    return 'spam'
1496                return super().__getattr__(name)
1497        class VA(metaclass=Meta):
1498            @types.DynamicClassAttribute
1499            def ham(self):
1500                return 'eggs'
1501        should_find_dca = inspect.Attribute('ham', 'data', VA, VA.__dict__['ham'])
1502        self.assertIn(should_find_dca, inspect.classify_class_attrs(VA))
1503        should_find_ga = inspect.Attribute('ham', 'data', Meta, 'spam')
1504        self.assertIn(should_find_ga, inspect.classify_class_attrs(VA))
1505
1506    def test_classify_overrides_bool(self):
1507        class NoBool(object):
1508            def __eq__(self, other):
1509                return NoBool()
1510
1511            def __bool__(self):
1512                raise NotImplementedError(
1513                    "This object does not specify a boolean value")
1514
1515        class HasNB(object):
1516            dd = NoBool()
1517
1518        should_find_attr = inspect.Attribute('dd', 'data', HasNB, HasNB.dd)
1519        self.assertIn(should_find_attr, inspect.classify_class_attrs(HasNB))
1520
1521    def test_classify_metaclass_class_attribute(self):
1522        class Meta(type):
1523            fish = 'slap'
1524            def __dir__(self):
1525                return ['__class__', '__module__', '__name__', 'fish']
1526        class Class(metaclass=Meta):
1527            pass
1528        should_find = inspect.Attribute('fish', 'data', Meta, 'slap')
1529        self.assertIn(should_find, inspect.classify_class_attrs(Class))
1530
1531    def test_classify_VirtualAttribute(self):
1532        class Meta(type):
1533            def __dir__(cls):
1534                return ['__class__', '__module__', '__name__', 'BOOM']
1535            def __getattr__(self, name):
1536                if name =='BOOM':
1537                    return 42
1538                return super().__getattr(name)
1539        class Class(metaclass=Meta):
1540            pass
1541        should_find = inspect.Attribute('BOOM', 'data', Meta, 42)
1542        self.assertIn(should_find, inspect.classify_class_attrs(Class))
1543
1544    def test_classify_VirtualAttribute_multi_classes(self):
1545        class Meta1(type):
1546            def __dir__(cls):
1547                return ['__class__', '__module__', '__name__', 'one']
1548            def __getattr__(self, name):
1549                if name =='one':
1550                    return 1
1551                return super().__getattr__(name)
1552        class Meta2(type):
1553            def __dir__(cls):
1554                return ['__class__', '__module__', '__name__', 'two']
1555            def __getattr__(self, name):
1556                if name =='two':
1557                    return 2
1558                return super().__getattr__(name)
1559        class Meta3(Meta1, Meta2):
1560            def __dir__(cls):
1561                return list(sorted(set(['__class__', '__module__', '__name__', 'three'] +
1562                    Meta1.__dir__(cls) + Meta2.__dir__(cls))))
1563            def __getattr__(self, name):
1564                if name =='three':
1565                    return 3
1566                return super().__getattr__(name)
1567        class Class1(metaclass=Meta1):
1568            pass
1569        class Class2(Class1, metaclass=Meta3):
1570            pass
1571
1572        should_find1 = inspect.Attribute('one', 'data', Meta1, 1)
1573        should_find2 = inspect.Attribute('two', 'data', Meta2, 2)
1574        should_find3 = inspect.Attribute('three', 'data', Meta3, 3)
1575        cca = inspect.classify_class_attrs(Class2)
1576        for sf in (should_find1, should_find2, should_find3):
1577            self.assertIn(sf, cca)
1578
1579    def test_classify_class_attrs_with_buggy_dir(self):
1580        class M(type):
1581            def __dir__(cls):
1582                return ['__class__', '__name__', 'missing']
1583        class C(metaclass=M):
1584            pass
1585        attrs = [a[0] for a in inspect.classify_class_attrs(C)]
1586        self.assertNotIn('missing', attrs)
1587
1588    def test_getmembers_descriptors(self):
1589        class A(object):
1590            dd = _BrokenDataDescriptor()
1591            md = _BrokenMethodDescriptor()
1592
1593        def pred_wrapper(pred):
1594            # A quick'n'dirty way to discard standard attributes of new-style
1595            # classes.
1596            class Empty(object):
1597                pass
1598            def wrapped(x):
1599                if '__name__' in dir(x) and hasattr(Empty, x.__name__):
1600                    return False
1601                return pred(x)
1602            return wrapped
1603
1604        ismethoddescriptor = pred_wrapper(inspect.ismethoddescriptor)
1605        isdatadescriptor = pred_wrapper(inspect.isdatadescriptor)
1606
1607        self.assertEqual(inspect.getmembers(A, ismethoddescriptor),
1608            [('md', A.__dict__['md'])])
1609        self.assertEqual(inspect.getmembers(A, isdatadescriptor),
1610            [('dd', A.__dict__['dd'])])
1611
1612        class B(A):
1613            pass
1614
1615        self.assertEqual(inspect.getmembers(B, ismethoddescriptor),
1616            [('md', A.__dict__['md'])])
1617        self.assertEqual(inspect.getmembers(B, isdatadescriptor),
1618            [('dd', A.__dict__['dd'])])
1619
1620    def test_getmembers_method(self):
1621        class B:
1622            def f(self):
1623                pass
1624
1625        self.assertIn(('f', B.f), inspect.getmembers(B))
1626        self.assertNotIn(('f', B.f), inspect.getmembers(B, inspect.ismethod))
1627        b = B()
1628        self.assertIn(('f', b.f), inspect.getmembers(b))
1629        self.assertIn(('f', b.f), inspect.getmembers(b, inspect.ismethod))
1630
1631    def test_getmembers_custom_dir(self):
1632        class CorrectDir:
1633            def __init__(self, attr):
1634                self.attr = attr
1635            def method(self):
1636                return self.attr + 1
1637            def __dir__(self):
1638                return ['attr', 'method']
1639
1640        cd = CorrectDir(5)
1641        self.assertEqual(inspect.getmembers(cd), [
1642            ('attr', 5),
1643            ('method', cd.method),
1644        ])
1645        self.assertEqual(inspect.getmembers(cd, inspect.ismethod), [
1646            ('method', cd.method),
1647        ])
1648
1649    def test_getmembers_custom_broken_dir(self):
1650        # inspect.getmembers calls `dir()` on the passed object inside.
1651        # if `__dir__` mentions some non-existent attribute,
1652        # we still need to return others correctly.
1653        class BrokenDir:
1654            existing = 1
1655            def method(self):
1656                return self.existing + 1
1657            def __dir__(self):
1658                return ['method', 'missing', 'existing']
1659
1660        bd = BrokenDir()
1661        self.assertEqual(inspect.getmembers(bd), [
1662            ('existing', 1),
1663            ('method', bd.method),
1664        ])
1665        self.assertEqual(inspect.getmembers(bd, inspect.ismethod), [
1666            ('method', bd.method),
1667        ])
1668
1669    def test_getmembers_custom_duplicated_dir(self):
1670        # Duplicates in `__dir__` must not fail and return just one result.
1671        class DuplicatedDir:
1672            attr = 1
1673            def __dir__(self):
1674                return ['attr', 'attr']
1675
1676        dd = DuplicatedDir()
1677        self.assertEqual(inspect.getmembers(dd), [
1678            ('attr', 1),
1679        ])
1680
1681    def test_getmembers_VirtualAttribute(self):
1682        class M(type):
1683            def __getattr__(cls, name):
1684                if name == 'eggs':
1685                    return 'scrambled'
1686                return super().__getattr__(name)
1687        class A(metaclass=M):
1688            @types.DynamicClassAttribute
1689            def eggs(self):
1690                return 'spam'
1691        class B:
1692            def __getattr__(self, attribute):
1693                return None
1694        self.assertIn(('eggs', 'scrambled'), inspect.getmembers(A))
1695        self.assertIn(('eggs', 'spam'), inspect.getmembers(A()))
1696        b = B()
1697        self.assertIn(('__getattr__', b.__getattr__), inspect.getmembers(b))
1698
1699    def test_getmembers_static(self):
1700        class A:
1701            @property
1702            def name(self):
1703                raise NotImplementedError
1704            @types.DynamicClassAttribute
1705            def eggs(self):
1706                raise NotImplementedError
1707
1708        a = A()
1709        instance_members = inspect.getmembers_static(a)
1710        class_members = inspect.getmembers_static(A)
1711        self.assertIn(('name', inspect.getattr_static(a, 'name')), instance_members)
1712        self.assertIn(('eggs', inspect.getattr_static(a, 'eggs')), instance_members)
1713        self.assertIn(('name', inspect.getattr_static(A, 'name')), class_members)
1714        self.assertIn(('eggs', inspect.getattr_static(A, 'eggs')), class_members)
1715
1716    def test_getmembers_with_buggy_dir(self):
1717        class M(type):
1718            def __dir__(cls):
1719                return ['__class__', '__name__', 'missing']
1720        class C(metaclass=M):
1721            pass
1722        attrs = [a[0] for a in inspect.getmembers(C)]
1723        self.assertNotIn('missing', attrs)
1724
1725    def test_get_annotations_with_stock_annotations(self):
1726        def foo(a:int, b:str): pass
1727        self.assertEqual(inspect.get_annotations(foo), {'a': int, 'b': str})
1728
1729        foo.__annotations__ = {'a': 'foo', 'b':'str'}
1730        self.assertEqual(inspect.get_annotations(foo), {'a': 'foo', 'b': 'str'})
1731
1732        self.assertEqual(inspect.get_annotations(foo, eval_str=True, locals=locals()), {'a': foo, 'b': str})
1733        self.assertEqual(inspect.get_annotations(foo, eval_str=True, globals=locals()), {'a': foo, 'b': str})
1734
1735        isa = inspect_stock_annotations
1736        self.assertEqual(inspect.get_annotations(isa), {'a': int, 'b': str})
1737        self.assertEqual(inspect.get_annotations(isa.MyClass), {'a': int, 'b': str})
1738        self.assertEqual(inspect.get_annotations(isa.function), {'a': int, 'b': str, 'return': isa.MyClass})
1739        self.assertEqual(inspect.get_annotations(isa.function2), {'a': int, 'b': 'str', 'c': isa.MyClass, 'return': isa.MyClass})
1740        self.assertEqual(inspect.get_annotations(isa.function3), {'a': 'int', 'b': 'str', 'c': 'MyClass'})
1741        self.assertEqual(inspect.get_annotations(inspect), {}) # inspect module has no annotations
1742        self.assertEqual(inspect.get_annotations(isa.UnannotatedClass), {})
1743        self.assertEqual(inspect.get_annotations(isa.unannotated_function), {})
1744
1745        self.assertEqual(inspect.get_annotations(isa, eval_str=True), {'a': int, 'b': str})
1746        self.assertEqual(inspect.get_annotations(isa.MyClass, eval_str=True), {'a': int, 'b': str})
1747        self.assertEqual(inspect.get_annotations(isa.function, eval_str=True), {'a': int, 'b': str, 'return': isa.MyClass})
1748        self.assertEqual(inspect.get_annotations(isa.function2, eval_str=True), {'a': int, 'b': str, 'c': isa.MyClass, 'return': isa.MyClass})
1749        self.assertEqual(inspect.get_annotations(isa.function3, eval_str=True), {'a': int, 'b': str, 'c': isa.MyClass})
1750        self.assertEqual(inspect.get_annotations(inspect, eval_str=True), {})
1751        self.assertEqual(inspect.get_annotations(isa.UnannotatedClass, eval_str=True), {})
1752        self.assertEqual(inspect.get_annotations(isa.unannotated_function, eval_str=True), {})
1753
1754        self.assertEqual(inspect.get_annotations(isa, eval_str=False), {'a': int, 'b': str})
1755        self.assertEqual(inspect.get_annotations(isa.MyClass, eval_str=False), {'a': int, 'b': str})
1756        self.assertEqual(inspect.get_annotations(isa.function, eval_str=False), {'a': int, 'b': str, 'return': isa.MyClass})
1757        self.assertEqual(inspect.get_annotations(isa.function2, eval_str=False), {'a': int, 'b': 'str', 'c': isa.MyClass, 'return': isa.MyClass})
1758        self.assertEqual(inspect.get_annotations(isa.function3, eval_str=False), {'a': 'int', 'b': 'str', 'c': 'MyClass'})
1759        self.assertEqual(inspect.get_annotations(inspect, eval_str=False), {})
1760        self.assertEqual(inspect.get_annotations(isa.UnannotatedClass, eval_str=False), {})
1761        self.assertEqual(inspect.get_annotations(isa.unannotated_function, eval_str=False), {})
1762
1763        def times_three(fn):
1764            @functools.wraps(fn)
1765            def wrapper(a, b):
1766                return fn(a*3, b*3)
1767            return wrapper
1768
1769        wrapped = times_three(isa.function)
1770        self.assertEqual(wrapped(1, 'x'), isa.MyClass(3, 'xxx'))
1771        self.assertIsNot(wrapped.__globals__, isa.function.__globals__)
1772        self.assertEqual(inspect.get_annotations(wrapped), {'a': int, 'b': str, 'return': isa.MyClass})
1773        self.assertEqual(inspect.get_annotations(wrapped, eval_str=True), {'a': int, 'b': str, 'return': isa.MyClass})
1774        self.assertEqual(inspect.get_annotations(wrapped, eval_str=False), {'a': int, 'b': str, 'return': isa.MyClass})
1775
1776    def test_get_annotations_with_stringized_annotations(self):
1777        isa = inspect_stringized_annotations
1778        self.assertEqual(inspect.get_annotations(isa), {'a': 'int', 'b': 'str'})
1779        self.assertEqual(inspect.get_annotations(isa.MyClass), {'a': 'int', 'b': 'str'})
1780        self.assertEqual(inspect.get_annotations(isa.function), {'a': 'int', 'b': 'str', 'return': 'MyClass'})
1781        self.assertEqual(inspect.get_annotations(isa.function2), {'a': 'int', 'b': "'str'", 'c': 'MyClass', 'return': 'MyClass'})
1782        self.assertEqual(inspect.get_annotations(isa.function3), {'a': "'int'", 'b': "'str'", 'c': "'MyClass'"})
1783        self.assertEqual(inspect.get_annotations(isa.UnannotatedClass), {})
1784        self.assertEqual(inspect.get_annotations(isa.unannotated_function), {})
1785
1786        self.assertEqual(inspect.get_annotations(isa, eval_str=True), {'a': int, 'b': str})
1787        self.assertEqual(inspect.get_annotations(isa.MyClass, eval_str=True), {'a': int, 'b': str})
1788        self.assertEqual(inspect.get_annotations(isa.function, eval_str=True), {'a': int, 'b': str, 'return': isa.MyClass})
1789        self.assertEqual(inspect.get_annotations(isa.function2, eval_str=True), {'a': int, 'b': 'str', 'c': isa.MyClass, 'return': isa.MyClass})
1790        self.assertEqual(inspect.get_annotations(isa.function3, eval_str=True), {'a': 'int', 'b': 'str', 'c': 'MyClass'})
1791        self.assertEqual(inspect.get_annotations(isa.UnannotatedClass, eval_str=True), {})
1792        self.assertEqual(inspect.get_annotations(isa.unannotated_function, eval_str=True), {})
1793
1794        self.assertEqual(inspect.get_annotations(isa, eval_str=False), {'a': 'int', 'b': 'str'})
1795        self.assertEqual(inspect.get_annotations(isa.MyClass, eval_str=False), {'a': 'int', 'b': 'str'})
1796        self.assertEqual(inspect.get_annotations(isa.function, eval_str=False), {'a': 'int', 'b': 'str', 'return': 'MyClass'})
1797        self.assertEqual(inspect.get_annotations(isa.function2, eval_str=False), {'a': 'int', 'b': "'str'", 'c': 'MyClass', 'return': 'MyClass'})
1798        self.assertEqual(inspect.get_annotations(isa.function3, eval_str=False), {'a': "'int'", 'b': "'str'", 'c': "'MyClass'"})
1799        self.assertEqual(inspect.get_annotations(isa.UnannotatedClass, eval_str=False), {})
1800        self.assertEqual(inspect.get_annotations(isa.unannotated_function, eval_str=False), {})
1801
1802        isa2 = inspect_stringized_annotations_2
1803        self.assertEqual(inspect.get_annotations(isa2), {})
1804        self.assertEqual(inspect.get_annotations(isa2, eval_str=True), {})
1805        self.assertEqual(inspect.get_annotations(isa2, eval_str=False), {})
1806
1807        def times_three(fn):
1808            @functools.wraps(fn)
1809            def wrapper(a, b):
1810                return fn(a*3, b*3)
1811            return wrapper
1812
1813        wrapped = times_three(isa.function)
1814        self.assertEqual(wrapped(1, 'x'), isa.MyClass(3, 'xxx'))
1815        self.assertIsNot(wrapped.__globals__, isa.function.__globals__)
1816        self.assertEqual(inspect.get_annotations(wrapped), {'a': 'int', 'b': 'str', 'return': 'MyClass'})
1817        self.assertEqual(inspect.get_annotations(wrapped, eval_str=True), {'a': int, 'b': str, 'return': isa.MyClass})
1818        self.assertEqual(inspect.get_annotations(wrapped, eval_str=False), {'a': 'int', 'b': 'str', 'return': 'MyClass'})
1819
1820        # test that local namespace lookups work
1821        self.assertEqual(inspect.get_annotations(isa.MyClassWithLocalAnnotations), {'x': 'mytype'})
1822        self.assertEqual(inspect.get_annotations(isa.MyClassWithLocalAnnotations, eval_str=True), {'x': int})
1823
1824    def test_pep695_generic_class_with_future_annotations(self):
1825        ann_module695 = inspect_stringized_annotations_pep695
1826        A_annotations = inspect.get_annotations(ann_module695.A, eval_str=True)
1827        A_type_params = ann_module695.A.__type_params__
1828        self.assertIs(A_annotations["x"], A_type_params[0])
1829        self.assertEqual(A_annotations["y"].__args__[0], Unpack[A_type_params[1]])
1830        self.assertIs(A_annotations["z"].__args__[0], A_type_params[2])
1831
1832    def test_pep695_generic_class_with_future_annotations_and_local_shadowing(self):
1833        B_annotations = inspect.get_annotations(
1834            inspect_stringized_annotations_pep695.B, eval_str=True
1835        )
1836        self.assertEqual(B_annotations, {"x": int, "y": str, "z": bytes})
1837
1838    def test_pep695_generic_class_with_future_annotations_name_clash_with_global_vars(self):
1839        ann_module695 = inspect_stringized_annotations_pep695
1840        C_annotations = inspect.get_annotations(ann_module695.C, eval_str=True)
1841        self.assertEqual(
1842            set(C_annotations.values()),
1843            set(ann_module695.C.__type_params__)
1844        )
1845
1846    def test_pep_695_generic_function_with_future_annotations(self):
1847        ann_module695 = inspect_stringized_annotations_pep695
1848        generic_func_annotations = inspect.get_annotations(
1849            ann_module695.generic_function, eval_str=True
1850        )
1851        func_t_params = ann_module695.generic_function.__type_params__
1852        self.assertEqual(
1853            generic_func_annotations.keys(), {"x", "y", "z", "zz", "return"}
1854        )
1855        self.assertIs(generic_func_annotations["x"], func_t_params[0])
1856        self.assertEqual(generic_func_annotations["y"], Unpack[func_t_params[1]])
1857        self.assertIs(generic_func_annotations["z"].__origin__, func_t_params[2])
1858        self.assertIs(generic_func_annotations["zz"].__origin__, func_t_params[2])
1859
1860    def test_pep_695_generic_function_with_future_annotations_name_clash_with_global_vars(self):
1861        self.assertEqual(
1862            set(
1863                inspect.get_annotations(
1864                    inspect_stringized_annotations_pep695.generic_function_2,
1865                    eval_str=True
1866                ).values()
1867            ),
1868            set(
1869                inspect_stringized_annotations_pep695.generic_function_2.__type_params__
1870            )
1871        )
1872
1873    def test_pep_695_generic_method_with_future_annotations(self):
1874        ann_module695 = inspect_stringized_annotations_pep695
1875        generic_method_annotations = inspect.get_annotations(
1876            ann_module695.D.generic_method, eval_str=True
1877        )
1878        params = {
1879            param.__name__: param
1880            for param in ann_module695.D.generic_method.__type_params__
1881        }
1882        self.assertEqual(
1883            generic_method_annotations,
1884            {"x": params["Foo"], "y": params["Bar"], "return": None}
1885        )
1886
1887    def test_pep_695_generic_method_with_future_annotations_name_clash_with_global_vars(self):
1888        self.assertEqual(
1889            set(
1890                inspect.get_annotations(
1891                    inspect_stringized_annotations_pep695.D.generic_method_2,
1892                    eval_str=True
1893                ).values()
1894            ),
1895            set(
1896                inspect_stringized_annotations_pep695.D.generic_method_2.__type_params__
1897            )
1898        )
1899
1900    def test_pep_695_generic_method_with_future_annotations_name_clash_with_global_and_local_vars(self):
1901        self.assertEqual(
1902            inspect.get_annotations(
1903                inspect_stringized_annotations_pep695.E, eval_str=True
1904            ),
1905            {"x": str},
1906        )
1907
1908    def test_pep_695_generics_with_future_annotations_nested_in_function(self):
1909        results = inspect_stringized_annotations_pep695.nested()
1910
1911        self.assertEqual(
1912            set(results.F_annotations.values()),
1913            set(results.F.__type_params__)
1914        )
1915        self.assertEqual(
1916            set(results.F_meth_annotations.values()),
1917            set(results.F.generic_method.__type_params__)
1918        )
1919        self.assertNotEqual(
1920            set(results.F_meth_annotations.values()),
1921            set(results.F.__type_params__)
1922        )
1923        self.assertEqual(
1924            set(results.F_meth_annotations.values()).intersection(results.F.__type_params__),
1925            set()
1926        )
1927
1928        self.assertEqual(results.G_annotations, {"x": str})
1929
1930        self.assertEqual(
1931            set(results.generic_func_annotations.values()),
1932            set(results.generic_func.__type_params__)
1933        )
1934
1935
1936class TestFormatAnnotation(unittest.TestCase):
1937    def test_typing_replacement(self):
1938        from test.typinganndata.ann_module9 import ann, ann1
1939        self.assertEqual(inspect.formatannotation(ann), 'Union[List[str], int]')
1940        self.assertEqual(inspect.formatannotation(ann1), 'Union[List[testModule.typing.A], int]')
1941
1942
1943class TestIsMethodDescriptor(unittest.TestCase):
1944
1945    def test_custom_descriptors(self):
1946        class MethodDescriptor:
1947            def __get__(self, *_): pass
1948        class MethodDescriptorSub(MethodDescriptor):
1949            pass
1950        class DataDescriptorWithNoGet:
1951            def __set__(self, *_): pass
1952        class DataDescriptorWithGetSet:
1953            def __get__(self, *_): pass
1954            def __set__(self, *_): pass
1955        class DataDescriptorWithGetDelete:
1956            def __get__(self, *_): pass
1957            def __delete__(self, *_): pass
1958        class DataDescriptorSub(DataDescriptorWithNoGet,
1959                                DataDescriptorWithGetDelete):
1960            pass
1961
1962        # Custom method descriptors:
1963        self.assertTrue(
1964            inspect.ismethoddescriptor(MethodDescriptor()),
1965            '__get__ and no __set__/__delete__ => method descriptor')
1966        self.assertTrue(
1967            inspect.ismethoddescriptor(MethodDescriptorSub()),
1968            '__get__ (inherited) and no __set__/__delete__'
1969            ' => method descriptor')
1970
1971        # Custom data descriptors:
1972        self.assertFalse(
1973            inspect.ismethoddescriptor(DataDescriptorWithNoGet()),
1974            '__set__ (and no __get__) => not a method descriptor')
1975        self.assertFalse(
1976            inspect.ismethoddescriptor(DataDescriptorWithGetSet()),
1977            '__get__ and __set__ => not a method descriptor')
1978        self.assertFalse(
1979            inspect.ismethoddescriptor(DataDescriptorWithGetDelete()),
1980            '__get__ and __delete__ => not a method descriptor')
1981        self.assertFalse(
1982            inspect.ismethoddescriptor(DataDescriptorSub()),
1983            '__get__, __set__ and __delete__ => not a method descriptor')
1984
1985        # Classes of descriptors (are *not* descriptors themselves):
1986        self.assertFalse(inspect.ismethoddescriptor(MethodDescriptor))
1987        self.assertFalse(inspect.ismethoddescriptor(MethodDescriptorSub))
1988        self.assertFalse(inspect.ismethoddescriptor(DataDescriptorSub))
1989
1990    def test_builtin_descriptors(self):
1991        builtin_slot_wrapper = int.__add__  # This one is mentioned in docs.
1992        class Owner:
1993            def instance_method(self): pass
1994            @classmethod
1995            def class_method(cls): pass
1996            @staticmethod
1997            def static_method(): pass
1998            @property
1999            def a_property(self): pass
2000        class Slotermeyer:
2001            __slots__ = 'a_slot',
2002        def function():
2003            pass
2004        a_lambda = lambda: None
2005
2006        # Example builtin method descriptors:
2007        self.assertTrue(
2008            inspect.ismethoddescriptor(builtin_slot_wrapper),
2009            'a builtin slot wrapper is a method descriptor')
2010        self.assertTrue(
2011            inspect.ismethoddescriptor(Owner.__dict__['class_method']),
2012            'a classmethod object is a method descriptor')
2013        self.assertTrue(
2014            inspect.ismethoddescriptor(Owner.__dict__['static_method']),
2015            'a staticmethod object is a method descriptor')
2016
2017        # Example builtin data descriptors:
2018        self.assertFalse(
2019            inspect.ismethoddescriptor(Owner.__dict__['a_property']),
2020            'a property is not a method descriptor')
2021        self.assertFalse(
2022            inspect.ismethoddescriptor(Slotermeyer.__dict__['a_slot']),
2023            'a slot is not a method descriptor')
2024
2025        # `types.MethodType`/`types.FunctionType` instances (they *are*
2026        # method descriptors, but `ismethoddescriptor()` explicitly
2027        # excludes them):
2028        self.assertFalse(inspect.ismethoddescriptor(Owner().instance_method))
2029        self.assertFalse(inspect.ismethoddescriptor(Owner().class_method))
2030        self.assertFalse(inspect.ismethoddescriptor(Owner().static_method))
2031        self.assertFalse(inspect.ismethoddescriptor(Owner.instance_method))
2032        self.assertFalse(inspect.ismethoddescriptor(Owner.class_method))
2033        self.assertFalse(inspect.ismethoddescriptor(Owner.static_method))
2034        self.assertFalse(inspect.ismethoddescriptor(function))
2035        self.assertFalse(inspect.ismethoddescriptor(a_lambda))
2036        self.assertFalse(inspect.ismethoddescriptor(functools.partial(function)))
2037
2038    def test_descriptor_being_a_class(self):
2039        class MethodDescriptorMeta(type):
2040            def __get__(self, *_): pass
2041        class ClassBeingMethodDescriptor(metaclass=MethodDescriptorMeta):
2042            pass
2043        # `ClassBeingMethodDescriptor` itself *is* a method descriptor,
2044        # but it is *also* a class, and `ismethoddescriptor()` explicitly
2045        # excludes classes.
2046        self.assertFalse(
2047            inspect.ismethoddescriptor(ClassBeingMethodDescriptor),
2048            'classes (instances of type) are explicitly excluded')
2049
2050    def test_non_descriptors(self):
2051        class Test:
2052            pass
2053        self.assertFalse(inspect.ismethoddescriptor(Test()))
2054        self.assertFalse(inspect.ismethoddescriptor(Test))
2055        self.assertFalse(inspect.ismethoddescriptor([42]))
2056        self.assertFalse(inspect.ismethoddescriptor(42))
2057
2058
2059class TestIsDataDescriptor(unittest.TestCase):
2060
2061    def test_custom_descriptors(self):
2062        class NonDataDescriptor:
2063            def __get__(self, value, type=None): pass
2064        class DataDescriptor0:
2065            def __set__(self, name, value): pass
2066        class DataDescriptor1:
2067            def __delete__(self, name): pass
2068        class DataDescriptor2:
2069            __set__ = None
2070        self.assertFalse(inspect.isdatadescriptor(NonDataDescriptor()),
2071                         'class with only __get__ not a data descriptor')
2072        self.assertTrue(inspect.isdatadescriptor(DataDescriptor0()),
2073                        'class with __set__ is a data descriptor')
2074        self.assertTrue(inspect.isdatadescriptor(DataDescriptor1()),
2075                        'class with __delete__ is a data descriptor')
2076        self.assertTrue(inspect.isdatadescriptor(DataDescriptor2()),
2077                        'class with __set__ = None is a data descriptor')
2078
2079    def test_slot(self):
2080        class Slotted:
2081            __slots__ = 'foo',
2082        self.assertTrue(inspect.isdatadescriptor(Slotted.foo),
2083                        'a slot is a data descriptor')
2084
2085    def test_property(self):
2086        class Propertied:
2087            @property
2088            def a_property(self):
2089                pass
2090        self.assertTrue(inspect.isdatadescriptor(Propertied.a_property),
2091                        'a property is a data descriptor')
2092
2093    def test_functions(self):
2094        class Test(object):
2095            def instance_method(self): pass
2096            @classmethod
2097            def class_method(cls): pass
2098            @staticmethod
2099            def static_method(): pass
2100        def function():
2101            pass
2102        a_lambda = lambda: None
2103        self.assertFalse(inspect.isdatadescriptor(Test().instance_method),
2104                         'a instance method is not a data descriptor')
2105        self.assertFalse(inspect.isdatadescriptor(Test().class_method),
2106                         'a class method is not a data descriptor')
2107        self.assertFalse(inspect.isdatadescriptor(Test().static_method),
2108                         'a static method is not a data descriptor')
2109        self.assertFalse(inspect.isdatadescriptor(function),
2110                         'a function is not a data descriptor')
2111        self.assertFalse(inspect.isdatadescriptor(a_lambda),
2112                         'a lambda is not a data descriptor')
2113
2114
2115_global_ref = object()
2116class TestGetClosureVars(unittest.TestCase):
2117
2118    def test_name_resolution(self):
2119        # Basic test of the 4 different resolution mechanisms
2120        def f(nonlocal_ref):
2121            def g(local_ref):
2122                print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
2123            return g
2124        _arg = object()
2125        nonlocal_vars = {"nonlocal_ref": _arg}
2126        global_vars = {"_global_ref": _global_ref}
2127        builtin_vars = {"print": print}
2128        unbound_names = {"unbound_ref"}
2129        expected = inspect.ClosureVars(nonlocal_vars, global_vars,
2130                                       builtin_vars, unbound_names)
2131        self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
2132
2133    def test_generator_closure(self):
2134        def f(nonlocal_ref):
2135            def g(local_ref):
2136                print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
2137                yield
2138            return g
2139        _arg = object()
2140        nonlocal_vars = {"nonlocal_ref": _arg}
2141        global_vars = {"_global_ref": _global_ref}
2142        builtin_vars = {"print": print}
2143        unbound_names = {"unbound_ref"}
2144        expected = inspect.ClosureVars(nonlocal_vars, global_vars,
2145                                       builtin_vars, unbound_names)
2146        self.assertEqual(inspect.getclosurevars(f(_arg)), expected)
2147
2148    def test_method_closure(self):
2149        class C:
2150            def f(self, nonlocal_ref):
2151                def g(local_ref):
2152                    print(local_ref, nonlocal_ref, _global_ref, unbound_ref)
2153                return g
2154        _arg = object()
2155        nonlocal_vars = {"nonlocal_ref": _arg}
2156        global_vars = {"_global_ref": _global_ref}
2157        builtin_vars = {"print": print}
2158        unbound_names = {"unbound_ref"}
2159        expected = inspect.ClosureVars(nonlocal_vars, global_vars,
2160                                       builtin_vars, unbound_names)
2161        self.assertEqual(inspect.getclosurevars(C().f(_arg)), expected)
2162
2163    def test_attribute_same_name_as_global_var(self):
2164        class C:
2165            _global_ref = object()
2166        def f():
2167            print(C._global_ref, _global_ref)
2168        nonlocal_vars = {"C": C}
2169        global_vars = {"_global_ref": _global_ref}
2170        builtin_vars = {"print": print}
2171        unbound_names = {"_global_ref"}
2172        expected = inspect.ClosureVars(nonlocal_vars, global_vars,
2173                                       builtin_vars, unbound_names)
2174        self.assertEqual(inspect.getclosurevars(f), expected)
2175
2176    def test_nonlocal_vars(self):
2177        # More complex tests of nonlocal resolution
2178        def _nonlocal_vars(f):
2179            return inspect.getclosurevars(f).nonlocals
2180
2181        def make_adder(x):
2182            def add(y):
2183                return x + y
2184            return add
2185
2186        def curry(func, arg1):
2187            return lambda arg2: func(arg1, arg2)
2188
2189        def less_than(a, b):
2190            return a < b
2191
2192        # The infamous Y combinator.
2193        def Y(le):
2194            def g(f):
2195                return le(lambda x: f(f)(x))
2196            Y.g_ref = g
2197            return g(g)
2198
2199        def check_y_combinator(func):
2200            self.assertEqual(_nonlocal_vars(func), {'f': Y.g_ref})
2201
2202        inc = make_adder(1)
2203        add_two = make_adder(2)
2204        greater_than_five = curry(less_than, 5)
2205
2206        self.assertEqual(_nonlocal_vars(inc), {'x': 1})
2207        self.assertEqual(_nonlocal_vars(add_two), {'x': 2})
2208        self.assertEqual(_nonlocal_vars(greater_than_five),
2209                         {'arg1': 5, 'func': less_than})
2210        self.assertEqual(_nonlocal_vars((lambda x: lambda y: x + y)(3)),
2211                         {'x': 3})
2212        Y(check_y_combinator)
2213
2214    def test_getclosurevars_empty(self):
2215        def foo(): pass
2216        _empty = inspect.ClosureVars({}, {}, {}, set())
2217        self.assertEqual(inspect.getclosurevars(lambda: True), _empty)
2218        self.assertEqual(inspect.getclosurevars(foo), _empty)
2219
2220    def test_getclosurevars_error(self):
2221        class T: pass
2222        self.assertRaises(TypeError, inspect.getclosurevars, 1)
2223        self.assertRaises(TypeError, inspect.getclosurevars, list)
2224        self.assertRaises(TypeError, inspect.getclosurevars, {})
2225
2226    def _private_globals(self):
2227        code = """def f(): print(path)"""
2228        ns = {}
2229        exec(code, ns)
2230        return ns["f"], ns
2231
2232    def test_builtins_fallback(self):
2233        f, ns = self._private_globals()
2234        ns.pop("__builtins__", None)
2235        expected = inspect.ClosureVars({}, {}, {"print":print}, {"path"})
2236        self.assertEqual(inspect.getclosurevars(f), expected)
2237
2238    def test_builtins_as_dict(self):
2239        f, ns = self._private_globals()
2240        ns["__builtins__"] = {"path":1}
2241        expected = inspect.ClosureVars({}, {}, {"path":1}, {"print"})
2242        self.assertEqual(inspect.getclosurevars(f), expected)
2243
2244    def test_builtins_as_module(self):
2245        f, ns = self._private_globals()
2246        ns["__builtins__"] = os
2247        expected = inspect.ClosureVars({}, {}, {"path":os.path}, {"print"})
2248        self.assertEqual(inspect.getclosurevars(f), expected)
2249
2250
2251class TestGetcallargsFunctions(unittest.TestCase):
2252
2253    def assertEqualCallArgs(self, func, call_params_string, locs=None):
2254        locs = dict(locs or {}, func=func)
2255        r1 = eval('func(%s)' % call_params_string, None, locs)
2256        r2 = eval('inspect.getcallargs(func, %s)' % call_params_string, None,
2257                  locs)
2258        self.assertEqual(r1, r2)
2259
2260    def assertEqualException(self, func, call_param_string, locs=None):
2261        locs = dict(locs or {}, func=func)
2262        try:
2263            eval('func(%s)' % call_param_string, None, locs)
2264        except Exception as e:
2265            ex1 = e
2266        else:
2267            self.fail('Exception not raised')
2268        try:
2269            eval('inspect.getcallargs(func, %s)' % call_param_string, None,
2270                 locs)
2271        except Exception as e:
2272            ex2 = e
2273        else:
2274            self.fail('Exception not raised')
2275        self.assertIs(type(ex1), type(ex2))
2276        self.assertEqual(str(ex1), str(ex2))
2277        del ex1, ex2
2278
2279    def makeCallable(self, signature):
2280        """Create a function that returns its locals()"""
2281        code = "lambda %s: locals()"
2282        return eval(code % signature)
2283
2284    def test_plain(self):
2285        f = self.makeCallable('a, b=1')
2286        self.assertEqualCallArgs(f, '2')
2287        self.assertEqualCallArgs(f, '2, 3')
2288        self.assertEqualCallArgs(f, 'a=2')
2289        self.assertEqualCallArgs(f, 'b=3, a=2')
2290        self.assertEqualCallArgs(f, '2, b=3')
2291        # expand *iterable / **mapping
2292        self.assertEqualCallArgs(f, '*(2,)')
2293        self.assertEqualCallArgs(f, '*[2]')
2294        self.assertEqualCallArgs(f, '*(2, 3)')
2295        self.assertEqualCallArgs(f, '*[2, 3]')
2296        self.assertEqualCallArgs(f, '**{"a":2}')
2297        self.assertEqualCallArgs(f, 'b=3, **{"a":2}')
2298        self.assertEqualCallArgs(f, '2, **{"b":3}')
2299        self.assertEqualCallArgs(f, '**{"b":3, "a":2}')
2300        # expand UserList / UserDict
2301        self.assertEqualCallArgs(f, '*collections.UserList([2])')
2302        self.assertEqualCallArgs(f, '*collections.UserList([2, 3])')
2303        self.assertEqualCallArgs(f, '**collections.UserDict(a=2)')
2304        self.assertEqualCallArgs(f, '2, **collections.UserDict(b=3)')
2305        self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3)')
2306
2307    def test_varargs(self):
2308        f = self.makeCallable('a, b=1, *c')
2309        self.assertEqualCallArgs(f, '2')
2310        self.assertEqualCallArgs(f, '2, 3')
2311        self.assertEqualCallArgs(f, '2, 3, 4')
2312        self.assertEqualCallArgs(f, '*(2,3,4)')
2313        self.assertEqualCallArgs(f, '2, *[3,4]')
2314        self.assertEqualCallArgs(f, '2, 3, *collections.UserList([4])')
2315
2316    def test_varkw(self):
2317        f = self.makeCallable('a, b=1, **c')
2318        self.assertEqualCallArgs(f, 'a=2')
2319        self.assertEqualCallArgs(f, '2, b=3, c=4')
2320        self.assertEqualCallArgs(f, 'b=3, a=2, c=4')
2321        self.assertEqualCallArgs(f, 'c=4, **{"a":2, "b":3}')
2322        self.assertEqualCallArgs(f, '2, c=4, **{"b":3}')
2323        self.assertEqualCallArgs(f, 'b=2, **{"a":3, "c":4}')
2324        self.assertEqualCallArgs(f, '**collections.UserDict(a=2, b=3, c=4)')
2325        self.assertEqualCallArgs(f, '2, c=4, **collections.UserDict(b=3)')
2326        self.assertEqualCallArgs(f, 'b=2, **collections.UserDict(a=3, c=4)')
2327
2328    def test_varkw_only(self):
2329        # issue11256:
2330        f = self.makeCallable('**c')
2331        self.assertEqualCallArgs(f, '')
2332        self.assertEqualCallArgs(f, 'a=1')
2333        self.assertEqualCallArgs(f, 'a=1, b=2')
2334        self.assertEqualCallArgs(f, 'c=3, **{"a": 1, "b": 2}')
2335        self.assertEqualCallArgs(f, '**collections.UserDict(a=1, b=2)')
2336        self.assertEqualCallArgs(f, 'c=3, **collections.UserDict(a=1, b=2)')
2337
2338    def test_keyword_only(self):
2339        f = self.makeCallable('a=3, *, c, d=2')
2340        self.assertEqualCallArgs(f, 'c=3')
2341        self.assertEqualCallArgs(f, 'c=3, a=3')
2342        self.assertEqualCallArgs(f, 'a=2, c=4')
2343        self.assertEqualCallArgs(f, '4, c=4')
2344        self.assertEqualException(f, '')
2345        self.assertEqualException(f, '3')
2346        self.assertEqualException(f, 'a=3')
2347        self.assertEqualException(f, 'd=4')
2348
2349        f = self.makeCallable('*, c, d=2')
2350        self.assertEqualCallArgs(f, 'c=3')
2351        self.assertEqualCallArgs(f, 'c=3, d=4')
2352        self.assertEqualCallArgs(f, 'd=4, c=3')
2353
2354    def test_multiple_features(self):
2355        f = self.makeCallable('a, b=2, *f, **g')
2356        self.assertEqualCallArgs(f, '2, 3, 7')
2357        self.assertEqualCallArgs(f, '2, 3, x=8')
2358        self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
2359        self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9')
2360        self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9')
2361        self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
2362                                 '[2, 3, (4,[5,6])]), **{"y":9, "z":10}')
2363        self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
2364                                 '(4,[5,6])]), **collections.UserDict('
2365                                 'y=9, z=10)')
2366
2367        f = self.makeCallable('a, b=2, *f, x, y=99, **g')
2368        self.assertEqualCallArgs(f, '2, 3, x=8')
2369        self.assertEqualCallArgs(f, '2, 3, x=8, *[(4,[5,6]), 7]')
2370        self.assertEqualCallArgs(f, '2, x=8, *[3, (4,[5,6]), 7], y=9, z=10')
2371        self.assertEqualCallArgs(f, 'x=8, *[2, 3, (4,[5,6])], y=9, z=10')
2372        self.assertEqualCallArgs(f, 'x=8, *collections.UserList('
2373                                 '[2, 3, (4,[5,6])]), q=0, **{"y":9, "z":10}')
2374        self.assertEqualCallArgs(f, '2, x=8, *collections.UserList([3, '
2375                                 '(4,[5,6])]), q=0, **collections.UserDict('
2376                                 'y=9, z=10)')
2377
2378    def test_errors(self):
2379        f0 = self.makeCallable('')
2380        f1 = self.makeCallable('a, b')
2381        f2 = self.makeCallable('a, b=1')
2382        # f0 takes no arguments
2383        self.assertEqualException(f0, '1')
2384        self.assertEqualException(f0, 'x=1')
2385        self.assertEqualException(f0, '1,x=1')
2386        # f1 takes exactly 2 arguments
2387        self.assertEqualException(f1, '')
2388        self.assertEqualException(f1, '1')
2389        self.assertEqualException(f1, 'a=2')
2390        self.assertEqualException(f1, 'b=3')
2391        # f2 takes at least 1 argument
2392        self.assertEqualException(f2, '')
2393        self.assertEqualException(f2, 'b=3')
2394        for f in f1, f2:
2395            # f1/f2 takes exactly/at most 2 arguments
2396            self.assertEqualException(f, '2, 3, 4')
2397            self.assertEqualException(f, '1, 2, 3, a=1')
2398            self.assertEqualException(f, '2, 3, 4, c=5')
2399            self.assertEqualException(f, '2, 3, 4, a=1, c=5')
2400            # f got an unexpected keyword argument
2401            self.assertEqualException(f, 'c=2')
2402            self.assertEqualException(f, '2, c=3')
2403            self.assertEqualException(f, '2, 3, c=4')
2404            self.assertEqualException(f, '2, c=4, b=3')
2405            self.assertEqualException(f, '**{u"\u03c0\u03b9": 4}')
2406            # f got multiple values for keyword argument
2407            self.assertEqualException(f, '1, a=2')
2408            self.assertEqualException(f, '1, **{"a":2}')
2409            self.assertEqualException(f, '1, 2, b=3')
2410            self.assertEqualException(f, '1, c=3, a=2')
2411        # issue11256:
2412        f3 = self.makeCallable('**c')
2413        self.assertEqualException(f3, '1, 2')
2414        self.assertEqualException(f3, '1, 2, a=1, b=2')
2415        f4 = self.makeCallable('*, a, b=0')
2416        self.assertEqualException(f4, '1, 2')
2417        self.assertEqualException(f4, '1, 2, a=1, b=2')
2418        self.assertEqualException(f4, 'a=1, a=3')
2419        self.assertEqualException(f4, 'a=1, c=3')
2420        self.assertEqualException(f4, 'a=1, a=3, b=4')
2421        self.assertEqualException(f4, 'a=1, b=2, a=3, b=4')
2422        self.assertEqualException(f4, 'a=1, a=2, a=3, b=4')
2423
2424        # issue #20816: getcallargs() fails to iterate over non-existent
2425        # kwonlydefaults and raises a wrong TypeError
2426        def f5(*, a): pass
2427        with self.assertRaisesRegex(TypeError,
2428                                    'missing 1 required keyword-only'):
2429            inspect.getcallargs(f5)
2430
2431
2432        # issue20817:
2433        def f6(a, b, c):
2434            pass
2435        with self.assertRaisesRegex(TypeError, "'a', 'b' and 'c'"):
2436            inspect.getcallargs(f6)
2437
2438        # bpo-33197
2439        with self.assertRaisesRegex(ValueError,
2440                                    'variadic keyword parameters cannot'
2441                                    ' have default values'):
2442            inspect.Parameter("foo", kind=inspect.Parameter.VAR_KEYWORD,
2443                              default=42)
2444        with self.assertRaisesRegex(ValueError,
2445                                    "value 5 is not a valid Parameter.kind"):
2446            inspect.Parameter("bar", kind=5, default=42)
2447
2448        with self.assertRaisesRegex(TypeError,
2449                                   'name must be a str, not a int'):
2450            inspect.Parameter(123, kind=4)
2451
2452class TestGetcallargsMethods(TestGetcallargsFunctions):
2453
2454    def setUp(self):
2455        class Foo(object):
2456            pass
2457        self.cls = Foo
2458        self.inst = Foo()
2459
2460    def makeCallable(self, signature):
2461        assert 'self' not in signature
2462        mk = super(TestGetcallargsMethods, self).makeCallable
2463        self.cls.method = mk('self, ' + signature)
2464        return self.inst.method
2465
2466class TestGetcallargsUnboundMethods(TestGetcallargsMethods):
2467
2468    def makeCallable(self, signature):
2469        super(TestGetcallargsUnboundMethods, self).makeCallable(signature)
2470        return self.cls.method
2471
2472    def assertEqualCallArgs(self, func, call_params_string, locs=None):
2473        return super(TestGetcallargsUnboundMethods, self).assertEqualCallArgs(
2474            *self._getAssertEqualParams(func, call_params_string, locs))
2475
2476    def assertEqualException(self, func, call_params_string, locs=None):
2477        return super(TestGetcallargsUnboundMethods, self).assertEqualException(
2478            *self._getAssertEqualParams(func, call_params_string, locs))
2479
2480    def _getAssertEqualParams(self, func, call_params_string, locs=None):
2481        assert 'inst' not in call_params_string
2482        locs = dict(locs or {}, inst=self.inst)
2483        return (func, 'inst,' + call_params_string, locs)
2484
2485
2486class TestGetattrStatic(unittest.TestCase):
2487
2488    def test_basic(self):
2489        class Thing(object):
2490            x = object()
2491
2492        thing = Thing()
2493        self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
2494        self.assertEqual(inspect.getattr_static(thing, 'x', None), Thing.x)
2495        with self.assertRaises(AttributeError):
2496            inspect.getattr_static(thing, 'y')
2497
2498        self.assertEqual(inspect.getattr_static(thing, 'y', 3), 3)
2499
2500    def test_inherited(self):
2501        class Thing(object):
2502            x = object()
2503        class OtherThing(Thing):
2504            pass
2505
2506        something = OtherThing()
2507        self.assertEqual(inspect.getattr_static(something, 'x'), Thing.x)
2508
2509    def test_instance_attr(self):
2510        class Thing(object):
2511            x = 2
2512            def __init__(self, x):
2513                self.x = x
2514        thing = Thing(3)
2515        self.assertEqual(inspect.getattr_static(thing, 'x'), 3)
2516        del thing.x
2517        self.assertEqual(inspect.getattr_static(thing, 'x'), 2)
2518
2519    def test_property(self):
2520        class Thing(object):
2521            @property
2522            def x(self):
2523                raise AttributeError("I'm pretending not to exist")
2524        thing = Thing()
2525        self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
2526
2527    def test_descriptor_raises_AttributeError(self):
2528        class descriptor(object):
2529            def __get__(*_):
2530                raise AttributeError("I'm pretending not to exist")
2531        desc = descriptor()
2532        class Thing(object):
2533            x = desc
2534        thing = Thing()
2535        self.assertEqual(inspect.getattr_static(thing, 'x'), desc)
2536
2537    def test_classAttribute(self):
2538        class Thing(object):
2539            x = object()
2540
2541        self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.x)
2542
2543    def test_classVirtualAttribute(self):
2544        class Thing(object):
2545            @types.DynamicClassAttribute
2546            def x(self):
2547                return self._x
2548            _x = object()
2549
2550        self.assertEqual(inspect.getattr_static(Thing, 'x'), Thing.__dict__['x'])
2551
2552    def test_inherited_classattribute(self):
2553        class Thing(object):
2554            x = object()
2555        class OtherThing(Thing):
2556            pass
2557
2558        self.assertEqual(inspect.getattr_static(OtherThing, 'x'), Thing.x)
2559
2560    def test_slots(self):
2561        class Thing(object):
2562            y = 'bar'
2563            __slots__ = ['x']
2564            def __init__(self):
2565                self.x = 'foo'
2566        thing = Thing()
2567        self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
2568        self.assertEqual(inspect.getattr_static(thing, 'y'), 'bar')
2569
2570        del thing.x
2571        self.assertEqual(inspect.getattr_static(thing, 'x'), Thing.x)
2572
2573    def test_metaclass(self):
2574        class meta(type):
2575            attr = 'foo'
2576        class Thing(object, metaclass=meta):
2577            pass
2578        self.assertEqual(inspect.getattr_static(Thing, 'attr'), 'foo')
2579
2580        class sub(meta):
2581            pass
2582        class OtherThing(object, metaclass=sub):
2583            x = 3
2584        self.assertEqual(inspect.getattr_static(OtherThing, 'attr'), 'foo')
2585
2586        class OtherOtherThing(OtherThing):
2587            pass
2588        # this test is odd, but it was added as it exposed a bug
2589        self.assertEqual(inspect.getattr_static(OtherOtherThing, 'x'), 3)
2590
2591    def test_no_dict_no_slots(self):
2592        self.assertEqual(inspect.getattr_static(1, 'foo', None), None)
2593        self.assertNotEqual(inspect.getattr_static('foo', 'lower'), None)
2594
2595    def test_no_dict_no_slots_instance_member(self):
2596        # returns descriptor
2597        with open(__file__, encoding='utf-8') as handle:
2598            self.assertEqual(inspect.getattr_static(handle, 'name'), type(handle).name)
2599
2600    def test_inherited_slots(self):
2601        # returns descriptor
2602        class Thing(object):
2603            __slots__ = ['x']
2604            def __init__(self):
2605                self.x = 'foo'
2606
2607        class OtherThing(Thing):
2608            pass
2609        # it would be nice if this worked...
2610        # we get the descriptor instead of the instance attribute
2611        self.assertEqual(inspect.getattr_static(OtherThing(), 'x'), Thing.x)
2612
2613    def test_descriptor(self):
2614        class descriptor(object):
2615            def __get__(self, instance, owner):
2616                return 3
2617        class Foo(object):
2618            d = descriptor()
2619
2620        foo = Foo()
2621
2622        # for a non data descriptor we return the instance attribute
2623        foo.__dict__['d'] = 1
2624        self.assertEqual(inspect.getattr_static(foo, 'd'), 1)
2625
2626        # if the descriptor is a data-descriptor we should return the
2627        # descriptor
2628        descriptor.__set__ = lambda s, i, v: None
2629        self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
2630
2631        del descriptor.__set__
2632        descriptor.__delete__ = lambda s, i, o: None
2633        self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d'])
2634
2635    def test_metaclass_with_descriptor(self):
2636        class descriptor(object):
2637            def __get__(self, instance, owner):
2638                return 3
2639        class meta(type):
2640            d = descriptor()
2641        class Thing(object, metaclass=meta):
2642            pass
2643        self.assertEqual(inspect.getattr_static(Thing, 'd'), meta.__dict__['d'])
2644
2645
2646    def test_class_as_property(self):
2647        class Base(object):
2648            foo = 3
2649
2650        class Something(Base):
2651            executed = False
2652            @property
2653            def __class__(self):
2654                self.executed = True
2655                return object
2656
2657        instance = Something()
2658        self.assertEqual(inspect.getattr_static(instance, 'foo'), 3)
2659        self.assertFalse(instance.executed)
2660        self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
2661
2662    def test_mro_as_property(self):
2663        class Meta(type):
2664            @property
2665            def __mro__(self):
2666                return (object,)
2667
2668        class Base(object):
2669            foo = 3
2670
2671        class Something(Base, metaclass=Meta):
2672            pass
2673
2674        self.assertEqual(inspect.getattr_static(Something(), 'foo'), 3)
2675        self.assertEqual(inspect.getattr_static(Something, 'foo'), 3)
2676
2677    def test_dict_as_property(self):
2678        test = self
2679        test.called = False
2680
2681        class Foo(dict):
2682            a = 3
2683            @property
2684            def __dict__(self):
2685                test.called = True
2686                return {}
2687
2688        foo = Foo()
2689        foo.a = 4
2690        self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
2691        self.assertFalse(test.called)
2692
2693        class Bar(Foo): pass
2694
2695        bar = Bar()
2696        bar.a = 5
2697        self.assertEqual(inspect.getattr_static(bar, 'a'), 3)
2698        self.assertFalse(test.called)
2699
2700    def test_mutated_mro(self):
2701        test = self
2702        test.called = False
2703
2704        class Foo(dict):
2705            a = 3
2706            @property
2707            def __dict__(self):
2708                test.called = True
2709                return {}
2710
2711        class Bar(dict):
2712            a = 4
2713
2714        class Baz(Bar): pass
2715
2716        baz = Baz()
2717        self.assertEqual(inspect.getattr_static(baz, 'a'), 4)
2718        Baz.__bases__ = (Foo,)
2719        self.assertEqual(inspect.getattr_static(baz, 'a'), 3)
2720        self.assertFalse(test.called)
2721
2722    def test_custom_object_dict(self):
2723        test = self
2724        test.called = False
2725
2726        class Custom(dict):
2727            def get(self, key, default=None):
2728                test.called = True
2729                super().get(key, default)
2730
2731        class Foo(object):
2732            a = 3
2733        foo = Foo()
2734        foo.__dict__ = Custom()
2735        self.assertEqual(inspect.getattr_static(foo, 'a'), 3)
2736        self.assertFalse(test.called)
2737
2738    def test_metaclass_dict_as_property(self):
2739        class Meta(type):
2740            @property
2741            def __dict__(self):
2742                self.executed = True
2743
2744        class Thing(metaclass=Meta):
2745            executed = False
2746
2747            def __init__(self):
2748                self.spam = 42
2749
2750        instance = Thing()
2751        self.assertEqual(inspect.getattr_static(instance, "spam"), 42)
2752        self.assertFalse(Thing.executed)
2753
2754    def test_module(self):
2755        sentinel = object()
2756        self.assertIsNot(inspect.getattr_static(sys, "version", sentinel),
2757                         sentinel)
2758
2759    def test_metaclass_with_metaclass_with_dict_as_property(self):
2760        class MetaMeta(type):
2761            @property
2762            def __dict__(self):
2763                self.executed = True
2764                return dict(spam=42)
2765
2766        class Meta(type, metaclass=MetaMeta):
2767            executed = False
2768
2769        class Thing(metaclass=Meta):
2770            pass
2771
2772        with self.assertRaises(AttributeError):
2773            inspect.getattr_static(Thing, "spam")
2774        self.assertFalse(Thing.executed)
2775
2776    def test_custom___getattr__(self):
2777        test = self
2778        test.called = False
2779
2780        class Foo:
2781            def __getattr__(self, attr):
2782                test.called = True
2783                return {}
2784
2785        with self.assertRaises(AttributeError):
2786            inspect.getattr_static(Foo(), 'whatever')
2787
2788        self.assertFalse(test.called)
2789
2790    def test_custom___getattribute__(self):
2791        test = self
2792        test.called = False
2793
2794        class Foo:
2795            def __getattribute__(self, attr):
2796                test.called = True
2797                return {}
2798
2799        with self.assertRaises(AttributeError):
2800            inspect.getattr_static(Foo(), 'really_could_be_anything')
2801
2802        self.assertFalse(test.called)
2803
2804    @suppress_immortalization()
2805    def test_cache_does_not_cause_classes_to_persist(self):
2806        # regression test for gh-118013:
2807        # check that the internal _shadowed_dict cache does not cause
2808        # dynamically created classes to have extended lifetimes even
2809        # when no other strong references to those classes remain.
2810        # Since these classes can themselves hold strong references to
2811        # other objects, this can cause unexpected memory consumption.
2812        class Foo: pass
2813        Foo.instance = Foo()
2814        weakref_to_class = weakref.ref(Foo)
2815        inspect.getattr_static(Foo.instance, 'whatever', 'irrelevant')
2816        del Foo
2817        gc.collect()
2818        self.assertIsNone(weakref_to_class())
2819
2820
2821class TestGetGeneratorState(unittest.TestCase):
2822
2823    def setUp(self):
2824        def number_generator():
2825            for number in range(5):
2826                yield number
2827        self.generator = number_generator()
2828
2829    def _generatorstate(self):
2830        return inspect.getgeneratorstate(self.generator)
2831
2832    def test_created(self):
2833        self.assertEqual(self._generatorstate(), inspect.GEN_CREATED)
2834
2835    def test_suspended(self):
2836        next(self.generator)
2837        self.assertEqual(self._generatorstate(), inspect.GEN_SUSPENDED)
2838
2839    def test_closed_after_exhaustion(self):
2840        for i in self.generator:
2841            pass
2842        self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
2843
2844    def test_closed_after_immediate_exception(self):
2845        with self.assertRaises(RuntimeError):
2846            self.generator.throw(RuntimeError)
2847        self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
2848
2849    def test_closed_after_close(self):
2850        self.generator.close()
2851        self.assertEqual(self._generatorstate(), inspect.GEN_CLOSED)
2852
2853    def test_running(self):
2854        # As mentioned on issue #10220, checking for the RUNNING state only
2855        # makes sense inside the generator itself.
2856        # The following generator checks for this by using the closure's
2857        # reference to self and the generator state checking helper method
2858        def running_check_generator():
2859            for number in range(5):
2860                self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
2861                yield number
2862                self.assertEqual(self._generatorstate(), inspect.GEN_RUNNING)
2863        self.generator = running_check_generator()
2864        # Running up to the first yield
2865        next(self.generator)
2866        # Running after the first yield
2867        next(self.generator)
2868
2869    def test_easy_debugging(self):
2870        # repr() and str() of a generator state should contain the state name
2871        names = 'GEN_CREATED GEN_RUNNING GEN_SUSPENDED GEN_CLOSED'.split()
2872        for name in names:
2873            state = getattr(inspect, name)
2874            self.assertIn(name, repr(state))
2875            self.assertIn(name, str(state))
2876
2877    def test_getgeneratorlocals(self):
2878        def each(lst, a=None):
2879            b=(1, 2, 3)
2880            for v in lst:
2881                if v == 3:
2882                    c = 12
2883                yield v
2884
2885        numbers = each([1, 2, 3])
2886        self.assertEqual(inspect.getgeneratorlocals(numbers),
2887                         {'a': None, 'lst': [1, 2, 3]})
2888        next(numbers)
2889        self.assertEqual(inspect.getgeneratorlocals(numbers),
2890                         {'a': None, 'lst': [1, 2, 3], 'v': 1,
2891                          'b': (1, 2, 3)})
2892        next(numbers)
2893        self.assertEqual(inspect.getgeneratorlocals(numbers),
2894                         {'a': None, 'lst': [1, 2, 3], 'v': 2,
2895                          'b': (1, 2, 3)})
2896        next(numbers)
2897        self.assertEqual(inspect.getgeneratorlocals(numbers),
2898                         {'a': None, 'lst': [1, 2, 3], 'v': 3,
2899                          'b': (1, 2, 3), 'c': 12})
2900        try:
2901            next(numbers)
2902        except StopIteration:
2903            pass
2904        self.assertEqual(inspect.getgeneratorlocals(numbers), {})
2905
2906    def test_getgeneratorlocals_empty(self):
2907        def yield_one():
2908            yield 1
2909        one = yield_one()
2910        self.assertEqual(inspect.getgeneratorlocals(one), {})
2911        try:
2912            next(one)
2913        except StopIteration:
2914            pass
2915        self.assertEqual(inspect.getgeneratorlocals(one), {})
2916
2917    def test_getgeneratorlocals_error(self):
2918        self.assertRaises(TypeError, inspect.getgeneratorlocals, 1)
2919        self.assertRaises(TypeError, inspect.getgeneratorlocals, lambda x: True)
2920        self.assertRaises(TypeError, inspect.getgeneratorlocals, set)
2921        self.assertRaises(TypeError, inspect.getgeneratorlocals, (2,3))
2922
2923
2924class TestGetCoroutineState(unittest.TestCase):
2925
2926    def setUp(self):
2927        @types.coroutine
2928        def number_coroutine():
2929            for number in range(5):
2930                yield number
2931        async def coroutine():
2932            await number_coroutine()
2933        self.coroutine = coroutine()
2934
2935    def tearDown(self):
2936        self.coroutine.close()
2937
2938    def _coroutinestate(self):
2939        return inspect.getcoroutinestate(self.coroutine)
2940
2941    def test_created(self):
2942        self.assertEqual(self._coroutinestate(), inspect.CORO_CREATED)
2943
2944    def test_suspended(self):
2945        self.coroutine.send(None)
2946        self.assertEqual(self._coroutinestate(), inspect.CORO_SUSPENDED)
2947
2948    def test_closed_after_exhaustion(self):
2949        while True:
2950            try:
2951                self.coroutine.send(None)
2952            except StopIteration:
2953                break
2954
2955        self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
2956
2957    def test_closed_after_immediate_exception(self):
2958        with self.assertRaises(RuntimeError):
2959            self.coroutine.throw(RuntimeError)
2960        self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
2961
2962    def test_closed_after_close(self):
2963        self.coroutine.close()
2964        self.assertEqual(self._coroutinestate(), inspect.CORO_CLOSED)
2965
2966    def test_easy_debugging(self):
2967        # repr() and str() of a coroutine state should contain the state name
2968        names = 'CORO_CREATED CORO_RUNNING CORO_SUSPENDED CORO_CLOSED'.split()
2969        for name in names:
2970            state = getattr(inspect, name)
2971            self.assertIn(name, repr(state))
2972            self.assertIn(name, str(state))
2973
2974    def test_getcoroutinelocals(self):
2975        @types.coroutine
2976        def gencoro():
2977            yield
2978
2979        gencoro = gencoro()
2980        async def func(a=None):
2981            b = 'spam'
2982            await gencoro
2983
2984        coro = func()
2985        self.assertEqual(inspect.getcoroutinelocals(coro),
2986                         {'a': None, 'gencoro': gencoro})
2987        coro.send(None)
2988        self.assertEqual(inspect.getcoroutinelocals(coro),
2989                         {'a': None, 'gencoro': gencoro, 'b': 'spam'})
2990
2991
2992@support.requires_working_socket()
2993class TestGetAsyncGenState(unittest.IsolatedAsyncioTestCase):
2994
2995    def setUp(self):
2996        async def number_asyncgen():
2997            for number in range(5):
2998                yield number
2999        self.asyncgen = number_asyncgen()
3000
3001    async def asyncTearDown(self):
3002        await self.asyncgen.aclose()
3003
3004    def _asyncgenstate(self):
3005        return inspect.getasyncgenstate(self.asyncgen)
3006
3007    def test_created(self):
3008        self.assertEqual(self._asyncgenstate(), inspect.AGEN_CREATED)
3009
3010    async def test_suspended(self):
3011        value = await anext(self.asyncgen)
3012        self.assertEqual(self._asyncgenstate(), inspect.AGEN_SUSPENDED)
3013        self.assertEqual(value, 0)
3014
3015    async def test_closed_after_exhaustion(self):
3016        countdown = 7
3017        with self.assertRaises(StopAsyncIteration):
3018            while countdown := countdown - 1:
3019                await anext(self.asyncgen)
3020        self.assertEqual(countdown, 1)
3021        self.assertEqual(self._asyncgenstate(), inspect.AGEN_CLOSED)
3022
3023    async def test_closed_after_immediate_exception(self):
3024        with self.assertRaises(RuntimeError):
3025            await self.asyncgen.athrow(RuntimeError)
3026        self.assertEqual(self._asyncgenstate(), inspect.AGEN_CLOSED)
3027
3028    async def test_running(self):
3029        async def running_check_asyncgen():
3030            for number in range(5):
3031                self.assertEqual(self._asyncgenstate(), inspect.AGEN_RUNNING)
3032                yield number
3033                self.assertEqual(self._asyncgenstate(), inspect.AGEN_RUNNING)
3034        self.asyncgen = running_check_asyncgen()
3035        # Running up to the first yield
3036        await anext(self.asyncgen)
3037        self.assertEqual(self._asyncgenstate(), inspect.AGEN_SUSPENDED)
3038        # Running after the first yield
3039        await anext(self.asyncgen)
3040        self.assertEqual(self._asyncgenstate(), inspect.AGEN_SUSPENDED)
3041
3042    def test_easy_debugging(self):
3043        # repr() and str() of a asyncgen state should contain the state name
3044        names = 'AGEN_CREATED AGEN_RUNNING AGEN_SUSPENDED AGEN_CLOSED'.split()
3045        for name in names:
3046            state = getattr(inspect, name)
3047            self.assertIn(name, repr(state))
3048            self.assertIn(name, str(state))
3049
3050    async def test_getasyncgenlocals(self):
3051        async def each(lst, a=None):
3052            b=(1, 2, 3)
3053            for v in lst:
3054                if v == 3:
3055                    c = 12
3056                yield v
3057
3058        numbers = each([1, 2, 3])
3059        self.assertEqual(inspect.getasyncgenlocals(numbers),
3060                         {'a': None, 'lst': [1, 2, 3]})
3061        await anext(numbers)
3062        self.assertEqual(inspect.getasyncgenlocals(numbers),
3063                         {'a': None, 'lst': [1, 2, 3], 'v': 1,
3064                          'b': (1, 2, 3)})
3065        await anext(numbers)
3066        self.assertEqual(inspect.getasyncgenlocals(numbers),
3067                         {'a': None, 'lst': [1, 2, 3], 'v': 2,
3068                          'b': (1, 2, 3)})
3069        await anext(numbers)
3070        self.assertEqual(inspect.getasyncgenlocals(numbers),
3071                         {'a': None, 'lst': [1, 2, 3], 'v': 3,
3072                          'b': (1, 2, 3), 'c': 12})
3073        with self.assertRaises(StopAsyncIteration):
3074            await anext(numbers)
3075        self.assertEqual(inspect.getasyncgenlocals(numbers), {})
3076
3077    async def test_getasyncgenlocals_empty(self):
3078        async def yield_one():
3079            yield 1
3080        one = yield_one()
3081        self.assertEqual(inspect.getasyncgenlocals(one), {})
3082        await anext(one)
3083        self.assertEqual(inspect.getasyncgenlocals(one), {})
3084        with self.assertRaises(StopAsyncIteration):
3085            await anext(one)
3086        self.assertEqual(inspect.getasyncgenlocals(one), {})
3087
3088    def test_getasyncgenlocals_error(self):
3089        self.assertRaises(TypeError, inspect.getasyncgenlocals, 1)
3090        self.assertRaises(TypeError, inspect.getasyncgenlocals, lambda x: True)
3091        self.assertRaises(TypeError, inspect.getasyncgenlocals, set)
3092        self.assertRaises(TypeError, inspect.getasyncgenlocals, (2,3))
3093
3094
3095class MySignature(inspect.Signature):
3096    # Top-level to make it picklable;
3097    # used in test_signature_object_pickle
3098    pass
3099
3100class MyParameter(inspect.Parameter):
3101    # Top-level to make it picklable;
3102    # used in test_signature_object_pickle
3103    pass
3104
3105
3106
3107class TestSignatureObject(unittest.TestCase):
3108    @staticmethod
3109    def signature(func, **kw):
3110        sig = inspect.signature(func, **kw)
3111        return (tuple((param.name,
3112                       (... if param.default is param.empty else param.default),
3113                       (... if param.annotation is param.empty
3114                                                        else param.annotation),
3115                       str(param.kind).lower())
3116                                    for param in sig.parameters.values()),
3117                (... if sig.return_annotation is sig.empty
3118                                            else sig.return_annotation))
3119
3120    def test_signature_object(self):
3121        S = inspect.Signature
3122        P = inspect.Parameter
3123
3124        self.assertEqual(str(S()), '()')
3125        self.assertEqual(repr(S().parameters), 'mappingproxy(OrderedDict())')
3126
3127        def test(po, /, pk, pkd=100, *args, ko, kod=10, **kwargs):
3128            pass
3129
3130        sig = inspect.signature(test)
3131        self.assertTrue(repr(sig).startswith('<Signature'))
3132        self.assertTrue('(po, /, pk' in repr(sig))
3133
3134        # We need two functions, because it is impossible to represent
3135        # all param kinds in a single one.
3136        def test2(pod=42, /):
3137            pass
3138
3139        sig2 = inspect.signature(test2)
3140        self.assertTrue(repr(sig2).startswith('<Signature'))
3141        self.assertTrue('(pod=42, /)' in repr(sig2))
3142
3143        po = sig.parameters['po']
3144        pod = sig2.parameters['pod']
3145        pk = sig.parameters['pk']
3146        pkd = sig.parameters['pkd']
3147        args = sig.parameters['args']
3148        ko = sig.parameters['ko']
3149        kod = sig.parameters['kod']
3150        kwargs = sig.parameters['kwargs']
3151
3152        S((po, pk, args, ko, kwargs))
3153        S((po, pk, ko, kod))
3154        S((po, pod, ko))
3155        S((po, pod, kod))
3156        S((pod, ko, kod))
3157        S((pod, kod))
3158        S((pod, args, kod, kwargs))
3159        # keyword-only parameters without default values
3160        # can follow keyword-only parameters with default values:
3161        S((kod, ko))
3162        S((kod, ko, kwargs))
3163        S((args, kod, ko))
3164
3165        with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
3166            S((pk, po, args, ko, kwargs))
3167
3168        with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
3169            S((po, args, pk, ko, kwargs))
3170
3171        with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
3172            S((args, po, pk, ko, kwargs))
3173
3174        with self.assertRaisesRegex(ValueError, 'wrong parameter order'):
3175            S((po, pk, args, kwargs, ko))
3176
3177        kwargs2 = kwargs.replace(name='args')
3178        with self.assertRaisesRegex(ValueError, 'duplicate parameter name'):
3179            S((po, pk, args, kwargs2, ko))
3180
3181        with self.assertRaisesRegex(ValueError, 'follows default argument'):
3182            S((pod, po))
3183
3184        with self.assertRaisesRegex(ValueError, 'follows default argument'):
3185            S((pod, pk))
3186
3187        with self.assertRaisesRegex(ValueError, 'follows default argument'):
3188            S((po, pod, pk))
3189
3190        with self.assertRaisesRegex(ValueError, 'follows default argument'):
3191            S((po, pkd, pk))
3192
3193        with self.assertRaisesRegex(ValueError, 'follows default argument'):
3194            S((pkd, pk))
3195
3196    def test_signature_object_pickle(self):
3197        def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
3198        foo_partial = functools.partial(foo, a=1)
3199
3200        sig = inspect.signature(foo_partial)
3201
3202        for ver in range(pickle.HIGHEST_PROTOCOL + 1):
3203            with self.subTest(pickle_ver=ver, subclass=False):
3204                sig_pickled = pickle.loads(pickle.dumps(sig, ver))
3205                self.assertEqual(sig, sig_pickled)
3206
3207        # Test that basic sub-classing works
3208        sig = inspect.signature(foo)
3209        myparam = MyParameter(name='z', kind=inspect.Parameter.POSITIONAL_ONLY)
3210        myparams = collections.OrderedDict(sig.parameters, a=myparam)
3211        mysig = MySignature().replace(parameters=myparams.values(),
3212                                      return_annotation=sig.return_annotation)
3213        self.assertTrue(isinstance(mysig, MySignature))
3214        self.assertTrue(isinstance(mysig.parameters['z'], MyParameter))
3215
3216        for ver in range(pickle.HIGHEST_PROTOCOL + 1):
3217            with self.subTest(pickle_ver=ver, subclass=True):
3218                sig_pickled = pickle.loads(pickle.dumps(mysig, ver))
3219                self.assertEqual(mysig, sig_pickled)
3220                self.assertTrue(isinstance(sig_pickled, MySignature))
3221                self.assertTrue(isinstance(sig_pickled.parameters['z'],
3222                                           MyParameter))
3223
3224    def test_signature_immutability(self):
3225        def test(a):
3226            pass
3227        sig = inspect.signature(test)
3228
3229        with self.assertRaises(AttributeError):
3230            sig.foo = 'bar'
3231
3232        with self.assertRaises(TypeError):
3233            sig.parameters['a'] = None
3234
3235    def test_signature_on_noarg(self):
3236        def test():
3237            pass
3238        self.assertEqual(self.signature(test), ((), ...))
3239
3240    def test_signature_on_wargs(self):
3241        def test(a, b:'foo') -> 123:
3242            pass
3243        self.assertEqual(self.signature(test),
3244                         ((('a', ..., ..., "positional_or_keyword"),
3245                           ('b', ..., 'foo', "positional_or_keyword")),
3246                          123))
3247
3248    def test_signature_on_wkwonly(self):
3249        def test(*, a:float, b:str) -> int:
3250            pass
3251        self.assertEqual(self.signature(test),
3252                         ((('a', ..., float, "keyword_only"),
3253                           ('b', ..., str, "keyword_only")),
3254                           int))
3255
3256    def test_signature_on_complex_args(self):
3257        def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int):
3258            pass
3259        self.assertEqual(self.signature(test),
3260                         ((('a', ..., ..., "positional_or_keyword"),
3261                           ('b', 10, 'foo', "positional_or_keyword"),
3262                           ('args', ..., 'bar', "var_positional"),
3263                           ('spam', ..., 'baz', "keyword_only"),
3264                           ('ham', 123, ..., "keyword_only"),
3265                           ('kwargs', ..., int, "var_keyword")),
3266                          ...))
3267
3268    def test_signature_without_self(self):
3269        def test_args_only(*args):  # NOQA
3270            pass
3271
3272        def test_args_kwargs_only(*args, **kwargs):  # NOQA
3273            pass
3274
3275        class A:
3276            @classmethod
3277            def test_classmethod(*args):  # NOQA
3278                pass
3279
3280            @staticmethod
3281            def test_staticmethod(*args):  # NOQA
3282                pass
3283
3284            f1 = functools.partialmethod((test_classmethod), 1)
3285            f2 = functools.partialmethod((test_args_only), 1)
3286            f3 = functools.partialmethod((test_staticmethod), 1)
3287            f4 = functools.partialmethod((test_args_kwargs_only),1)
3288
3289        self.assertEqual(self.signature(test_args_only),
3290                         ((('args', ..., ..., 'var_positional'),), ...))
3291        self.assertEqual(self.signature(test_args_kwargs_only),
3292                         ((('args', ..., ..., 'var_positional'),
3293                           ('kwargs', ..., ..., 'var_keyword')), ...))
3294        self.assertEqual(self.signature(A.f1),
3295                         ((('args', ..., ..., 'var_positional'),), ...))
3296        self.assertEqual(self.signature(A.f2),
3297                         ((('args', ..., ..., 'var_positional'),), ...))
3298        self.assertEqual(self.signature(A.f3),
3299                         ((('args', ..., ..., 'var_positional'),), ...))
3300        self.assertEqual(self.signature(A.f4),
3301                         ((('args', ..., ..., 'var_positional'),
3302                            ('kwargs', ..., ..., 'var_keyword')), ...))
3303    @cpython_only
3304    @unittest.skipIf(MISSING_C_DOCSTRINGS,
3305                     "Signature information for builtins requires docstrings")
3306    def test_signature_on_builtins(self):
3307        _testcapi = import_helper.import_module("_testcapi")
3308
3309        def test_unbound_method(o):
3310            """Use this to test unbound methods (things that should have a self)"""
3311            signature = inspect.signature(o)
3312            self.assertTrue(isinstance(signature, inspect.Signature))
3313            self.assertEqual(list(signature.parameters.values())[0].name, 'self')
3314            return signature
3315
3316        def test_callable(o):
3317            """Use this to test bound methods or normal callables (things that don't expect self)"""
3318            signature = inspect.signature(o)
3319            self.assertTrue(isinstance(signature, inspect.Signature))
3320            if signature.parameters:
3321                self.assertNotEqual(list(signature.parameters.values())[0].name, 'self')
3322            return signature
3323
3324        signature = test_callable(_testcapi.docstring_with_signature_with_defaults)
3325        def p(name): return signature.parameters[name].default
3326        self.assertEqual(p('s'), 'avocado')
3327        self.assertEqual(p('b'), b'bytes')
3328        self.assertEqual(p('d'), 3.14)
3329        self.assertEqual(p('i'), 35)
3330        self.assertEqual(p('n'), None)
3331        self.assertEqual(p('t'), True)
3332        self.assertEqual(p('f'), False)
3333        self.assertEqual(p('local'), 3)
3334        self.assertEqual(p('sys'), sys.maxsize)
3335        self.assertEqual(p('exp'), sys.maxsize - 1)
3336
3337        test_callable(object)
3338
3339        # normal method
3340        # (PyMethodDescr_Type, "method_descriptor")
3341        test_unbound_method(_pickle.Pickler.dump)
3342        d = _pickle.Pickler(io.StringIO())
3343        test_callable(d.dump)
3344
3345        # static method
3346        test_callable(bytes.maketrans)
3347        test_callable(b'abc'.maketrans)
3348
3349        # class method
3350        test_callable(dict.fromkeys)
3351        test_callable({}.fromkeys)
3352
3353        # wrapper around slot (PyWrapperDescr_Type, "wrapper_descriptor")
3354        test_unbound_method(type.__call__)
3355        test_unbound_method(int.__add__)
3356        test_callable((3).__add__)
3357
3358        # _PyMethodWrapper_Type
3359        # support for 'method-wrapper'
3360        test_callable(min.__call__)
3361
3362        # This doesn't work now.
3363        # (We don't have a valid signature for "type" in 3.4)
3364        class ThisWorksNow:
3365            __call__ = type
3366        # TODO: Support type.
3367        self.assertEqual(ThisWorksNow()(1), int)
3368        self.assertEqual(ThisWorksNow()('A', (), {}).__name__, 'A')
3369        with self.assertRaisesRegex(ValueError, "no signature found"):
3370            test_callable(ThisWorksNow())
3371
3372        # Regression test for issue #20786
3373        test_unbound_method(dict.__delitem__)
3374        test_unbound_method(property.__delete__)
3375
3376        # Regression test for issue #20586
3377        test_callable(_testcapi.docstring_with_signature_but_no_doc)
3378
3379        # Regression test for gh-104955
3380        method = bytearray.__release_buffer__
3381        sig = test_unbound_method(method)
3382        self.assertEqual(list(sig.parameters), ['self', 'buffer'])
3383
3384    @cpython_only
3385    @unittest.skipIf(MISSING_C_DOCSTRINGS,
3386                     "Signature information for builtins requires docstrings")
3387    def test_signature_on_decorated_builtins(self):
3388        _testcapi = import_helper.import_module("_testcapi")
3389        func = _testcapi.docstring_with_signature_with_defaults
3390
3391        def decorator(func):
3392            @functools.wraps(func)
3393            def wrapper(*args, **kwargs) -> int:
3394                return func(*args, **kwargs)
3395            return wrapper
3396
3397        decorated_func = decorator(func)
3398
3399        self.assertEqual(inspect.signature(func),
3400                         inspect.signature(decorated_func))
3401
3402        def wrapper_like(*args, **kwargs) -> int: pass
3403        self.assertEqual(inspect.signature(decorated_func,
3404                                           follow_wrapped=False),
3405                         inspect.signature(wrapper_like))
3406
3407    @cpython_only
3408    def test_signature_on_builtins_no_signature(self):
3409        _testcapi = import_helper.import_module("_testcapi")
3410        with self.assertRaisesRegex(ValueError,
3411                                    'no signature found for builtin'):
3412            inspect.signature(_testcapi.docstring_no_signature)
3413
3414        with self.assertRaisesRegex(ValueError,
3415                                    'no signature found for builtin'):
3416            inspect.signature(str)
3417
3418        cls = _testcapi.DocStringNoSignatureTest
3419        obj = _testcapi.DocStringNoSignatureTest()
3420        tests = [
3421            (_testcapi.docstring_no_signature_noargs, meth_noargs),
3422            (_testcapi.docstring_no_signature_o, meth_o),
3423            (cls.meth_noargs, meth_self_noargs),
3424            (cls.meth_o, meth_self_o),
3425            (obj.meth_noargs, meth_noargs),
3426            (obj.meth_o, meth_o),
3427            (cls.meth_noargs_class, meth_noargs),
3428            (cls.meth_o_class, meth_o),
3429            (cls.meth_noargs_static, meth_noargs),
3430            (cls.meth_o_static, meth_o),
3431            (cls.meth_noargs_coexist, meth_self_noargs),
3432            (cls.meth_o_coexist, meth_self_o),
3433
3434            (time.time, meth_noargs),
3435            (str.lower, meth_self_noargs),
3436            (''.lower, meth_noargs),
3437            (set.add, meth_self_o),
3438            (set().add, meth_o),
3439            (set.__contains__, meth_self_o),
3440            (set().__contains__, meth_o),
3441            (datetime.datetime.__dict__['utcnow'], meth_type_noargs),
3442            (datetime.datetime.utcnow, meth_noargs),
3443            (dict.__dict__['__class_getitem__'], meth_type_o),
3444            (dict.__class_getitem__, meth_o),
3445        ]
3446        try:
3447            import _stat
3448        except ImportError:
3449            # if the _stat extension is not available, stat.S_IMODE() is
3450            # implemented in Python, not in C
3451            pass
3452        else:
3453            tests.append((stat.S_IMODE, meth_o))
3454        for builtin, template in tests:
3455            with self.subTest(builtin):
3456                self.assertEqual(inspect.signature(builtin),
3457                                 inspect.signature(template))
3458
3459    @unittest.skipIf(MISSING_C_DOCSTRINGS,
3460                     "Signature information for builtins requires docstrings")
3461    def test_signature_parsing_with_defaults(self):
3462        _testcapi = import_helper.import_module("_testcapi")
3463        meth = _testcapi.DocStringUnrepresentableSignatureTest.with_default
3464        self.assertEqual(str(inspect.signature(meth)), '(self, /, x=1)')
3465
3466    def test_signature_on_non_function(self):
3467        with self.assertRaisesRegex(TypeError, 'is not a callable object'):
3468            inspect.signature(42)
3469
3470    def test_signature_from_functionlike_object(self):
3471        def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
3472            pass
3473
3474        class funclike:
3475            # Has to be callable, and have correct
3476            # __code__, __annotations__, __defaults__, __name__,
3477            # and __kwdefaults__ attributes
3478
3479            def __init__(self, func):
3480                self.__name__ = func.__name__
3481                self.__code__ = func.__code__
3482                self.__annotations__ = func.__annotations__
3483                self.__defaults__ = func.__defaults__
3484                self.__kwdefaults__ = func.__kwdefaults__
3485                self.func = func
3486
3487            def __call__(self, *args, **kwargs):
3488                return self.func(*args, **kwargs)
3489
3490        sig_func = inspect.Signature.from_callable(func)
3491
3492        sig_funclike = inspect.Signature.from_callable(funclike(func))
3493        self.assertEqual(sig_funclike, sig_func)
3494
3495        sig_funclike = inspect.signature(funclike(func))
3496        self.assertEqual(sig_funclike, sig_func)
3497
3498        # If object is not a duck type of function, then
3499        # signature will try to get a signature for its '__call__'
3500        # method
3501        fl = funclike(func)
3502        del fl.__defaults__
3503        self.assertEqual(self.signature(fl),
3504                         ((('args', ..., ..., "var_positional"),
3505                           ('kwargs', ..., ..., "var_keyword")),
3506                           ...))
3507
3508        # Test with cython-like builtins:
3509        _orig_isdesc = inspect.ismethoddescriptor
3510        def _isdesc(obj):
3511            if hasattr(obj, '_builtinmock'):
3512                return True
3513            return _orig_isdesc(obj)
3514
3515        with unittest.mock.patch('inspect.ismethoddescriptor', _isdesc):
3516            builtin_func = funclike(func)
3517            # Make sure that our mock setup is working
3518            self.assertFalse(inspect.ismethoddescriptor(builtin_func))
3519            builtin_func._builtinmock = True
3520            self.assertTrue(inspect.ismethoddescriptor(builtin_func))
3521            self.assertEqual(inspect.signature(builtin_func), sig_func)
3522
3523    def test_signature_functionlike_class(self):
3524        # We only want to duck type function-like objects,
3525        # not classes.
3526
3527        def func(a,b, *args, kwonly=True, kwonlyreq, **kwargs):
3528            pass
3529
3530        class funclike:
3531            def __init__(self, marker):
3532                pass
3533
3534            __name__ = func.__name__
3535            __code__ = func.__code__
3536            __annotations__ = func.__annotations__
3537            __defaults__ = func.__defaults__
3538            __kwdefaults__ = func.__kwdefaults__
3539
3540        self.assertEqual(str(inspect.signature(funclike)), '(marker)')
3541
3542    def test_signature_on_method(self):
3543        class Test:
3544            def __init__(*args):
3545                pass
3546            def m1(self, arg1, arg2=1) -> int:
3547                pass
3548            def m2(*args):
3549                pass
3550            def __call__(*, a):
3551                pass
3552
3553        self.assertEqual(self.signature(Test().m1),
3554                         ((('arg1', ..., ..., "positional_or_keyword"),
3555                           ('arg2', 1, ..., "positional_or_keyword")),
3556                          int))
3557
3558        self.assertEqual(self.signature(Test().m2),
3559                         ((('args', ..., ..., "var_positional"),),
3560                          ...))
3561
3562        self.assertEqual(self.signature(Test),
3563                         ((('args', ..., ..., "var_positional"),),
3564                          ...))
3565
3566        with self.assertRaisesRegex(ValueError, 'invalid method signature'):
3567            self.signature(Test())
3568
3569    def test_signature_wrapped_bound_method(self):
3570        # Issue 24298
3571        class Test:
3572            def m1(self, arg1, arg2=1) -> int:
3573                pass
3574        @functools.wraps(Test().m1)
3575        def m1d(*args, **kwargs):
3576            pass
3577        self.assertEqual(self.signature(m1d),
3578                         ((('arg1', ..., ..., "positional_or_keyword"),
3579                           ('arg2', 1, ..., "positional_or_keyword")),
3580                          int))
3581
3582    def test_signature_on_classmethod(self):
3583        self.assertEqual(self.signature(classmethod),
3584                         ((('function', ..., ..., "positional_only"),),
3585                          ...))
3586
3587        class Test:
3588            @classmethod
3589            def foo(cls, arg1, *, arg2=1):
3590                pass
3591
3592        meth = Test().foo
3593        self.assertEqual(self.signature(meth),
3594                         ((('arg1', ..., ..., "positional_or_keyword"),
3595                           ('arg2', 1, ..., "keyword_only")),
3596                          ...))
3597
3598        meth = Test.foo
3599        self.assertEqual(self.signature(meth),
3600                         ((('arg1', ..., ..., "positional_or_keyword"),
3601                           ('arg2', 1, ..., "keyword_only")),
3602                          ...))
3603
3604    def test_signature_on_staticmethod(self):
3605        self.assertEqual(self.signature(staticmethod),
3606                         ((('function', ..., ..., "positional_only"),),
3607                          ...))
3608
3609        class Test:
3610            @staticmethod
3611            def foo(cls, *, arg):
3612                pass
3613
3614        meth = Test().foo
3615        self.assertEqual(self.signature(meth),
3616                         ((('cls', ..., ..., "positional_or_keyword"),
3617                           ('arg', ..., ..., "keyword_only")),
3618                          ...))
3619
3620        meth = Test.foo
3621        self.assertEqual(self.signature(meth),
3622                         ((('cls', ..., ..., "positional_or_keyword"),
3623                           ('arg', ..., ..., "keyword_only")),
3624                          ...))
3625
3626    def test_signature_on_partial(self):
3627        from functools import partial
3628
3629        def test():
3630            pass
3631
3632        self.assertEqual(self.signature(partial(test)), ((), ...))
3633
3634        with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
3635            inspect.signature(partial(test, 1))
3636
3637        with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
3638            inspect.signature(partial(test, a=1))
3639
3640        def test(a, b, *, c, d):
3641            pass
3642
3643        self.assertEqual(self.signature(partial(test)),
3644                         ((('a', ..., ..., "positional_or_keyword"),
3645                           ('b', ..., ..., "positional_or_keyword"),
3646                           ('c', ..., ..., "keyword_only"),
3647                           ('d', ..., ..., "keyword_only")),
3648                          ...))
3649
3650        self.assertEqual(self.signature(partial(test, 1)),
3651                         ((('b', ..., ..., "positional_or_keyword"),
3652                           ('c', ..., ..., "keyword_only"),
3653                           ('d', ..., ..., "keyword_only")),
3654                          ...))
3655
3656        self.assertEqual(self.signature(partial(test, 1, c=2)),
3657                         ((('b', ..., ..., "positional_or_keyword"),
3658                           ('c', 2, ..., "keyword_only"),
3659                           ('d', ..., ..., "keyword_only")),
3660                          ...))
3661
3662        self.assertEqual(self.signature(partial(test, b=1, c=2)),
3663                         ((('a', ..., ..., "positional_or_keyword"),
3664                           ('b', 1, ..., "keyword_only"),
3665                           ('c', 2, ..., "keyword_only"),
3666                           ('d', ..., ..., "keyword_only")),
3667                          ...))
3668
3669        self.assertEqual(self.signature(partial(test, 0, b=1, c=2)),
3670                         ((('b', 1, ..., "keyword_only"),
3671                           ('c', 2, ..., "keyword_only"),
3672                           ('d', ..., ..., "keyword_only")),
3673                          ...))
3674
3675        self.assertEqual(self.signature(partial(test, a=1)),
3676                         ((('a', 1, ..., "keyword_only"),
3677                           ('b', ..., ..., "keyword_only"),
3678                           ('c', ..., ..., "keyword_only"),
3679                           ('d', ..., ..., "keyword_only")),
3680                          ...))
3681
3682        def test(a, *args, b, **kwargs):
3683            pass
3684
3685        self.assertEqual(self.signature(partial(test, 1)),
3686                         ((('args', ..., ..., "var_positional"),
3687                           ('b', ..., ..., "keyword_only"),
3688                           ('kwargs', ..., ..., "var_keyword")),
3689                          ...))
3690
3691        self.assertEqual(self.signature(partial(test, a=1)),
3692                         ((('a', 1, ..., "keyword_only"),
3693                           ('b', ..., ..., "keyword_only"),
3694                           ('kwargs', ..., ..., "var_keyword")),
3695                          ...))
3696
3697        self.assertEqual(self.signature(partial(test, 1, 2, 3)),
3698                         ((('args', ..., ..., "var_positional"),
3699                           ('b', ..., ..., "keyword_only"),
3700                           ('kwargs', ..., ..., "var_keyword")),
3701                          ...))
3702
3703        self.assertEqual(self.signature(partial(test, 1, 2, 3, test=True)),
3704                         ((('args', ..., ..., "var_positional"),
3705                           ('b', ..., ..., "keyword_only"),
3706                           ('kwargs', ..., ..., "var_keyword")),
3707                          ...))
3708
3709        self.assertEqual(self.signature(partial(test, 1, 2, 3, test=1, b=0)),
3710                         ((('args', ..., ..., "var_positional"),
3711                           ('b', 0, ..., "keyword_only"),
3712                           ('kwargs', ..., ..., "var_keyword")),
3713                          ...))
3714
3715        self.assertEqual(self.signature(partial(test, b=0)),
3716                         ((('a', ..., ..., "positional_or_keyword"),
3717                           ('args', ..., ..., "var_positional"),
3718                           ('b', 0, ..., "keyword_only"),
3719                           ('kwargs', ..., ..., "var_keyword")),
3720                          ...))
3721
3722        self.assertEqual(self.signature(partial(test, b=0, test=1)),
3723                         ((('a', ..., ..., "positional_or_keyword"),
3724                           ('args', ..., ..., "var_positional"),
3725                           ('b', 0, ..., "keyword_only"),
3726                           ('kwargs', ..., ..., "var_keyword")),
3727                          ...))
3728
3729        def test(a, b, c:int) -> 42:
3730            pass
3731
3732        sig = test.__signature__ = inspect.signature(test)
3733
3734        self.assertEqual(self.signature(partial(partial(test, 1))),
3735                         ((('b', ..., ..., "positional_or_keyword"),
3736                           ('c', ..., int, "positional_or_keyword")),
3737                          42))
3738
3739        self.assertEqual(self.signature(partial(partial(test, 1), 2)),
3740                         ((('c', ..., int, "positional_or_keyword"),),
3741                          42))
3742
3743        def foo(a):
3744            return a
3745        _foo = partial(partial(foo, a=10), a=20)
3746        self.assertEqual(self.signature(_foo),
3747                         ((('a', 20, ..., "keyword_only"),),
3748                          ...))
3749        # check that we don't have any side-effects in signature(),
3750        # and the partial object is still functioning
3751        self.assertEqual(_foo(), 20)
3752
3753        def foo(a, b, c):
3754            return a, b, c
3755        _foo = partial(partial(foo, 1, b=20), b=30)
3756
3757        self.assertEqual(self.signature(_foo),
3758                         ((('b', 30, ..., "keyword_only"),
3759                           ('c', ..., ..., "keyword_only")),
3760                          ...))
3761        self.assertEqual(_foo(c=10), (1, 30, 10))
3762
3763        def foo(a, b, c, *, d):
3764            return a, b, c, d
3765        _foo = partial(partial(foo, d=20, c=20), b=10, d=30)
3766        self.assertEqual(self.signature(_foo),
3767                         ((('a', ..., ..., "positional_or_keyword"),
3768                           ('b', 10, ..., "keyword_only"),
3769                           ('c', 20, ..., "keyword_only"),
3770                           ('d', 30, ..., "keyword_only"),
3771                           ),
3772                          ...))
3773        ba = inspect.signature(_foo).bind(a=200, b=11)
3774        self.assertEqual(_foo(*ba.args, **ba.kwargs), (200, 11, 20, 30))
3775
3776        def foo(a=1, b=2, c=3):
3777            return a, b, c
3778        _foo = partial(foo, c=13) # (a=1, b=2, *, c=13)
3779
3780        ba = inspect.signature(_foo).bind(a=11)
3781        self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 2, 13))
3782
3783        ba = inspect.signature(_foo).bind(11, 12)
3784        self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
3785
3786        ba = inspect.signature(_foo).bind(11, b=12)
3787        self.assertEqual(_foo(*ba.args, **ba.kwargs), (11, 12, 13))
3788
3789        ba = inspect.signature(_foo).bind(b=12)
3790        self.assertEqual(_foo(*ba.args, **ba.kwargs), (1, 12, 13))
3791
3792        _foo = partial(_foo, b=10, c=20)
3793        ba = inspect.signature(_foo).bind(12)
3794        self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 10, 20))
3795
3796
3797        def foo(a, b, /, c, d, **kwargs):
3798            pass
3799        sig = inspect.signature(foo)
3800        self.assertEqual(str(sig), '(a, b, /, c, d, **kwargs)')
3801
3802        self.assertEqual(self.signature(partial(foo, 1)),
3803                         ((('b', ..., ..., 'positional_only'),
3804                           ('c', ..., ..., 'positional_or_keyword'),
3805                           ('d', ..., ..., 'positional_or_keyword'),
3806                           ('kwargs', ..., ..., 'var_keyword')),
3807                         ...))
3808
3809        self.assertEqual(self.signature(partial(foo, 1, 2)),
3810                         ((('c', ..., ..., 'positional_or_keyword'),
3811                           ('d', ..., ..., 'positional_or_keyword'),
3812                           ('kwargs', ..., ..., 'var_keyword')),
3813                         ...))
3814
3815        self.assertEqual(self.signature(partial(foo, 1, 2, 3)),
3816                         ((('d', ..., ..., 'positional_or_keyword'),
3817                           ('kwargs', ..., ..., 'var_keyword')),
3818                         ...))
3819
3820        self.assertEqual(self.signature(partial(foo, 1, 2, c=3)),
3821                         ((('c', 3, ..., 'keyword_only'),
3822                           ('d', ..., ..., 'keyword_only'),
3823                           ('kwargs', ..., ..., 'var_keyword')),
3824                         ...))
3825
3826        self.assertEqual(self.signature(partial(foo, 1, c=3)),
3827                         ((('b', ..., ..., 'positional_only'),
3828                           ('c', 3, ..., 'keyword_only'),
3829                           ('d', ..., ..., 'keyword_only'),
3830                           ('kwargs', ..., ..., 'var_keyword')),
3831                         ...))
3832
3833    def test_signature_on_partialmethod(self):
3834        from functools import partialmethod
3835
3836        class Spam:
3837            def test():
3838                pass
3839            ham = partialmethod(test)
3840
3841        with self.assertRaisesRegex(ValueError, "has incorrect arguments"):
3842            inspect.signature(Spam.ham)
3843
3844        class Spam:
3845            def test(it, a, *, c) -> 'spam':
3846                pass
3847            ham = partialmethod(test, c=1)
3848
3849        self.assertEqual(self.signature(Spam.ham, eval_str=False),
3850                         ((('it', ..., ..., 'positional_or_keyword'),
3851                           ('a', ..., ..., 'positional_or_keyword'),
3852                           ('c', 1, ..., 'keyword_only')),
3853                          'spam'))
3854
3855        self.assertEqual(self.signature(Spam().ham, eval_str=False),
3856                         ((('a', ..., ..., 'positional_or_keyword'),
3857                           ('c', 1, ..., 'keyword_only')),
3858                          'spam'))
3859
3860        class Spam:
3861            def test(self: 'anno', x):
3862                pass
3863
3864            g = partialmethod(test, 1)
3865
3866        self.assertEqual(self.signature(Spam.g, eval_str=False),
3867                         ((('self', ..., 'anno', 'positional_or_keyword'),),
3868                          ...))
3869
3870    def test_signature_on_fake_partialmethod(self):
3871        def foo(a): pass
3872        foo.__partialmethod__ = 'spam'
3873        self.assertEqual(str(inspect.signature(foo)), '(a)')
3874
3875    def test_signature_on_decorated(self):
3876        def decorator(func):
3877            @functools.wraps(func)
3878            def wrapper(*args, **kwargs) -> int:
3879                return func(*args, **kwargs)
3880            return wrapper
3881
3882        class Foo:
3883            @decorator
3884            def bar(self, a, b):
3885                pass
3886
3887        bar = decorator(Foo().bar)
3888
3889        self.assertEqual(self.signature(Foo.bar),
3890                         ((('self', ..., ..., "positional_or_keyword"),
3891                           ('a', ..., ..., "positional_or_keyword"),
3892                           ('b', ..., ..., "positional_or_keyword")),
3893                          ...))
3894
3895        self.assertEqual(self.signature(Foo().bar),
3896                         ((('a', ..., ..., "positional_or_keyword"),
3897                           ('b', ..., ..., "positional_or_keyword")),
3898                          ...))
3899
3900        self.assertEqual(self.signature(Foo.bar, follow_wrapped=False),
3901                         ((('args', ..., ..., "var_positional"),
3902                           ('kwargs', ..., ..., "var_keyword")),
3903                          ...)) # functools.wraps will copy __annotations__
3904                                # from "func" to "wrapper", hence no
3905                                # return_annotation
3906
3907        self.assertEqual(self.signature(bar),
3908                         ((('a', ..., ..., "positional_or_keyword"),
3909                           ('b', ..., ..., "positional_or_keyword")),
3910                          ...))
3911
3912        # Test that we handle method wrappers correctly
3913        def decorator(func):
3914            @functools.wraps(func)
3915            def wrapper(*args, **kwargs) -> int:
3916                return func(42, *args, **kwargs)
3917            sig = inspect.signature(func)
3918            new_params = tuple(sig.parameters.values())[1:]
3919            wrapper.__signature__ = sig.replace(parameters=new_params)
3920            return wrapper
3921
3922        class Foo:
3923            @decorator
3924            def __call__(self, a, b):
3925                pass
3926
3927        self.assertEqual(self.signature(Foo.__call__),
3928                         ((('a', ..., ..., "positional_or_keyword"),
3929                           ('b', ..., ..., "positional_or_keyword")),
3930                          ...))
3931
3932        self.assertEqual(self.signature(Foo().__call__),
3933                         ((('b', ..., ..., "positional_or_keyword"),),
3934                          ...))
3935
3936        # Test we handle __signature__ partway down the wrapper stack
3937        def wrapped_foo_call():
3938            pass
3939        wrapped_foo_call.__wrapped__ = Foo.__call__
3940
3941        self.assertEqual(self.signature(wrapped_foo_call),
3942                         ((('a', ..., ..., "positional_or_keyword"),
3943                           ('b', ..., ..., "positional_or_keyword")),
3944                          ...))
3945
3946
3947    def test_signature_on_class(self):
3948        class C:
3949            def __init__(self, a):
3950                pass
3951
3952        self.assertEqual(self.signature(C),
3953                         ((('a', ..., ..., "positional_or_keyword"),),
3954                          ...))
3955
3956        class CM(type):
3957            def __call__(cls, a):
3958                pass
3959        class C(metaclass=CM):
3960            def __init__(self, b):
3961                pass
3962
3963        self.assertEqual(self.signature(C),
3964                         ((('a', ..., ..., "positional_or_keyword"),),
3965                          ...))
3966
3967        with self.subTest('classmethod'):
3968            class CM(type):
3969                @classmethod
3970                def __call__(cls, a):
3971                    return a
3972            class C(metaclass=CM):
3973                def __init__(self, b):
3974                    pass
3975
3976            self.assertEqual(C(1), 1)
3977            self.assertEqual(self.signature(C),
3978                            ((('a', ..., ..., "positional_or_keyword"),),
3979                            ...))
3980
3981        with self.subTest('staticmethod'):
3982            class CM(type):
3983                @staticmethod
3984                def __call__(a):
3985                    return a
3986            class C(metaclass=CM):
3987                def __init__(self, b):
3988                    pass
3989
3990            self.assertEqual(C(1), 1)
3991            self.assertEqual(self.signature(C),
3992                            ((('a', ..., ..., "positional_or_keyword"),),
3993                            ...))
3994
3995        with self.subTest('MethodType'):
3996            class A:
3997                def call(self, a):
3998                    return a
3999            class CM(type):
4000                __call__ = A().call
4001            class C(metaclass=CM):
4002                def __init__(self, b):
4003                    pass
4004
4005            self.assertEqual(C(1), 1)
4006            self.assertEqual(self.signature(C),
4007                            ((('a', ..., ..., "positional_or_keyword"),),
4008                            ...))
4009
4010        with self.subTest('partial'):
4011            class CM(type):
4012                __call__ = functools.partial(lambda x, a: (x, a), 2)
4013            class C(metaclass=CM):
4014                def __init__(self, b):
4015                    pass
4016
4017            with self.assertWarns(FutureWarning):
4018                self.assertEqual(C(1), (2, 1))
4019            with self.assertWarns(FutureWarning):
4020                self.assertEqual(self.signature(C),
4021                                ((('a', ..., ..., "positional_or_keyword"),),
4022                                ...))
4023
4024        with self.subTest('partialmethod'):
4025            class CM(type):
4026                __call__ = functools.partialmethod(lambda self, x, a: (x, a), 2)
4027            class C(metaclass=CM):
4028                def __init__(self, b):
4029                    pass
4030
4031            self.assertEqual(C(1), (2, 1))
4032            self.assertEqual(self.signature(C),
4033                            ((('a', ..., ..., "positional_or_keyword"),),
4034                            ...))
4035
4036        with self.subTest('BuiltinMethodType'):
4037            class CM(type):
4038                __call__ = ':'.join
4039            class C(metaclass=CM):
4040                def __init__(self, b):
4041                    pass
4042
4043            self.assertEqual(C(['a', 'bc']), 'a:bc')
4044            # BUG: Returns '<Signature (b)>'
4045            with self.assertRaises(AssertionError):
4046                self.assertEqual(self.signature(C), self.signature(''.join))
4047
4048        with self.subTest('MethodWrapperType'):
4049            class CM(type):
4050                __call__ = (2).__pow__
4051            class C(metaclass=CM):
4052                def __init__(self, b):
4053                    pass
4054
4055            self.assertEqual(C(3), 8)
4056            self.assertEqual(C(3, 7), 1)
4057            # BUG: Returns '<Signature (b)>'
4058            with self.assertRaises(AssertionError):
4059                self.assertEqual(self.signature(C), self.signature((0).__pow__))
4060
4061        class CM(type):
4062            def __new__(mcls, name, bases, dct, *, foo=1):
4063                return super().__new__(mcls, name, bases, dct)
4064        class C(metaclass=CM):
4065            def __init__(self, b):
4066                pass
4067
4068        self.assertEqual(self.signature(C),
4069                         ((('b', ..., ..., "positional_or_keyword"),),
4070                          ...))
4071
4072        self.assertEqual(self.signature(CM),
4073                         ((('name', ..., ..., "positional_or_keyword"),
4074                           ('bases', ..., ..., "positional_or_keyword"),
4075                           ('dct', ..., ..., "positional_or_keyword"),
4076                           ('foo', 1, ..., "keyword_only")),
4077                          ...))
4078
4079        class CMM(type):
4080            def __new__(mcls, name, bases, dct, *, foo=1):
4081                return super().__new__(mcls, name, bases, dct)
4082            def __call__(cls, nm, bs, dt):
4083                return type(nm, bs, dt)
4084        class CM(type, metaclass=CMM):
4085            def __new__(mcls, name, bases, dct, *, bar=2):
4086                return super().__new__(mcls, name, bases, dct)
4087        class C(metaclass=CM):
4088            def __init__(self, b):
4089                pass
4090
4091        self.assertEqual(self.signature(CMM),
4092                         ((('name', ..., ..., "positional_or_keyword"),
4093                           ('bases', ..., ..., "positional_or_keyword"),
4094                           ('dct', ..., ..., "positional_or_keyword"),
4095                           ('foo', 1, ..., "keyword_only")),
4096                          ...))
4097
4098        self.assertEqual(self.signature(CM),
4099                         ((('nm', ..., ..., "positional_or_keyword"),
4100                           ('bs', ..., ..., "positional_or_keyword"),
4101                           ('dt', ..., ..., "positional_or_keyword")),
4102                          ...))
4103
4104        self.assertEqual(self.signature(C),
4105                         ((('b', ..., ..., "positional_or_keyword"),),
4106                          ...))
4107
4108        class CM(type):
4109            def __init__(cls, name, bases, dct, *, bar=2):
4110                return super().__init__(name, bases, dct)
4111        class C(metaclass=CM):
4112            def __init__(self, b):
4113                pass
4114
4115        self.assertEqual(self.signature(CM),
4116                         ((('name', ..., ..., "positional_or_keyword"),
4117                           ('bases', ..., ..., "positional_or_keyword"),
4118                           ('dct', ..., ..., "positional_or_keyword"),
4119                           ('bar', 2, ..., "keyword_only")),
4120                          ...))
4121
4122    def test_signature_on_class_with_init(self):
4123        class C:
4124            def __init__(self, b):
4125                pass
4126
4127        C(1)  # does not raise
4128        self.assertEqual(self.signature(C),
4129                        ((('b', ..., ..., "positional_or_keyword"),),
4130                        ...))
4131
4132        with self.subTest('classmethod'):
4133            class C:
4134                @classmethod
4135                def __init__(cls, b):
4136                    pass
4137
4138            C(1)  # does not raise
4139            self.assertEqual(self.signature(C),
4140                            ((('b', ..., ..., "positional_or_keyword"),),
4141                            ...))
4142
4143        with self.subTest('staticmethod'):
4144            class C:
4145                @staticmethod
4146                def __init__(b):
4147                    pass
4148
4149            C(1)  # does not raise
4150            self.assertEqual(self.signature(C),
4151                            ((('b', ..., ..., "positional_or_keyword"),),
4152                            ...))
4153
4154        with self.subTest('MethodType'):
4155            class A:
4156                def call(self, a):
4157                    pass
4158            class C:
4159                __init__ = A().call
4160
4161            C(1)  # does not raise
4162            self.assertEqual(self.signature(C),
4163                            ((('a', ..., ..., "positional_or_keyword"),),
4164                            ...))
4165
4166        with self.subTest('partial'):
4167            class C:
4168                __init__ = functools.partial(lambda x, a: None, 2)
4169
4170            with self.assertWarns(FutureWarning):
4171                C(1)  # does not raise
4172            with self.assertWarns(FutureWarning):
4173                self.assertEqual(self.signature(C),
4174                                ((('a', ..., ..., "positional_or_keyword"),),
4175                                ...))
4176
4177        with self.subTest('partialmethod'):
4178            class C:
4179                def _init(self, x, a):
4180                    self.a = (x, a)
4181                __init__ = functools.partialmethod(_init, 2)
4182
4183            self.assertEqual(C(1).a, (2, 1))
4184            self.assertEqual(self.signature(C),
4185                            ((('a', ..., ..., "positional_or_keyword"),),
4186                            ...))
4187
4188    def test_signature_on_class_with_new(self):
4189        with self.subTest('FunctionType'):
4190            class C:
4191                def __new__(cls, a):
4192                    return a
4193
4194            self.assertEqual(C(1), 1)
4195            self.assertEqual(self.signature(C),
4196                            ((('a', ..., ..., "positional_or_keyword"),),
4197                            ...))
4198
4199        with self.subTest('classmethod'):
4200            class C:
4201                @classmethod
4202                def __new__(cls, cls2, a):
4203                    return a
4204
4205            self.assertEqual(C(1), 1)
4206            self.assertEqual(self.signature(C),
4207                            ((('a', ..., ..., "positional_or_keyword"),),
4208                            ...))
4209
4210        with self.subTest('staticmethod'):
4211            class C:
4212                @staticmethod
4213                def __new__(cls, a):
4214                    return a
4215
4216            self.assertEqual(C(1), 1)
4217            self.assertEqual(self.signature(C),
4218                            ((('a', ..., ..., "positional_or_keyword"),),
4219                            ...))
4220
4221        with self.subTest('MethodType'):
4222            class A:
4223                def call(self, cls, a):
4224                    return a
4225            class C:
4226                __new__ = A().call
4227
4228            self.assertEqual(C(1), 1)
4229            self.assertEqual(self.signature(C),
4230                            ((('a', ..., ..., "positional_or_keyword"),),
4231                            ...))
4232
4233        with self.subTest('partial'):
4234            class C:
4235                __new__ = functools.partial(lambda x, cls, a: (x, a), 2)
4236
4237            self.assertEqual(C(1), (2, 1))
4238            self.assertEqual(self.signature(C),
4239                            ((('a', ..., ..., "positional_or_keyword"),),
4240                            ...))
4241
4242        with self.subTest('partialmethod'):
4243            class C:
4244                __new__ = functools.partialmethod(lambda cls, x, a: (x, a), 2)
4245
4246            self.assertEqual(C(1), (2, 1))
4247            self.assertEqual(self.signature(C),
4248                            ((('a', ..., ..., "positional_or_keyword"),),
4249                            ...))
4250
4251        with self.subTest('BuiltinMethodType'):
4252            class C:
4253                __new__ = str.__subclasscheck__
4254
4255            self.assertEqual(C(), False)
4256            # TODO: Support BuiltinMethodType
4257            # self.assertEqual(self.signature(C), ((), ...))
4258            self.assertRaises(ValueError, self.signature, C)
4259
4260        with self.subTest('MethodWrapperType'):
4261            class C:
4262                __new__ = type.__or__.__get__(int, type)
4263
4264            self.assertEqual(C(), C | int)
4265            # TODO: Support MethodWrapperType
4266            # self.assertEqual(self.signature(C), ((), ...))
4267            self.assertRaises(ValueError, self.signature, C)
4268
4269        # TODO: Test ClassMethodDescriptorType
4270
4271        with self.subTest('MethodDescriptorType'):
4272            class C:
4273                __new__ = type.__dict__['__subclasscheck__']
4274
4275            self.assertEqual(C(C), True)
4276            self.assertEqual(self.signature(C), self.signature(C.__subclasscheck__))
4277
4278        with self.subTest('WrapperDescriptorType'):
4279            class C:
4280                __new__ = type.__or__
4281
4282            self.assertEqual(C(int), C | int)
4283            # TODO: Support WrapperDescriptorType
4284            # self.assertEqual(self.signature(C), self.signature(C.__or__))
4285            self.assertRaises(ValueError, self.signature, C)
4286
4287    def test_signature_on_subclass(self):
4288        class A:
4289            def __new__(cls, a=1, *args, **kwargs):
4290                return object.__new__(cls)
4291        class B(A):
4292            def __init__(self, b):
4293                pass
4294        class C(A):
4295            def __new__(cls, a=1, b=2, *args, **kwargs):
4296                return object.__new__(cls)
4297        class D(A):
4298            pass
4299
4300        self.assertEqual(self.signature(B),
4301                         ((('b', ..., ..., "positional_or_keyword"),),
4302                          ...))
4303        self.assertEqual(self.signature(C),
4304                         ((('a', 1, ..., 'positional_or_keyword'),
4305                           ('b', 2, ..., 'positional_or_keyword'),
4306                           ('args', ..., ..., 'var_positional'),
4307                           ('kwargs', ..., ..., 'var_keyword')),
4308                          ...))
4309        self.assertEqual(self.signature(D),
4310                         ((('a', 1, ..., 'positional_or_keyword'),
4311                           ('args', ..., ..., 'var_positional'),
4312                           ('kwargs', ..., ..., 'var_keyword')),
4313                          ...))
4314
4315    def test_signature_on_generic_subclass(self):
4316        from typing import Generic, TypeVar
4317
4318        T = TypeVar('T')
4319
4320        class A(Generic[T]):
4321            def __init__(self, *, a: int) -> None:
4322                pass
4323
4324        self.assertEqual(self.signature(A),
4325                         ((('a', ..., int, 'keyword_only'),),
4326                          None))
4327
4328    @unittest.skipIf(MISSING_C_DOCSTRINGS,
4329                     "Signature information for builtins requires docstrings")
4330    def test_signature_on_class_without_init(self):
4331        # Test classes without user-defined __init__ or __new__
4332        class C: pass
4333        self.assertEqual(str(inspect.signature(C)), '()')
4334        class D(C): pass
4335        self.assertEqual(str(inspect.signature(D)), '()')
4336
4337        # Test meta-classes without user-defined __init__ or __new__
4338        class C(type): pass
4339        class D(C): pass
4340        self.assertEqual(C('A', (), {}).__name__, 'A')
4341        # TODO: Support type.
4342        with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
4343            self.assertEqual(inspect.signature(C), None)
4344        self.assertEqual(D('A', (), {}).__name__, 'A')
4345        with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
4346            self.assertEqual(inspect.signature(D), None)
4347
4348    @unittest.skipIf(MISSING_C_DOCSTRINGS,
4349                     "Signature information for builtins requires docstrings")
4350    def test_signature_on_builtin_class(self):
4351        expected = ('(file, protocol=None, fix_imports=True, '
4352                    'buffer_callback=None)')
4353        self.assertEqual(str(inspect.signature(_pickle.Pickler)), expected)
4354
4355        class P(_pickle.Pickler): pass
4356        class EmptyTrait: pass
4357        class P2(EmptyTrait, P): pass
4358        self.assertEqual(str(inspect.signature(P)), expected)
4359        self.assertEqual(str(inspect.signature(P2)), expected)
4360
4361        class P3(P2):
4362            def __init__(self, spam):
4363                pass
4364        self.assertEqual(str(inspect.signature(P3)), '(spam)')
4365
4366        class MetaP(type):
4367            def __call__(cls, foo, bar):
4368                pass
4369        class P4(P2, metaclass=MetaP):
4370            pass
4371        self.assertEqual(str(inspect.signature(P4)), '(foo, bar)')
4372
4373    def test_signature_on_callable_objects(self):
4374        class Foo:
4375            def __call__(self, a):
4376                pass
4377
4378        self.assertEqual(self.signature(Foo()),
4379                         ((('a', ..., ..., "positional_or_keyword"),),
4380                          ...))
4381
4382        class Spam:
4383            pass
4384        with self.assertRaisesRegex(TypeError, "is not a callable object"):
4385            inspect.signature(Spam())
4386
4387        class Bar(Spam, Foo):
4388            pass
4389
4390        self.assertEqual(self.signature(Bar()),
4391                         ((('a', ..., ..., "positional_or_keyword"),),
4392                          ...))
4393
4394        with self.subTest('classmethod'):
4395            class C:
4396                @classmethod
4397                def __call__(cls, a):
4398                    pass
4399
4400            self.assertEqual(self.signature(C()),
4401                            ((('a', ..., ..., "positional_or_keyword"),),
4402                            ...))
4403
4404        with self.subTest('staticmethod'):
4405            class C:
4406                @staticmethod
4407                def __call__(a):
4408                    pass
4409
4410            self.assertEqual(self.signature(C()),
4411                            ((('a', ..., ..., "positional_or_keyword"),),
4412                            ...))
4413
4414        with self.subTest('MethodType'):
4415            class A:
4416                def call(self, a):
4417                    return a
4418            class C:
4419                __call__ = A().call
4420
4421            self.assertEqual(C()(1), 1)
4422            self.assertEqual(self.signature(C()),
4423                            ((('a', ..., ..., "positional_or_keyword"),),
4424                            ...))
4425
4426        with self.subTest('partial'):
4427            class C:
4428                __call__ = functools.partial(lambda x, a: (x, a), 2)
4429
4430            c = C()
4431            with self.assertWarns(FutureWarning):
4432                self.assertEqual(c(1), (2, 1))
4433            with self.assertWarns(FutureWarning):
4434                self.assertEqual(self.signature(c),
4435                                ((('a', ..., ..., "positional_or_keyword"),),
4436                                ...))
4437
4438        with self.subTest('partialmethod'):
4439            class C:
4440                __call__ = functools.partialmethod(lambda self, x, a: (x, a), 2)
4441
4442            self.assertEqual(C()(1), (2, 1))
4443            self.assertEqual(self.signature(C()),
4444                            ((('a', ..., ..., "positional_or_keyword"),),
4445                            ...))
4446
4447        with self.subTest('BuiltinMethodType'):
4448            class C:
4449                __call__ = ':'.join
4450
4451            self.assertEqual(C()(['a', 'bc']), 'a:bc')
4452            self.assertEqual(self.signature(C()), self.signature(''.join))
4453
4454        with self.subTest('MethodWrapperType'):
4455            class C:
4456                __call__ = (2).__pow__
4457
4458            self.assertEqual(C()(3), 8)
4459            self.assertEqual(self.signature(C()), self.signature((0).__pow__))
4460
4461        with self.subTest('ClassMethodDescriptorType'):
4462            class C(dict):
4463                __call__ = dict.__dict__['fromkeys']
4464
4465            res = C()([1, 2], 3)
4466            self.assertEqual(res, {1: 3, 2: 3})
4467            self.assertEqual(type(res), C)
4468            self.assertEqual(self.signature(C()), self.signature(dict.fromkeys))
4469
4470        with self.subTest('MethodDescriptorType'):
4471            class C(str):
4472                __call__ = str.join
4473
4474            self.assertEqual(C(':')(['a', 'bc']), 'a:bc')
4475            self.assertEqual(self.signature(C()), self.signature(''.join))
4476
4477        with self.subTest('WrapperDescriptorType'):
4478            class C(int):
4479                __call__ = int.__pow__
4480
4481            self.assertEqual(C(2)(3), 8)
4482            self.assertEqual(self.signature(C()), self.signature((0).__pow__))
4483
4484        with self.subTest('MemberDescriptorType'):
4485            class C:
4486                __slots__ = '__call__'
4487            c = C()
4488            c.__call__ = lambda a: a
4489            self.assertEqual(c(1), 1)
4490            self.assertEqual(self.signature(c),
4491                            ((('a', ..., ..., "positional_or_keyword"),),
4492                            ...))
4493
4494    def test_signature_on_callable_objects_with_text_signature_attr(self):
4495        class C:
4496            __text_signature__ = '(a, /, b, c=True)'
4497            def __call__(self, *args, **kwargs):
4498                pass
4499
4500        self.assertEqual(self.signature(C), ((), ...))
4501        self.assertEqual(self.signature(C()),
4502                         ((('a', ..., ..., "positional_only"),
4503                           ('b', ..., ..., "positional_or_keyword"),
4504                           ('c', True, ..., "positional_or_keyword"),
4505                          ),
4506                          ...))
4507
4508        c = C()
4509        c.__text_signature__ = '(x, y)'
4510        self.assertEqual(self.signature(c),
4511                         ((('x', ..., ..., "positional_or_keyword"),
4512                           ('y', ..., ..., "positional_or_keyword"),
4513                          ),
4514                          ...))
4515
4516    def test_signature_on_wrapper(self):
4517        class Wrapper:
4518            def __call__(self, b):
4519                pass
4520        wrapper = Wrapper()
4521        wrapper.__wrapped__ = lambda a: None
4522        self.assertEqual(self.signature(wrapper),
4523                         ((('a', ..., ..., "positional_or_keyword"),),
4524                          ...))
4525        # wrapper loop:
4526        wrapper = Wrapper()
4527        wrapper.__wrapped__ = wrapper
4528        with self.assertRaisesRegex(ValueError, 'wrapper loop'):
4529            self.signature(wrapper)
4530
4531    def test_signature_on_lambdas(self):
4532        self.assertEqual(self.signature((lambda a=10: a)),
4533                         ((('a', 10, ..., "positional_or_keyword"),),
4534                          ...))
4535
4536    def test_signature_on_mocks(self):
4537        # https://github.com/python/cpython/issues/96127
4538        for mock in (
4539            unittest.mock.Mock(),
4540            unittest.mock.AsyncMock(),
4541            unittest.mock.MagicMock(),
4542        ):
4543            with self.subTest(mock=mock):
4544                self.assertEqual(str(inspect.signature(mock)), '(*args, **kwargs)')
4545
4546    def test_signature_on_noncallable_mocks(self):
4547        for mock in (
4548            unittest.mock.NonCallableMock(),
4549            unittest.mock.NonCallableMagicMock(),
4550        ):
4551            with self.subTest(mock=mock):
4552                with self.assertRaises(TypeError):
4553                    inspect.signature(mock)
4554
4555    def test_signature_equality(self):
4556        def foo(a, *, b:int) -> float: pass
4557        self.assertFalse(inspect.signature(foo) == 42)
4558        self.assertTrue(inspect.signature(foo) != 42)
4559        self.assertTrue(inspect.signature(foo) == ALWAYS_EQ)
4560        self.assertFalse(inspect.signature(foo) != ALWAYS_EQ)
4561
4562        def bar(a, *, b:int) -> float: pass
4563        self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
4564        self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
4565        self.assertEqual(
4566            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
4567
4568        def bar(a, *, b:int) -> int: pass
4569        self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
4570        self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
4571        self.assertNotEqual(
4572            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
4573
4574        def bar(a, *, b:int): pass
4575        self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
4576        self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
4577        self.assertNotEqual(
4578            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
4579
4580        def bar(a, *, b:int=42) -> float: pass
4581        self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
4582        self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
4583        self.assertNotEqual(
4584            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
4585
4586        def bar(a, *, c) -> float: pass
4587        self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
4588        self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
4589        self.assertNotEqual(
4590            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
4591
4592        def bar(a, b:int) -> float: pass
4593        self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
4594        self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
4595        self.assertNotEqual(
4596            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
4597        def spam(b:int, a) -> float: pass
4598        self.assertFalse(inspect.signature(spam) == inspect.signature(bar))
4599        self.assertTrue(inspect.signature(spam) != inspect.signature(bar))
4600        self.assertNotEqual(
4601            hash(inspect.signature(spam)), hash(inspect.signature(bar)))
4602
4603        def foo(*, a, b, c): pass
4604        def bar(*, c, b, a): pass
4605        self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
4606        self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
4607        self.assertEqual(
4608            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
4609
4610        def foo(*, a=1, b, c): pass
4611        def bar(*, c, b, a=1): pass
4612        self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
4613        self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
4614        self.assertEqual(
4615            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
4616
4617        def foo(pos, *, a=1, b, c): pass
4618        def bar(pos, *, c, b, a=1): pass
4619        self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
4620        self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
4621        self.assertEqual(
4622            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
4623
4624        def foo(pos, *, a, b, c): pass
4625        def bar(pos, *, c, b, a=1): pass
4626        self.assertFalse(inspect.signature(foo) == inspect.signature(bar))
4627        self.assertTrue(inspect.signature(foo) != inspect.signature(bar))
4628        self.assertNotEqual(
4629            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
4630
4631        def foo(pos, *args, a=42, b, c, **kwargs:int): pass
4632        def bar(pos, *args, c, b, a=42, **kwargs:int): pass
4633        self.assertTrue(inspect.signature(foo) == inspect.signature(bar))
4634        self.assertFalse(inspect.signature(foo) != inspect.signature(bar))
4635        self.assertEqual(
4636            hash(inspect.signature(foo)), hash(inspect.signature(bar)))
4637
4638    def test_signature_hashable(self):
4639        S = inspect.Signature
4640        P = inspect.Parameter
4641
4642        def foo(a): pass
4643        foo_sig = inspect.signature(foo)
4644
4645        manual_sig = S(parameters=[P('a', P.POSITIONAL_OR_KEYWORD)])
4646
4647        self.assertEqual(hash(foo_sig), hash(manual_sig))
4648        self.assertNotEqual(hash(foo_sig),
4649                            hash(manual_sig.replace(return_annotation='spam')))
4650
4651        def bar(a) -> 1: pass
4652        self.assertNotEqual(hash(foo_sig), hash(inspect.signature(bar)))
4653
4654        def foo(a={}): pass
4655        with self.assertRaisesRegex(TypeError, 'unhashable type'):
4656            hash(inspect.signature(foo))
4657
4658        def foo(a) -> {}: pass
4659        with self.assertRaisesRegex(TypeError, 'unhashable type'):
4660            hash(inspect.signature(foo))
4661
4662    def test_signature_str(self):
4663        def foo(a:int=1, *, b, c=None, **kwargs) -> 42:
4664            pass
4665        self.assertEqual(str(inspect.signature(foo)),
4666                         '(a: int = 1, *, b, c=None, **kwargs) -> 42')
4667        self.assertEqual(str(inspect.signature(foo)),
4668                         inspect.signature(foo).format())
4669
4670        def foo(a:int=1, *args, b, c=None, **kwargs) -> 42:
4671            pass
4672        self.assertEqual(str(inspect.signature(foo)),
4673                         '(a: int = 1, *args, b, c=None, **kwargs) -> 42')
4674        self.assertEqual(str(inspect.signature(foo)),
4675                         inspect.signature(foo).format())
4676
4677        def foo():
4678            pass
4679        self.assertEqual(str(inspect.signature(foo)), '()')
4680        self.assertEqual(str(inspect.signature(foo)),
4681                         inspect.signature(foo).format())
4682
4683        def foo(a: list[str]) -> tuple[str, float]:
4684            pass
4685        self.assertEqual(str(inspect.signature(foo)),
4686                         '(a: list[str]) -> tuple[str, float]')
4687        self.assertEqual(str(inspect.signature(foo)),
4688                         inspect.signature(foo).format())
4689
4690        from typing import Tuple
4691        def foo(a: list[str]) -> Tuple[str, float]:
4692            pass
4693        self.assertEqual(str(inspect.signature(foo)),
4694                         '(a: list[str]) -> Tuple[str, float]')
4695        self.assertEqual(str(inspect.signature(foo)),
4696                         inspect.signature(foo).format())
4697
4698    def test_signature_str_positional_only(self):
4699        P = inspect.Parameter
4700        S = inspect.Signature
4701
4702        def test(a_po, /, *, b, **kwargs):
4703            return a_po, kwargs
4704
4705        self.assertEqual(str(inspect.signature(test)),
4706                         '(a_po, /, *, b, **kwargs)')
4707        self.assertEqual(str(inspect.signature(test)),
4708                         inspect.signature(test).format())
4709
4710        test = S(parameters=[P('foo', P.POSITIONAL_ONLY)])
4711        self.assertEqual(str(test), '(foo, /)')
4712        self.assertEqual(str(test), test.format())
4713
4714        test = S(parameters=[P('foo', P.POSITIONAL_ONLY),
4715                             P('bar', P.VAR_KEYWORD)])
4716        self.assertEqual(str(test), '(foo, /, **bar)')
4717        self.assertEqual(str(test), test.format())
4718
4719        test = S(parameters=[P('foo', P.POSITIONAL_ONLY),
4720                             P('bar', P.VAR_POSITIONAL)])
4721        self.assertEqual(str(test), '(foo, /, *bar)')
4722        self.assertEqual(str(test), test.format())
4723
4724    def test_signature_format(self):
4725        from typing import Annotated, Literal
4726
4727        def func(x: Annotated[int, 'meta'], y: Literal['a', 'b'], z: 'LiteralString'):
4728            pass
4729
4730        expected_singleline = "(x: Annotated[int, 'meta'], y: Literal['a', 'b'], z: 'LiteralString')"
4731        expected_multiline = """(
4732    x: Annotated[int, 'meta'],
4733    y: Literal['a', 'b'],
4734    z: 'LiteralString'
4735)"""
4736        self.assertEqual(
4737            inspect.signature(func).format(),
4738            expected_singleline,
4739        )
4740        self.assertEqual(
4741            inspect.signature(func).format(max_width=None),
4742            expected_singleline,
4743        )
4744        self.assertEqual(
4745            inspect.signature(func).format(max_width=len(expected_singleline)),
4746            expected_singleline,
4747        )
4748        self.assertEqual(
4749            inspect.signature(func).format(max_width=len(expected_singleline) - 1),
4750            expected_multiline,
4751        )
4752        self.assertEqual(
4753            inspect.signature(func).format(max_width=0),
4754            expected_multiline,
4755        )
4756        self.assertEqual(
4757            inspect.signature(func).format(max_width=-1),
4758            expected_multiline,
4759        )
4760
4761    def test_signature_format_all_arg_types(self):
4762        from typing import Annotated, Literal
4763
4764        def func(
4765            x: Annotated[int, 'meta'],
4766            /,
4767            y: Literal['a', 'b'],
4768            *,
4769            z: 'LiteralString',
4770            **kwargs: object,
4771        ) -> None:
4772            pass
4773
4774        expected_multiline = """(
4775    x: Annotated[int, 'meta'],
4776    /,
4777    y: Literal['a', 'b'],
4778    *,
4779    z: 'LiteralString',
4780    **kwargs: object
4781) -> None"""
4782        self.assertEqual(
4783            inspect.signature(func).format(max_width=-1),
4784            expected_multiline,
4785        )
4786
4787    def test_signature_replace_parameters(self):
4788        def test(a, b) -> 42:
4789            pass
4790
4791        sig = inspect.signature(test)
4792        parameters = sig.parameters
4793        sig = sig.replace(parameters=list(parameters.values())[1:])
4794        self.assertEqual(list(sig.parameters), ['b'])
4795        self.assertEqual(sig.parameters['b'], parameters['b'])
4796        self.assertEqual(sig.return_annotation, 42)
4797        sig = sig.replace(parameters=())
4798        self.assertEqual(dict(sig.parameters), {})
4799
4800        sig = inspect.signature(test)
4801        parameters = sig.parameters
4802        sig = copy.replace(sig, parameters=list(parameters.values())[1:])
4803        self.assertEqual(list(sig.parameters), ['b'])
4804        self.assertEqual(sig.parameters['b'], parameters['b'])
4805        self.assertEqual(sig.return_annotation, 42)
4806        sig = copy.replace(sig, parameters=())
4807        self.assertEqual(dict(sig.parameters), {})
4808
4809    def test_signature_replace_anno(self):
4810        def test() -> 42:
4811            pass
4812
4813        sig = inspect.signature(test)
4814        sig = sig.replace(return_annotation=None)
4815        self.assertIs(sig.return_annotation, None)
4816        sig = sig.replace(return_annotation=sig.empty)
4817        self.assertIs(sig.return_annotation, sig.empty)
4818        sig = sig.replace(return_annotation=42)
4819        self.assertEqual(sig.return_annotation, 42)
4820        self.assertEqual(sig, inspect.signature(test))
4821
4822        sig = inspect.signature(test)
4823        sig = copy.replace(sig, return_annotation=None)
4824        self.assertIs(sig.return_annotation, None)
4825        sig = copy.replace(sig, return_annotation=sig.empty)
4826        self.assertIs(sig.return_annotation, sig.empty)
4827        sig = copy.replace(sig, return_annotation=42)
4828        self.assertEqual(sig.return_annotation, 42)
4829        self.assertEqual(sig, inspect.signature(test))
4830
4831    def test_signature_replaced(self):
4832        def test():
4833            pass
4834
4835        spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY)
4836        sig = test.__signature__ = inspect.Signature(parameters=(spam_param,))
4837        self.assertEqual(sig, inspect.signature(test))
4838
4839    def test_signature_on_mangled_parameters(self):
4840        class Spam:
4841            def foo(self, __p1:1=2, *, __p2:2=3):
4842                pass
4843        class Ham(Spam):
4844            pass
4845
4846        self.assertEqual(self.signature(Spam.foo),
4847                         ((('self', ..., ..., "positional_or_keyword"),
4848                           ('_Spam__p1', 2, 1, "positional_or_keyword"),
4849                           ('_Spam__p2', 3, 2, "keyword_only")),
4850                          ...))
4851
4852        self.assertEqual(self.signature(Spam.foo),
4853                         self.signature(Ham.foo))
4854
4855    def test_signature_from_callable_python_obj(self):
4856        class MySignature(inspect.Signature): pass
4857        def foo(a, *, b:1): pass
4858        foo_sig = MySignature.from_callable(foo)
4859        self.assertIsInstance(foo_sig, MySignature)
4860
4861    @unittest.skipIf(MISSING_C_DOCSTRINGS,
4862                     "Signature information for builtins requires docstrings")
4863    def test_signature_from_callable_class(self):
4864        # A regression test for a class inheriting its signature from `object`.
4865        class MySignature(inspect.Signature): pass
4866        class foo: pass
4867        foo_sig = MySignature.from_callable(foo)
4868        self.assertIsInstance(foo_sig, MySignature)
4869
4870    @unittest.skipIf(MISSING_C_DOCSTRINGS,
4871                     "Signature information for builtins requires docstrings")
4872    def test_signature_from_callable_builtin_obj(self):
4873        class MySignature(inspect.Signature): pass
4874        sig = MySignature.from_callable(_pickle.Pickler)
4875        self.assertIsInstance(sig, MySignature)
4876
4877    def test_signature_definition_order_preserved_on_kwonly(self):
4878        for fn in signatures_with_lexicographic_keyword_only_parameters():
4879            signature = inspect.signature(fn)
4880            l = list(signature.parameters)
4881            sorted_l = sorted(l)
4882            self.assertTrue(l)
4883            self.assertEqual(l, sorted_l)
4884        signature = inspect.signature(unsorted_keyword_only_parameters_fn)
4885        l = list(signature.parameters)
4886        self.assertEqual(l, unsorted_keyword_only_parameters)
4887
4888    def test_signater_parameters_is_ordered(self):
4889        p1 = inspect.signature(lambda x, y: None).parameters
4890        p2 = inspect.signature(lambda y, x: None).parameters
4891        self.assertNotEqual(p1, p2)
4892
4893    def test_signature_annotations_with_local_namespaces(self):
4894        class Foo: ...
4895        def func(foo: Foo) -> int: pass
4896        def func2(foo: Foo, bar: 'Bar') -> int: pass
4897
4898        for signature_func in (inspect.signature, inspect.Signature.from_callable):
4899            with self.subTest(signature_func = signature_func):
4900                sig1 = signature_func(func)
4901                self.assertEqual(sig1.return_annotation, int)
4902                self.assertEqual(sig1.parameters['foo'].annotation, Foo)
4903
4904                sig2 = signature_func(func, locals=locals())
4905                self.assertEqual(sig2.return_annotation, int)
4906                self.assertEqual(sig2.parameters['foo'].annotation, Foo)
4907
4908                sig3 = signature_func(func2, globals={'Bar': int}, locals=locals())
4909                self.assertEqual(sig3.return_annotation, int)
4910                self.assertEqual(sig3.parameters['foo'].annotation, Foo)
4911                self.assertEqual(sig3.parameters['bar'].annotation, 'Bar')
4912
4913    def test_signature_eval_str(self):
4914        isa = inspect_stringized_annotations
4915        sig = inspect.Signature
4916        par = inspect.Parameter
4917        PORK = inspect.Parameter.POSITIONAL_OR_KEYWORD
4918        for signature_func in (inspect.signature, inspect.Signature.from_callable):
4919            with self.subTest(signature_func = signature_func):
4920                self.assertEqual(
4921                    signature_func(isa.MyClass),
4922                    sig(
4923                        parameters=(
4924                            par('a', PORK),
4925                            par('b', PORK),
4926                        )))
4927                self.assertEqual(
4928                    signature_func(isa.function),
4929                    sig(
4930                        return_annotation='MyClass',
4931                        parameters=(
4932                            par('a', PORK, annotation='int'),
4933                            par('b', PORK, annotation='str'),
4934                        )))
4935                self.assertEqual(
4936                    signature_func(isa.function2),
4937                    sig(
4938                        return_annotation='MyClass',
4939                        parameters=(
4940                            par('a', PORK, annotation='int'),
4941                            par('b', PORK, annotation="'str'"),
4942                            par('c', PORK, annotation="MyClass"),
4943                        )))
4944                self.assertEqual(
4945                    signature_func(isa.function3),
4946                    sig(
4947                        parameters=(
4948                            par('a', PORK, annotation="'int'"),
4949                            par('b', PORK, annotation="'str'"),
4950                            par('c', PORK, annotation="'MyClass'"),
4951                        )))
4952
4953                if not MISSING_C_DOCSTRINGS:
4954                    self.assertEqual(signature_func(isa.UnannotatedClass), sig())
4955                self.assertEqual(signature_func(isa.unannotated_function),
4956                    sig(
4957                        parameters=(
4958                            par('a', PORK),
4959                            par('b', PORK),
4960                            par('c', PORK),
4961                        )))
4962
4963                self.assertEqual(
4964                    signature_func(isa.MyClass, eval_str=True),
4965                    sig(
4966                        parameters=(
4967                            par('a', PORK),
4968                            par('b', PORK),
4969                        )))
4970                self.assertEqual(
4971                    signature_func(isa.function, eval_str=True),
4972                    sig(
4973                        return_annotation=isa.MyClass,
4974                        parameters=(
4975                            par('a', PORK, annotation=int),
4976                            par('b', PORK, annotation=str),
4977                        )))
4978                self.assertEqual(
4979                    signature_func(isa.function2, eval_str=True),
4980                    sig(
4981                        return_annotation=isa.MyClass,
4982                        parameters=(
4983                            par('a', PORK, annotation=int),
4984                            par('b', PORK, annotation='str'),
4985                            par('c', PORK, annotation=isa.MyClass),
4986                        )))
4987                self.assertEqual(
4988                    signature_func(isa.function3, eval_str=True),
4989                    sig(
4990                        parameters=(
4991                            par('a', PORK, annotation='int'),
4992                            par('b', PORK, annotation='str'),
4993                            par('c', PORK, annotation='MyClass'),
4994                        )))
4995
4996                globalns = {'int': float, 'str': complex}
4997                localns = {'str': tuple, 'MyClass': dict}
4998                with self.assertRaises(NameError):
4999                    signature_func(isa.function, eval_str=True, globals=globalns)
5000
5001                self.assertEqual(
5002                    signature_func(isa.function, eval_str=True, locals=localns),
5003                    sig(
5004                        return_annotation=dict,
5005                        parameters=(
5006                            par('a', PORK, annotation=int),
5007                            par('b', PORK, annotation=tuple),
5008                        )))
5009
5010                self.assertEqual(
5011                    signature_func(isa.function, eval_str=True, globals=globalns, locals=localns),
5012                    sig(
5013                        return_annotation=dict,
5014                        parameters=(
5015                            par('a', PORK, annotation=float),
5016                            par('b', PORK, annotation=tuple),
5017                        )))
5018
5019    def test_signature_none_annotation(self):
5020        class funclike:
5021            # Has to be callable, and have correct
5022            # __code__, __annotations__, __defaults__, __name__,
5023            # and __kwdefaults__ attributes
5024
5025            def __init__(self, func):
5026                self.__name__ = func.__name__
5027                self.__code__ = func.__code__
5028                self.__annotations__ = func.__annotations__
5029                self.__defaults__ = func.__defaults__
5030                self.__kwdefaults__ = func.__kwdefaults__
5031                self.func = func
5032
5033            def __call__(self, *args, **kwargs):
5034                return self.func(*args, **kwargs)
5035
5036        def foo(): pass
5037        foo = funclike(foo)
5038        foo.__annotations__ = None
5039        for signature_func in (inspect.signature, inspect.Signature.from_callable):
5040            with self.subTest(signature_func = signature_func):
5041                self.assertEqual(signature_func(foo), inspect.Signature())
5042        self.assertEqual(inspect.get_annotations(foo), {})
5043
5044    def test_signature_as_str(self):
5045        self.maxDiff = None
5046        class S:
5047            __signature__ = '(a, b=2)'
5048
5049        self.assertEqual(self.signature(S),
5050                         ((('a', ..., ..., 'positional_or_keyword'),
5051                           ('b', 2, ..., 'positional_or_keyword')),
5052                          ...))
5053
5054    def test_signature_as_callable(self):
5055        # __signature__ should be either a staticmethod or a bound classmethod
5056        class S:
5057            @classmethod
5058            def __signature__(cls):
5059                return '(a, b=2)'
5060
5061        self.assertEqual(self.signature(S),
5062                         ((('a', ..., ..., 'positional_or_keyword'),
5063                           ('b', 2, ..., 'positional_or_keyword')),
5064                          ...))
5065
5066        class S:
5067            @staticmethod
5068            def __signature__():
5069                return '(a, b=2)'
5070
5071        self.assertEqual(self.signature(S),
5072                         ((('a', ..., ..., 'positional_or_keyword'),
5073                           ('b', 2, ..., 'positional_or_keyword')),
5074                          ...))
5075
5076    def test_signature_on_derived_classes(self):
5077        # gh-105080: Make sure that signatures are consistent on derived classes
5078
5079        class B:
5080            def __new__(self, *args, **kwargs):
5081                return super().__new__(self)
5082            def __init__(self, value):
5083                self.value = value
5084
5085        class D1(B):
5086            def __init__(self, value):
5087                super().__init__(value)
5088
5089        class D2(D1):
5090            pass
5091
5092        self.assertEqual(inspect.signature(D2), inspect.signature(D1))
5093
5094    def test_signature_on_non_comparable(self):
5095        class NoncomparableCallable:
5096            def __call__(self, a):
5097                pass
5098            def __eq__(self, other):
5099                1/0
5100        self.assertEqual(self.signature(NoncomparableCallable()),
5101                         ((('a', ..., ..., 'positional_or_keyword'),),
5102                          ...))
5103
5104
5105class TestParameterObject(unittest.TestCase):
5106    def test_signature_parameter_kinds(self):
5107        P = inspect.Parameter
5108        self.assertTrue(P.POSITIONAL_ONLY < P.POSITIONAL_OR_KEYWORD < \
5109                        P.VAR_POSITIONAL < P.KEYWORD_ONLY < P.VAR_KEYWORD)
5110
5111        self.assertEqual(str(P.POSITIONAL_ONLY), 'POSITIONAL_ONLY')
5112        self.assertTrue('POSITIONAL_ONLY' in repr(P.POSITIONAL_ONLY))
5113
5114    def test_signature_parameter_object(self):
5115        p = inspect.Parameter('foo', default=10,
5116                              kind=inspect.Parameter.POSITIONAL_ONLY)
5117        self.assertEqual(p.name, 'foo')
5118        self.assertEqual(p.default, 10)
5119        self.assertIs(p.annotation, p.empty)
5120        self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
5121
5122        with self.assertRaisesRegex(ValueError, "value '123' is "
5123                                    "not a valid Parameter.kind"):
5124            inspect.Parameter('foo', default=10, kind='123')
5125
5126        with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
5127            inspect.Parameter('1', kind=inspect.Parameter.VAR_KEYWORD)
5128
5129        with self.assertRaisesRegex(ValueError, 'not a valid parameter name'):
5130            inspect.Parameter('from', kind=inspect.Parameter.VAR_KEYWORD)
5131
5132        with self.assertRaisesRegex(TypeError, 'name must be a str'):
5133            inspect.Parameter(None, kind=inspect.Parameter.VAR_KEYWORD)
5134
5135        with self.assertRaisesRegex(ValueError,
5136                                    'is not a valid parameter name'):
5137            inspect.Parameter('$', kind=inspect.Parameter.VAR_KEYWORD)
5138
5139        with self.assertRaisesRegex(ValueError,
5140                                    'is not a valid parameter name'):
5141            inspect.Parameter('.a', kind=inspect.Parameter.VAR_KEYWORD)
5142
5143        with self.assertRaisesRegex(ValueError, 'cannot have default values'):
5144            inspect.Parameter('a', default=42,
5145                              kind=inspect.Parameter.VAR_KEYWORD)
5146
5147        with self.assertRaisesRegex(ValueError, 'cannot have default values'):
5148            inspect.Parameter('a', default=42,
5149                              kind=inspect.Parameter.VAR_POSITIONAL)
5150
5151        p = inspect.Parameter('a', default=42,
5152                              kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
5153        with self.assertRaisesRegex(ValueError, 'cannot have default values'):
5154            p.replace(kind=inspect.Parameter.VAR_POSITIONAL)
5155
5156        self.assertTrue(repr(p).startswith('<Parameter'))
5157        self.assertTrue('"a=42"' in repr(p))
5158
5159    def test_signature_parameter_hashable(self):
5160        P = inspect.Parameter
5161        foo = P('foo', kind=P.POSITIONAL_ONLY)
5162        self.assertEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY)))
5163        self.assertNotEqual(hash(foo), hash(P('foo', kind=P.POSITIONAL_ONLY,
5164                                              default=42)))
5165        self.assertNotEqual(hash(foo),
5166                            hash(foo.replace(kind=P.VAR_POSITIONAL)))
5167
5168    def test_signature_parameter_equality(self):
5169        P = inspect.Parameter
5170        p = P('foo', default=42, kind=inspect.Parameter.KEYWORD_ONLY)
5171
5172        self.assertTrue(p == p)
5173        self.assertFalse(p != p)
5174        self.assertFalse(p == 42)
5175        self.assertTrue(p != 42)
5176        self.assertTrue(p == ALWAYS_EQ)
5177        self.assertFalse(p != ALWAYS_EQ)
5178
5179        self.assertTrue(p == P('foo', default=42,
5180                               kind=inspect.Parameter.KEYWORD_ONLY))
5181        self.assertFalse(p != P('foo', default=42,
5182                                kind=inspect.Parameter.KEYWORD_ONLY))
5183
5184    def test_signature_parameter_replace(self):
5185        p = inspect.Parameter('foo', default=42,
5186                              kind=inspect.Parameter.KEYWORD_ONLY)
5187
5188        self.assertIsNot(p.replace(), p)
5189        self.assertEqual(p.replace(), p)
5190        self.assertIsNot(copy.replace(p), p)
5191        self.assertEqual(copy.replace(p), p)
5192
5193        p2 = p.replace(annotation=1)
5194        self.assertEqual(p2.annotation, 1)
5195        p2 = p2.replace(annotation=p2.empty)
5196        self.assertEqual(p2, p)
5197        p3 = copy.replace(p, annotation=1)
5198        self.assertEqual(p3.annotation, 1)
5199        p3 = copy.replace(p3, annotation=p3.empty)
5200        self.assertEqual(p3, p)
5201
5202        p2 = p2.replace(name='bar')
5203        self.assertEqual(p2.name, 'bar')
5204        self.assertNotEqual(p2, p)
5205        p3 = copy.replace(p3, name='bar')
5206        self.assertEqual(p3.name, 'bar')
5207        self.assertNotEqual(p3, p)
5208
5209        with self.assertRaisesRegex(ValueError,
5210                                    'name is a required attribute'):
5211            p2 = p2.replace(name=p2.empty)
5212        with self.assertRaisesRegex(ValueError,
5213                                    'name is a required attribute'):
5214            p3 = copy.replace(p3, name=p3.empty)
5215
5216        p2 = p2.replace(name='foo', default=None)
5217        self.assertIs(p2.default, None)
5218        self.assertNotEqual(p2, p)
5219        p3 = copy.replace(p3, name='foo', default=None)
5220        self.assertIs(p3.default, None)
5221        self.assertNotEqual(p3, p)
5222
5223        p2 = p2.replace(name='foo', default=p2.empty)
5224        self.assertIs(p2.default, p2.empty)
5225        p3 = copy.replace(p3, name='foo', default=p3.empty)
5226        self.assertIs(p3.default, p3.empty)
5227
5228        p2 = p2.replace(default=42, kind=p2.POSITIONAL_OR_KEYWORD)
5229        self.assertEqual(p2.kind, p2.POSITIONAL_OR_KEYWORD)
5230        self.assertNotEqual(p2, p)
5231        p3 = copy.replace(p3, default=42, kind=p3.POSITIONAL_OR_KEYWORD)
5232        self.assertEqual(p3.kind, p3.POSITIONAL_OR_KEYWORD)
5233        self.assertNotEqual(p3, p)
5234
5235        with self.assertRaisesRegex(ValueError,
5236                                    "value <class 'inspect._empty'> "
5237                                    "is not a valid Parameter.kind"):
5238            p2 = p2.replace(kind=p2.empty)
5239        with self.assertRaisesRegex(ValueError,
5240                                    "value <class 'inspect._empty'> "
5241                                    "is not a valid Parameter.kind"):
5242            p3 = copy.replace(p3, kind=p3.empty)
5243
5244        p2 = p2.replace(kind=p2.KEYWORD_ONLY)
5245        self.assertEqual(p2, p)
5246        p3 = copy.replace(p3, kind=p3.KEYWORD_ONLY)
5247        self.assertEqual(p3, p)
5248
5249    def test_signature_parameter_positional_only(self):
5250        with self.assertRaisesRegex(TypeError, 'name must be a str'):
5251            inspect.Parameter(None, kind=inspect.Parameter.POSITIONAL_ONLY)
5252
5253    @cpython_only
5254    def test_signature_parameter_implicit(self):
5255        with self.assertRaisesRegex(ValueError,
5256                                    'implicit arguments must be passed as '
5257                                    'positional or keyword arguments, '
5258                                    'not positional-only'):
5259            inspect.Parameter('.0', kind=inspect.Parameter.POSITIONAL_ONLY)
5260
5261        param = inspect.Parameter(
5262            '.0', kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
5263        self.assertEqual(param.kind, inspect.Parameter.POSITIONAL_ONLY)
5264        self.assertEqual(param.name, 'implicit0')
5265
5266    def test_signature_parameter_immutability(self):
5267        p = inspect.Parameter('spam', kind=inspect.Parameter.KEYWORD_ONLY)
5268
5269        with self.assertRaises(AttributeError):
5270            p.foo = 'bar'
5271
5272        with self.assertRaises(AttributeError):
5273            p.kind = 123
5274
5275
5276class TestSignatureBind(unittest.TestCase):
5277    @staticmethod
5278    def call(func, *args, **kwargs):
5279        sig = inspect.signature(func)
5280        ba = sig.bind(*args, **kwargs)
5281        return func(*ba.args, **ba.kwargs)
5282
5283    def test_signature_bind_empty(self):
5284        def test():
5285            return 42
5286
5287        self.assertEqual(self.call(test), 42)
5288        with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
5289            self.call(test, 1)
5290        with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
5291            self.call(test, 1, spam=10)
5292        with self.assertRaisesRegex(
5293            TypeError, "got an unexpected keyword argument 'spam'"):
5294
5295            self.call(test, spam=1)
5296
5297    def test_signature_bind_var(self):
5298        def test(*args, **kwargs):
5299            return args, kwargs
5300
5301        self.assertEqual(self.call(test), ((), {}))
5302        self.assertEqual(self.call(test, 1), ((1,), {}))
5303        self.assertEqual(self.call(test, 1, 2), ((1, 2), {}))
5304        self.assertEqual(self.call(test, foo='bar'), ((), {'foo': 'bar'}))
5305        self.assertEqual(self.call(test, 1, foo='bar'), ((1,), {'foo': 'bar'}))
5306        self.assertEqual(self.call(test, args=10), ((), {'args': 10}))
5307        self.assertEqual(self.call(test, 1, 2, foo='bar'),
5308                         ((1, 2), {'foo': 'bar'}))
5309
5310    def test_signature_bind_just_args(self):
5311        def test(a, b, c):
5312            return a, b, c
5313
5314        self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
5315
5316        with self.assertRaisesRegex(TypeError, 'too many positional arguments'):
5317            self.call(test, 1, 2, 3, 4)
5318
5319        with self.assertRaisesRegex(TypeError,
5320                                    "missing a required argument: 'b'"):
5321            self.call(test, 1)
5322
5323        with self.assertRaisesRegex(TypeError,
5324                                    "missing a required argument: 'a'"):
5325            self.call(test)
5326
5327        def test(a, b, c=10):
5328            return a, b, c
5329        self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
5330        self.assertEqual(self.call(test, 1, 2), (1, 2, 10))
5331
5332        def test(a=1, b=2, c=3):
5333            return a, b, c
5334        self.assertEqual(self.call(test, a=10, c=13), (10, 2, 13))
5335        self.assertEqual(self.call(test, a=10), (10, 2, 3))
5336        self.assertEqual(self.call(test, b=10), (1, 10, 3))
5337
5338    def test_signature_bind_varargs_order(self):
5339        def test(*args):
5340            return args
5341
5342        self.assertEqual(self.call(test), ())
5343        self.assertEqual(self.call(test, 1, 2, 3), (1, 2, 3))
5344
5345    def test_signature_bind_args_and_varargs(self):
5346        def test(a, b, c=3, *args):
5347            return a, b, c, args
5348
5349        self.assertEqual(self.call(test, 1, 2, 3, 4, 5), (1, 2, 3, (4, 5)))
5350        self.assertEqual(self.call(test, 1, 2), (1, 2, 3, ()))
5351        self.assertEqual(self.call(test, b=1, a=2), (2, 1, 3, ()))
5352        self.assertEqual(self.call(test, 1, b=2), (1, 2, 3, ()))
5353
5354        with self.assertRaisesRegex(TypeError,
5355                                     "multiple values for argument 'c'"):
5356            self.call(test, 1, 2, 3, c=4)
5357
5358    def test_signature_bind_just_kwargs(self):
5359        def test(**kwargs):
5360            return kwargs
5361
5362        self.assertEqual(self.call(test), {})
5363        self.assertEqual(self.call(test, foo='bar', spam='ham'),
5364                         {'foo': 'bar', 'spam': 'ham'})
5365
5366    def test_signature_bind_args_and_kwargs(self):
5367        def test(a, b, c=3, **kwargs):
5368            return a, b, c, kwargs
5369
5370        self.assertEqual(self.call(test, 1, 2), (1, 2, 3, {}))
5371        self.assertEqual(self.call(test, 1, 2, foo='bar', spam='ham'),
5372                         (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
5373        self.assertEqual(self.call(test, b=2, a=1, foo='bar', spam='ham'),
5374                         (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
5375        self.assertEqual(self.call(test, a=1, b=2, foo='bar', spam='ham'),
5376                         (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
5377        self.assertEqual(self.call(test, 1, b=2, foo='bar', spam='ham'),
5378                         (1, 2, 3, {'foo': 'bar', 'spam': 'ham'}))
5379        self.assertEqual(self.call(test, 1, b=2, c=4, foo='bar', spam='ham'),
5380                         (1, 2, 4, {'foo': 'bar', 'spam': 'ham'}))
5381        self.assertEqual(self.call(test, 1, 2, 4, foo='bar'),
5382                         (1, 2, 4, {'foo': 'bar'}))
5383        self.assertEqual(self.call(test, c=5, a=4, b=3),
5384                         (4, 3, 5, {}))
5385
5386    def test_signature_bind_kwonly(self):
5387        def test(*, foo):
5388            return foo
5389        with self.assertRaisesRegex(TypeError,
5390                                     'too many positional arguments'):
5391            self.call(test, 1)
5392        self.assertEqual(self.call(test, foo=1), 1)
5393
5394        def test(a, *, foo=1, bar):
5395            return foo
5396        with self.assertRaisesRegex(TypeError,
5397                                     "missing a required argument: 'bar'"):
5398            self.call(test, 1)
5399
5400        def test(foo, *, bar):
5401            return foo, bar
5402        self.assertEqual(self.call(test, 1, bar=2), (1, 2))
5403        self.assertEqual(self.call(test, bar=2, foo=1), (1, 2))
5404
5405        with self.assertRaisesRegex(
5406            TypeError, "got an unexpected keyword argument 'spam'"):
5407
5408            self.call(test, bar=2, foo=1, spam=10)
5409
5410        with self.assertRaisesRegex(TypeError,
5411                                     'too many positional arguments'):
5412            self.call(test, 1, 2)
5413
5414        with self.assertRaisesRegex(TypeError,
5415                                     'too many positional arguments'):
5416            self.call(test, 1, 2, bar=2)
5417
5418        with self.assertRaisesRegex(
5419            TypeError, "got an unexpected keyword argument 'spam'"):
5420
5421            self.call(test, 1, bar=2, spam='ham')
5422
5423        with self.assertRaisesRegex(TypeError,
5424                                     "missing a required keyword-only "
5425                                     "argument: 'bar'"):
5426            self.call(test, 1)
5427
5428        def test(foo, *, bar, **bin):
5429            return foo, bar, bin
5430        self.assertEqual(self.call(test, 1, bar=2), (1, 2, {}))
5431        self.assertEqual(self.call(test, foo=1, bar=2), (1, 2, {}))
5432        self.assertEqual(self.call(test, 1, bar=2, spam='ham'),
5433                         (1, 2, {'spam': 'ham'}))
5434        self.assertEqual(self.call(test, spam='ham', foo=1, bar=2),
5435                         (1, 2, {'spam': 'ham'}))
5436        with self.assertRaisesRegex(TypeError,
5437                                    "missing a required argument: 'foo'"):
5438            self.call(test, spam='ham', bar=2)
5439        self.assertEqual(self.call(test, 1, bar=2, bin=1, spam=10),
5440                         (1, 2, {'bin': 1, 'spam': 10}))
5441
5442    def test_signature_bind_arguments(self):
5443        def test(a, *args, b, z=100, **kwargs):
5444            pass
5445        sig = inspect.signature(test)
5446        ba = sig.bind(10, 20, b=30, c=40, args=50, kwargs=60)
5447        # we won't have 'z' argument in the bound arguments object, as we didn't
5448        # pass it to the 'bind'
5449        self.assertEqual(tuple(ba.arguments.items()),
5450                         (('a', 10), ('args', (20,)), ('b', 30),
5451                          ('kwargs', {'c': 40, 'args': 50, 'kwargs': 60})))
5452        self.assertEqual(ba.kwargs,
5453                         {'b': 30, 'c': 40, 'args': 50, 'kwargs': 60})
5454        self.assertEqual(ba.args, (10, 20))
5455
5456    def test_signature_bind_positional_only(self):
5457        def test(a_po, b_po, c_po=3, /, foo=42, *, bar=50, **kwargs):
5458            return a_po, b_po, c_po, foo, bar, kwargs
5459
5460        self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6),
5461                         (1, 2, 4, 5, 6, {}))
5462
5463        self.assertEqual(self.call(test, 1, 2),
5464                         (1, 2, 3, 42, 50, {}))
5465
5466        self.assertEqual(self.call(test, 1, 2, foo=4, bar=5),
5467                         (1, 2, 3, 4, 5, {}))
5468
5469        self.assertEqual(self.call(test, 1, 2, foo=4, bar=5, c_po=10),
5470                         (1, 2, 3, 4, 5, {'c_po': 10}))
5471
5472        self.assertEqual(self.call(test, 1, 2, 30, c_po=31, foo=4, bar=5),
5473                         (1, 2, 30, 4, 5, {'c_po': 31}))
5474
5475        self.assertEqual(self.call(test, 1, 2, 30, foo=4, bar=5, c_po=31),
5476                         (1, 2, 30, 4, 5, {'c_po': 31}))
5477
5478        self.assertEqual(self.call(test, 1, 2, c_po=4),
5479                         (1, 2, 3, 42, 50, {'c_po': 4}))
5480
5481        with self.assertRaisesRegex(TypeError, "missing 2 required positional arguments"):
5482            self.call(test, a_po=1, b_po=2)
5483
5484        def without_var_kwargs(c_po=3, d_po=4, /):
5485            return c_po, d_po
5486
5487        with self.assertRaisesRegex(
5488            TypeError,
5489            "positional-only arguments passed as keyword arguments: 'c_po, d_po'",
5490        ):
5491            self.call(without_var_kwargs, c_po=33, d_po=44)
5492
5493    def test_signature_bind_with_self_arg(self):
5494        # Issue #17071: one of the parameters is named "self
5495        def test(a, self, b):
5496            pass
5497        sig = inspect.signature(test)
5498        ba = sig.bind(1, 2, 3)
5499        self.assertEqual(ba.args, (1, 2, 3))
5500        ba = sig.bind(1, self=2, b=3)
5501        self.assertEqual(ba.args, (1, 2, 3))
5502
5503    def test_signature_bind_vararg_name(self):
5504        def test(a, *args):
5505            return a, args
5506        sig = inspect.signature(test)
5507
5508        with self.assertRaisesRegex(
5509            TypeError, "got an unexpected keyword argument 'args'"):
5510
5511            sig.bind(a=0, args=1)
5512
5513        def test(*args, **kwargs):
5514            return args, kwargs
5515        self.assertEqual(self.call(test, args=1), ((), {'args': 1}))
5516
5517        sig = inspect.signature(test)
5518        ba = sig.bind(args=1)
5519        self.assertEqual(ba.arguments, {'kwargs': {'args': 1}})
5520
5521    @cpython_only
5522    def test_signature_bind_implicit_arg(self):
5523        # Issue #19611: getcallargs should work with comprehensions
5524        def make_set():
5525            return set(z * z for z in range(5))
5526        gencomp_code = make_set.__code__.co_consts[1]
5527        gencomp_func = types.FunctionType(gencomp_code, {})
5528
5529        iterator = iter(range(5))
5530        self.assertEqual(set(self.call(gencomp_func, iterator)), {0, 1, 4, 9, 16})
5531
5532    def test_signature_bind_posonly_kwargs(self):
5533        def foo(bar, /, **kwargs):
5534            return bar, kwargs.get(bar)
5535
5536        sig = inspect.signature(foo)
5537        result = sig.bind("pos-only", bar="keyword")
5538
5539        self.assertEqual(result.kwargs, {"bar": "keyword"})
5540        self.assertIn(("bar", "pos-only"), result.arguments.items())
5541
5542
5543class TestBoundArguments(unittest.TestCase):
5544    def test_signature_bound_arguments_unhashable(self):
5545        def foo(a): pass
5546        ba = inspect.signature(foo).bind(1)
5547
5548        with self.assertRaisesRegex(TypeError, 'unhashable type'):
5549            hash(ba)
5550
5551    def test_signature_bound_arguments_equality(self):
5552        def foo(a): pass
5553        ba = inspect.signature(foo).bind(1)
5554        self.assertTrue(ba == ba)
5555        self.assertFalse(ba != ba)
5556        self.assertTrue(ba == ALWAYS_EQ)
5557        self.assertFalse(ba != ALWAYS_EQ)
5558
5559        ba2 = inspect.signature(foo).bind(1)
5560        self.assertTrue(ba == ba2)
5561        self.assertFalse(ba != ba2)
5562
5563        ba3 = inspect.signature(foo).bind(2)
5564        self.assertFalse(ba == ba3)
5565        self.assertTrue(ba != ba3)
5566        ba3.arguments['a'] = 1
5567        self.assertTrue(ba == ba3)
5568        self.assertFalse(ba != ba3)
5569
5570        def bar(b): pass
5571        ba4 = inspect.signature(bar).bind(1)
5572        self.assertFalse(ba == ba4)
5573        self.assertTrue(ba != ba4)
5574
5575        def foo(*, a, b): pass
5576        sig = inspect.signature(foo)
5577        ba1 = sig.bind(a=1, b=2)
5578        ba2 = sig.bind(b=2, a=1)
5579        self.assertTrue(ba1 == ba2)
5580        self.assertFalse(ba1 != ba2)
5581
5582    def test_signature_bound_arguments_pickle(self):
5583        def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
5584        sig = inspect.signature(foo)
5585        ba = sig.bind(20, 30, z={})
5586
5587        for ver in range(pickle.HIGHEST_PROTOCOL + 1):
5588            with self.subTest(pickle_ver=ver):
5589                ba_pickled = pickle.loads(pickle.dumps(ba, ver))
5590                self.assertEqual(ba, ba_pickled)
5591
5592    def test_signature_bound_arguments_repr(self):
5593        def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass
5594        sig = inspect.signature(foo)
5595        ba = sig.bind(20, 30, z={})
5596        self.assertRegex(repr(ba), r'<BoundArguments \(a=20,.*\}\}\)>')
5597
5598    def test_signature_bound_arguments_apply_defaults(self):
5599        def foo(a, b=1, *args, c:1={}, **kw): pass
5600        sig = inspect.signature(foo)
5601
5602        ba = sig.bind(20)
5603        ba.apply_defaults()
5604        self.assertEqual(
5605            list(ba.arguments.items()),
5606            [('a', 20), ('b', 1), ('args', ()), ('c', {}), ('kw', {})])
5607
5608        # Make sure that we preserve the order:
5609        # i.e. 'c' should be *before* 'kw'.
5610        ba = sig.bind(10, 20, 30, d=1)
5611        ba.apply_defaults()
5612        self.assertEqual(
5613            list(ba.arguments.items()),
5614            [('a', 10), ('b', 20), ('args', (30,)), ('c', {}), ('kw', {'d':1})])
5615
5616        # Make sure that BoundArguments produced by bind_partial()
5617        # are supported.
5618        def foo(a, b): pass
5619        sig = inspect.signature(foo)
5620        ba = sig.bind_partial(20)
5621        ba.apply_defaults()
5622        self.assertEqual(
5623            list(ba.arguments.items()),
5624            [('a', 20)])
5625
5626        # Test no args
5627        def foo(): pass
5628        sig = inspect.signature(foo)
5629        ba = sig.bind()
5630        ba.apply_defaults()
5631        self.assertEqual(list(ba.arguments.items()), [])
5632
5633        # Make sure a no-args binding still acquires proper defaults.
5634        def foo(a='spam'): pass
5635        sig = inspect.signature(foo)
5636        ba = sig.bind()
5637        ba.apply_defaults()
5638        self.assertEqual(list(ba.arguments.items()), [('a', 'spam')])
5639
5640    def test_signature_bound_arguments_arguments_type(self):
5641        def foo(a): pass
5642        ba = inspect.signature(foo).bind(1)
5643        self.assertIs(type(ba.arguments), dict)
5644
5645class TestSignaturePrivateHelpers(unittest.TestCase):
5646    def _strip_non_python_syntax(self, input,
5647        clean_signature, self_parameter):
5648        computed_clean_signature, \
5649            computed_self_parameter = \
5650            inspect._signature_strip_non_python_syntax(input)
5651        self.assertEqual(computed_clean_signature, clean_signature)
5652        self.assertEqual(computed_self_parameter, self_parameter)
5653
5654    def test_signature_strip_non_python_syntax(self):
5655        self._strip_non_python_syntax(
5656            "($module, /, path, mode, *, dir_fd=None, " +
5657                "effective_ids=False,\n       follow_symlinks=True)",
5658            "(module, /, path, mode, *, dir_fd=None, " +
5659                "effective_ids=False, follow_symlinks=True)",
5660            0)
5661
5662        self._strip_non_python_syntax(
5663            "($module, word, salt, /)",
5664            "(module, word, salt, /)",
5665            0)
5666
5667        self._strip_non_python_syntax(
5668            "(x, y=None, z=None, /)",
5669            "(x, y=None, z=None, /)",
5670            None)
5671
5672        self._strip_non_python_syntax(
5673            "(x, y=None, z=None)",
5674            "(x, y=None, z=None)",
5675            None)
5676
5677        self._strip_non_python_syntax(
5678            "(x,\n    y=None,\n      z = None  )",
5679            "(x, y=None, z=None)",
5680            None)
5681
5682        self._strip_non_python_syntax(
5683            "",
5684            "",
5685            None)
5686
5687        self._strip_non_python_syntax(
5688            None,
5689            None,
5690            None)
5691
5692class TestSignatureDefinitions(unittest.TestCase):
5693    # This test case provides a home for checking that particular APIs
5694    # have signatures available for introspection
5695
5696    @staticmethod
5697    def is_public(name):
5698        return not name.startswith('_') or name.startswith('__') and name.endswith('__')
5699
5700    @cpython_only
5701    @unittest.skipIf(MISSING_C_DOCSTRINGS,
5702                     "Signature information for builtins requires docstrings")
5703    def _test_module_has_signatures(self, module,
5704                no_signature=(), unsupported_signature=(),
5705                methods_no_signature={}, methods_unsupported_signature={},
5706                good_exceptions=()):
5707        # This checks all builtin callables in CPython have signatures
5708        # A few have signatures Signature can't yet handle, so we skip those
5709        # since they will have to wait until PEP 457 adds the required
5710        # introspection support to the inspect module
5711        # Some others also haven't been converted yet for various other
5712        # reasons, so we also skip those for the time being, but design
5713        # the test to fail in order to indicate when it needs to be
5714        # updated.
5715        no_signature = no_signature or set()
5716        # Check the signatures we expect to be there
5717        ns = vars(module)
5718        try:
5719            names = set(module.__all__)
5720        except AttributeError:
5721            names = set(name for name in ns if self.is_public(name))
5722        for name, obj in sorted(ns.items()):
5723            if name not in names:
5724                continue
5725            if not callable(obj):
5726                continue
5727            if (isinstance(obj, type) and
5728                issubclass(obj, BaseException) and
5729                name not in good_exceptions):
5730                no_signature.add(name)
5731            if name not in no_signature and name not in unsupported_signature:
5732                with self.subTest('supported', builtin=name):
5733                    self.assertIsNotNone(inspect.signature(obj))
5734            if isinstance(obj, type):
5735                with self.subTest(type=name):
5736                    self._test_builtin_methods_have_signatures(obj,
5737                            methods_no_signature.get(name, ()),
5738                            methods_unsupported_signature.get(name, ()))
5739        # Check callables that haven't been converted don't claim a signature
5740        # This ensures this test will start failing as more signatures are
5741        # added, so the affected items can be moved into the scope of the
5742        # regression test above
5743        for name in no_signature:
5744            with self.subTest('none', builtin=name):
5745                obj = ns[name]
5746                self.assertIsNone(obj.__text_signature__)
5747                self.assertRaises(ValueError, inspect.signature, obj)
5748        for name in unsupported_signature:
5749            with self.subTest('unsupported', builtin=name):
5750                obj = ns[name]
5751                self.assertIsNotNone(obj.__text_signature__)
5752                self.assertRaises(ValueError, inspect.signature, obj)
5753
5754    def _test_builtin_methods_have_signatures(self, cls, no_signature, unsupported_signature):
5755        ns = vars(cls)
5756        for name in ns:
5757            obj = getattr(cls, name, None)
5758            if not callable(obj) or isinstance(obj, type):
5759                continue
5760            if name not in no_signature and name not in unsupported_signature:
5761                with self.subTest('supported', method=name):
5762                    self.assertIsNotNone(inspect.signature(obj))
5763        for name in no_signature:
5764            with self.subTest('none', method=name):
5765                self.assertIsNone(getattr(cls, name).__text_signature__)
5766                self.assertRaises(ValueError, inspect.signature, getattr(cls, name))
5767        for name in unsupported_signature:
5768            with self.subTest('unsupported', method=name):
5769                self.assertIsNotNone(getattr(cls, name).__text_signature__)
5770                self.assertRaises(ValueError, inspect.signature, getattr(cls, name))
5771
5772    def test_builtins_have_signatures(self):
5773        no_signature = {'type', 'super', 'bytearray', 'bytes', 'dict', 'int', 'str'}
5774        # These need PEP 457 groups
5775        needs_groups = {"range", "slice", "dir", "getattr",
5776                        "next", "iter", "vars"}
5777        no_signature |= needs_groups
5778        # These have unrepresentable parameter default values of NULL
5779        unsupported_signature = {"anext"}
5780        # These need *args support in Argument Clinic
5781        needs_varargs = {"min", "max", "__build_class__"}
5782        no_signature |= needs_varargs
5783
5784        methods_no_signature = {
5785            'dict': {'update'},
5786            'object': {'__class__'},
5787        }
5788        methods_unsupported_signature = {
5789            'bytearray': {'count', 'endswith', 'find', 'hex', 'index', 'rfind', 'rindex', 'startswith'},
5790            'bytes': {'count', 'endswith', 'find', 'hex', 'index', 'rfind', 'rindex', 'startswith'},
5791            'dict': {'pop'},
5792            'int': {'__round__'},
5793            'memoryview': {'cast', 'hex'},
5794            'str': {'count', 'endswith', 'find', 'index', 'maketrans', 'rfind', 'rindex', 'startswith'},
5795        }
5796        self._test_module_has_signatures(builtins,
5797                no_signature, unsupported_signature,
5798                methods_no_signature, methods_unsupported_signature)
5799
5800    def test_types_module_has_signatures(self):
5801        unsupported_signature = {'CellType'}
5802        methods_no_signature = {
5803            'AsyncGeneratorType': {'athrow'},
5804            'CoroutineType': {'throw'},
5805            'GeneratorType': {'throw'},
5806        }
5807        self._test_module_has_signatures(types,
5808                unsupported_signature=unsupported_signature,
5809                methods_no_signature=methods_no_signature)
5810
5811    def test_sys_module_has_signatures(self):
5812        no_signature = {'getsizeof', 'set_asyncgen_hooks'}
5813        no_signature |= {name for name in ['getobjects']
5814                         if hasattr(sys, name)}
5815        self._test_module_has_signatures(sys, no_signature)
5816
5817    def test_abc_module_has_signatures(self):
5818        import abc
5819        self._test_module_has_signatures(abc)
5820
5821    def test_atexit_module_has_signatures(self):
5822        import atexit
5823        self._test_module_has_signatures(atexit)
5824
5825    def test_codecs_module_has_signatures(self):
5826        import codecs
5827        methods_no_signature = {'StreamReader': {'charbuffertype'}}
5828        self._test_module_has_signatures(codecs,
5829                methods_no_signature=methods_no_signature)
5830
5831    def test_collections_module_has_signatures(self):
5832        no_signature = {'OrderedDict', 'defaultdict'}
5833        unsupported_signature = {'deque'}
5834        methods_no_signature = {
5835            'OrderedDict': {'update'},
5836        }
5837        methods_unsupported_signature = {
5838            'deque': {'index'},
5839            'OrderedDict': {'pop'},
5840            'UserString': {'maketrans'},
5841        }
5842        self._test_module_has_signatures(collections,
5843                no_signature, unsupported_signature,
5844                methods_no_signature, methods_unsupported_signature)
5845
5846    def test_collections_abc_module_has_signatures(self):
5847        import collections.abc
5848        self._test_module_has_signatures(collections.abc)
5849
5850    def test_errno_module_has_signatures(self):
5851        import errno
5852        self._test_module_has_signatures(errno)
5853
5854    def test_faulthandler_module_has_signatures(self):
5855        import faulthandler
5856        unsupported_signature = {'dump_traceback', 'dump_traceback_later', 'enable'}
5857        unsupported_signature |= {name for name in ['register']
5858                                  if hasattr(faulthandler, name)}
5859        self._test_module_has_signatures(faulthandler, unsupported_signature=unsupported_signature)
5860
5861    def test_functools_module_has_signatures(self):
5862        no_signature = {'reduce'}
5863        self._test_module_has_signatures(functools, no_signature)
5864
5865    def test_gc_module_has_signatures(self):
5866        import gc
5867        no_signature = {'set_threshold'}
5868        self._test_module_has_signatures(gc, no_signature)
5869
5870    def test_io_module_has_signatures(self):
5871        methods_no_signature = {
5872            'BufferedRWPair': {'read', 'peek', 'read1', 'readinto', 'readinto1', 'write'},
5873        }
5874        self._test_module_has_signatures(io,
5875                methods_no_signature=methods_no_signature)
5876
5877    def test_itertools_module_has_signatures(self):
5878        import itertools
5879        no_signature = {'islice', 'repeat'}
5880        self._test_module_has_signatures(itertools, no_signature)
5881
5882    def test_locale_module_has_signatures(self):
5883        import locale
5884        self._test_module_has_signatures(locale)
5885
5886    def test_marshal_module_has_signatures(self):
5887        import marshal
5888        self._test_module_has_signatures(marshal)
5889
5890    def test_operator_module_has_signatures(self):
5891        import operator
5892        self._test_module_has_signatures(operator)
5893
5894    def test_os_module_has_signatures(self):
5895        unsupported_signature = {'chmod', 'utime'}
5896        unsupported_signature |= {name for name in
5897            ['get_terminal_size', 'posix_spawn', 'posix_spawnp',
5898             'register_at_fork', 'startfile']
5899            if hasattr(os, name)}
5900        self._test_module_has_signatures(os, unsupported_signature=unsupported_signature)
5901
5902    def test_pwd_module_has_signatures(self):
5903        pwd = import_helper.import_module('pwd')
5904        self._test_module_has_signatures(pwd)
5905
5906    def test_re_module_has_signatures(self):
5907        import re
5908        methods_no_signature = {'Match': {'group'}}
5909        self._test_module_has_signatures(re,
5910                methods_no_signature=methods_no_signature,
5911                good_exceptions={'error', 'PatternError'})
5912
5913    def test_signal_module_has_signatures(self):
5914        import signal
5915        self._test_module_has_signatures(signal)
5916
5917    def test_stat_module_has_signatures(self):
5918        import stat
5919        self._test_module_has_signatures(stat)
5920
5921    def test_string_module_has_signatures(self):
5922        import string
5923        self._test_module_has_signatures(string)
5924
5925    def test_symtable_module_has_signatures(self):
5926        import symtable
5927        self._test_module_has_signatures(symtable)
5928
5929    def test_sysconfig_module_has_signatures(self):
5930        import sysconfig
5931        self._test_module_has_signatures(sysconfig)
5932
5933    def test_threading_module_has_signatures(self):
5934        import threading
5935        self._test_module_has_signatures(threading)
5936
5937    def test_thread_module_has_signatures(self):
5938        import _thread
5939        no_signature = {'RLock'}
5940        self._test_module_has_signatures(_thread, no_signature)
5941
5942    def test_time_module_has_signatures(self):
5943        no_signature = {
5944            'asctime', 'ctime', 'get_clock_info', 'gmtime', 'localtime',
5945            'strftime', 'strptime'
5946        }
5947        no_signature |= {name for name in
5948            ['clock_getres', 'clock_settime', 'clock_settime_ns',
5949             'pthread_getcpuclockid']
5950            if hasattr(time, name)}
5951        self._test_module_has_signatures(time, no_signature)
5952
5953    def test_tokenize_module_has_signatures(self):
5954        import tokenize
5955        self._test_module_has_signatures(tokenize)
5956
5957    def test_tracemalloc_module_has_signatures(self):
5958        import tracemalloc
5959        self._test_module_has_signatures(tracemalloc)
5960
5961    def test_typing_module_has_signatures(self):
5962        import typing
5963        no_signature = {'ParamSpec', 'ParamSpecArgs', 'ParamSpecKwargs',
5964                        'Text', 'TypeAliasType', 'TypeVar', 'TypeVarTuple'}
5965        methods_no_signature = {
5966            'Generic': {'__class_getitem__', '__init_subclass__'},
5967        }
5968        methods_unsupported_signature = {
5969            'Text': {'count', 'find', 'index', 'rfind', 'rindex', 'startswith', 'endswith', 'maketrans'},
5970        }
5971        self._test_module_has_signatures(typing, no_signature,
5972                methods_no_signature=methods_no_signature,
5973                methods_unsupported_signature=methods_unsupported_signature)
5974
5975    def test_warnings_module_has_signatures(self):
5976        unsupported_signature = {'warn', 'warn_explicit'}
5977        self._test_module_has_signatures(warnings, unsupported_signature=unsupported_signature)
5978
5979    def test_weakref_module_has_signatures(self):
5980        import weakref
5981        no_signature = {'ReferenceType', 'ref'}
5982        self._test_module_has_signatures(weakref, no_signature)
5983
5984    def test_python_function_override_signature(self):
5985        def func(*args, **kwargs):
5986            pass
5987        func.__text_signature__ = '($self, a, b=1, *args, c, d=2, **kwargs)'
5988        sig = inspect.signature(func)
5989        self.assertIsNotNone(sig)
5990        self.assertEqual(str(sig), '(self, /, a, b=1, *args, c, d=2, **kwargs)')
5991
5992        func.__text_signature__ = '($self, a, b=1, /, *args, c, d=2, **kwargs)'
5993        sig = inspect.signature(func)
5994        self.assertEqual(str(sig), '(self, a, b=1, /, *args, c, d=2, **kwargs)')
5995
5996        func.__text_signature__ = '(self, a=1+2, b=4-3, c=1 | 3 | 16)'
5997        sig = inspect.signature(func)
5998        self.assertEqual(str(sig), '(self, a=3, b=1, c=19)')
5999
6000        func.__text_signature__ = '(self, a=1,\nb=2,\n\n\n   c=3)'
6001        sig = inspect.signature(func)
6002        self.assertEqual(str(sig), '(self, a=1, b=2, c=3)')
6003
6004        func.__text_signature__ = '(self, x=does_not_exist)'
6005        with self.assertRaises(ValueError):
6006            inspect.signature(func)
6007        func.__text_signature__ = '(self, x=sys, y=inspect)'
6008        with self.assertRaises(ValueError):
6009            inspect.signature(func)
6010        func.__text_signature__ = '(self, 123)'
6011        with self.assertRaises(ValueError):
6012            inspect.signature(func)
6013
6014    @support.requires_docstrings
6015    def test_base_class_have_text_signature(self):
6016        # see issue 43118
6017        from test.typinganndata.ann_module7 import BufferedReader
6018        class MyBufferedReader(BufferedReader):
6019            """buffer reader class."""
6020
6021        text_signature = BufferedReader.__text_signature__
6022        self.assertEqual(text_signature, '(raw, buffer_size=DEFAULT_BUFFER_SIZE)')
6023        sig = inspect.signature(MyBufferedReader)
6024        self.assertEqual(str(sig), '(raw, buffer_size=8192)')
6025
6026
6027class NTimesUnwrappable:
6028    def __init__(self, n):
6029        self.n = n
6030        self._next = None
6031
6032    @property
6033    def __wrapped__(self):
6034        if self.n <= 0:
6035            raise Exception("Unwrapped too many times")
6036        if self._next is None:
6037            self._next = NTimesUnwrappable(self.n - 1)
6038        return self._next
6039
6040class TestUnwrap(unittest.TestCase):
6041
6042    def test_unwrap_one(self):
6043        def func(a, b):
6044            return a + b
6045        wrapper = functools.lru_cache(maxsize=20)(func)
6046        self.assertIs(inspect.unwrap(wrapper), func)
6047
6048    def test_unwrap_several(self):
6049        def func(a, b):
6050            return a + b
6051        wrapper = func
6052        for __ in range(10):
6053            @functools.wraps(wrapper)
6054            def wrapper():
6055                pass
6056        self.assertIsNot(wrapper.__wrapped__, func)
6057        self.assertIs(inspect.unwrap(wrapper), func)
6058
6059    def test_stop(self):
6060        def func1(a, b):
6061            return a + b
6062        @functools.wraps(func1)
6063        def func2():
6064            pass
6065        @functools.wraps(func2)
6066        def wrapper():
6067            pass
6068        func2.stop_here = 1
6069        unwrapped = inspect.unwrap(wrapper,
6070                                   stop=(lambda f: hasattr(f, "stop_here")))
6071        self.assertIs(unwrapped, func2)
6072
6073    def test_cycle(self):
6074        def func1(): pass
6075        func1.__wrapped__ = func1
6076        with self.assertRaisesRegex(ValueError, 'wrapper loop'):
6077            inspect.unwrap(func1)
6078
6079        def func2(): pass
6080        func2.__wrapped__ = func1
6081        func1.__wrapped__ = func2
6082        with self.assertRaisesRegex(ValueError, 'wrapper loop'):
6083            inspect.unwrap(func1)
6084        with self.assertRaisesRegex(ValueError, 'wrapper loop'):
6085            inspect.unwrap(func2)
6086
6087    def test_unhashable(self):
6088        def func(): pass
6089        func.__wrapped__ = None
6090        class C:
6091            __hash__ = None
6092            __wrapped__ = func
6093        self.assertIsNone(inspect.unwrap(C()))
6094
6095    def test_recursion_limit(self):
6096        obj = NTimesUnwrappable(sys.getrecursionlimit() + 1)
6097        with self.assertRaisesRegex(ValueError, 'wrapper loop'):
6098            inspect.unwrap(obj)
6099
6100    def test_wrapped_descriptor(self):
6101        self.assertIs(inspect.unwrap(NTimesUnwrappable), NTimesUnwrappable)
6102        self.assertIs(inspect.unwrap(staticmethod), staticmethod)
6103        self.assertIs(inspect.unwrap(classmethod), classmethod)
6104        self.assertIs(inspect.unwrap(staticmethod(classmethod)), classmethod)
6105        self.assertIs(inspect.unwrap(classmethod(staticmethod)), staticmethod)
6106
6107
6108class TestMain(unittest.TestCase):
6109    def test_only_source(self):
6110        module = importlib.import_module('unittest')
6111        rc, out, err = assert_python_ok('-m', 'inspect',
6112                                        'unittest')
6113        lines = out.decode().splitlines()
6114        # ignore the final newline
6115        self.assertEqual(lines[:-1], inspect.getsource(module).splitlines())
6116        self.assertEqual(err, b'')
6117
6118    def test_custom_getattr(self):
6119        def foo():
6120            pass
6121        foo.__signature__ = 42
6122        with self.assertRaises(TypeError):
6123            inspect.signature(foo)
6124
6125    @unittest.skipIf(ThreadPoolExecutor is None,
6126            'threads required to test __qualname__ for source files')
6127    def test_qualname_source(self):
6128        rc, out, err = assert_python_ok('-m', 'inspect',
6129                                     'concurrent.futures:ThreadPoolExecutor')
6130        lines = out.decode().splitlines()
6131        # ignore the final newline
6132        self.assertEqual(lines[:-1],
6133                         inspect.getsource(ThreadPoolExecutor).splitlines())
6134        self.assertEqual(err, b'')
6135
6136    def test_builtins(self):
6137        _, out, err = assert_python_failure('-m', 'inspect',
6138                                            'sys')
6139        lines = err.decode().splitlines()
6140        self.assertEqual(lines, ["Can't get info for builtin modules."])
6141
6142    def test_details(self):
6143        module = importlib.import_module('unittest')
6144        args = support.optim_args_from_interpreter_flags()
6145        rc, out, err = assert_python_ok(*args, '-m', 'inspect',
6146                                        'unittest', '--details')
6147        output = out.decode()
6148        # Just a quick sanity check on the output
6149        self.assertIn(module.__spec__.name, output)
6150        self.assertIn(module.__name__, output)
6151        self.assertIn(module.__spec__.origin, output)
6152        self.assertIn(module.__file__, output)
6153        self.assertIn(module.__spec__.cached, output)
6154        self.assertIn(module.__cached__, output)
6155        self.assertEqual(err, b'')
6156
6157
6158class TestReload(unittest.TestCase):
6159
6160    src_before = textwrap.dedent("""\
6161def foo():
6162    print("Bla")
6163    """)
6164
6165    src_after = textwrap.dedent("""\
6166def foo():
6167    print("Oh no!")
6168    """)
6169
6170    def assertInspectEqual(self, path, source):
6171        inspected_src = inspect.getsource(source)
6172        with open(path, encoding='utf-8') as src:
6173            self.assertEqual(
6174                src.read().splitlines(True),
6175                inspected_src.splitlines(True)
6176            )
6177
6178    def test_getsource_reload(self):
6179        # see issue 1218234
6180        with ready_to_import('reload_bug', self.src_before) as (name, path):
6181            module = importlib.import_module(name)
6182            self.assertInspectEqual(path, module)
6183            with open(path, 'w', encoding='utf-8') as src:
6184                src.write(self.src_after)
6185            self.assertInspectEqual(path, module)
6186
6187
6188class TestRepl(unittest.TestCase):
6189
6190    def spawn_repl(self, *args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kw):
6191        """Run the Python REPL with the given arguments.
6192
6193        kw is extra keyword args to pass to subprocess.Popen. Returns a Popen
6194        object.
6195        """
6196
6197        # To run the REPL without using a terminal, spawn python with the command
6198        # line option '-i' and the process name set to '<stdin>'.
6199        # The directory of argv[0] must match the directory of the Python
6200        # executable for the Popen() call to python to succeed as the directory
6201        # path may be used by Py_GetPath() to build the default module search
6202        # path.
6203        stdin_fname = os.path.join(os.path.dirname(sys.executable), "<stdin>")
6204        cmd_line = [stdin_fname, '-E', '-i']
6205        cmd_line.extend(args)
6206
6207        # Set TERM=vt100, for the rationale see the comments in spawn_python() of
6208        # test.support.script_helper.
6209        env = kw.setdefault('env', dict(os.environ))
6210        env['TERM'] = 'vt100'
6211        return subprocess.Popen(cmd_line,
6212                                executable=sys.executable,
6213                                text=True,
6214                                stdin=subprocess.PIPE,
6215                                stdout=stdout, stderr=stderr,
6216                                **kw)
6217
6218    def run_on_interactive_mode(self, source):
6219        """Spawn a new Python interpreter, pass the given
6220        input source code from the stdin and return the
6221        result back. If the interpreter exits non-zero, it
6222        raises a ValueError."""
6223
6224        process = self.spawn_repl()
6225        process.stdin.write(source)
6226        output = kill_python(process)
6227
6228        if process.returncode != 0:
6229            raise ValueError("Process didn't exit properly.")
6230        return output
6231
6232    @unittest.skipIf(not has_subprocess_support, "test requires subprocess")
6233    def test_getsource(self):
6234        output = self.run_on_interactive_mode(textwrap.dedent("""\
6235        def f():
6236            print(0)
6237            return 1 + 2
6238
6239        import inspect
6240        print(f"The source is: <<<{inspect.getsource(f)}>>>")
6241        """))
6242
6243        expected = "The source is: <<<def f():\n    print(0)\n    return 1 + 2\n>>>"
6244        self.assertIn(expected, output)
6245
6246
6247
6248
6249if __name__ == "__main__":
6250    unittest.main()
6251