pytest-resources 0.2.1__tar.gz → 0.2.2__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 (36) hide show
  1. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/CHANGELOG.md +18 -1
  2. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/PKG-INFO +16 -4
  3. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/README.md +15 -3
  4. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/pyproject.toml +1 -1
  5. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/tests/integration/test_synth_library.py +18 -1
  6. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/tests/unit/test_formats.py +10 -0
  7. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/tests/unit/test_nodes_synth.py +12 -0
  8. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/.gitignore +0 -0
  9. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/LICENSE +0 -0
  10. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/src/pytest_resources/__init__.py +0 -0
  11. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/src/pytest_resources/errors.py +0 -0
  12. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/src/pytest_resources/formats.py +0 -0
  13. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/src/pytest_resources/hooks.py +0 -0
  14. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/src/pytest_resources/index.py +0 -0
  15. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/src/pytest_resources/loaders.py +0 -0
  16. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/src/pytest_resources/nodes.py +0 -0
  17. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/src/pytest_resources/plugin.py +0 -0
  18. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/src/pytest_resources/py.typed +0 -0
  19. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/src/pytest_resources/synth.py +0 -0
  20. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/tests/integration/test_library.py +0 -0
  21. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/tests/resources/binary/blob.dat +0 -0
  22. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/tests/resources/config/app.ini +0 -0
  23. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/tests/resources/config/manifest.jsonc +0 -0
  24. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/tests/resources/config/settings.toml +0 -0
  25. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/tests/resources/data/movies.csv +0 -0
  26. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/tests/resources/structured/nested/deep.json +0 -0
  27. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/tests/resources/structured/sample.json +0 -0
  28. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/tests/resources/structured/sample2.json +0 -0
  29. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/tests/resources/unstructured/sample.md +0 -0
  30. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/tests/resources/unstructured/sample2.md +0 -0
  31. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/tests/unit/test_hook.py +0 -0
  32. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/tests/unit/test_index.py +0 -0
  33. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/tests/unit/test_init.py +0 -0
  34. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/tests/unit/test_loaders.py +0 -0
  35. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/tests/unit/test_plugin.py +0 -0
  36. {pytest_resources-0.2.1 → pytest_resources-0.2.2}/tests/unit/test_synth.py +0 -0
