@ai-devtools/dbspec-windows-x64 1.6.2 → 1.6.3
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.
- package/bin/dbspec/_internal/base_library.zip +0 -0
- package/bin/dbspec/_internal/dbspec.egg-info/PKG-INFO +1 -1
- package/bin/dbspec/_internal/dbspec.egg-info/SOURCES.txt +3 -0
- package/bin/dbspec/_internal/{pydantic-2.14.1.dist-info → pydantic-2.14.2.dist-info}/METADATA +61 -2
- package/bin/dbspec/_internal/{pydantic-2.14.1.dist-info → pydantic-2.14.2.dist-info}/RECORD +21 -21
- package/bin/dbspec/_internal/{pydantic-2.14.1.dist-info → pydantic-2.14.2.dist-info}/WHEEL +1 -1
- package/bin/dbspec/_internal/pydantic_core/_pydantic_core.cp313-win_amd64.pyd +0 -0
- package/bin/dbspec/_internal/pyproject.toml +1 -1
- package/bin/dbspec/_internal/src/resources/sqlalchemy_templates/alembic_default_comparator.py.j2 +144 -62
- package/bin/dbspec/dbspec.exe +0 -0
- package/package.json +1 -1
- /package/bin/dbspec/_internal/{pydantic-2.14.1.dist-info → pydantic-2.14.2.dist-info}/INSTALLER +0 -0
- /package/bin/dbspec/_internal/{pydantic-2.14.1.dist-info → pydantic-2.14.2.dist-info}/licenses/LICENSE +0 -0
|
Binary file
|
|
@@ -137,6 +137,7 @@ src/resources/sqlalchemy_templates/package_init.py.j2
|
|
|
137
137
|
src/reveng/__init__.py
|
|
138
138
|
src/storage/__init__.py
|
|
139
139
|
src/storage/alembic_env_patching.py
|
|
140
|
+
src/storage/alembic_service_table.py
|
|
140
141
|
src/storage/atomic.py
|
|
141
142
|
src/storage/config.py
|
|
142
143
|
src/storage/file_utils.py
|
|
@@ -254,6 +255,8 @@ src/tui/styles/__init__.py
|
|
|
254
255
|
src/tui/styles/build.py
|
|
255
256
|
src/tui/styles/tokens.py
|
|
256
257
|
src/utils/__init__.py
|
|
258
|
+
src/utils/default_comparison.py
|
|
259
|
+
src/utils/default_literals.py
|
|
257
260
|
src/utils/parsing.py
|
|
258
261
|
src/utils/postgres_types.py
|
|
259
262
|
src/utils/progress.py
|
package/bin/dbspec/_internal/{pydantic-2.14.1.dist-info → pydantic-2.14.2.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: pydantic
|
|
3
|
-
Version: 2.14.
|
|
3
|
+
Version: 2.14.2
|
|
4
4
|
Summary: Data validation using Python type hints
|
|
5
5
|
Project-URL: Homepage, https://github.com/pydantic/pydantic
|
|
6
6
|
Project-URL: Documentation, https://pydantic.dev/docs/validation/latest/get-started/
|
|
@@ -31,7 +31,7 @@ Classifier: Topic :: Internet
|
|
|
31
31
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
32
32
|
Requires-Python: >=3.10
|
|
33
33
|
Requires-Dist: annotated-types>=0.6.0
|
|
34
|
-
Requires-Dist: pydantic-core==2.50.
|
|
34
|
+
Requires-Dist: pydantic-core==2.50.2
|
|
35
35
|
Requires-Dist: typing-extensions>=4.16.0
|
|
36
36
|
Requires-Dist: typing-inspection>=0.4.4
|
|
37
37
|
Provides-Extra: email
|
|
@@ -117,6 +117,65 @@ See our [security policy](https://github.com/pydantic/pydantic/security/policy).
|
|
|
117
117
|
<!-- markdownlint-disable descriptive-link-text -->
|
|
118
118
|
<!-- markdownlint-disable-next-line first-line-heading -->
|
|
119
119
|
|
|
120
|
+
## v2.14.2 (2026-10-29)
|
|
121
|
+
|
|
122
|
+
[GitHub release](https://github.com/pydantic/pydantic/releases/tag/v2.14.2)
|
|
123
|
+
|
|
124
|
+
### What's Changed
|
|
125
|
+
|
|
126
|
+
#### Packaging
|
|
127
|
+
|
|
128
|
+
* Bump PyO3 to 0.30.1, jiter to 0.18.0, use `PyFrozenDict` by [@Viicos](https://github.com/Viicos) in [#14003](https://github.com/pydantic/pydantic/pull/14003)
|
|
129
|
+
* Bump speedate to v0.18.0 by [@Viicos](https://github.com/Viicos) in [#14007](https://github.com/pydantic/pydantic/pull/14007)
|
|
130
|
+
* Publish `pydantic-core` wheels for PyPy 8.0 (`pp80` ABI) by [@Viicos](https://github.com/Viicos) in [#14083](https://github.com/pydantic/pydantic/pull/14083)
|
|
131
|
+
|
|
132
|
+
#### Performance
|
|
133
|
+
|
|
134
|
+
* Avoid Python tuple allocation during model fields validation by [@Viicos](https://github.com/Viicos) in [#13955](https://github.com/pydantic/pydantic/pull/13955)
|
|
135
|
+
* Lazily call repr of values during nested union serialization by [@Viicos](https://github.com/Viicos) in [#14082](https://github.com/pydantic/pydantic/pull/14082)
|
|
136
|
+
* Skip decorator field checks when no field decorators exist by [@alexmojaki](https://github.com/alexmojaki) in [#14111](https://github.com/pydantic/pydantic/pull/14111)
|
|
137
|
+
* Avoid heap allocation for small JSON model field buffers by [@alexmojaki](https://github.com/alexmojaki) in [#14113](https://github.com/pydantic/pydantic/pull/14113)
|
|
138
|
+
|
|
139
|
+
#### Fixes
|
|
140
|
+
|
|
141
|
+
* Make JSON validation by iteration consistent with Python approach by [@davidhewitt](https://github.com/davidhewitt) in [#13275](https://github.com/pydantic/pydantic/pull/13275).
|
|
142
|
+
|
|
143
|
+
JSON validation now handles field lookup and extra data the same way as Python validation. In particular, keys that only match an
|
|
144
|
+
unused alias or field name are now treated as extra data, instead of being silently dropped:
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
from pydantic import BaseModel, ConfigDict
|
|
148
|
+
from pydantic.alias_generators import to_camel
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
class Page(BaseModel):
|
|
152
|
+
model_config = ConfigDict(extra='forbid', alias_generator=to_camel)
|
|
153
|
+
|
|
154
|
+
page_size: int = 10
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
Page.model_validate_json('{"page_size": 50}')
|
|
158
|
+
# Before: Page(page_size=10)
|
|
159
|
+
# After: ValidationError (extra_forbidden)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
See the [pull request](https://github.com/pydantic/pydantic/pull/13275) for the full list of behavior changes.
|
|
163
|
+
|
|
164
|
+
* Fix unpickling of generic classes defined in separate module by [@Viicos](https://github.com/Viicos) in [#13994](https://github.com/pydantic/pydantic/pull/13994)
|
|
165
|
+
* Support explicit `by_alias` overriding `validate_by_alias` in validation JSON schemas by [@Viicos](https://github.com/Viicos) in [#13997](https://github.com/pydantic/pydantic/pull/13997)
|
|
166
|
+
* Fix mypy plugin crash on deferred empty model by [@ilevkivskyi](https://github.com/ilevkivskyi) in [#14027](https://github.com/pydantic/pydantic/pull/14027)
|
|
167
|
+
* Fix infinite recursion when validating an invalid default with `PydanticUseDefault` by [@Viicos](https://github.com/Viicos) in [#14028](https://github.com/pydantic/pydantic/pull/14028)
|
|
168
|
+
* Implement recursion guard for `validate_strings()` by [@Viicos](https://github.com/Viicos) in [#14029](https://github.com/pydantic/pydantic/pull/14029)
|
|
169
|
+
* Support named tuples in `Sequence` serialization by [@Viicos](https://github.com/Viicos) in [#14033](https://github.com/pydantic/pydantic/pull/14033)
|
|
170
|
+
* Take `preserve_empty_path` into account in URL types equality by [@Viicos](https://github.com/Viicos) in [#14035](https://github.com/pydantic/pydantic/pull/14035)
|
|
171
|
+
* Fix pickling of `PydanticCustomError` and `ValidationError`s containing custom errors by [@Viicos](https://github.com/Viicos) in [#14051](https://github.com/pydantic/pydantic/pull/14051)
|
|
172
|
+
* Do not extract attribute docstrings from nested classes and functions by [@Viicos](https://github.com/Viicos) in [#14052](https://github.com/pydantic/pydantic/pull/14052)
|
|
173
|
+
* Fix forward annotations evaluation and type variables substitution when rebuilding parametrized generic models by [@Viicos](https://github.com/Viicos) in [#14054](https://github.com/pydantic/pydantic/pull/14054)
|
|
174
|
+
* Fix `Self` resolution in parametrized generics by [@Viicos](https://github.com/Viicos) in [#14065](https://github.com/pydantic/pydantic/pull/14065)
|
|
175
|
+
* Ignore extra data matching a field name in `TypedDict` and dataclasses with `extra=allow` by [@Viicos](https://github.com/Viicos) in [#14090](https://github.com/pydantic/pydantic/pull/14090)
|
|
176
|
+
* Check mapping `max_length` constraint during validation by [@Viicos](https://github.com/Viicos) in [#14092](https://github.com/pydantic/pydantic/pull/14092)
|
|
177
|
+
* Fix deep copy of self-referential models by [@Viicos](https://github.com/Viicos) in [#14116](https://github.com/pydantic/pydantic/pull/14116)
|
|
178
|
+
|
|
120
179
|
## v2.14.1 (2026-10-11)
|
|
121
180
|
|
|
122
181
|
[GitHub release](https://github.com/pydantic/pydantic/releases/tag/v2.14.1)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
pydantic-2.14.
|
|
2
|
-
pydantic-2.14.
|
|
3
|
-
pydantic-2.14.
|
|
4
|
-
pydantic-2.14.
|
|
5
|
-
pydantic-2.14.
|
|
1
|
+
pydantic-2.14.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
|
2
|
+
pydantic-2.14.2.dist-info/METADATA,sha256=XidxXTUMyZvDOHdATeuiqUkSIa6XLbj4x59kAyvuOgE,137593
|
|
3
|
+
pydantic-2.14.2.dist-info/RECORD,,
|
|
4
|
+
pydantic-2.14.2.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
|
|
5
|
+
pydantic-2.14.2.dist-info/licenses/LICENSE,sha256=qeGG88oWte74QxjnpwFyE1GgDLe4rjpDlLZ7SeNSnvM,1129
|
|
6
6
|
pydantic/__init__.py,sha256=5SSMubvik7NTbb7X_qVDJtzfPAM3CuXwPXlMWEluwBs,15951
|
|
7
7
|
pydantic/__pycache__/__init__.cpython-313.pyc,,
|
|
8
8
|
pydantic/__pycache__/_migration.cpython-313.pyc,,
|
|
@@ -76,11 +76,11 @@ pydantic/_internal/_dataclasses.py,sha256=Oxv8s2EK-PQvYAe_9kD1yKg9cMNJtm1lg0SWtR
|
|
|
76
76
|
pydantic/_internal/_decorators.py,sha256=ZqaoKcwtWudWa-WsopixHSZeA75YGIkI9GOigCmIzlk,35483
|
|
77
77
|
pydantic/_internal/_decorators_v1.py,sha256=v7_cyEBvJceFO0aYa1AuvYeaMvjEYRQ3-TbW8U8Ghds,6198
|
|
78
78
|
pydantic/_internal/_discriminated_union.py,sha256=HdRL2XOFoCeV95rK0YkxJWPhSdmZWnutRaaBkmQ60Hs,27686
|
|
79
|
-
pydantic/_internal/_docs_extraction.py,sha256=
|
|
80
|
-
pydantic/_internal/_fields.py,sha256
|
|
79
|
+
pydantic/_internal/_docs_extraction.py,sha256=V8_-TfG1oUHpEThCvNtZjJaPwd-zVodn4EqkAGv17hY,4708
|
|
80
|
+
pydantic/_internal/_fields.py,sha256=OlKgiqVO6ITTezu46rIDkGdf0gh3qnphx92RhrP4m28,41083
|
|
81
81
|
pydantic/_internal/_forward_ref.py,sha256=q6SQhW8wo9vPZiuXJ661Vfg7PgoqeJBQTA3dpInXWlA,641
|
|
82
|
-
pydantic/_internal/_generate_schema.py,sha256=
|
|
83
|
-
pydantic/_internal/_generics.py,sha256=
|
|
82
|
+
pydantic/_internal/_generate_schema.py,sha256=_BIwnVrd3fVO9eSIOvP6-39o7kzsHii1Wbe8eVwJbwY,142174
|
|
83
|
+
pydantic/_internal/_generics.py,sha256=LRATBwa-ezzQkFfTUXET4zfZaQT7U0hPUBioml_fIP0,24847
|
|
84
84
|
pydantic/_internal/_git.py,sha256=IwPh3DPfa2Xq3rBuB9Nx8luR2A1i69QdeTfWWXIuCVg,809
|
|
85
85
|
pydantic/_internal/_import_utils.py,sha256=TRhxD5OuY6CUosioBdBcJUs0om7IIONiZdYAV7zQ8jM,402
|
|
86
86
|
pydantic/_internal/_known_annotated_metadata.py,sha256=KSObdJ3af4YRPEcLFR65XBizJF33h5Ypckeu9JAvKxQ,16863
|
|
@@ -90,7 +90,7 @@ pydantic/_internal/_namespace_utils.py,sha256=8_QlLr773kmPzIGCu8RjExBJhGwBn0RAjK
|
|
|
90
90
|
pydantic/_internal/_repr.py,sha256=MNka4onC9u-tXJvV2rsz3JXsuxqlwKbKnd16-tgxriw,4981
|
|
91
91
|
pydantic/_internal/_schema_gather.py,sha256=0qGbiz4pdcfvdMiH7JueJ10tQ8c750g1OkZ0xyP_20Q,1892
|
|
92
92
|
pydantic/_internal/_schema_generation_shared.py,sha256=8nLsSaqgEebxeF26OwiPBt0ZVPipGqW1IV40agkRfxw,4869
|
|
93
|
-
pydantic/_internal/_serializers.py,sha256=
|
|
93
|
+
pydantic/_internal/_serializers.py,sha256=evOucDhMiIjaik5f4yMLdDP08ODB0l2pCir22HuQ-Ag,1786
|
|
94
94
|
pydantic/_internal/_signature.py,sha256=64JyRJJ8Gf-JOfrZa2xTNUdGpd7RGqdNLYFXYOFuPZU,7143
|
|
95
95
|
pydantic/_internal/_type_refs.py,sha256=nxJgVhwwxiSOcQbrc1e5La-Dpm5wU_4SSKJUBkp0hOU,4521
|
|
96
96
|
pydantic/_internal/_typing_extra.py,sha256=5WgRV0MVsZqah9pW4o_Bbmsu73BEmELVhO7k23NUNwQ,20967
|
|
@@ -139,9 +139,9 @@ pydantic/functional_serializers.py,sha256=wcF7l3ZzY4rEXBG0IkU3KLGr5_NIEKS6-CFq14
|
|
|
139
139
|
pydantic/functional_validators.py,sha256=ungjnjugPxAh7vPhU7Yp7k6zdPUfKZrtOFbRzN064fw,33225
|
|
140
140
|
pydantic/generics.py,sha256=0ZqZ9O9annIj_3mGBRqps4htey3b5lV1-d2tUxPMMnA,144
|
|
141
141
|
pydantic/json.py,sha256=ZH8RkI7h4Bz-zp8OdTAxbJUoVvcoU-jhMdRZ0B-k0xc,140
|
|
142
|
-
pydantic/json_schema.py,sha256=
|
|
143
|
-
pydantic/main.py,sha256=
|
|
144
|
-
pydantic/mypy.py,sha256=
|
|
142
|
+
pydantic/json_schema.py,sha256=OM7Qy6JgZ1Gr7ln_2-4lGbAa7N1ftl1-7pYVzO3jtok,143064
|
|
143
|
+
pydantic/main.py,sha256=oYoupv4Cq9EDXdVrNQBv0psMkCJ_cdd-RfoOUq7Vruc,91726
|
|
144
|
+
pydantic/mypy.py,sha256=qWTROdLlgp9sRNXTPd4F3nQke818LSWdr7r83_5lmv4,64611
|
|
145
145
|
pydantic/networks.py,sha256=YIXsCaWUqE7FMwAO5ujYXClMLxI3KP6e2MdVwnP5X4s,44516
|
|
146
146
|
pydantic/parse.py,sha256=wkd82dgtvWtD895U_I6E1htqMlGhBSYEV39cuBSeo3A,141
|
|
147
147
|
pydantic/plugin/__init__.py,sha256=SrVX9XDbUKzt6BVNBRKXKmEqxecEREq6A4WoV_RMJhc,7263
|
|
@@ -151,10 +151,10 @@ pydantic/plugin/__pycache__/_schema_validator.cpython-313.pyc,,
|
|
|
151
151
|
pydantic/plugin/_loader.py,sha256=hAjgSljoIhGx3AVpIpuqw5SPttBNNeGBSTrqSMnNiJk,2213
|
|
152
152
|
pydantic/plugin/_schema_validator.py,sha256=__9f3t6adZxNgyzajuNda5siIvKWDDXssE6QD8hzXB4,5815
|
|
153
153
|
pydantic/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
154
|
-
pydantic/root_model.py,sha256=
|
|
154
|
+
pydantic/root_model.py,sha256=7enqbPZHFXk7DO-2H9wG9NxmIGeJcbHSewhKSLS8a4A,8777
|
|
155
155
|
pydantic/schema.py,sha256=Vqqjvq_LnapVknebUd3Bp_J1p2gXZZnZRgL48bVEG7o,142
|
|
156
156
|
pydantic/tools.py,sha256=iHQpd8SJ5DCTtPV5atAV06T89bjSaMFeZZ2LX9lasZY,141
|
|
157
|
-
pydantic/type_adapter.py,sha256=
|
|
157
|
+
pydantic/type_adapter.py,sha256=HuIrYnURDsX0TS1L8A_AKxymlqg9MA-ODuaCp99v-kc,36569
|
|
158
158
|
pydantic/types.py,sha256=5IFO7vOYHyaPf4VE2bRi9aUdH1CY-NgADjpYDfwIWQQ,110280
|
|
159
159
|
pydantic/typing.py,sha256=P7feA35MwTcLsR1uL7db0S-oydBxobmXa55YDoBgajQ,138
|
|
160
160
|
pydantic/utils.py,sha256=15nR2QpqTBFlQV4TNtTItMyTJx_fbyV-gPmIEY1Gooc,141
|
|
@@ -190,8 +190,8 @@ pydantic/v1/annotated_types.py,sha256=uk2NAAxqiNELKjiHhyhxKaIOh8F1lYW_LzrW3X7oZB
|
|
|
190
190
|
pydantic/v1/class_validators.py,sha256=ULOaIUgYUDBsHL7EEVEarcM-UubKUggoN8hSbDonsFE,14672
|
|
191
191
|
pydantic/v1/color.py,sha256=iZABLYp6OVoo2AFkP9Ipri_wSc6-Kklu8YuhSartd5g,16844
|
|
192
192
|
pydantic/v1/config.py,sha256=a6P0Wer9x4cbwKW7Xv8poSUqM4WP-RLWwX6YMpYq9AA,6532
|
|
193
|
-
pydantic/v1/dataclasses.py,sha256=
|
|
194
|
-
pydantic/v1/datetime_parse.py,sha256=
|
|
193
|
+
pydantic/v1/dataclasses.py,sha256=0Sfk-TNwm21SqiGhhpzs1DsXajhdWM6Eh5ZiSu4bjIA,18358
|
|
194
|
+
pydantic/v1/datetime_parse.py,sha256=exzh-Ul0IWR4FwRVpvE5aoTQ69DK6R-vNCtUakowBxs,7728
|
|
195
195
|
pydantic/v1/decorator.py,sha256=zaaxxxoWPCm818D1bs0yhapRjXm32V8G0ZHWCdM1uXA,10339
|
|
196
196
|
pydantic/v1/env_settings.py,sha256=A9VXwtRl02AY-jH0C0ouy5VNw3fi6F_pkzuHDjgAAOM,14105
|
|
197
197
|
pydantic/v1/error_wrappers.py,sha256=6625Mfw9qkC2NwitB_JFAWe8B-Xv6zBU7rL9k28tfyo,5196
|
|
@@ -200,18 +200,18 @@ pydantic/v1/fields.py,sha256=MjiQ6Q5RkE-koXfmx8tYJbfe97_QeYtnpkQf8OTve_s,50646
|
|
|
200
200
|
pydantic/v1/generics.py,sha256=YzyKTZN6x5Q1RGJ3WQ9jN-uwHJxL3W4qoZqwcZXqxWg,17829
|
|
201
201
|
pydantic/v1/json.py,sha256=WQ5Hy_hIpfdR3YS8k6N2E6KMJzsdbBi_ldWOPJaV81M,3390
|
|
202
202
|
pydantic/v1/main.py,sha256=vRB1TbpkzPN3P5ijJlc-cjNuO-HciNOpC4b8K3zZnfc,45697
|
|
203
|
-
pydantic/v1/mypy.py,sha256=
|
|
203
|
+
pydantic/v1/mypy.py,sha256=egR4NqF3clfaVYPP5nmj36jjdOHJpRPeGYS83mzNTJY,38898
|
|
204
204
|
pydantic/v1/networks.py,sha256=HYNtKAfOmOnKJpsDg1g6SIkj9WPhU_-i8l5e2JKBpG4,22124
|
|
205
205
|
pydantic/v1/parse.py,sha256=BJtdqiZRtav9VRFCmOxoY-KImQmjPy-A_NoojiFUZxY,1821
|
|
206
206
|
pydantic/v1/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
207
207
|
pydantic/v1/schema.py,sha256=aqBuA--cq8gAVkim5BJPFASHzOZ8dFtmFX_fNGr6ip4,47801
|
|
208
208
|
pydantic/v1/tools.py,sha256=1lDdXHk0jL5uP3u5RCYAvUAlGClgAO-45lkq9j7fyBA,2881
|
|
209
|
-
pydantic/v1/types.py,sha256=
|
|
209
|
+
pydantic/v1/types.py,sha256=RfJ19cNFhy-VKs2lzIIl9_dHYn8Vlabd7VktOvoQawI,35793
|
|
210
210
|
pydantic/v1/typing.py,sha256=ovwtLpEZCbnghZaHfSNJupzetzHNkLXjn_66kgTnIV4,20102
|
|
211
211
|
pydantic/v1/utils.py,sha256=1PqOIlz6OVWwGds3HBKlw4Et6asFou0UUpAto7jFOCs,26014
|
|
212
212
|
pydantic/v1/validators.py,sha256=lyUkn1MWhHxlCX5ZfEgFj_CAHojoiPcaQeMdEM9XviU,22187
|
|
213
|
-
pydantic/v1/version.py,sha256=
|
|
213
|
+
pydantic/v1/version.py,sha256=51ZPNC7FcsbAGRl-p2_vbJ0-bKUtjtwc6hiKrBoG4ZA,1039
|
|
214
214
|
pydantic/validate_call_decorator.py,sha256=oktZNbH04RAEV99NSvl5ETPNLTEEE_HLkwj64TOsWd0,4749
|
|
215
215
|
pydantic/validators.py,sha256=pwbIJXVb1CV2mAE4w_EGfNj7DwzsKaWw_tTL6cviTus,146
|
|
216
|
-
pydantic/version.py,sha256=
|
|
216
|
+
pydantic/version.py,sha256=mmIXsYMfk9459TcBRmYuHsYc6wO9c9iMFbAT8GZZUFs,3985
|
|
217
217
|
pydantic/warnings.py,sha256=tIhE-YCNiWNgO53dwo7jYdOFv7AHzJmTkbMdEGZLEko,5177
|
|
Binary file
|
package/bin/dbspec/_internal/src/resources/sqlalchemy_templates/alembic_default_comparator.py.j2
CHANGED
|
@@ -7,11 +7,12 @@ from collections.abc import Iterator as _DBSpecIterator
|
|
|
7
7
|
|
|
8
8
|
_dbspec_NEXTVAL_RE = _dbspec_re.compile(
|
|
9
9
|
r"\bnextval\s*\(\s*'((?:[^']|'')+)'\s*(?:::\s*(?:pg_catalog\.)?regclass)?\s*\)",
|
|
10
|
-
_dbspec_re.IGNORECASE,
|
|
10
|
+
_dbspec_re.IGNORECASE | _dbspec_re.ASCII,
|
|
11
11
|
)
|
|
12
12
|
_dbspec_SEQUENCE_IDENTIFIER_RE = _dbspec_re.compile(r'"((?:[^"]|"")+)"|([^\W\d][\w$]*)')
|
|
13
13
|
_dbspec_DOLLAR_QUOTE_RE = _dbspec_re.compile(r"\$(?:[^\W\d]\w*)?\$")
|
|
14
14
|
_dbspec_INVALID_SEQUENCE_IDENTIFIER = "Invalid nextval sequence identifier"
|
|
15
|
+
_dbspec_SQL_WHITESPACE = " \t\n\r\f\v"
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
def _dbspec_sequence_identity(value: str) -> tuple[str, ...]:
|
|
@@ -19,7 +20,7 @@ def _dbspec_sequence_identity(value: str) -> tuple[str, ...]:
|
|
|
19
20
|
parts: list[str] = []
|
|
20
21
|
end = 0
|
|
21
22
|
for match in _dbspec_SEQUENCE_IDENTIFIER_RE.finditer(value):
|
|
22
|
-
separator = value[end : match.start()].strip()
|
|
23
|
+
separator = value[end : match.start()].strip(_dbspec_SQL_WHITESPACE)
|
|
23
24
|
if separator != ("." if parts else ""):
|
|
24
25
|
raise ValueError(f"{_dbspec_INVALID_SEQUENCE_IDENTIFIER}: {value!r}")
|
|
25
26
|
quoted, unquoted = match.groups()
|
|
@@ -29,7 +30,7 @@ def _dbspec_sequence_identity(value: str) -> tuple[str, ...]:
|
|
|
29
30
|
else "".join(char.lower() if char.isascii() else char for char in unquoted)
|
|
30
31
|
)
|
|
31
32
|
end = match.end()
|
|
32
|
-
if value[end:].strip() or len(parts) not in (1, 2):
|
|
33
|
+
if value[end:].strip(_dbspec_SQL_WHITESPACE) or len(parts) not in (1, 2):
|
|
33
34
|
raise ValueError(f"{_dbspec_INVALID_SEQUENCE_IDENTIFIER}: {value!r}")
|
|
34
35
|
return tuple(parts)
|
|
35
36
|
|
|
@@ -85,11 +86,7 @@ def _dbspec_executed_nextval_arguments(sql: str) -> _DBSpecIterator[str]:
|
|
|
85
86
|
position += 1
|
|
86
87
|
|
|
87
88
|
|
|
88
|
-
_dbspec_CAST_RE = _dbspec_re.compile(
|
|
89
|
-
r"::\s*(?:pg_catalog\.)?[a-z_][\w. ]*(?:\(\s*\d+\s*\))?$", _dbspec_re.I
|
|
90
|
-
)
|
|
91
89
|
_dbspec_INTEGER_RE = _dbspec_re.compile(r"[+-]?\d+")
|
|
92
|
-
_dbspec_WHITESPACE_RE = _dbspec_re.compile(r"\s+")
|
|
93
90
|
|
|
94
91
|
|
|
95
92
|
def dbspec_compare_server_default(
|
|
@@ -126,21 +123,21 @@ def _dbspec_normalize_default(
|
|
|
126
123
|
) -> tuple[str, tuple[str, ...] | str] | None:
|
|
127
124
|
if value is None:
|
|
128
125
|
return None
|
|
129
|
-
text = str(value).strip()
|
|
126
|
+
text = str(value).strip(_dbspec_SQL_WHITESPACE)
|
|
130
127
|
if not text:
|
|
131
128
|
return None
|
|
132
129
|
sequence = _dbspec_normalize_nextval(text, column)
|
|
133
130
|
if sequence is not None:
|
|
134
131
|
return ("nextval", sequence)
|
|
135
|
-
return ("literal", _dbspec_normalize_literal_default(text))
|
|
132
|
+
return ("literal", _dbspec_normalize_literal_default(text, column))
|
|
136
133
|
|
|
137
134
|
|
|
138
135
|
def _dbspec_normalize_nextval(value: str, column: _DBSpecAny) -> tuple[str, ...] | None:
|
|
139
136
|
try:
|
|
140
|
-
|
|
141
|
-
if
|
|
137
|
+
match = _dbspec_NEXTVAL_RE.fullmatch(_dbspec_strip_balanced_parentheses(value))
|
|
138
|
+
if match is None:
|
|
142
139
|
return None
|
|
143
|
-
identity = _dbspec_sequence_identity(
|
|
140
|
+
identity = _dbspec_sequence_identity(match[1].replace("''", "'"))
|
|
144
141
|
except ValueError:
|
|
145
142
|
return None
|
|
146
143
|
if len(identity) == 1:
|
|
@@ -156,58 +153,143 @@ def _dbspec_column_schema(column: _DBSpecAny) -> str | None:
|
|
|
156
153
|
return schema if isinstance(schema, str) and schema else None
|
|
157
154
|
|
|
158
155
|
|
|
159
|
-
def
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
156
|
+
def _dbspec_sql_tokens(value: str) -> list[str]:
|
|
157
|
+
"""Tokenize enough PostgreSQL syntax to preserve literals and grouping."""
|
|
158
|
+
tokens: list[str] = []
|
|
159
|
+
position = 0
|
|
160
|
+
whitespace = ""
|
|
161
|
+
while position < len(value):
|
|
162
|
+
if value[position] in _dbspec_SQL_WHITESPACE:
|
|
163
|
+
whitespace += value[position]
|
|
164
|
+
position += 1
|
|
165
|
+
continue
|
|
166
|
+
start = position
|
|
167
|
+
if value.startswith("--", position):
|
|
168
|
+
end = value.find("\n", position)
|
|
169
|
+
position = len(value) if end < 0 else end + 1
|
|
170
|
+
elif value.startswith("/*", position):
|
|
171
|
+
depth = 1
|
|
172
|
+
position += 2
|
|
173
|
+
while position < len(value) and depth:
|
|
174
|
+
if value.startswith("/*", position):
|
|
175
|
+
depth += 1
|
|
176
|
+
position += 2
|
|
177
|
+
elif value.startswith("*/", position):
|
|
178
|
+
depth -= 1
|
|
179
|
+
position += 2
|
|
180
|
+
else:
|
|
181
|
+
position += 1
|
|
182
|
+
elif match := _dbspec_DOLLAR_QUOTE_RE.match(value, position):
|
|
183
|
+
end = value.find(match[0], match.end())
|
|
184
|
+
position = len(value) if end < 0 else end + len(match[0])
|
|
185
|
+
elif value[position] in ("'", '"') or (
|
|
186
|
+
value[position] in "eEbBxXnN" and value[position + 1:position + 2] == "'"
|
|
187
|
+
) or (
|
|
188
|
+
value[position] in "uU" and value[position + 1:position + 2] == "&"
|
|
189
|
+
and value[position + 2:position + 3] in ("'", '"')
|
|
190
|
+
):
|
|
191
|
+
escaped = value[position] in "eE"
|
|
192
|
+
if value[position] in "uU":
|
|
193
|
+
position += 2
|
|
194
|
+
elif value[position] in "eEbBxXnN":
|
|
195
|
+
position += 1
|
|
196
|
+
quote = value[position]
|
|
197
|
+
position += 1
|
|
198
|
+
while position < len(value):
|
|
199
|
+
if value.startswith(quote * 2, position):
|
|
200
|
+
position += 2
|
|
201
|
+
elif escaped and value[position] == "\\":
|
|
202
|
+
position += 2
|
|
203
|
+
elif value[position] == quote:
|
|
204
|
+
position += 1
|
|
205
|
+
break
|
|
206
|
+
else:
|
|
207
|
+
position += 1
|
|
208
|
+
else:
|
|
209
|
+
match = _dbspec_re.match(
|
|
210
|
+
r"(?:[A-Za-z_]|[^\x00-\x7f])(?:[A-Za-z_0-9$]|[^\x00-\x7f])*|[0-9]+(?:\.[0-9]+)?|[+*/<>=~!@#%^&|`?:-]+|.",
|
|
211
|
+
value[position:],
|
|
212
|
+
)
|
|
213
|
+
assert match is not None
|
|
214
|
+
position += len(match[0])
|
|
215
|
+
token = value[start:position]
|
|
216
|
+
# Adjacent string literals separated by a newline concatenate in PostgreSQL.
|
|
217
|
+
if whitespace and tokens and tokens[-1].endswith("'") and token.startswith("'"):
|
|
218
|
+
tokens.append("\n" if "\n" in whitespace else " ")
|
|
219
|
+
whitespace = ""
|
|
220
|
+
opaque = token.startswith(("'", '"', "$", "--", "/*")) or (
|
|
221
|
+
len(token) >= 2 and token[0] in "eEbBxXnN" and token[1] == "'"
|
|
222
|
+
) or (len(token) >= 3 and token[0] in "uU" and token[1] == "&" and token[2] in ("'", '"'))
|
|
223
|
+
folded = "".join(char.lower() if char.isascii() else char for char in token)
|
|
224
|
+
tokens.append(token if opaque else folded)
|
|
225
|
+
return tokens
|
|
175
226
|
|
|
176
227
|
|
|
177
228
|
def _dbspec_strip_balanced_parentheses(value: str) -> str:
|
|
178
|
-
|
|
179
|
-
while (
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
229
|
+
tokens = _dbspec_sql_tokens(value)
|
|
230
|
+
while len(tokens) >= 2 and tokens[0] == "(" and tokens[-1] == ")":
|
|
231
|
+
depth = 0
|
|
232
|
+
for position, token in enumerate(tokens):
|
|
233
|
+
if token == "(":
|
|
234
|
+
depth += 1
|
|
235
|
+
elif token == ")":
|
|
236
|
+
depth -= 1
|
|
237
|
+
if depth <= 0 and position != len(tokens) - 1:
|
|
238
|
+
return " ".join(tokens)
|
|
239
|
+
if depth != 0:
|
|
240
|
+
break
|
|
241
|
+
tokens = tokens[1:-1]
|
|
242
|
+
return " ".join(tokens)
|
|
186
243
|
|
|
187
244
|
|
|
188
|
-
def
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
245
|
+
def _dbspec_normalize_sql_expression(value: str) -> str:
|
|
246
|
+
return _dbspec_strip_balanced_parentheses(value)
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def _dbspec_string_literal(value: str) -> str | None:
|
|
250
|
+
match = _dbspec_re.fullmatch(
|
|
251
|
+
r"'((?:[^']|'')*)'(?:\s*::\s*(?:pg_catalog\s*\.\s*)?(?:text|varchar|character\s+varying))?",
|
|
252
|
+
value, _dbspec_re.IGNORECASE | _dbspec_re.ASCII,
|
|
253
|
+
)
|
|
254
|
+
return match[1].replace("''", "'") if match else None
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
def _dbspec_normalize_literal_default(value: str, column: _DBSpecAny = None) -> str:
|
|
258
|
+
text = value.strip(_dbspec_SQL_WHITESPACE)
|
|
259
|
+
if text.lower().startswith("default "):
|
|
260
|
+
text = text[8:].strip(_dbspec_SQL_WHITESPACE)
|
|
261
|
+
text = _dbspec_strip_balanced_parentheses(text)
|
|
262
|
+
column_type = str(getattr(column, "type", "")).lower()
|
|
263
|
+
if _dbspec_re.fullmatch(r"(?:varchar|character varying|text)(?:\(\d+\))?", column_type):
|
|
264
|
+
literal = _dbspec_string_literal(text)
|
|
265
|
+
if literal is not None:
|
|
266
|
+
return "string:" + literal
|
|
267
|
+
return "sql:" + text
|
|
268
|
+
# Only normalize primitive casts; expressions and domain casts stay visible.
|
|
269
|
+
cast = _dbspec_re.fullmatch(
|
|
270
|
+
r"(.+?)\s*::\s*(?:pg_catalog\s*\.\s*)?(boolean|bool|integer|int|int4|bigint|int8|smallint|int2)",
|
|
271
|
+
text, _dbspec_re.IGNORECASE | _dbspec_re.ASCII,
|
|
272
|
+
)
|
|
273
|
+
primitive_text = _dbspec_strip_balanced_parentheses(cast[1]) if cast else text
|
|
274
|
+
cast_type = cast[2].lower() if cast else ""
|
|
275
|
+
boolean_casts = {"boolean", "bool"}
|
|
276
|
+
if cast_type in boolean_casts:
|
|
277
|
+
boolean = _dbspec_re.fullmatch(r"(?:'(true|false)'|(true|false))", primitive_text, _dbspec_re.IGNORECASE | _dbspec_re.ASCII)
|
|
278
|
+
if boolean:
|
|
279
|
+
return (boolean[1] or boolean[2]).lower()
|
|
280
|
+
return text
|
|
281
|
+
if cast:
|
|
282
|
+
# Quoted numeric literals are safe only with an explicit integer cast.
|
|
283
|
+
quoted = _dbspec_re.fullmatch(r"'([+-]?[0-9]+)'", primitive_text)
|
|
284
|
+
if quoted:
|
|
285
|
+
primitive_text = quoted[1]
|
|
286
|
+
integer = _dbspec_re.fullmatch(r"([+-]?)[ \t\n\r\f\v]*([0-9]+)", primitive_text)
|
|
287
|
+
if integer:
|
|
288
|
+
number = int(integer[1] + integer[2])
|
|
289
|
+
bit_width = {"smallint": 16, "int2": 16, "integer": 32, "int": 32, "int4": 32, "bigint": 64, "int8": 64}.get(cast_type)
|
|
290
|
+
if bit_width is not None and not -(2 ** (bit_width - 1)) <= number < 2 ** (bit_width - 1):
|
|
291
|
+
return text
|
|
292
|
+
return str(number)
|
|
293
|
+
if not cast and primitive_text.lower() in {"true", "false"}:
|
|
294
|
+
return primitive_text.lower()
|
|
295
|
+
return text
|
package/bin/dbspec/dbspec.exe
CHANGED
|
Binary file
|
package/package.json
CHANGED
/package/bin/dbspec/_internal/{pydantic-2.14.1.dist-info → pydantic-2.14.2.dist-info}/INSTALLER
RENAMED
|
File without changes
|
|
File without changes
|