self.assertEqual(A.__module__, __name__)
self.assertEqual(A.__bases__, (object,))
self.assertIs(A.__base__, object)
+ self.assertNotIn('__firstlineno__', A.__dict__)
x = A()
self.assertIs(type(x), A)
self.assertIs(x.__class__, A)
A.__qualname__ = b'B'
self.assertEqual(A.__qualname__, 'D.E')
+ def test_type_firstlineno(self):
+ A = type('A', (), {'__firstlineno__': 42})
+ self.assertEqual(A.__name__, 'A')
+ self.assertEqual(A.__module__, __name__)
+ self.assertEqual(A.__dict__['__firstlineno__'], 42)
+ A.__module__ = 'testmodule'
+ self.assertEqual(A.__module__, 'testmodule')
+ self.assertNotIn('__firstlineno__', A.__dict__)
+ A.__firstlineno__ = 43
+ self.assertEqual(A.__dict__['__firstlineno__'], 43)
+
def test_type_typeparams(self):
class A[T]:
pass
nonlocal __firstlineno__
self.assertRaises(OSError, inspect.getsource, C)
+class TestGetsourceStdlib(unittest.TestCase):
+ # Test Python implementations of the stdlib modules
+
+ def test_getsource_stdlib_collections_abc(self):
+ import collections.abc
+ lines, lineno = inspect.getsourcelines(collections.abc.Sequence)
+ self.assertEqual(lines[0], 'class Sequence(Reversible, Collection):\n')
+ src = inspect.getsource(collections.abc.Sequence)
+ self.assertEqual(src.splitlines(True), lines)
+
+ def test_getsource_stdlib_tomllib(self):
+ import tomllib
+ self.assertRaises(OSError, inspect.getsource, tomllib.TOMLDecodeError)
+ self.assertRaises(OSError, inspect.getsourcelines, tomllib.TOMLDecodeError)
+
+ def test_getsource_stdlib_abc(self):
+ # Pure Python implementation
+ abc = import_helper.import_fresh_module('abc', blocked=['_abc'])
+ with support.swap_item(sys.modules, 'abc', abc):
+ self.assertRaises(OSError, inspect.getsource, abc.ABCMeta)
+ self.assertRaises(OSError, inspect.getsourcelines, abc.ABCMeta)
+ # With C acceleration
+ import abc
+ try:
+ src = inspect.getsource(abc.ABCMeta)
+ lines, lineno = inspect.getsourcelines(abc.ABCMeta)
+ except OSError:
+ pass
+ else:
+ self.assertEqual(lines[0], ' class ABCMeta(type):\n')
+ self.assertEqual(src.splitlines(True), lines)
+
+ def test_getsource_stdlib_decimal(self):
+ # Pure Python implementation
+ decimal = import_helper.import_fresh_module('decimal', blocked=['_decimal'])
+ with support.swap_item(sys.modules, 'decimal', decimal):
+ src = inspect.getsource(decimal.Decimal)
+ lines, lineno = inspect.getsourcelines(decimal.Decimal)
+ self.assertEqual(lines[0], 'class Decimal(object):\n')
+ self.assertEqual(src.splitlines(True), lines)
+
class TestGetsourceInteractive(unittest.TestCase):
def test_getclasses_interactive(self):
# bpo-44648: simulate a REPL session;
self.assertSourceEqual(mod2.td354, 354, 356)
self.assertRaises(OSError, inspect.getsource, mod2.td359)
+ def test_dataclass(self):
+ self.assertSourceEqual(mod2.dc364, 364, 367)
+ self.assertRaises(OSError, inspect.getsource, mod2.dc370)
+ self.assertRaises(OSError, inspect.getsource, mod2.dc371)
+
class TestBlockComments(GetSourceBase):
fodderModule = mod
self.assertRaises(IOError, inspect.findsource, co)
self.assertRaises(IOError, inspect.getsource, co)
- def test_findsource_with_out_of_bounds_lineno(self):
+ def test_findsource_on_func_with_out_of_bounds_lineno(self):
mod_len = len(inspect.getsource(mod))
src = '\n' * 2* mod_len + "def f(): pass"
co = compile(src, mod.__file__, "exec")
eval(co, g, l)
func = l['f']
self.assertEqual(func.__code__.co_firstlineno, 1+2*mod_len)
- with self.assertRaisesRegex(IOError, "lineno is out of bounds"):
+ with self.assertRaisesRegex(OSError, "lineno is out of bounds"):
inspect.findsource(func)
+ def test_findsource_on_class_with_out_of_bounds_lineno(self):
+ mod_len = len(inspect.getsource(mod))
+ src = '\n' * 2* mod_len + "class A: pass"
+ co = compile(src, mod.__file__, "exec")
+ g, l = {'__name__': mod.__name__}, {}
+ eval(co, g, l)
+ cls = l['A']
+ self.assertEqual(cls.__firstlineno__, 1+2*mod_len)
+ with self.assertRaisesRegex(OSError, "lineno is out of bounds"):
+ inspect.findsource(cls)
+
def test_getsource_on_method(self):
self.assertSourceEqual(mod2.ClassWithMethod.method, 118, 119)