pydantic-pint 0.1__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.
@@ -0,0 +1,16 @@
1
+ version: 2
2
+
3
+ build:
4
+ os: ubuntu-22.04
5
+ tools:
6
+ python: "3.12"
7
+
8
+ python:
9
+ install:
10
+ - method: pip
11
+ path: .
12
+ extra_requirements:
13
+ - docs
14
+
15
+ mkdocs:
16
+ configuration: mkdocs.yaml
@@ -0,0 +1,14 @@
1
+ # Changes
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [Unreleased](https://github.com/tylerh111/pydantic-pint/compare/0.0...main)
6
+
7
+ <!-- release notes -->
8
+
9
+ ## [0.1](https://github.com/tylerh111/pydantic-pint/releases/tag/0.1) - 2024-05-06
10
+
11
+
12
+ ### Features
13
+
14
+ - Added initial code, docs, and tools.
@@ -0,0 +1,136 @@
1
+ # Contributing
2
+
3
+ Thank you for taking the time to contribute to Pydantic Pint!
4
+ All types of contributions are encouraged and valued.
5
+ Please refer to this page for ways to contribute.
6
+
7
+ ## Overview
8
+
9
+ > There are plenty of ways to support the project and show your appreciation!
10
+ >
11
+ > - Create and comment on [issues].
12
+ > - Create and comment on [pull requests].
13
+ > - [Fork] the project.
14
+ > - [Star] the project.
15
+ > - [Watch] the project.
16
+ > - Talk about the project!
17
+
18
+ ## Creating Issues
19
+
20
+ GitHub [issues] track any enhancements, bugs, questions, or suggestions for this project.
21
+
22
+ - [Open an issue].
23
+ - Provide as much detail as you can.
24
+ - Provide project and platform version (python, pydantic, pint, etc.).
25
+
26
+ #### Asking Questions
27
+
28
+ If you have a question, create an issue with the `question` label.
29
+ We will try to answer it as best we can.
30
+
31
+ Provide the following information when asking questions.
32
+
33
+ - Ask the question in a clear and concise manner.
34
+ - Search and link relevant issues and pull requests.
35
+ - Provide details and context separate from the question.
36
+ In other words, the question and context should be separate.
37
+ This makes it easier to answer the question if it is clearly stated.
38
+ Anything passed that can be a discussion.
39
+
40
+ #### Requesting Features
41
+
42
+ If you have an idea for enhancements, open an issue with the `enhancement` label.
43
+ We will determine if such an enhancement is worth implementing.
44
+ Enhancements should improve the use of the project without breaking the existing functionality.
45
+
46
+ Provide the following information when requesting features.
47
+
48
+ - Explain what currently does not exist with the project.
49
+ - Explain how the feature request can address the issue.
50
+ - Include usecases for the feature.
51
+ - Include examples for using the feature.
52
+
53
+ #### Reporting Bugs
54
+
55
+ If you find a bug, open an issue with the `bug` label.
56
+ Bug reports should contain information about the environment in which you are running.
57
+ This is key in order to replicate the issue to further investigate and fix it.
58
+
59
+ Provide the following information when reporting a bug.
60
+
61
+ - Environment, including project and platform information (python, pydantic, pint, etc.).
62
+ - Current behavior, include examples for replication.
63
+ - Expected behavior, include examples for verification.
64
+
65
+ #### Updating Documentation
66
+
67
+ If you think the documentation should be updated, open an issue with the `documentation` label.
68
+ Documentation might have small issues that need fixed, e.g. misspellings or grammar mistakes, or might be related to enhancements or bugs, e.g. new or changed functionality.
69
+
70
+ Provide the following information when updating the documentation.
71
+
72
+ - The documentation page that should be added.
73
+ - The documentation page that should be modified.
74
+ - The documentation page that should be removed.
75
+ - Updates to examples.
76
+
77
+ ## Creating Pull Requests
78
+
79
+ GitHub [pull requests] address the issues of the project.
80
+
81
+ - [Fork] the project.
82
+ - Create a branch from the latest revision on `main`.
83
+ - Implement the changes to address a particular issue(s).
84
+ - [Open a pull request].
85
+ - Add the issue number to the description of the pull request.
86
+ It should be clear which issue (or issues) are addressed.
87
+
88
+ #### Fixing Bugs
89
+
90
+ Fixing a bug should have an associated issue labeled as a `bug`.
91
+ Make sure the bug is fixed correctly and completely.
92
+ The following additions to your bugfix could help improve it.
93
+
94
+ - Add unit tests to cover the bugfix.
95
+ This ensures that it never pops back up.
96
+ - Test all facets of your changes so that no other parts of the code base breaks.
97
+ Check how the new feature interacts with other features.
98
+ - Make sure each commit is deliberate and meaningful.
99
+ Changes like spacing, formatting, or typos (in unrelated locations) are not necessary to change while implementing a feature or bugfix.
100
+ Ensure other parts of the code have not been modified that do not need to be modified to implement your feature or bugfix.
101
+ - Limit the size of your changes.
102
+ Large diffs can be difficult to verify and validate.
103
+
104
+ #### Implementing Features
105
+
106
+ Implementing a feature should have an associated issue labeled as an `enhancement`.
107
+ Make sure the feature is implemented correctly and completely.
108
+ The following additions to your feature could help improve it.
109
+
110
+ - Add documentation.
111
+ - Add unit tests.
112
+ Check corner cases, and how the feature works with bad or invalid input.
113
+ - Test all facets of your changes so that no other parts of the code base breaks.
114
+ Check how the new feature interacts with other features.
115
+ - Make sure each commit is deliberate and meaningful.
116
+ Changes like spacing, formatting, or typos (in unrelated locations) are not necessary to change while implementing a feature or bugfix.
117
+ Ensure other parts of the code have not been modified that do not need to be modified to implement your feature or bugfix.
118
+ - Limit the size of your changes.
119
+ Large diffs can be difficult to verify and validate.
120
+
121
+
122
+ ## Thank You!
123
+
124
+ You are help Pydantic Pint grow and prosper with your involvement.
125
+ We hope to see your contributions in the project soon!
126
+
127
+ <!-- links -->
128
+ [project]: https://github.com/tylerh111/pydantic-pint
129
+ [star]: https://github.com/tylerh111/pydantic-pint
130
+ [watch]: https://github.com/tylerh111/pydantic-pint
131
+ [fork]: https://github.com/tylerh111/pydantic-pint/fork
132
+ [issues]: https://github.com/tylerh111/pydantic-pint/issues
133
+ [open an issue]: https://github.com/tylerh111/pydantic-pint/issues/new
134
+ [pull requests]: https://github.com/tylerh111/pydantic-pint/pulls
135
+ [open a pull request]: https://github.com/tylerh111/pydantic-pint/compare
136
+ [documentation]: https://pydantic-pint.readthedocs.io
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Tyler Hughes
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,167 @@
1
+ Metadata-Version: 2.1
2
+ Name: pydantic-pint
3
+ Version: 0.1
4
+ Summary: Pydantic validation for Pint Quantities.
5
+ Author-email: Tyler Hughes <tylerxh111+git@proton.me>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2024 Tyler Hughes
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: source, https://github.com/tylerh111/pydantic-pint
29
+ Project-URL: issues, https://github.com/tylerh111/pydantic-pint/issues
30
+ Project-URL: changes, https://github.com/tylerh111/pydantic-pint/blob/main/CHANGES.md
31
+ Project-URL: documentation, https://pydantic-pint.readthedocs.io
32
+ Keywords: pydantic-pint,pydantic,pint
33
+ Classifier: Development Status :: 1 - Planning
34
+ Classifier: Framework :: Pydantic
35
+ Classifier: Framework :: Pydantic :: 2
36
+ Classifier: Intended Audience :: Developers
37
+ Classifier: License :: OSI Approved :: MIT License
38
+ Classifier: Operating System :: OS Independent
39
+ Classifier: Programming Language :: Python
40
+ Classifier: Programming Language :: Python :: 3
41
+ Classifier: Programming Language :: Python :: 3.8
42
+ Classifier: Programming Language :: Python :: 3.9
43
+ Classifier: Programming Language :: Python :: 3.10
44
+ Classifier: Programming Language :: Python :: 3.11
45
+ Classifier: Programming Language :: Python :: 3.12
46
+ Classifier: Programming Language :: Python :: 3 :: Only
47
+ Classifier: Topic :: Scientific/Engineering
48
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
49
+ Classifier: Typing :: Typed
50
+ Requires-Python: >=3.8
51
+ Description-Content-Type: text/markdown
52
+ License-File: LICENSE.md
53
+ Requires-Dist: pint>=0.20
54
+ Requires-Dist: pydantic>=2.0
55
+ Provides-Extra: build
56
+ Requires-Dist: build; extra == "build"
57
+ Requires-Dist: bumpver; extra == "build"
58
+ Requires-Dist: setuptools>=61; extra == "build"
59
+ Requires-Dist: setuptools-scm; extra == "build"
60
+ Requires-Dist: towncrier; extra == "build"
61
+ Requires-Dist: twine; extra == "build"
62
+ Provides-Extra: dev
63
+ Requires-Dist: nox; extra == "dev"
64
+ Requires-Dist: setuptools-scm; extra == "dev"
65
+ Requires-Dist: pydantic-pint[build,docs,lint,tests]; extra == "dev"
66
+ Provides-Extra: docs
67
+ Requires-Dist: mike; extra == "docs"
68
+ Requires-Dist: mkdocs; extra == "docs"
69
+ Requires-Dist: mkdocs-exclude; extra == "docs"
70
+ Requires-Dist: mkdocs-material; extra == "docs"
71
+ Requires-Dist: mkdocs-material-extensions; extra == "docs"
72
+ Requires-Dist: mkdocs-minify-plugin; extra == "docs"
73
+ Requires-Dist: mkdocs-redirects; extra == "docs"
74
+ Requires-Dist: mkdocstrings; extra == "docs"
75
+ Requires-Dist: mkdocstrings-python; extra == "docs"
76
+ Requires-Dist: pygments; extra == "docs"
77
+ Requires-Dist: pymdown-extensions; extra == "docs"
78
+ Provides-Extra: lint
79
+ Requires-Dist: ruff; extra == "lint"
80
+ Provides-Extra: tests
81
+ Requires-Dist: pytest; extra == "tests"
82
+ Requires-Dist: pytest-cov; extra == "tests"
83
+
84
+ # Pydantic Pint
85
+
86
+ [![_](https://img.shields.io/pypi/v/pydantic-pint)](https://pypi.python.org/pypi/pydantic-pint)
87
+ [![_](https://img.shields.io/pypi/pyversions/pydantic-pint)](https://github.com/tylerh111/pydantic-pint)
88
+ [![_](https://img.shields.io/pypi/l/pydantic-pint)](https://github.com/tylerh111/pydantic-pint/blob/main/LICENSE.md)
89
+ [![_](https://img.shields.io/readthedocs/pydantic-pint)](https://pydantic-pint.readthedocs.io)
90
+
91
+ ---
92
+
93
+ [Pydantic](https://docs.pydantic.dev) is a Python library for data validation and data serialization.
94
+ [Pint](https://pint.readthedocs.io) is a Python library for defining, operating, and manipulating physical quantities.
95
+ By default, they do not play well with each other.
96
+
97
+ Many projects that have a need for data validation may also need to work with physical quantities.
98
+ [Pydantic Pint](https://pydantic-pint.readthedocs.io) aims to bridge that gap by providing Pydantic validation for Pint quantities.
99
+
100
+ ```python
101
+ from pydantic import BaseModel
102
+ from pydantic_pint import PydanticPintQuantity
103
+ from pint import Quantity
104
+ from typing import Annotations
105
+
106
+ class Box(BaseModel):
107
+ length: Annotated[Quantity, PydanticPintQuantity("m")]
108
+ width: Annotated[Quantity, PydanticPintQuantity("m")]
109
+
110
+ box = Box(
111
+ length="4m",
112
+ width="2m",
113
+ )
114
+ ```
115
+
116
+ ## Getting Started
117
+
118
+ ### Installation
119
+
120
+ Pydantic Pint is available as [`pydantic-pint`](https://pypi.python.org/pypi/pydantic-pint) on PyPI.
121
+
122
+ Pydantic Pint requires both Pydantic and Pint to be installed.
123
+ It also requires [`typing.Annotated`](https://docs.python.org/3/library/typing.html#typing.Annotated) (for older version of python use [`typing-extensions`](https://pypi.org/project/typing-extensions/)).
124
+
125
+ ```shell
126
+ pip install pydantic-pint
127
+ ```
128
+
129
+ ### Usage
130
+
131
+ Pydantic Pint provides `PydanticPintQuantity` which enabled Pydantic validation for Pint quantities.
132
+ For a field of a Pydantic model to have quantity validation, it must be annotated with a `PydanticPintQuantity` for a given unit.
133
+
134
+ ```python
135
+ from pydantic import BaseModel
136
+ from pydantic_pint import PydanticPintQuantity
137
+ from pint import Quantity
138
+ from typing import Annotated
139
+
140
+ class Coordinates(BaseModel):
141
+ latitude: Annotated[Quantity, PydanticPintQuantity("deg")]
142
+ longitude: Annotated[Quantity, PydanticPintQuantity("deg")]
143
+ altitude: Annotated[Quantity, PydanticPintQuantity("km")]
144
+ ```
145
+
146
+ Users of the model can input anything to the field with a specified unit that is convertible to the units declared in the annotation.
147
+ For instance, the units for `Coordinates.altitude` are kilometers, however users can specify meters instead.
148
+ `PydanticPintQuantity` will handle the conversion from meters to kilometers.
149
+
150
+ ```python
151
+ coord = Coordinates(
152
+ latitude="39.905705 deg",
153
+ longitude="-75.166519 deg",
154
+ altitude="12 meters",
155
+ )
156
+
157
+ print(coord)
158
+ #> latitude=<Quantity(39.905705, 'degree')> longitude=<Quantity(-75.166519, 'degree')> altitude=<Quantity(0.012, 'kilometer')>
159
+ print(f"{coord!r}")
160
+ #> Coordinates(latitude=<Quantity(39.905705, 'degree')>, longitude=<Quantity(-75.166519, 'degree')>, altitude=<Quantity(0.012, 'kilometer')>)
161
+ print(coord.model_dump())
162
+ #> {'latitude': <Quantity(39.905705, 'degree')>, 'longitude': <Quantity(-75.166519, 'degree')>, 'altitude': <Quantity(0.012, 'kilometer')>}
163
+ print(coord.model_dump(mode="json"))
164
+ #> {'latitude': '39.905705 degree', 'longitude': '-75.166519 degree', 'altitude': '0.012 kilometer'}
165
+ print(f"{coord.model_dump_json()!r}")
166
+ #> '{"latitude":"39.905705 degree","longitude":"-75.166519 degree","altitude":"0.012 kilometer"}'
167
+ ```
@@ -0,0 +1,84 @@
1
+ # Pydantic Pint
2
+
3
+ [![_](https://img.shields.io/pypi/v/pydantic-pint)](https://pypi.python.org/pypi/pydantic-pint)
4
+ [![_](https://img.shields.io/pypi/pyversions/pydantic-pint)](https://github.com/tylerh111/pydantic-pint)
5
+ [![_](https://img.shields.io/pypi/l/pydantic-pint)](https://github.com/tylerh111/pydantic-pint/blob/main/LICENSE.md)
6
+ [![_](https://img.shields.io/readthedocs/pydantic-pint)](https://pydantic-pint.readthedocs.io)
7
+
8
+ ---
9
+
10
+ [Pydantic](https://docs.pydantic.dev) is a Python library for data validation and data serialization.
11
+ [Pint](https://pint.readthedocs.io) is a Python library for defining, operating, and manipulating physical quantities.
12
+ By default, they do not play well with each other.
13
+
14
+ Many projects that have a need for data validation may also need to work with physical quantities.
15
+ [Pydantic Pint](https://pydantic-pint.readthedocs.io) aims to bridge that gap by providing Pydantic validation for Pint quantities.
16
+
17
+ ```python
18
+ from pydantic import BaseModel
19
+ from pydantic_pint import PydanticPintQuantity
20
+ from pint import Quantity
21
+ from typing import Annotations
22
+
23
+ class Box(BaseModel):
24
+ length: Annotated[Quantity, PydanticPintQuantity("m")]
25
+ width: Annotated[Quantity, PydanticPintQuantity("m")]
26
+
27
+ box = Box(
28
+ length="4m",
29
+ width="2m",
30
+ )
31
+ ```
32
+
33
+ ## Getting Started
34
+
35
+ ### Installation
36
+
37
+ Pydantic Pint is available as [`pydantic-pint`](https://pypi.python.org/pypi/pydantic-pint) on PyPI.
38
+
39
+ Pydantic Pint requires both Pydantic and Pint to be installed.
40
+ It also requires [`typing.Annotated`](https://docs.python.org/3/library/typing.html#typing.Annotated) (for older version of python use [`typing-extensions`](https://pypi.org/project/typing-extensions/)).
41
+
42
+ ```shell
43
+ pip install pydantic-pint
44
+ ```
45
+
46
+ ### Usage
47
+
48
+ Pydantic Pint provides `PydanticPintQuantity` which enabled Pydantic validation for Pint quantities.
49
+ For a field of a Pydantic model to have quantity validation, it must be annotated with a `PydanticPintQuantity` for a given unit.
50
+
51
+ ```python
52
+ from pydantic import BaseModel
53
+ from pydantic_pint import PydanticPintQuantity
54
+ from pint import Quantity
55
+ from typing import Annotated
56
+
57
+ class Coordinates(BaseModel):
58
+ latitude: Annotated[Quantity, PydanticPintQuantity("deg")]
59
+ longitude: Annotated[Quantity, PydanticPintQuantity("deg")]
60
+ altitude: Annotated[Quantity, PydanticPintQuantity("km")]
61
+ ```
62
+
63
+ Users of the model can input anything to the field with a specified unit that is convertible to the units declared in the annotation.
64
+ For instance, the units for `Coordinates.altitude` are kilometers, however users can specify meters instead.
65
+ `PydanticPintQuantity` will handle the conversion from meters to kilometers.
66
+
67
+ ```python
68
+ coord = Coordinates(
69
+ latitude="39.905705 deg",
70
+ longitude="-75.166519 deg",
71
+ altitude="12 meters",
72
+ )
73
+
74
+ print(coord)
75
+ #> latitude=<Quantity(39.905705, 'degree')> longitude=<Quantity(-75.166519, 'degree')> altitude=<Quantity(0.012, 'kilometer')>
76
+ print(f"{coord!r}")
77
+ #> Coordinates(latitude=<Quantity(39.905705, 'degree')>, longitude=<Quantity(-75.166519, 'degree')>, altitude=<Quantity(0.012, 'kilometer')>)
78
+ print(coord.model_dump())
79
+ #> {'latitude': <Quantity(39.905705, 'degree')>, 'longitude': <Quantity(-75.166519, 'degree')>, 'altitude': <Quantity(0.012, 'kilometer')>}
80
+ print(coord.model_dump(mode="json"))
81
+ #> {'latitude': '39.905705 degree', 'longitude': '-75.166519 degree', 'altitude': '0.012 kilometer'}
82
+ print(f"{coord.model_dump_json()!r}")
83
+ #> '{"latitude":"39.905705 degree","longitude":"-75.166519 degree","altitude":"0.012 kilometer"}'
84
+ ```
@@ -0,0 +1 @@
1
+ !.gitignore
@@ -0,0 +1,2 @@
1
+
2
+ ::: pydantic_pint.quantity
@@ -0,0 +1,84 @@
1
+ # Pydantic Pint
2
+
3
+ [![_](https://img.shields.io/pypi/v/pydantic-pint)](https://pypi.python.org/pypi/pydantic-pint)
4
+ [![_](https://img.shields.io/pypi/pyversions/pydantic-pint)](https://github.com/tylerh111/pydantic-pint)
5
+ [![_](https://img.shields.io/pypi/l/pydantic-pint)](https://github.com/tylerh111/pydantic-pint/blob/main/LICENSE.md)
6
+ [![_](https://img.shields.io/readthedocs/pydantic-pint)](https://pydantic-pint.readthedocs.io)
7
+
8
+ ---
9
+
10
+ [Pydantic](https://docs.pydantic.dev) is a Python library for data validation and data serialization.
11
+ [Pint](https://pint.readthedocs.io) is a Python library for defining, operating, and manipulating physical quantities.
12
+ By default, they do not play well with each other.
13
+
14
+ Many projects that have a need for data validation may also need to work with physical quantities.
15
+ [Pydantic Pint](https://pydantic-pint.readthedocs.io) aims to bridge that gap by providing Pydantic validation for Pint quantities.
16
+
17
+ ```python
18
+ from pydantic import BaseModel
19
+ from pydantic_pint import PydanticPintQuantity
20
+ from pint import Quantity
21
+ from typing import Annotations
22
+
23
+ class Box(BaseModel):
24
+ length: Annotated[Quantity, PydanticPintQuantity("m")]
25
+ width: Annotated[Quantity, PydanticPintQuantity("m")]
26
+
27
+ box = Box(
28
+ length="4m",
29
+ width="2m",
30
+ )
31
+ ```
32
+
33
+ ## Getting Started
34
+
35
+ ### Installation
36
+
37
+ Pydantic Pint is available as [`pydantic-pint`](https://pypi.python.org/pypi/pydantic-pint) on PyPI.
38
+
39
+ Pydantic Pint requires both Pydantic and Pint to be installed.
40
+ It also requires [`typing.Annotated`](https://docs.python.org/3/library/typing.html#typing.Annotated) (for older version of python use [`typing_extensions`](https://pypi.org/project/typing-extensions/)).
41
+
42
+ ```shell
43
+ pip install pydantic-pint
44
+ ```
45
+
46
+ ### Usage
47
+
48
+ Pydantic Pint provides `PydanticPintQuantity` which enabled Pydantic validation for Pint quantities.
49
+ For a field of a Pydantic model to have quantity validation, it must be annotated with a `PydanticPintQuantity` for a given unit.
50
+
51
+ ```python
52
+ from pydantic import BaseModel
53
+ from pydantic_pint import PydanticPintQuantity
54
+ from pint import Quantity
55
+ from typing import Annotated
56
+
57
+ class Coordinates(BaseModel):
58
+ latitude: Annotated[Quantity, PydanticPintQuantity("deg")]
59
+ longitude: Annotated[Quantity, PydanticPintQuantity("deg")]
60
+ altitude: Annotated[Quantity, PydanticPintQuantity("km")]
61
+ ```
62
+
63
+ Users of the model can input anything to the field with a specified unit that is convertible to the units declared in the annotation.
64
+ For instance, the units for `Coordinates.altitude` are kilometers, however users can specify meters instead.
65
+ `PydanticPintQuantity` will handle the conversion from meters to kilometers.
66
+
67
+ ```python
68
+ coord = Coordinates(
69
+ latitude="39.905705 deg",
70
+ longitude="-75.166519 deg",
71
+ altitude="12 meters",
72
+ )
73
+
74
+ print(coord)
75
+ #> latitude=<Quantity(39.905705, 'degree')> longitude=<Quantity(-75.166519, 'degree')> altitude=<Quantity(0.012, 'kilometer')>
76
+ print(f"{coord!r}")
77
+ #> Coordinates(latitude=<Quantity(39.905705, 'degree')>, longitude=<Quantity(-75.166519, 'degree')>, altitude=<Quantity(0.012, 'kilometer')>)
78
+ print(coord.model_dump())
79
+ #> {'latitude': <Quantity(39.905705, 'degree')>, 'longitude': <Quantity(-75.166519, 'degree')>, 'altitude': <Quantity(0.012, 'kilometer')>}
80
+ print(coord.model_dump(mode="json"))
81
+ #> {'latitude': '39.905705 degree', 'longitude': '-75.166519 degree', 'altitude': '0.012 kilometer'}
82
+ print(f"{coord.model_dump_json()!r}")
83
+ #> '{"latitude":"39.905705 degree","longitude":"-75.166519 degree","altitude":"0.012 kilometer"}'
84
+ ```
@@ -0,0 +1,21 @@
1
+ <!-- Table of contents item -->
2
+ <li class="md-nav__item">
3
+ <a href="{{ toc_item.url }}" class="md-nav__link">
4
+ <span class="md-ellipsis">
5
+ {{ toc_item.title }}
6
+ </span>
7
+ </a>
8
+
9
+ <!-- Table of contents list -->
10
+ {% if toc_item.children %}
11
+ <nav class="md-nav" aria-label="{{ toc_item.title | striptags }}">
12
+ <ul class="md-nav__list">
13
+ {% for toc_item in toc_item.children %}
14
+ {% if not page.meta.toc_depth or toc_item.level <= page.meta.toc_depth %}
15
+ {% include "partials/toc-item.html" %}
16
+ {% endif %}
17
+ {% endfor %}
18
+ </ul>
19
+ </nav>
20
+ {% endif %}
21
+ </li>
@@ -0,0 +1,58 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ import textwrap
5
+ from pathlib import Path
6
+
7
+ from mkdocs.config import Config
8
+
9
+ logger = logging.getLogger("mkdocs.plugin")
10
+
11
+ ROOT = Path(__file__).parents[2]
12
+ DOCS = ROOT / "docs"
13
+
14
+
15
+ def on_pre_build(config: Config):
16
+ """Before build starts."""
17
+ _add_tracked_file(
18
+ ROOT / "CHANGES.md",
19
+ DOCS / "changes.md",
20
+ prepend=(
21
+ """
22
+ ---
23
+ toc_depth: 2
24
+ ---
25
+ """
26
+ ),
27
+ )
28
+ _add_tracked_file(
29
+ ROOT / "CONTRIBUTING.md",
30
+ DOCS / "contributing.md",
31
+ )
32
+ _add_tracked_file(
33
+ ROOT / "LICENSE.md",
34
+ DOCS / "license.md",
35
+ )
36
+
37
+
38
+ def _add_tracked_file(
39
+ file: Path,
40
+ new_file: Path,
41
+ prepend: str = "",
42
+ append: str = "",
43
+ ):
44
+ prepend = prepend.lstrip("\n") + "\n" if prepend else ""
45
+ append = append.lstrip("\n") + "\n" if append else ""
46
+
47
+ text = file.read_text(encoding="utf-8")
48
+ text = "".join(
49
+ (
50
+ textwrap.dedent(prepend),
51
+ text,
52
+ textwrap.dedent(append),
53
+ )
54
+ )
55
+
56
+ # avoid writing file unless the content has changed to avoid infinite build loop
57
+ if not new_file.is_file() or new_file.read_text(encoding="utf-8") != text:
58
+ new_file.write_text(text, encoding="utf-8")