-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Disable assertion rewriting external modules #13421
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
231cb63
bdc096c
0701fcb
0d0551e
3ec4da8
f03f24e
b6db388
1346500
023dfdb
1fee11d
ba41963
253497e
67e7a69
ee836ad
e7a98bb
c947f9a
abd69ac
fd59d87
3da821d
48cfbc3
eceae2e
8c95bcd
1d5a612
c1f3772
edcf484
5116841
6a67526
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Disable assertion for modules outside current working dir(cwd) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[pytest] | ||
python_files = *.py |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
from __future__ import annotations | ||
|
||
import pytest | ||
|
||
|
||
@pytest.fixture | ||
def special_asserter(): | ||
def special_assert(x, y): | ||
assert {"x": x} == {"x": y} | ||
|
||
return special_assert |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
"""Stub file for testing""" | ||
|
||
from __future__ import annotations | ||
|
||
|
||
def func(x: int, y: int) -> int: | ||
"""Stub function""" | ||
assert (x) > 0 | ||
return 0 if x == y else 1 if x > y else -1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from __future__ import annotations | ||
|
||
from _pytest.fixtures import fixture | ||
|
||
|
||
pytest_plugins = ["pytester", "some_plugin"] | ||
|
||
|
||
@fixture | ||
def b(): | ||
return 1 | ||
|
||
|
||
@fixture | ||
def a(): | ||
return 2 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from __future__ import annotations | ||
|
||
from typing import Callable | ||
|
||
from testing.example_scripts.rewrite.src.main import func | ||
|
||
|
||
def test_plugin(a: int, b: int, special_asserter: Callable[[int, int], bool]): | ||
special_asserter(a, b) | ||
|
||
|
||
def test_func(a: int, b: int, special_asserter: Callable[[int, int], bool]): | ||
assert {"res": func(a, b)} == {"res": 0} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
def some_check(a: int): | ||
assert abs(a)<2 | ||
return a in set(0, 1, -1) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,12 +29,14 @@ | |
from _pytest.assertion.rewrite import _get_maxsize_for_saferepr | ||
from _pytest.assertion.rewrite import _saferepr | ||
from _pytest.assertion.rewrite import AssertionRewritingHook | ||
from _pytest.assertion.rewrite import assertstate_key | ||
from _pytest.assertion.rewrite import get_cache_dir | ||
from _pytest.assertion.rewrite import PYC_TAIL | ||
from _pytest.assertion.rewrite import PYTEST_TAG | ||
from _pytest.assertion.rewrite import rewrite_asserts | ||
from _pytest.config import Config | ||
from _pytest.config import ExitCode | ||
from _pytest.monkeypatch import MonkeyPatch | ||
from _pytest.pathlib import make_numbered_dir | ||
from _pytest.pytester import Pytester | ||
import pytest | ||
|
@@ -370,6 +372,7 @@ def test_rewrites_plugin_as_a_package(self, pytester: Pytester) -> None: | |
pytester.makeconftest('pytest_plugins = ["plugin"]') | ||
pytester.makepyfile("def test(special_asserter): special_asserter(1, 2)\n") | ||
result = pytester.runpytest() | ||
|
||
result.stdout.fnmatch_lines(["*assert 1 == 2*"]) | ||
|
||
def test_honors_pep_235(self, pytester: Pytester, monkeypatch) -> None: | ||
|
@@ -1294,6 +1297,36 @@ def test_meta_path(): | |
) | ||
assert pytester.runpytest().ret == 0 | ||
|
||
def test_invocation_dir(self, pytester: Pytester, monkeypatch: MonkeyPatch) -> None: | ||
"""Test get invocation param from AssertionState""" | ||
from _pytest.assertion import AssertionState | ||
|
||
config = pytester.parseconfig() | ||
state = AssertionState(config, "rewrite") | ||
|
||
assert state.invocation_path == str(config.invocation_params.dir) | ||
|
||
new_rootpath = pytester.path / "test" | ||
if not os.path.exists(new_rootpath): | ||
os.mkdir(new_rootpath) | ||
monkeypatch.setattr( | ||
config, | ||
"invocation_params", | ||
Config.InvocationParams( | ||
args=(), | ||
plugins=(), | ||
dir=new_rootpath, | ||
), | ||
) | ||
state = AssertionState(config, "rewrite") | ||
assert state.invocation_path == str(new_rootpath) | ||
|
||
@pytest.mark.skipif( | ||
sys.platform.startswith("win32"), reason="cannot remove cwd on Windows" | ||
) | ||
@pytest.mark.skipif( | ||
sys.platform.startswith("sunos5"), reason="cannot remove cwd on Solaris" | ||
) | ||
Comment on lines
+1324
to
+1329
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are these There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is sunos still a supported python platform As far as I'm aware sun is down |
||
def test_write_pyc(self, pytester: Pytester, tmp_path) -> None: | ||
from _pytest.assertion import AssertionState | ||
from _pytest.assertion.rewrite import _write_pyc | ||
|
@@ -1971,6 +2004,32 @@ def test_simple_failure(): | |
assert hook.find_spec("file") is not None | ||
assert self.find_spec_calls == ["file"] | ||
|
||
def test_assert_rewrites_only_invocation_path( | ||
self, pytester: Pytester, hook: AssertionRewritingHook, monkeypatch | ||
) -> None: | ||
"""Do not rewrite assertions in tests outside `AssertState.rootpath` (#13403).""" | ||
pytester.makepyfile( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would prefer to avoid mocking here, instead using a real scenario to ensure Python files outside of the rootpath do not have their assertions rewritten. Please create a simple but real-world project using
Then execute If I understand the objective of the issue correctly:
I think the scenario above should cover what needs to be tested. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need to include an external plugin here too, to test the same scenario as in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've tried to create the structure along with a some conftest plugin. Even witout changes it doen't rewrite conftest plugins assertions Example: However it sees only top-level plugins: Does it an expected behavior? How does pytest provide plugins which are needed to be rewritten at the import stage? May be I do something wrong There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should rewrite the conftest files If it doesn't then we have a bug we missed that needs a additional regression test |
||
**{ | ||
"file.py": """\ | ||
def test_simple_failure(): | ||
assert 1 + 1 == 3 | ||
""" | ||
} | ||
) | ||
|
||
with mock.patch.object(hook, "fnpats", ["*.py"]): | ||
assert hook.find_spec("file") is not None | ||
|
||
invocation_path = f"{os.getcwd()}/tests" | ||
monkeypatch.setattr( | ||
pytester._request.config.stash[assertstate_key], | ||
"invocation_path", | ||
invocation_path, | ||
) | ||
|
||
with mock.patch.object(hook, "fnpats", ["*.py"]): | ||
assert hook.find_spec("file") is None | ||
|
||
@pytest.mark.skipif( | ||
sys.platform.startswith("win32"), reason="cannot remove cwd on Windows" | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do i gather correct that this bit is to alter the assertion rewtiter state
we should alter only that state, not the full pytest config of the surrounding pytest - this looks like a assertion rewriter shortcoming that needs a followup after this
but we certainly need to alter the assertion hook in sys metapath instead of a pytest config
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pytester doesn't know anything about the AssertionState yet. In order to solve that I need to think in someway how to do this better
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should go with a temporary solution and add a followup issue