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