@@ -6,6 +6,22 @@ adheres to [Semantic Versioning](https://semver.org/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.2.2] - 2026-09-24
10
+
11
+ ### Changed
12
+
13
+ - Documentation: the synthesis surface (`make` / `batch` / `file`) is covered end to end,
14
+ with a new async-testing section (pure-CPU `make`/`batch`, `awalk` over adopted files,
15
+ off-loop `to_thread` for the network-backed `mp3`); the format matrix notes the document
16
+ and image kinds. The coverage floor is raised from 90% to 95% (current: 100%).
17
+
18
+ ### Added
19
+
20
+ - Tests for `TypedDict` model synthesis, the `batch` default size, the extra synthetic file
21
+ suffixes, and the synthesis provider's memoization.
22
+
23
+ No behavioural change to the packaged wheel.
24
+
9
25
  ## [0.2.1] - 2026-09-24
10
26
 
11
27
  ### Fixed
@@ -63,7 +79,8 @@ First release.
63
79
  - A module-lifetime decode cache per tree, and typed misses (`EntryNotFoundError` /
64
80
  `KeyError`) that carry a `difflib` "did you mean" hint.
65
81
 
66
- [unreleased]: https://github.com/damvolkov/pytest-resources/compare/v0.2.1...HEAD
82
+ [unreleased]: https://github.com/damvolkov/pytest-resources/compare/v0.2.2...HEAD
83
+ [0.2.2]: https://github.com/damvolkov/pytest-resources/releases/tag/v0.2.2
67
84
  [0.2.1]: https://github.com/damvolkov/pytest-resources/releases/tag/v0.2.1
68
85
  [0.2.0]: https://github.com/damvolkov/pytest-resources/releases/tag/v0.2.0
69
86
  [0.1.0]: https://github.com/damvolkov/pytest-resources/releases/tag/v0.1.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: pytest-resources
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: Lazy, typed, attribute-navigable fixtures for test resource files, with pluggable canonical loaders (e-serde by default).
5
5
  Project-URL: Homepage, https://github.com/damvolkov/pytest-resources
6
6
  Project-URL: Source, https://github.com/damvolkov/pytest-resources
@@ -39,12 +39,21 @@ extensible to **any** canonical `bytes -> object` loader, and anything else hand
39
39
  raw `bytes`.
40
40
 
41
41
  You point it at one or more directories of sample files; it recursively indexes the tree
42
- without reading anything, and you reach, filter and randomise parsed values the way they
43
- read:
42
+ without reading anything, and you reach, filter, randomise and synthesize parsed values
43
+ the way they read:
44
44
 
45
45
  ```python
46
+ from dataclasses import dataclass
47
+
46
48
  import pytest_resources as pr
47
49
 
50
+
51
+ @dataclass
52
+ class User:
53
+ name: str
54
+ age: int
55
+
56
+
48
57
  def test_profile(resources: pr.Resources):
49
58
  user = resources.structured.user # sample dir -> dict (decoded, cached)
50
59
  body = resources.unstructured.intro # a .md -> str
@@ -69,7 +78,10 @@ uv add --group test "pytest-resources[random]" # both
69
78
  ```
70
79
 
71
80
  The `resources` fixture auto-loads via the `pytest11` entry point — no imports in your
72
- `conftest.py`.
81
+ `conftest.py`. Everything (index, navigation, synthesis) is async-test friendly:
82
+ `make`/`batch` are pure in-memory CPU and `abuild_resources`/`awalk` keep the loop free;
83
+ calling a synthesis method without its extra raises `ExtraNotInstalledError` with the
84
+ exact install command — the plugin never hard-depends on polyfactory or faker-file.
73
85
 
74
86
  ## What you get
75
87
 
@@ -6,12 +6,21 @@ extensible to **any** canonical `bytes -> object` loader, and anything else hand
6
6
  raw `bytes`.
7
7
 
8
8
  You point it at one or more directories of sample files; it recursively indexes the tree
9
- without reading anything, and you reach, filter and randomise parsed values the way they
10
- read:
9
+ without reading anything, and you reach, filter, randomise and synthesize parsed values
10
+ the way they read:
11
11
 
12
12
  ```python
13
+ from dataclasses import dataclass
14
+
13
15
  import pytest_resources as pr
14
16
 
17
+
18
+ @dataclass
19
+ class User:
20
+ name: str
21
+ age: int
22
+
23
+
15
24
  def test_profile(resources: pr.Resources):
16
25
  user = resources.structured.user # sample dir -> dict (decoded, cached)
17
26
  body = resources.unstructured.intro # a .md -> str
@@ -36,7 +45,10 @@ uv add --group test "pytest-resources[random]" # both
36
45
  ```
37
46
 
38
47
  The `resources` fixture auto-loads via the `pytest11` entry point — no imports in your
39
- `conftest.py`.
48
+ `conftest.py`. Everything (index, navigation, synthesis) is async-test friendly:
49
+ `make`/`batch` are pure in-memory CPU and `abuild_resources`/`awalk` keep the loop free;
50
+ calling a synthesis method without its extra raises `ExtraNotInstalledError` with the
51
+ exact install command — the plugin never hard-depends on polyfactory or faker-file.
40
52
 
41
53
  ## What you get
42
54
 
@@ -160,7 +160,7 @@ branch = true
160
160
  parallel = true
161
161
 
162
162
  [tool.coverage.report]
163
- fail_under = 90
163
+ fail_under = 95
164
164
  show_missing = true
165
165
  skip_covered = true
166
166
  exclude_also = ["if TYPE_CHECKING:", "@overload", "raise NotImplementedError", '^\s*\.\.\.$']
@@ -8,7 +8,7 @@ same loader table as any authored resource.
8
8
  from __future__ import annotations
9
9
 
10
10
  from dataclasses import dataclass
11
- from typing import TYPE_CHECKING, Any
11
+ from typing import TYPE_CHECKING, Any, TypedDict
12
12
 
13
13
  import attrs
14
14
  import msgspec
@@ -45,6 +45,11 @@ class Book:
45
45
  pages: int
46
46
 
47
47
 
48
+ class Row(TypedDict):
49
+ k: str
50
+ v: int
51
+
52
+
48
53
  @pytest.fixture
49
54
  def tree(tmp_path: Path) -> Resources:
50
55
  return pr.build_resources(tmp_path)
@@ -62,6 +67,18 @@ def test_make_autodetects_every_model_family(tree: Resources, model: type[Any])
62
67
  assert isinstance(tree.make(model), model)
63
68
 
64
69
 
70
+ def test_make_builds_a_typeddict_model(tree: Resources) -> None:
71
+ row = tree.make(Row)
72
+ assert isinstance(row, dict)
73
+ assert set(row) == {"k", "v"}
74
+ assert isinstance(row["k"], str)
75
+ assert isinstance(row["v"], int)
76
+
77
+
78
+ def test_batch_defaults_to_ten(tree: Resources) -> None:
79
+ assert len(tree.batch(User)) == 10
80
+
81
+
65
82
  def test_batch_returns_n_instances(tree: Resources) -> None:
66
83
  squad = tree.batch(User, 4)
67
84
  assert [type(item) for item in squad] == [User] * 4
@@ -16,6 +16,16 @@ from pytest_resources import FileType
16
16
  (".cfg", FileType.INI),
17
17
  (".jsonl", FileType.NDJSON),
18
18
  (".md", FileType.MARKDOWN),
19
+ (".pdf", FileType.PDF),
20
+ (".docx", FileType.DOCX),
21
+ (".xlsx", FileType.XLSX),
22
+ (".jpg", FileType.JPEG),
23
+ (".jpeg", FileType.JPEG),
24
+ (".tif", FileType.TIFF),
25
+ (".tiff", FileType.TIFF),
26
+ (".webp", FileType.WEBP),
27
+ (".eml", FileType.EML),
28
+ (".zip", FileType.ZIP),
19
29
  ],
20
30
  )
21
31
  def test_filetype_of_known_suffix(suffix: str, expected: FileType) -> None:
@@ -9,6 +9,7 @@ from typing import TYPE_CHECKING
9
9
  import pytest
10
10
 
11
11
  from pytest_resources import build_resources
12
+ from pytest_resources.synth import SynthProvider
12
13
 
13
14
  if TYPE_CHECKING:
14
15
  from pytest_resources.nodes import Resources
@@ -50,6 +51,17 @@ def test_synth_module_stays_unloaded_until_first_use(tree: Resources) -> None:
50
51
  assert tree._synth is None
51
52
 
52
53
 
54
+ def test_synth_is_built_once_and_memoized(tree: Resources) -> None:
55
+ tree.make(int)
56
+ assert isinstance(tree._synth, SynthProvider)
57
+ assert tree._common_synth() is tree._synth
58
+
59
+
60
+ def test_assigned_synth_is_not_rebuilt(tree: Resources) -> None:
61
+ tree._synth = stub = _StubProvider()
62
+ assert tree._common_synth() is stub
63
+
64
+
53
65
  def test_make_forwards_spec_seed_and_fields(tree: Resources) -> None:
54
66
  tree._synth = stub = _StubProvider()
55
67
  assert tree.make(User, seed=5, name="ada") == "OBJECT"