capper 0.4.0__tar.gz → 0.5.0__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.
- {capper-0.4.0 → capper-0.5.0}/PKG-INFO +8 -3
- {capper-0.4.0 → capper-0.5.0}/README.md +7 -2
- {capper-0.4.0 → capper-0.5.0}/capper/__init__.py +1 -1
- capper-0.5.0/capper/_deprecations.py +29 -0
- {capper-0.4.0 → capper-0.5.0}/capper/cli.py +29 -4
- {capper-0.4.0 → capper-0.5.0}/capper/tests/test_cli.py +1 -0
- capper-0.5.0/capper/tests/test_deprecations.py +26 -0
- {capper-0.4.0 → capper-0.5.0}/capper/tests/test_edge_cases.py +2 -2
- {capper-0.4.0 → capper-0.5.0}/capper.egg-info/PKG-INFO +8 -3
- {capper-0.4.0 → capper-0.5.0}/capper.egg-info/SOURCES.txt +2 -0
- {capper-0.4.0 → capper-0.5.0}/pyproject.toml +1 -1
- {capper-0.4.0 → capper-0.5.0}/capper/barcode.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/base.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/color.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/commerce.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/date_time.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/examples/user_factory.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/file.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/finance.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/geo.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/internet.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/misc.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/person.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/phone.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/registry.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/strategies.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/tests/__init__.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/tests/benchmark_core.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/tests/conftest.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/tests/test_docs_examples.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/tests/test_hypothesis_strategies.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/tests/test_polyfactory_integration.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/tests/test_thread_safety.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/tests/test_types.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper/text.py +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper.egg-info/dependency_links.txt +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper.egg-info/entry_points.txt +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper.egg-info/requires.txt +0 -0
- {capper-0.4.0 → capper-0.5.0}/capper.egg-info/top_level.txt +0 -0
- {capper-0.4.0 → capper-0.5.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: capper
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Semantic, typed wrappers for Faker with automatic Polyfactory integration
|
|
5
5
|
Author-email: Odos Matthews <odosmatthews@gmail.com>
|
|
6
6
|
Project-URL: Documentation, https://github.com/eddiethedean/capper#readme
|
|
@@ -160,7 +160,7 @@ Use `-n`/`--count` for the number of rows and `-s`/`--seed` for reproducible out
|
|
|
160
160
|
|
|
161
161
|
## Compatibility
|
|
162
162
|
|
|
163
|
-
Capper targets **Python 3.10+**, **Faker >= 20.0**, and **Polyfactory >= 2.0**. For version ranges, upgrade guidance, and the deprecation policy, see [Compatibility](docs/compatibility.md).
|
|
163
|
+
Capper targets **Python 3.10+**, **Faker >= 20.0**, and **Polyfactory >= 2.0**. For version ranges, upgrade guidance, the versioning policy, and the deprecation policy, see [Compatibility](docs/compatibility.md).
|
|
164
164
|
|
|
165
165
|
## What's new in 0.4.0
|
|
166
166
|
|
|
@@ -208,7 +208,7 @@ Releases are built and published to PyPI via [GitHub Actions](https://github.com
|
|
|
208
208
|
|
|
209
209
|
1. Update [CHANGELOG.md](CHANGELOG.md): move Unreleased entries into a new version section and date it.
|
|
210
210
|
2. Add a `PYPI_API_TOKEN` secret (PyPI API token) to the repo.
|
|
211
|
-
3. Create a GitHub release (tag e.g. `v0.4.
|
|
211
|
+
3. Create a GitHub release (tag e.g. `v0.4.1`). The workflow runs tests, builds the package, and uploads to PyPI.
|
|
212
212
|
|
|
213
213
|
To build and upload manually: `pip install build twine`, `python -m build`, `twine upload dist/*`.
|
|
214
214
|
|
|
@@ -222,6 +222,11 @@ To build and upload manually: `pip install build twine`, `python -m build`, `twi
|
|
|
222
222
|
- [Models and factories](docs/user_guides/models_and_factories.md) — Pydantic, dataclasses, batches
|
|
223
223
|
- [Reproducible data](docs/user_guides/reproducible_data.md) — seeding for tests and demos
|
|
224
224
|
- [Custom types](docs/user_guides/custom_types.md) — `FakerType` subclasses and `faker_kwargs`
|
|
225
|
+
- [FastAPI + Pydantic](docs/user_guides/fastapi_pydantic.md) — API payloads and tests using Capper-backed Pydantic models
|
|
226
|
+
- [Django patterns](docs/user_guides/django_patterns.md) — Django-style schemas, factories, and service tests
|
|
227
|
+
- [Dataclasses and attrs](docs/user_guides/dataclasses_and_attrs.md) — non-Pydantic projects with `DataclassFactory`
|
|
228
|
+
- [Test setup templates](docs/user_guides/test_setup_templates.md) — pytest/Hypothesis fixtures and seeding patterns
|
|
229
|
+
- [Project structure](docs/user_guides/project_structure.md) — organizing Capper types, factories, and type packs
|
|
225
230
|
- [Package plan](docs/capper_package_plan.md) — design and rationale
|
|
226
231
|
- [Roadmap](docs/ROADMAP.md) — development phases and status
|
|
227
232
|
- [Faker provider mapping](docs/FAKER_PROVIDERS.md) — which Faker method each type uses
|
|
@@ -132,7 +132,7 @@ Use `-n`/`--count` for the number of rows and `-s`/`--seed` for reproducible out
|
|
|
132
132
|
|
|
133
133
|
## Compatibility
|
|
134
134
|
|
|
135
|
-
Capper targets **Python 3.10+**, **Faker >= 20.0**, and **Polyfactory >= 2.0**. For version ranges, upgrade guidance, and the deprecation policy, see [Compatibility](docs/compatibility.md).
|
|
135
|
+
Capper targets **Python 3.10+**, **Faker >= 20.0**, and **Polyfactory >= 2.0**. For version ranges, upgrade guidance, the versioning policy, and the deprecation policy, see [Compatibility](docs/compatibility.md).
|
|
136
136
|
|
|
137
137
|
## What's new in 0.4.0
|
|
138
138
|
|
|
@@ -180,7 +180,7 @@ Releases are built and published to PyPI via [GitHub Actions](https://github.com
|
|
|
180
180
|
|
|
181
181
|
1. Update [CHANGELOG.md](CHANGELOG.md): move Unreleased entries into a new version section and date it.
|
|
182
182
|
2. Add a `PYPI_API_TOKEN` secret (PyPI API token) to the repo.
|
|
183
|
-
3. Create a GitHub release (tag e.g. `v0.4.
|
|
183
|
+
3. Create a GitHub release (tag e.g. `v0.4.1`). The workflow runs tests, builds the package, and uploads to PyPI.
|
|
184
184
|
|
|
185
185
|
To build and upload manually: `pip install build twine`, `python -m build`, `twine upload dist/*`.
|
|
186
186
|
|
|
@@ -194,6 +194,11 @@ To build and upload manually: `pip install build twine`, `python -m build`, `twi
|
|
|
194
194
|
- [Models and factories](docs/user_guides/models_and_factories.md) — Pydantic, dataclasses, batches
|
|
195
195
|
- [Reproducible data](docs/user_guides/reproducible_data.md) — seeding for tests and demos
|
|
196
196
|
- [Custom types](docs/user_guides/custom_types.md) — `FakerType` subclasses and `faker_kwargs`
|
|
197
|
+
- [FastAPI + Pydantic](docs/user_guides/fastapi_pydantic.md) — API payloads and tests using Capper-backed Pydantic models
|
|
198
|
+
- [Django patterns](docs/user_guides/django_patterns.md) — Django-style schemas, factories, and service tests
|
|
199
|
+
- [Dataclasses and attrs](docs/user_guides/dataclasses_and_attrs.md) — non-Pydantic projects with `DataclassFactory`
|
|
200
|
+
- [Test setup templates](docs/user_guides/test_setup_templates.md) — pytest/Hypothesis fixtures and seeding patterns
|
|
201
|
+
- [Project structure](docs/user_guides/project_structure.md) — organizing Capper types, factories, and type packs
|
|
197
202
|
- [Package plan](docs/capper_package_plan.md) — design and rationale
|
|
198
203
|
- [Roadmap](docs/ROADMAP.md) — development phases and status
|
|
199
204
|
- [Faker provider mapping](docs/FAKER_PROVIDERS.md) — which Faker method each type uses
|
|
@@ -11,7 +11,7 @@ try:
|
|
|
11
11
|
|
|
12
12
|
__version__ = _version("capper")
|
|
13
13
|
except Exception: # Package not installed (e.g. dev tree) or metadata missing
|
|
14
|
-
__version__ = "0.
|
|
14
|
+
__version__ = "0.5.0"
|
|
15
15
|
|
|
16
16
|
from .barcode import EAN8, EAN13
|
|
17
17
|
from .base import FakerType, faker, seed, use_faker
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Internal helpers for deprecation warnings.
|
|
2
|
+
|
|
3
|
+
Use warn_deprecated() to emit consistent DeprecationWarning messages.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from warnings import warn
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def warn_deprecated(
|
|
12
|
+
name: str,
|
|
13
|
+
*,
|
|
14
|
+
removal_version: str,
|
|
15
|
+
alternative: str | None = None,
|
|
16
|
+
stacklevel: int = 2,
|
|
17
|
+
) -> None:
|
|
18
|
+
"""Emit a standardized DeprecationWarning for a Capper API.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
name: Fully qualified name of the deprecated API.
|
|
22
|
+
removal_version: Target version where the API is expected to be removed.
|
|
23
|
+
alternative: Optional string describing the preferred replacement.
|
|
24
|
+
stacklevel: Passed through to warnings.warn to point at the caller.
|
|
25
|
+
"""
|
|
26
|
+
message = f"{name} is deprecated and will be removed in {removal_version}."
|
|
27
|
+
if alternative:
|
|
28
|
+
message += f" Use {alternative} instead."
|
|
29
|
+
warn(message, DeprecationWarning, stacklevel=stacklevel)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""CLI for ad-hoc fake data generation."""
|
|
2
2
|
|
|
3
3
|
import argparse
|
|
4
|
+
import difflib
|
|
4
5
|
import sys
|
|
5
6
|
from typing import Mapping, Sequence, Type
|
|
6
7
|
|
|
@@ -32,14 +33,26 @@ def _generate_rows(types: Sequence[Type[FakerType]], count: int) -> list[str]:
|
|
|
32
33
|
return rows
|
|
33
34
|
|
|
34
35
|
|
|
36
|
+
def _unknown_type_message(name: str, registry: Mapping[str, Type[FakerType]]) -> str:
|
|
37
|
+
known_names = sorted(registry)
|
|
38
|
+
suggestions = difflib.get_close_matches(name, known_names, n=3)
|
|
39
|
+
parts = [f"Unknown type: {name}."]
|
|
40
|
+
if suggestions:
|
|
41
|
+
parts.append(f" Did you mean: {', '.join(suggestions)}?")
|
|
42
|
+
else:
|
|
43
|
+
sample = ", ".join(known_names[:5])
|
|
44
|
+
parts.append(f" Known types include: {sample}, ...")
|
|
45
|
+
parts.append(" See the Capper docs or `FAKER_PROVIDERS.md` for the full list.")
|
|
46
|
+
return "".join(parts)
|
|
47
|
+
|
|
48
|
+
|
|
35
49
|
def cmd_generate(args: argparse.Namespace) -> int:
|
|
36
50
|
"""Run generate subcommand."""
|
|
37
51
|
registry = _type_registry()
|
|
38
52
|
types: list[Type[FakerType]] = []
|
|
39
53
|
for name in args.types:
|
|
40
54
|
if name not in registry:
|
|
41
|
-
|
|
42
|
-
print(f"Unknown type: {name}. Known: {known}", file=sys.stderr)
|
|
55
|
+
print(_unknown_type_message(name, registry), file=sys.stderr)
|
|
43
56
|
return 1
|
|
44
57
|
types.append(registry[name])
|
|
45
58
|
|
|
@@ -54,11 +67,23 @@ def cmd_generate(args: argparse.Namespace) -> int:
|
|
|
54
67
|
def main() -> int:
|
|
55
68
|
"""Entry point for the capper CLI."""
|
|
56
69
|
parser = argparse.ArgumentParser(
|
|
57
|
-
prog="capper",
|
|
70
|
+
prog="capper",
|
|
71
|
+
description="Capper: fake data via Faker-backed types, integrated with Polyfactory.",
|
|
72
|
+
epilog=(
|
|
73
|
+
"Examples:\n"
|
|
74
|
+
" capper generate Name Email --count 5\n"
|
|
75
|
+
" capper generate Name Email --count 3 --seed 42\n"
|
|
76
|
+
"\n"
|
|
77
|
+
"Type names match the Python types, e.g. Name, Email, Address."
|
|
78
|
+
),
|
|
79
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
58
80
|
)
|
|
59
81
|
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
60
82
|
|
|
61
|
-
gen = subparsers.add_parser(
|
|
83
|
+
gen = subparsers.add_parser(
|
|
84
|
+
"generate",
|
|
85
|
+
help="Generate tab-separated fake values for one or more Capper types.",
|
|
86
|
+
)
|
|
62
87
|
gen.add_argument(
|
|
63
88
|
"types",
|
|
64
89
|
nargs="+",
|
|
@@ -62,6 +62,7 @@ def test_cli_unknown_type_exits_nonzero_and_stderr(capsys: pytest.CaptureFixture
|
|
|
62
62
|
err = capsys.readouterr().err
|
|
63
63
|
assert "Unknown type" in err
|
|
64
64
|
assert "NonExistentType" in err
|
|
65
|
+
assert "Known types include" in err or "Did you mean" in err
|
|
65
66
|
finally:
|
|
66
67
|
sys.argv = orig_argv
|
|
67
68
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""Tests for the internal deprecation helper."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from warnings import catch_warnings, simplefilter
|
|
6
|
+
|
|
7
|
+
from capper._deprecations import warn_deprecated
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def test_warn_deprecated_emits_standard_message() -> None:
|
|
11
|
+
"""warn_deprecated() emits a DeprecationWarning with the expected text."""
|
|
12
|
+
with catch_warnings(record=True) as caught:
|
|
13
|
+
simplefilter("always", DeprecationWarning)
|
|
14
|
+
warn_deprecated(
|
|
15
|
+
"capper.some_api",
|
|
16
|
+
removal_version="0.6.0",
|
|
17
|
+
alternative="capper.new_api",
|
|
18
|
+
stacklevel=1,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
assert caught, "Expected at least one DeprecationWarning"
|
|
22
|
+
warning = caught[0]
|
|
23
|
+
assert issubclass(warning.category, DeprecationWarning)
|
|
24
|
+
message = str(warning.message)
|
|
25
|
+
assert "capper.some_api is deprecated and will be removed in 0.6.0." in message
|
|
26
|
+
assert "Use capper.new_api instead." in message
|
|
@@ -10,13 +10,13 @@ from capper.base import FakerType
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
def test_version_fallback_when_metadata_missing() -> None:
|
|
13
|
-
"""When importlib.metadata.version raises, __version__ falls back to
|
|
13
|
+
"""When importlib.metadata.version raises, __version__ falls back to the bundled version."""
|
|
14
14
|
with patch("importlib.metadata.version", side_effect=Exception("no metadata")):
|
|
15
15
|
if "capper" in sys.modules:
|
|
16
16
|
del sys.modules["capper"]
|
|
17
17
|
import capper as capper_mod
|
|
18
18
|
|
|
19
|
-
assert capper_mod.__version__ == "0.
|
|
19
|
+
assert capper_mod.__version__ == "0.5.0"
|
|
20
20
|
# Reimport so later tests see the real version
|
|
21
21
|
if "capper" in sys.modules:
|
|
22
22
|
del sys.modules["capper"]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: capper
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Semantic, typed wrappers for Faker with automatic Polyfactory integration
|
|
5
5
|
Author-email: Odos Matthews <odosmatthews@gmail.com>
|
|
6
6
|
Project-URL: Documentation, https://github.com/eddiethedean/capper#readme
|
|
@@ -160,7 +160,7 @@ Use `-n`/`--count` for the number of rows and `-s`/`--seed` for reproducible out
|
|
|
160
160
|
|
|
161
161
|
## Compatibility
|
|
162
162
|
|
|
163
|
-
Capper targets **Python 3.10+**, **Faker >= 20.0**, and **Polyfactory >= 2.0**. For version ranges, upgrade guidance, and the deprecation policy, see [Compatibility](docs/compatibility.md).
|
|
163
|
+
Capper targets **Python 3.10+**, **Faker >= 20.0**, and **Polyfactory >= 2.0**. For version ranges, upgrade guidance, the versioning policy, and the deprecation policy, see [Compatibility](docs/compatibility.md).
|
|
164
164
|
|
|
165
165
|
## What's new in 0.4.0
|
|
166
166
|
|
|
@@ -208,7 +208,7 @@ Releases are built and published to PyPI via [GitHub Actions](https://github.com
|
|
|
208
208
|
|
|
209
209
|
1. Update [CHANGELOG.md](CHANGELOG.md): move Unreleased entries into a new version section and date it.
|
|
210
210
|
2. Add a `PYPI_API_TOKEN` secret (PyPI API token) to the repo.
|
|
211
|
-
3. Create a GitHub release (tag e.g. `v0.4.
|
|
211
|
+
3. Create a GitHub release (tag e.g. `v0.4.1`). The workflow runs tests, builds the package, and uploads to PyPI.
|
|
212
212
|
|
|
213
213
|
To build and upload manually: `pip install build twine`, `python -m build`, `twine upload dist/*`.
|
|
214
214
|
|
|
@@ -222,6 +222,11 @@ To build and upload manually: `pip install build twine`, `python -m build`, `twi
|
|
|
222
222
|
- [Models and factories](docs/user_guides/models_and_factories.md) — Pydantic, dataclasses, batches
|
|
223
223
|
- [Reproducible data](docs/user_guides/reproducible_data.md) — seeding for tests and demos
|
|
224
224
|
- [Custom types](docs/user_guides/custom_types.md) — `FakerType` subclasses and `faker_kwargs`
|
|
225
|
+
- [FastAPI + Pydantic](docs/user_guides/fastapi_pydantic.md) — API payloads and tests using Capper-backed Pydantic models
|
|
226
|
+
- [Django patterns](docs/user_guides/django_patterns.md) — Django-style schemas, factories, and service tests
|
|
227
|
+
- [Dataclasses and attrs](docs/user_guides/dataclasses_and_attrs.md) — non-Pydantic projects with `DataclassFactory`
|
|
228
|
+
- [Test setup templates](docs/user_guides/test_setup_templates.md) — pytest/Hypothesis fixtures and seeding patterns
|
|
229
|
+
- [Project structure](docs/user_guides/project_structure.md) — organizing Capper types, factories, and type packs
|
|
225
230
|
- [Package plan](docs/capper_package_plan.md) — design and rationale
|
|
226
231
|
- [Roadmap](docs/ROADMAP.md) — development phases and status
|
|
227
232
|
- [Faker provider mapping](docs/FAKER_PROVIDERS.md) — which Faker method each type uses
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
README.md
|
|
2
2
|
pyproject.toml
|
|
3
3
|
capper/__init__.py
|
|
4
|
+
capper/_deprecations.py
|
|
4
5
|
capper/barcode.py
|
|
5
6
|
capper/base.py
|
|
6
7
|
capper/cli.py
|
|
@@ -28,6 +29,7 @@ capper/tests/__init__.py
|
|
|
28
29
|
capper/tests/benchmark_core.py
|
|
29
30
|
capper/tests/conftest.py
|
|
30
31
|
capper/tests/test_cli.py
|
|
32
|
+
capper/tests/test_deprecations.py
|
|
31
33
|
capper/tests/test_docs_examples.py
|
|
32
34
|
capper/tests/test_edge_cases.py
|
|
33
35
|
capper/tests/test_hypothesis_strategies.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|