-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 6dd19a7
Showing
65 changed files
with
5,435 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
name: python | ||
|
||
on: [push] | ||
|
||
env: | ||
python-version: "3.10" | ||
poetry-version: "1.2.1" | ||
|
||
jobs: | ||
test: | ||
strategy: | ||
matrix: | ||
python-version: ['3.10'] | ||
runs-on: ubuntu-22.04 | ||
steps: | ||
- name: Checkout repo | ||
uses: actions/checkout@v3 | ||
- name: Install Poetry | ||
run: pipx install poetry==${{ env.poetry-version }} | ||
- name: Install Python ${{ matrix.python-version }} | ||
uses: actions/setup-python@v4 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
cache: poetry | ||
- name: Install environment | ||
run: poetry install | ||
- name: Test with nox | ||
run: >- | ||
poetry run nox -s | ||
test-${{ matrix.python-version }} | ||
test_fastapi-${{ matrix.python-version }} | ||
test_numpy-${{ matrix.python-version }} | ||
- name: Store coverage | ||
uses: actions/upload-artifact@v3 | ||
with: | ||
name: coverage | ||
path: .coverage.* | ||
coverage: | ||
needs: test | ||
runs-on: ubuntu-22.04 | ||
steps: | ||
- name: Checkout repo | ||
uses: actions/checkout@v3 | ||
- name: Install Poetry | ||
run: pipx install poetry==${{ env.poetry-version }} | ||
- name: Install Python | ||
uses: actions/setup-python@v4 | ||
with: | ||
python-version: ${{ env.python-version }} | ||
cache: poetry | ||
- name: Install environment | ||
run: poetry install | ||
- name: Fetch coverage | ||
uses: actions/download-artifact@v3 | ||
with: | ||
name: coverage | ||
- name: Combine coverage and generate report | ||
run: poetry run nox -s coverage | ||
- name: Upload coverage to Codecov | ||
uses: codecov/codecov-action@v3 | ||
with: | ||
token: ${{ secrets.CODECOV_TOKEN }} | ||
quality: | ||
runs-on: ubuntu-22.04 | ||
steps: | ||
- name: Checkout repo | ||
uses: actions/checkout@v3 | ||
- name: Install Poetry | ||
run: pipx install poetry==${{ env.poetry-version }} | ||
- name: Install Python | ||
uses: actions/setup-python@v4 | ||
with: | ||
python-version: ${{ env.python-version }} | ||
cache: poetry | ||
- name: Install environment | ||
run: poetry install | ||
- name: Run code quality checks | ||
run: poetry run nox -s black isort flake8 | ||
poetry-check: | ||
runs-on: ubuntu-22.04 | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Install Poetry | ||
run: pipx install poetry==${{ env.poetry-version }} | ||
- name: Set up Python | ||
uses: actions/setup-python@v4 | ||
with: | ||
python-version: ${{ env.python-version }} | ||
- name: Validate Poetry configuration and lockfile freshness | ||
run: poetry lock --check |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
__pycache__ | ||
/.nox | ||
/.coverage* | ||
/coverage.xml | ||
/dist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
Copyright (c) 2022 David R Hagen | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# Serialite | ||
|
||
Serialite is a library serializing and deserializing arbitrarily complex objects in Python. You | ||
apply the `@serializable` decorator to a dataclass to automatically create `to_data` and `from_data` | ||
methods using the type annotations. Or for more control, inherit from the `SerializableMixin` and | ||
implement the class attribute `__fields_serializer__`. For even more control, inherit from the | ||
abstract base class `Serializer` and implement the `to_data` and `from_data` methods directly. | ||
|
||
## Basics | ||
|
||
The abstract base class is `Serializer`: | ||
|
||
```python | ||
class Serializer(Generic[Output]): | ||
def from_data(self, data: Json) -> DeserializationSuccess[Output]: ... | ||
def to_data(self, value: Output) -> Json: ... | ||
``` | ||
|
||
The class is generic in the type of the object that it serializes. The two abstract methods | ||
`from_data` and `to_data` are the key to the whole design, which revolves around getting objects to | ||
and from JSON-serializable data, which are objects constructed entirely of `bool`s, `int`s, | ||
`float`s, `list`s, and `dict`s. Such structures can be consumed by `json.dumps` to produce a string | ||
and produced by `json.loads` after consuming a string. By basing the serialization around JSON | ||
serializable data, complex structures can be built up or torn down piece by piece while | ||
alternatively building up complex error messages during deserialization which pinpoint the location | ||
in the structure where the bad data exist. | ||
|
||
For new classes, it is recommended that the `Serializer` be implemented on the class itself. There is | ||
an abstract base class `Serializable` that classes can inherit from to indicate this. There is a mixin | ||
`SerializableMixin` that provides an implementation of `from_data` and `to_data` for any class that | ||
implements the `__fields_serializer` class attribute. | ||
|
||
For `dataclass`es, it is even easier. There is a decorator `serializable` that inserts | ||
`SerializableMixin` into the list of base classes after the `dataclass` decorator has run and also | ||
generates `__fields_serializer__` from the data class attributes. | ||
|
||
Finding the correct serializer for each type can be a pain, so | ||
`serializer(cls: type) -> Serializer` is provided as a convenience function. This is a single | ||
dispatch function, which looks up the serializer registered for a particular type. For example, | ||
`serializer(list[float])` will return `ListSerializer(FloatSerializer)`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import nox_poetry | ||
|
||
|
||
@nox_poetry.session(python=["3.10"]) | ||
def test(session: nox_poetry.Session): | ||
session.install(".", "pytest", "pytest-cov") | ||
session.env["COVERAGE_FILE"] = f".coverage.{session.python}" | ||
session.run("python", "-m", "pytest", "--cov", "serialite") | ||
|
||
|
||
@nox_poetry.session(python=["3.10"]) | ||
def test_fastapi(session: nox_poetry.Session): | ||
session.install(".[fastapi]", "pytest", "pytest-cov", "requests") | ||
session.env["COVERAGE_FILE"] = f".coverage.fastapi.{session.python}" | ||
session.run("python", "-m", "pytest", "--cov", "serialite", "tests/fastapi") | ||
|
||
|
||
@nox_poetry.session(python=["3.10"]) | ||
def test_numpy(session: nox_poetry.Session): | ||
session.install(".[numpy]", "pytest", "pytest-cov") | ||
session.env["COVERAGE_FILE"] = f".coverage.numpy.{session.python}" | ||
session.run("python", "-m", "pytest", "--cov", "serialite", "tests/test_numpy.py") | ||
|
||
|
||
@nox_poetry.session(venv_backend="none") | ||
def coverage(session: nox_poetry.Session): | ||
session.run("coverage", "combine") | ||
session.run("coverage", "html") | ||
session.run("coverage", "xml") | ||
|
||
|
||
@nox_poetry.session(venv_backend="none") | ||
def black(session: nox_poetry.Session): | ||
session.run("black", "--check", ".") | ||
|
||
|
||
@nox_poetry.session(venv_backend="none") | ||
def isort(session: nox_poetry.Session): | ||
session.run("isort", "--check", ".") | ||
|
||
|
||
@nox_poetry.session(venv_backend="none") | ||
def flake8(session: nox_poetry.Session): | ||
session.run("pflake8", "src", "tests") |
Oops, something went wrong.