diff --git a/AUTHORS b/AUTHORS index cb73916bc..1eeb3869a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -376,6 +376,7 @@ Tomer Keren Tony Narlock Tor Colvin Trevor Bekolay +Tushar Sadhwani Tyler Goodlet Tyler Smart Tzu-ping Chung diff --git a/changelog/11140.bugfix.rst b/changelog/11140.bugfix.rst new file mode 100644 index 000000000..cdf0b37c7 --- /dev/null +++ b/changelog/11140.bugfix.rst @@ -0,0 +1 @@ +Fix non-string constants at the top of file being detected as docstrings on Python>=3.8. diff --git a/src/_pytest/assertion/rewrite.py b/src/_pytest/assertion/rewrite.py index fd2355297..d1974bb3b 100644 --- a/src/_pytest/assertion/rewrite.py +++ b/src/_pytest/assertion/rewrite.py @@ -604,6 +604,13 @@ def _get_assertion_exprs(src: bytes) -> Dict[int, str]: return ret +def _get_ast_constant_value(value: astStr) -> object: + if sys.version_info >= (3, 8): + return value.value + else: + return value.s + + class AssertionRewriter(ast.NodeVisitor): """Assertion rewriting implementation. @@ -700,11 +707,10 @@ class AssertionRewriter(ast.NodeVisitor): expect_docstring and isinstance(item, ast.Expr) and isinstance(item.value, astStr) + and isinstance(_get_ast_constant_value(item.value), str) ): - if sys.version_info >= (3, 8): - doc = item.value.value - else: - doc = item.value.s + doc = _get_ast_constant_value(item.value) + assert isinstance(doc, str) if self.is_rewrite_disabled(doc): return expect_docstring = False diff --git a/testing/test_assertrewrite.py b/testing/test_assertrewrite.py index fbf285495..2f59ace54 100644 --- a/testing/test_assertrewrite.py +++ b/testing/test_assertrewrite.py @@ -2077,3 +2077,17 @@ class TestReprSizeVerbosity: self.create_test_file(pytester, DEFAULT_REPR_MAX_SIZE * 10) result = pytester.runpytest("-vv") result.stdout.no_fnmatch_line("*xxx...xxx*") + + +class TestIssue11140: + def test_constant_not_picked_as_module_docstring(self, pytester: Pytester) -> None: + pytester.makepyfile( + """\ + 0 + + def test_foo(): + pass + """ + ) + result = pytester.runpytest() + assert result.ret == 0