11[case testSignaturesBasic]
2- import inspect
3-
42def f1(): pass
53def f2(x): pass
64def f3(x, /): pass
@@ -12,21 +10,25 @@ def f8(x=None, /): pass
1210def f9(*, x=None): pass
1311def f10(a, /, b, c=None, *args, d=None, **h): pass
1412
15- def test_basic() -> None:
16- assert str(inspect.signature(f1)) == "()"
17- assert str(inspect.signature(f2)) == "(x)"
18- assert str(inspect.signature(f3)) == "(x, /)"
19- assert str(inspect.signature(f4)) == "(*, x)"
20- assert str(inspect.signature(f5)) == "(*x)"
21- assert str(inspect.signature(f6)) == "(**x)"
22- assert str(inspect.signature(f7)) == "(x=None)"
23- assert str(inspect.signature(f8)) == "(x=None, /)"
24- assert str(inspect.signature(f9)) == "(*, x=None)"
25- assert str(inspect.signature(f10)) == "(a, /, b, c=None, *args, d=None, **h)"
26-
27- [case testSignaturesValidDefaults]
13+ [file driver.py]
2814import inspect
15+ from native import *
16+
17+ assert str(inspect.signature(f1)) == "()"
18+ assert str(inspect.signature(f2)) == "(x)"
19+ assert str(inspect.signature(f3)) == "(x, /)"
20+ assert str(inspect.signature(f4)) == "(*, x)"
21+ assert str(inspect.signature(f5)) == "(*x)"
22+ assert str(inspect.signature(f6)) == "(**x)"
23+ assert str(inspect.signature(f7)) == "(x=None)"
24+ assert str(inspect.signature(f8)) == "(x=None, /)"
25+ assert str(inspect.signature(f9)) == "(*, x=None)"
26+ assert str(inspect.signature(f10)) == "(a, /, b, c=None, *args, d=None, **h)"
27+
28+ for fn in [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10]:
29+ assert getattr(fn, "__doc__") is None
2930
31+ [case testSignaturesValidDefaults]
3032def default_int(x=1): pass
3133def default_str(x="a"): pass
3234def default_float(x=1.0): pass
@@ -37,44 +39,43 @@ def default_tuple_empty(x=()): pass
3739def default_tuple_literals(x=(1, "a", 1.0, False, True, None, (), (1,2,(3,4)))): pass
3840def default_tuple_singleton(x=(1,)): pass
3941
40- def test_valid_defaults() -> None:
41- assert str(inspect.signature(default_int)) == "(x=1)"
42- assert str(inspect.signature(default_str)) == "(x='a')"
43- assert str(inspect.signature(default_float)) == "(x=1.0)"
44- assert str(inspect.signature(default_true)) == "(x=True)"
45- assert str(inspect.signature(default_false)) == "(x=False)"
46- assert str(inspect.signature(default_none)) == "(x=None)"
47- assert str(inspect.signature(default_tuple_empty)) == "(x=())"
48- assert str(inspect.signature(default_tuple_literals)) == "(x=(1, 'a', 1.0, False, True, None, (), (1, 2, (3, 4))))"
49-
50- # Check __text_signature__ directly since inspect.signature produces
51- # an incorrect signature for 1-tuple default arguments prior to
52- # Python 3.12 (cpython#102379).
53- # assert str(inspect.signature(default_tuple_singleton)) == "(x=(1,))"
54- assert getattr(default_tuple_singleton, "__text_signature__") == "(x=(1,))"
55-
56- [case testSignaturesStringDefaults]
42+ [file driver.py]
5743import inspect
44+ from native import *
45+
46+ assert str(inspect.signature(default_int)) == "(x=1)"
47+ assert str(inspect.signature(default_str)) == "(x='a')"
48+ assert str(inspect.signature(default_float)) == "(x=1.0)"
49+ assert str(inspect.signature(default_true)) == "(x=True)"
50+ assert str(inspect.signature(default_false)) == "(x=False)"
51+ assert str(inspect.signature(default_none)) == "(x=None)"
52+ assert str(inspect.signature(default_tuple_empty)) == "(x=())"
53+ assert str(inspect.signature(default_tuple_literals)) == "(x=(1, 'a', 1.0, False, True, None, (), (1, 2, (3, 4))))"
54+
55+ # Check __text_signature__ directly since inspect.signature produces
56+ # an incorrect signature for 1-tuple default arguments prior to
57+ # Python 3.12 (cpython#102379).
58+ # assert str(inspect.signature(default_tuple_singleton)) == "(x=(1,))"
59+ assert getattr(default_tuple_singleton, "__text_signature__") == "(x=(1,))"
5860
61+ [case testSignaturesStringDefaults]
5962def f1(x="'foo"): pass
6063def f2(x='"foo'): pass
6164def f3(x=""""Isn\'t," they said."""): pass
6265def f4(x="\\ \a \b \f \n \r \t \v \x00"): pass
6366def f5(x="\N{BANANA}sv"): pass
6467
65- def test_string_defaults() -> None:
66- assert str(inspect.signature(f1)) == """(x="'foo")"""
67- assert str(inspect.signature(f2)) == """(x='"foo')"""
68- assert str(inspect.signature(f3)) == r"""(x='"Isn\'t," they said.')"""
69- assert str(inspect.signature(f4)) == r"""(x='\\ \x07 \x08 \x0c \n \r \t \x0b \x00')"""
70- assert str(inspect.signature(f5)) == """(x='\U0001F34Csv')"""
71-
72- [case testSignaturesIrrepresentableDefaults]
68+ [file driver.py]
7369import inspect
74- from typing import Any
70+ from native import *
7571
76- from testutil import assertRaises
72+ assert str(inspect.signature(f1)) == """(x="'foo")"""
73+ assert str(inspect.signature(f2)) == """(x='"foo')"""
74+ assert str(inspect.signature(f3)) == r"""(x='"Isn\'t," they said.')"""
75+ assert str(inspect.signature(f4)) == r"""(x='\\ \x07 \x08 \x0c \n \r \t \x0b \x00')"""
76+ assert str(inspect.signature(f5)) == """(x='\N{BANANA}sv')"""
7777
78+ [case testSignaturesIrrepresentableDefaults]
7879def bad1(x=[]): pass
7980def bad2(x={}): pass
8081def bad3(x=set()): pass
@@ -88,16 +89,17 @@ def bad9(x=1|2): pass
8889def bad10(x=float("nan")): pass
8990def bad11(x=([],)): pass
9091
91- def test_irrepresentable_defaults() -> None:
92- bad: Any
93- for bad in [bad1, bad2, bad3, bad4, bad5, bad6, bad7, bad8, bad9, bad10, bad11]:
94- assert bad.__text_signature__ is None, f"{bad.__name__} has unexpected __text_signature__"
95- with assertRaises(ValueError, "no signature found for builtin"):
96- inspect.signature(bad)
97-
98- [case testSignaturesMethods]
92+ [file driver.py]
9993import inspect
94+ from testutil import assertRaises
95+ from native import *
10096
97+ for bad in [bad1, bad2, bad3, bad4, bad5, bad6, bad7, bad8, bad9, bad10, bad11]:
98+ assert bad.__text_signature__ is None, f"{bad.__name__} has unexpected __text_signature__"
99+ with assertRaises(ValueError, "no signature found for builtin"):
100+ inspect.signature(bad)
101+
102+ [case testSignaturesMethods]
101103class Foo:
102104 def f1(self, x): pass
103105 @classmethod
@@ -106,26 +108,59 @@ class Foo:
106108 def f3(x): pass
107109 def __eq__(self, x: object): pass
108110
109- def test_methods() -> None:
110- assert getattr(Foo.f1, "__text_signature__") == "($self, x)"
111- assert getattr(Foo().f1, "__text_signature__") == "($self, x)"
112- assert str(inspect.signature(Foo.f1)) == "(self, /, x)"
113- assert str(inspect.signature(Foo().f1)) == "(x)"
114-
115- assert getattr(Foo.f2, "__text_signature__") == "($cls, x)"
116- assert getattr(Foo().f2, "__text_signature__") == "($cls, x)"
117- assert str(inspect.signature(Foo.f2)) == "(x)"
118- assert str(inspect.signature(Foo().f2)) == "(x)"
119-
120- assert getattr(Foo.f3, "__text_signature__") == "(x)"
121- assert getattr(Foo().f3, "__text_signature__") == "(x)"
122- assert str(inspect.signature(Foo.f3)) == "(x)"
123- assert str(inspect.signature(Foo().f3)) == "(x)"
124-
125- assert getattr(Foo.__eq__, "__text_signature__") == "($self, value, /)"
126- assert getattr(Foo().__eq__, "__text_signature__") == "($self, value, /)"
127- assert str(inspect.signature(Foo.__eq__)) == "(self, value, /)"
128- assert str(inspect.signature(Foo().__eq__)) == "(value, /)"
111+ [file driver.py]
112+ import inspect
113+ from native import *
114+
115+ assert str(inspect.signature(Foo.f1)) == "(self, /, x)"
116+ assert str(inspect.signature(Foo().f1)) == "(x)"
117+
118+ assert str(inspect.signature(Foo.f2)) == "(x)"
119+ assert str(inspect.signature(Foo().f2)) == "(x)"
120+
121+ assert str(inspect.signature(Foo.f3)) == "(x)"
122+ assert str(inspect.signature(Foo().f3)) == "(x)"
123+
124+ assert str(inspect.signature(Foo.__eq__)) == "(self, value, /)"
125+ assert str(inspect.signature(Foo().__eq__)) == "(value, /)"
126+
127+ [case testSignaturesConstructors]
128+ class Empty: pass
129+
130+ class HasInit:
131+ def __init__(self, x) -> None: pass
132+
133+ class InheritedInit(HasInit): pass
134+
135+ class HasInitBad:
136+ def __init__(self, x=[]) -> None: pass
137+
138+ [file driver.py]
139+ import inspect
140+ from testutil import assertRaises
141+ from native import *
142+
143+ assert str(inspect.signature(Empty)) == "()"
144+ assert str(inspect.signature(Empty.__init__)) == "(self, /, *args, **kwargs)"
145+
146+ assert str(inspect.signature(HasInit)) == "(x)"
147+ assert str(inspect.signature(HasInit.__init__)) == "(self, /, *args, **kwargs)"
148+
149+ assert str(inspect.signature(InheritedInit)) == "(x)"
150+ assert str(inspect.signature(InheritedInit.__init__)) == "(self, /, *args, **kwargs)"
151+
152+ assert getattr(HasInitBad, "__text_signature__") is None
153+ with assertRaises(ValueError, "no signature found for builtin"):
154+ inspect.signature(HasInitBad)
155+
156+ # CPython detail note: type objects whose tp_doc contains only a text signature behave
157+ # differently from method objects whose ml_doc contains only a test signature: type
158+ # objects will have __doc__="" whereas method objects will have __doc__=None. This
159+ # difference stems from the former using _PyType_GetDocFromInternalDoc(...) and the
160+ # latter using PyUnicode_FromString(_PyType_DocWithoutSignature(...)).
161+ for cls in [Empty, HasInit, InheritedInit]:
162+ assert getattr(cls, "__doc__") == ""
163+ assert getattr(HasInitBad, "__doc__") is None
129164
130165[case testSignaturesHistoricalPositionalOnly]
131166import inspect
0 commit comments