objbase 0.3.0__tar.gz → 0.4.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.
- objbase-0.4.0/DEVELOPER.md +131 -0
- {objbase-0.3.0 → objbase-0.4.0}/PKG-INFO +99 -210
- {objbase-0.3.0 → objbase-0.4.0}/README.md +98 -209
- {objbase-0.3.0 → objbase-0.4.0}/examples/async_directory_example.py +3 -3
- {objbase-0.3.0 → objbase-0.4.0}/examples/async_example.py +4 -4
- {objbase-0.3.0 → objbase-0.4.0}/examples/async_file_example.py +3 -3
- {objbase-0.3.0 → objbase-0.4.0}/examples/async_mongodb_example.py +3 -3
- {objbase-0.3.0 → objbase-0.4.0}/examples/async_pydantic_example.py +3 -3
- {objbase-0.3.0 → objbase-0.4.0}/examples/async_sqlite_example.py +3 -3
- {objbase-0.3.0 → objbase-0.4.0}/examples/dict_example.py +2 -2
- {objbase-0.3.0 → objbase-0.4.0}/examples/mongodb_example.py +2 -2
- {objbase-0.3.0 → objbase-0.4.0}/examples/pydantic_example.py +2 -2
- {objbase-0.3.0 → objbase-0.4.0}/pyproject.toml +1 -1
- objbase-0.4.0/src/objbase/__init__.py +58 -0
- objbase-0.3.0/src/objbase/asyncio/async_inventory.py → objbase-0.4.0/src/objbase/asyncio/inventory.py +5 -6
- objbase-0.3.0/src/objbase/asyncio/async_file_storage.py → objbase-0.4.0/src/objbase/asyncio/storage/file_storage.py +9 -9
- objbase-0.3.0/src/objbase/asyncio/async_mongodb_storage.py → objbase-0.4.0/src/objbase/asyncio/storage/mongodb_storage.py +3 -4
- objbase-0.3.0/src/objbase/asyncio/async_redis_storage.py → objbase-0.4.0/src/objbase/asyncio/storage/redis_storage.py +3 -4
- objbase-0.3.0/src/objbase/asyncio/async_sqlite_storage.py → objbase-0.4.0/src/objbase/asyncio/storage/sqlite_storage.py +5 -5
- {objbase-0.3.0/src/objbase/asyncio → objbase-0.4.0/src/objbase/asyncio/storage}/threaded_storage.py +2 -3
- {objbase-0.3.0 → objbase-0.4.0}/src/objbase/interface.py +16 -1
- {objbase-0.3.0 → objbase-0.4.0}/src/objbase/inventory.py +2 -2
- {objbase-0.3.0 → objbase-0.4.0}/src/objbase/pydantic.py +7 -8
- {objbase-0.3.0 → objbase-0.4.0}/src/objbase/storage/file_storage.py +3 -3
- {objbase-0.3.0 → objbase-0.4.0}/src/objbase/storage/inmemory_storage.py +2 -3
- {objbase-0.3.0 → objbase-0.4.0}/src/objbase/storage/mongodb_storage.py +2 -2
- {objbase-0.3.0 → objbase-0.4.0}/src/objbase/storage/redis_storage.py +2 -2
- {objbase-0.3.0 → objbase-0.4.0}/src/objbase/storage/sqlite_storage.py +2 -2
- objbase-0.4.0/src/objbase/util/__init__.py +0 -0
- {objbase-0.3.0 → objbase-0.4.0}/tests/test_async_file_storage.py +8 -8
- {objbase-0.3.0 → objbase-0.4.0}/tests/test_async_inventory.py +10 -10
- {objbase-0.3.0 → objbase-0.4.0}/tests/test_async_mongodb_storage.py +13 -13
- {objbase-0.3.0 → objbase-0.4.0}/tests/test_async_redis_storage.py +12 -12
- {objbase-0.3.0 → objbase-0.4.0}/tests/test_async_sqlite_storage.py +14 -14
- {objbase-0.3.0 → objbase-0.4.0}/tests/test_file_storage.py +34 -34
- {objbase-0.3.0 → objbase-0.4.0}/tests/test_inmemory_storage.py +10 -10
- {objbase-0.3.0 → objbase-0.4.0}/tests/test_inventory.py +5 -5
- {objbase-0.3.0 → objbase-0.4.0}/tests/test_mongodb_storage.py +10 -10
- {objbase-0.3.0 → objbase-0.4.0}/tests/test_package.py +1 -1
- {objbase-0.3.0 → objbase-0.4.0}/tests/test_redis_storage.py +14 -14
- {objbase-0.3.0 → objbase-0.4.0}/tests/test_sqlite_storage.py +15 -15
- {objbase-0.3.0 → objbase-0.4.0}/tests/test_storage_contract.py +33 -33
- {objbase-0.3.0 → objbase-0.4.0}/uv.lock +235 -235
- objbase-0.3.0/src/objbase/__init__.py +0 -59
- objbase-0.3.0/src/objbase/asyncio/async_storage.py +0 -18
- {objbase-0.3.0 → objbase-0.4.0}/.github/dependabot.yml +0 -0
- {objbase-0.3.0 → objbase-0.4.0}/.github/workflows/ci.yml +0 -0
- {objbase-0.3.0 → objbase-0.4.0}/.github/workflows/release.yml +0 -0
- {objbase-0.3.0 → objbase-0.4.0}/.gitignore +0 -0
- {objbase-0.3.0 → objbase-0.4.0}/LICENSE +0 -0
- {objbase-0.3.0 → objbase-0.4.0}/release.sh +0 -0
- {objbase-0.3.0 → objbase-0.4.0}/src/objbase/asyncio/__init__.py +0 -0
- {objbase-0.3.0/src/objbase → objbase-0.4.0/src/objbase/asyncio}/storage/__init__.py +0 -0
- {objbase-0.3.0 → objbase-0.4.0}/src/objbase/errors.py +0 -0
- {objbase-0.3.0 → objbase-0.4.0}/src/objbase/py.typed +0 -0
- {objbase-0.3.0/src/objbase/util → objbase-0.4.0/src/objbase/storage}/__init__.py +0 -0
- {objbase-0.3.0 → objbase-0.4.0}/src/objbase/util/file_util.py +0 -0
- {objbase-0.3.0 → objbase-0.4.0}/src/objbase/util/mongodb_util.py +0 -0
- {objbase-0.3.0 → objbase-0.4.0}/src/objbase/util/redis_util.py +0 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
|
|
2
|
+
## Development
|
|
3
|
+
|
|
4
|
+
Requires [uv](https://docs.astral.sh/uv/). Install the package with all
|
|
5
|
+
development dependencies (pinned in `uv.lock`):
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
uv sync
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Tests
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
uv run pytest
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The Redis and MongoDB tests start containers via
|
|
18
|
+
[testcontainers](https://testcontainers.com/), so Docker must be running. Without
|
|
19
|
+
Docker, the shared contract tests skip those backends, but the Redis and MongoDB test
|
|
20
|
+
modules fail; exclude them to run everything else:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
uv run pytest --ignore=tests/test_redis_storage.py --ignore=tests/test_async_redis_storage.py \
|
|
24
|
+
--ignore=tests/test_mongodb_storage.py --ignore=tests/test_async_mongodb_storage.py
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
MongoDB tests use
|
|
28
|
+
`mongo:7.0`, because `mongo:latest` does not start on Linux kernels 6.19+ (as used by
|
|
29
|
+
recent Docker Desktop VMs). Override the image with `OBJBASE_TEST_MONGO_IMAGE`.
|
|
30
|
+
|
|
31
|
+
### Linting and formatting
|
|
32
|
+
|
|
33
|
+
[Ruff](https://docs.astral.sh/ruff/) checks for likely bugs, style issues, import
|
|
34
|
+
order and outdated syntax. The enabled rules are listed under `[tool.ruff.lint]` in
|
|
35
|
+
`pyproject.toml`.
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
uv run ruff check . # report issues
|
|
39
|
+
uv run ruff check --fix . # apply safe automatic fixes
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Code is formatted with Ruff's formatter (line length 120, set under `[tool.ruff]`).
|
|
43
|
+
CI fails if any file is not formatted:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
uv run ruff format . # format all files
|
|
47
|
+
uv run ruff format --check . # check only, as CI does
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Type checking
|
|
51
|
+
|
|
52
|
+
[mypy](https://mypy.readthedocs.io/) checks the library in strict mode (configured
|
|
53
|
+
under `[tool.mypy]` in `pyproject.toml`):
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
uv run mypy
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Tests and examples are checked too, with rules for unannotated test functions
|
|
60
|
+
relaxed. They use the public API the way users do, so this catches annotations
|
|
61
|
+
that are correct internally but awkward for callers:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
uv run mypy --allow-untyped-defs --allow-incomplete-defs --allow-untyped-calls tests examples
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Continuous integration
|
|
68
|
+
|
|
69
|
+
[GitHub Actions](.github/workflows/ci.yml) runs on every push to `main`, every
|
|
70
|
+
pull request, and as the first stage of every [release](#releasing):
|
|
71
|
+
|
|
72
|
+
| Job | What it does |
|
|
73
|
+
|---|---|
|
|
74
|
+
| Lint, format and type check | Ruff lint, Ruff format check, and the mypy commands above (the library is also checked as Windows sees it, with `--platform win32`) |
|
|
75
|
+
| Test | Full test suite on Python 3.13 and 3.14 |
|
|
76
|
+
| Test (Windows / macOS, no containers) | Test suite without the Redis and MongoDB tests, covering platform-specific code such as file locking |
|
|
77
|
+
| Test (minimum dependency versions) | Test suite with the lowest versions of `redis`, `pymongo` and `pydantic` allowed by `pyproject.toml` |
|
|
78
|
+
| Build distributions | Builds the sdist and wheel, and checks their metadata and contents |
|
|
79
|
+
|
|
80
|
+
Run the lint, format, type check and test commands above before pushing to catch
|
|
81
|
+
failures early.
|
|
82
|
+
|
|
83
|
+
[Dependabot](.github/dependabot.yml) checks weekly for updates and skips
|
|
84
|
+
releases less than a week old:
|
|
85
|
+
|
|
86
|
+
- **GitHub Actions:** all actions in both workflows are pinned to commit SHAs;
|
|
87
|
+
one PR updates the SHAs and their version comments.
|
|
88
|
+
- **Python dependencies:** PRs that update `uv.lock`, one for the backend
|
|
89
|
+
libraries (`redis`, `pymongo`, `pydantic`) and one for dev tools. The `>=`
|
|
90
|
+
minimum versions in `pyproject.toml` are left unchanged.
|
|
91
|
+
|
|
92
|
+
### Releasing
|
|
93
|
+
|
|
94
|
+
Releases are published by the [release workflow](.github/workflows/release.yml)
|
|
95
|
+
when a tag starting with `v` is pushed. Bump the version, commit, then tag the
|
|
96
|
+
commit with the same version:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
uv version 0.3.0
|
|
100
|
+
git commit -am "release 0.3.0"
|
|
101
|
+
git tag v0.3.0
|
|
102
|
+
git push origin main v0.3.0
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The workflow then:
|
|
106
|
+
|
|
107
|
+
1. Checks that the tag matches the version in `pyproject.toml` (`v0.3.0` ↔ `0.3.0`) and fails otherwise.
|
|
108
|
+
2. Runs the full CI workflow.
|
|
109
|
+
3. Builds the sdist and wheel and checks their metadata.
|
|
110
|
+
4. Publishes to TestPyPI and checks that the new version installs from there.
|
|
111
|
+
If either fails, nothing is published to PyPI.
|
|
112
|
+
5. Publishes to PyPI. Both uploads use
|
|
113
|
+
[trusted publishing](https://docs.pypi.org/trusted-publishers/), so no API tokens are stored.
|
|
114
|
+
6. Creates a GitHub release for the tag with generated release notes and the
|
|
115
|
+
distributions attached. Pre-release versions (`a`, `b`, `rc`, `.dev`) are
|
|
116
|
+
marked as pre-releases.
|
|
117
|
+
|
|
118
|
+
One-time setup:
|
|
119
|
+
|
|
120
|
+
- On [PyPI](https://pypi.org), add a trusted publisher for the `fm-labs/objbase`
|
|
121
|
+
repository with workflow `release.yml` and environment `pypi`.
|
|
122
|
+
- On [TestPyPI](https://test.pypi.org), add the same trusted publisher with
|
|
123
|
+
environment `testpypi`.
|
|
124
|
+
- In the GitHub repository settings, create the `testpypi` and `pypi`
|
|
125
|
+
environments. Add required reviewers to `pypi` to approve each release after
|
|
126
|
+
the TestPyPI check and before it's published.
|
|
127
|
+
|
|
128
|
+
To publish from a local machine instead, `release.sh` refuses to run with
|
|
129
|
+
uncommitted changes, runs the tests, builds into a clean `dist/`, and publishes
|
|
130
|
+
to TestPyPI and/or PyPI depending on which of `TESTPYPI_PUBLISH_TOKEN` and
|
|
131
|
+
`PYPI_PUBLISH_TOKEN` are set.
|