New submission from Nikita Sobolev <m...@sobolevn.me>: This line `lineno = getattr(obj, 'co_firstlineno', None)-1` does not look good. Link: https://github.com/python/cpython/blame/45d44b950f1dab0ef90d0a8f4fa75ffaae71500b/Lib/doctest.py#L1116
Why? 1. `CodeType` is guaranteed to have `co_firstlineno`. Docs: https://github.com/python/cpython/blob/45d44b950f1dab0ef90d0a8f4fa75ffaae71500b/Lib/inspect.py#L487 2. Even if it does not have it for some reason, this `getattr` does not help. It raises unhandled `TypeError`. We can simulate it by replacing `lineno = getattr(obj, 'co_firstlineno', None)-1` with `lineno = None-1` Here's what happens in this case: ``` » ./python.exe -m test -v test_doctest == CPython 3.11.0a3+ (heads/issue-26767:45d44b950f, Jan 8 2022, 12:23:45) [Clang 11.0.0 (clang-1100.0.33.16)] == Darwin-18.7.0-x86_64-i386-64bit little-endian == cwd: /Users/sobolev/Desktop/cpython/build/test_python_78065æ == CPU count: 4 == encodings: locale=UTF-8, FS=utf-8 0:00:00 load avg: 3.51 Run tests sequentially 0:00:00 load avg: 3.51 [1/1] test_doctest Failed to call load_tests: Traceback (most recent call last): File "/Users/sobolev/Desktop/cpython/Lib/unittest/loader.py", line 108, in loadTestsFromModule return load_tests(self, tests, pattern) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/sobolev/Desktop/cpython/Lib/test/test_doctest.py", line 3134, in load_tests tests.addTest(doctest.DocTestSuite(doctest)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/sobolev/Desktop/cpython/Lib/doctest.py", line 2391, in DocTestSuite tests = test_finder.find(module, globs=globs, extraglobs=extraglobs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/sobolev/Desktop/cpython/Lib/doctest.py", line 940, in find self._find(tests, obj, name, module, source_lines, globs, {}) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/sobolev/Desktop/cpython/Lib/doctest.py", line 1013, in _find self._find(tests, val, valname, module, source_lines, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/sobolev/Desktop/cpython/Lib/doctest.py", line 1001, in _find test = self._get_test(obj, name, module, globs, source_lines) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/sobolev/Desktop/cpython/Lib/doctest.py", line 1069, in _get_test lineno = self._find_lineno(obj, source_lines) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/sobolev/Desktop/cpython/Lib/doctest.py", line 1117, in _find_lineno None - 1 ~~~~~^~~ TypeError: unsupported operand type(s) for -: 'NoneType' and 'int' test test_doctest crashed -- Traceback (most recent call last): File "/Users/sobolev/Desktop/cpython/Lib/test/libregrtest/runtest.py", line 352, in _runtest_inner refleak = _runtest_inner2(ns, test_name) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/sobolev/Desktop/cpython/Lib/test/libregrtest/runtest.py", line 309, in _runtest_inner2 test_runner() ^^^^^^^^^^^^^ File "/Users/sobolev/Desktop/cpython/Lib/test/libregrtest/runtest.py", line 272, in _test_module raise Exception("errors while loading tests") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Exception: errors while loading tests test_doctest failed (uncaught exception) == Tests result: FAILURE == 1 test failed: test_doctest Total duration: 1.0 sec Tests result: FAILURE ``` So, we have two options: 1. Think of a case when `CodeType` does not have `co_firstlineno` and handle it properly, like using `0` or `None` as `lineno` 2. Simplify this line to remove potential `TypeError` I think that this line should be rewritten as `lineno = obj.co_firstlineno - 1` I will send a PR for others to judge. ---------- components: Library (Lib) messages: 410092 nosy: sobolevn priority: normal severity: normal status: open title: Suspicios operation in `doctest.py`: `None - 1` type: behavior versions: Python 3.10, Python 3.11, Python 3.9 _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue46306> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com