pytest-regtest 2.3.3__tar.gz → 2.3.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. {pytest_regtest-2.3.3/src/pytest_regtest.egg-info → pytest_regtest-2.3.5}/PKG-INFO +4 -4
  2. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/pyproject.toml +26 -10
  3. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/src/pytest_regtest/__init__.py +0 -1
  4. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/src/pytest_regtest/numpy_handler.py +1 -2
  5. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/src/pytest_regtest/pandas_handler.py +8 -13
  6. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/src/pytest_regtest/pytest_regtest.py +16 -8
  7. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5/src/pytest_regtest.egg-info}/PKG-INFO +4 -4
  8. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/tests/conftest.py +1 -0
  9. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/tests/test_regtest.py +49 -2
  10. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/LICENSE.txt +0 -0
  11. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/MANIFEST.in +0 -0
  12. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/README.md +0 -0
  13. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/setup.cfg +0 -0
  14. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/src/pytest_regtest/polars_handler.py +0 -0
  15. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/src/pytest_regtest/register_third_party_handlers.py +0 -0
  16. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/src/pytest_regtest/snapshot_handler.py +0 -0
  17. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/src/pytest_regtest/utils.py +0 -0
  18. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/src/pytest_regtest.egg-info/SOURCES.txt +0 -0
  19. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/src/pytest_regtest.egg-info/dependency_links.txt +0 -0
  20. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/src/pytest_regtest.egg-info/entry_points.txt +0 -0
  21. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/src/pytest_regtest.egg-info/requires.txt +0 -0
  22. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/src/pytest_regtest.egg-info/top_level.txt +0 -0
  23. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/tests/test_cli.py +0 -0
  24. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/tests/test_snapshot.py +0 -0
  25. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/tests/test_snapshot_numpy.py +0 -0
  26. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/tests/test_snapshot_pandas.py +0 -0
  27. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/tests/test_snapshot_polars.py +0 -0
  28. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/tests/test_snapshot_python_types.py +0 -0
  29. {pytest_regtest-2.3.3 → pytest_regtest-2.3.5}/tests/test_utils.py +0 -0
@@ -1,9 +1,9 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: pytest-regtest
3
- Version: 2.3.3
3
+ Version: 2.3.5
4
4
  Summary: pytest plugin for snapshot regression testing
5
5
  Author-email: Uwe Schmitt <uwe.schmitt@id.ethz.ch>
6
- License: MIT License
6
+ License-Expression: MIT
7
7
  Project-URL: Source, https://gitlab.com/uweschmitt/pytest-regtest
8
8
  Project-URL: Documentation, https://pytest-regtest.readthedocs.org
9
9
  Classifier: Intended Audience :: Developers
@@ -11,10 +11,10 @@ Classifier: Programming Language :: Python :: 3.9
11
11
  Classifier: Programming Language :: Python :: 3.10
12
12
  Classifier: Programming Language :: Python :: 3.11
13
13
  Classifier: Programming Language :: Python :: 3.12
14
- Classifier: License :: OSI Approved :: MIT License
15
14
  Description-Content-Type: text/markdown
16
15
  License-File: LICENSE.txt
17
16
  Requires-Dist: pytest>7.2
17
+ Dynamic: license-file
18
18
 
19
19
  ![](https://gitlab.com/uweschmitt/pytest-regtest/badges/main/pipeline.svg)
20
20
  ![](https://gitlab.com/uweschmitt/pytest-regtest/badges/main/coverage.svg?job=coverage)
@@ -6,14 +6,14 @@ build-backend = "setuptools.build_meta"
6
6
 
7
7
  [project]
8
8
  name = "pytest-regtest"
9
- version = "2.3.3"
9
+ version = "2.3.5"
10
10
  description = "pytest plugin for snapshot regression testing"
11
11
  readme = "README.md"
12
12
  authors = [
13
13
  {name = "Uwe Schmitt", email = "uwe.schmitt@id.ethz.ch"}
14
14
  ]
15
15
 
16
- license = {text = "MIT License"}
16
+ license = "MIT"
17
17
 
18
18
  classifiers = [
19
19
  "Intended Audience :: Developers",
@@ -21,7 +21,6 @@ classifiers = [
21
21
  "Programming Language :: Python :: 3.10",
22
22
  "Programming Language :: Python :: 3.11",
23
23
  "Programming Language :: Python :: 3.12",
24
- "License :: OSI Approved :: MIT License"
25
24
  ]
26
25
 
27
26
  dependencies = [
@@ -43,11 +42,28 @@ exclude = ["_regtest_output"]
43
42
  [tool.ruff.lint]
44
43
  ignore = ["E731", "E203"]
45
44
 
46
- [tool.uv]
47
- dev-dependencies = [
48
- "twine", "build", "hatchling", "wheel", "pre-commit", "ruff", "black",
49
- "pytest-cov", "numpy", "pandas", "mkdocs", "mkdocs-material", "mistletoe",
50
- "mkdocs-awesome-pages-plugin", "jinja2-cli", "mkdocstrings[python]",
51
- "numpy>=2", "pandas>=2", "polars>=1.9",
52
- "md-transformer>=0.0.3"
45
+ [dependency-groups]
46
+ dev = [
47
+ "pandas>=2.2.3",
48
+ "twine",
49
+ "build",
50
+ "hatchling",
51
+ "wheel",
52
+ "pre-commit",
53
+ "ruff",
54
+ "black",
55
+ "pytest-cov",
56
+ "numpy",
57
+ "pandas",
58
+ "mkdocs",
59
+ "mkdocs-material",
60
+ "mistletoe",
61
+ "mkdocs-awesome-pages-plugin",
62
+ "jinja2-cli",
63
+ "mkdocstrings[python]",
64
+ "numpy>=2",
65
+ "pandas>=2",
66
+ "polars>=1.9",
67
+ "md-transformer>=0.0.3",
68
+ "pdbp>=1.7.1",
53
69
  ]
@@ -18,7 +18,6 @@ from .register_third_party_handlers import (
18
18
  register_pandas_handler,
19
19
  register_polars_handler,
20
20
  )
21
-
22
21
  from .snapshot_handler import register_python_object_handler
23
22
 
24
23
  __version__ = _version(__package__)
@@ -145,8 +145,7 @@ class NumpyHandler(BaseSnapshotHandler):
145
145
  " entries"
146
146
  )
147
147
  lines.append(
148
- f"up to given precision settings rtol={self.rtol:e} and"
149
- f" atol={self.atol:e}"
148
+ f"up to given precision settings rtol={self.rtol:e} and atol={self.atol:e}"
150
149
  )
151
150
 
152
151
  return lines
@@ -75,21 +75,16 @@ class DataFrameHandler(BaseSnapshotHandler):
75
75
  def extract(df, selector):
76
76
  return df[[n for (n, t) in zip(df.columns, df.dtypes) if selector(t)]]
77
77
 
78
- current_reduced_floats = extract(
79
- current_reduced, lambda t: t.type is np.float64
80
- ).to_numpy()
78
+ def is_float(t):
79
+ return t.type in (np.float64, np.float32)
81
80
 
82
- current_reduced_other = extract(
83
- current_reduced, lambda t: t.type is not np.float64
84
- )
81
+ current_reduced_floats = extract(current_reduced, is_float).to_numpy()
85
82
 
86
- recorded_reduced_floats = extract(
87
- recorded_reduced, lambda t: t.type is np.float64
88
- ).to_numpy()
83
+ current_reduced_other = extract(current_reduced, lambda t: not is_float(t))
89
84
 
90
- recorded_reduced_other = extract(
91
- recorded_reduced, lambda t: t.type is not np.float64
92
- )
85
+ recorded_reduced_floats = extract(recorded_reduced, is_float).to_numpy()
86
+
87
+ recorded_reduced_other = extract(recorded_reduced, lambda t: not is_float(t))
93
88
 
94
89
  return np.allclose(
95
90
  current_reduced_floats,
@@ -97,7 +92,7 @@ class DataFrameHandler(BaseSnapshotHandler):
97
92
  atol=self.atol,
98
93
  rtol=self.rtol,
99
94
  equal_nan=True,
100
- ) and (current_reduced_other == recorded_reduced_other).all(axis=None)
95
+ ) and current_reduced_other.equals(recorded_reduced_other)
101
96
 
102
97
  def show_differences(self, current, recorded, has_markup):
103
98
  lines = []
@@ -108,10 +108,6 @@ class PytestRegtestPlugin:
108
108
  if output_exception is not None:
109
109
  raise output_exception
110
110
 
111
- if item.get_closest_marker("xfail") and item.config.getvalue("--regtest-reset"):
112
- # enforce consistency with xfail:
113
- assert False
114
-
115
111
  def check_recorded_output(self, item):
116
112
  test_folder = item.fspath.dirname
117
113
  regtest_stream = item.regtest_stream
@@ -127,6 +123,14 @@ class PytestRegtestPlugin:
127
123
  consider_line_endings = config.getvalue("--regtest-consider-line-endings")
128
124
  reset = config.getvalue("--regtest-reset")
129
125
 
126
+ # Skip reset for xfail tests that are actually expected to fail
127
+ xfail_marker = item.get_closest_marker("xfail")
128
+ if xfail_marker:
129
+ # Check if xfail condition evaluates to True
130
+ condition = xfail_marker.kwargs.get("condition", True)
131
+ if condition is True or (condition is not False and condition):
132
+ reset = False
133
+
130
134
  if reset:
131
135
  os.makedirs(os.path.dirname(recorded_output_path), exist_ok=True)
132
136
  with open(recorded_output_path + ".out", "w", encoding="utf-8") as fh:
@@ -252,10 +256,6 @@ class SnapshotPlugin:
252
256
  if snapshot_exception is not None:
253
257
  raise snapshot_exception
254
258
 
255
- if item.get_closest_marker("xfail") and item.config.getvalue("--regtest-reset"):
256
- # enforce fail
257
- assert False
258
-
259
259
  def check_snapshots(self, item):
260
260
  results = []
261
261
 
@@ -287,6 +287,14 @@ class SnapshotPlugin:
287
287
 
288
288
  reset = config.getvalue("--regtest-reset")
289
289
 
290
+ # Skip reset for xfail tests that are actually expected to fail
291
+ xfail_marker = item.get_closest_marker("xfail")
292
+ if xfail_marker:
293
+ # Check if xfail condition evaluates to True
294
+ condition = xfail_marker.kwargs.get("condition", True)
295
+ if condition is True or (condition is not False and condition):
296
+ reset = False
297
+
290
298
  if reset:
291
299
  os.makedirs(recorded_output_path, exist_ok=True)
292
300
  handler.save(recorded_output_path, obj)
@@ -1,9 +1,9 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: pytest-regtest
3
- Version: 2.3.3
3
+ Version: 2.3.5
4
4
  Summary: pytest plugin for snapshot regression testing
5
5
  Author-email: Uwe Schmitt <uwe.schmitt@id.ethz.ch>
6
- License: MIT License
6
+ License-Expression: MIT
7
7
  Project-URL: Source, https://gitlab.com/uweschmitt/pytest-regtest
8
8
  Project-URL: Documentation, https://pytest-regtest.readthedocs.org
9
9
  Classifier: Intended Audience :: Developers
@@ -11,10 +11,10 @@ Classifier: Programming Language :: Python :: 3.9
11
11
  Classifier: Programming Language :: Python :: 3.10
12
12
  Classifier: Programming Language :: Python :: 3.11
13
13
  Classifier: Programming Language :: Python :: 3.12
14
- Classifier: License :: OSI Approved :: MIT License
15
14
  Description-Content-Type: text/markdown
16
15
  License-File: LICENSE.txt
17
16
  Requires-Dist: pytest>7.2
17
+ Dynamic: license-file
18
18
 
19
19
  ![](https://gitlab.com/uweschmitt/pytest-regtest/badges/main/pipeline.svg)
20
20
  ![](https://gitlab.com/uweschmitt/pytest-regtest/badges/main/coverage.svg?job=coverage)
@@ -1,6 +1,7 @@
1
1
  import sys
2
2
 
3
3
  import numpy
4
+ import pdbp # noqa
4
5
  import pytest
5
6
 
6
7
  # hack to disable reload numpy in pytester (current code only prevent reload of
@@ -135,11 +135,13 @@ def test_xfail(testdir, assert_outcomes):
135
135
  result = testdir.runpytest()
136
136
  assert_outcomes(result, xfailed=1)
137
137
 
138
+ # With --regtest-reset, xfail tests are not reset (output not recorded)
138
139
  result = testdir.runpytest("--regtest-reset")
139
140
  assert_outcomes(result, xfailed=1)
140
141
 
142
+ # Run again - still xfailed because no output was recorded
141
143
  result = testdir.runpytest()
142
- assert_outcomes(result, xpassed=1)
144
+ assert_outcomes(result, xfailed=1)
143
145
 
144
146
 
145
147
  def test_xfail_strict(testdir, assert_outcomes):
@@ -161,11 +163,56 @@ def test_xfail_strict(testdir, assert_outcomes):
161
163
  result = testdir.runpytest()
162
164
  assert_outcomes(result, failed=0, passed=0, xfailed=1)
163
165
 
166
+ # With --regtest-reset, xfail tests are not reset (output not recorded)
164
167
  result = testdir.runpytest("--regtest-reset")
165
168
  assert_outcomes(result, xfailed=1)
166
169
 
170
+ # Run again - still xfailed because no output was recorded
171
+ # With strict=True, an xpass would become a failure, but this stays xfailed
167
172
  result = testdir.runpytest()
168
- assert_outcomes(result, failed=1)
173
+ assert_outcomes(result, xfailed=1)
174
+
175
+
176
+ def test_conditional_xfail(testdir, assert_outcomes):
177
+ testdir.makepyfile(
178
+ """
179
+ import sys
180
+ import pytest
181
+
182
+ @pytest.mark.xfail(condition=sys.platform == "win32", reason="Windows only")
183
+ def test_conditional_xfail_windows(regtest_all):
184
+ print("This test is xfailed on Windows only")
185
+ print(f"Platform: {sys.platform}")
186
+ # This should pass on non-Windows
187
+
188
+ @pytest.mark.xfail(condition=sys.platform != "win32", reason="Non-Windows only")
189
+ def test_conditional_xfail_non_windows(regtest_all):
190
+ print("This test is xfailed on non-Windows only")
191
+ print(f"Platform: {sys.platform}")
192
+ # This should pass on Windows
193
+ """
194
+ )
195
+
196
+ # Run initially - one should fail (no recorded output), one should xfail
197
+ result = testdir.runpytest()
198
+ assert_outcomes(result, failed=1, xfailed=1)
199
+
200
+ # Run with --regtest-reset
201
+ # xfail tests should NOT be reset - they run but output is not recorded
202
+ # The non-xfailed test gets reset, the xfailed one still fails (no output file)
203
+ result = testdir.runpytest("--regtest-reset")
204
+ if IS_WIN:
205
+ # On Windows: test_windows is xfailed, test_non_windows gets reset
206
+ assert_outcomes(result, passed=1, xfailed=1)
207
+ else:
208
+ # On non-Windows: test_windows gets reset, test_non_windows is xfailed
209
+ assert_outcomes(result, passed=1, xfailed=1)
210
+
211
+ # Run again to verify
212
+ # The non-xfailed test should pass (was reset)
213
+ # The xfailed test should still fail (no output file was created)
214
+ result = testdir.runpytest()
215
+ assert_outcomes(result, passed=1, xfailed=1)
169
216
 
170
217
 
171
218
  def test_failed_test(testdir, assert_outcomes):
File without changes
File without changes