From f42634e25d8482973fdf150eb0590415e3b523d7 Mon Sep 17 00:00:00 2001 From: Harrison Liew Date: Wed, 6 Mar 2024 17:11:42 -0800 Subject: [PATCH] Pydantic bump, fix readthedocs w/ Poetry 1.8 (#847) * ran bump-pydantic utility * docs clarifications, try creating venv * RTD identified bug with poetry 1.8, implementing workaround * don't set create venv false * typo * fix pydantic deprecations * added tests/ to CI mypy --- .github/workflows/pr.yml | 1 + .readthedocs.yml | 8 +- doc/Hammer-Basics/Hammer-Setup.md | 12 ++- hammer/tech/__init__.py | 54 +++++----- hammer/tech/specialcells.py | 13 +-- hammer/tech/stackup.py | 21 ++-- hammer/vlsi/hammer_vlsi_impl.py | 2 +- poetry.lock | 170 +++++++++++++++++++++--------- pyproject.toml | 2 +- tests/test_hooks.py | 8 +- tests/test_pcb_tool.py | 6 +- tests/test_power_straps.py | 24 ++--- tests/test_sdc.py | 2 +- tests/test_signoff_tools.py | 9 +- tests/test_sim_tool.py | 6 +- tests/test_sram_generator.py | 6 +- tests/test_stackup.py | 10 +- tests/test_submit_command.py | 15 ++- tests/test_tech.py | 10 +- tests/test_tool.py | 28 ++--- 20 files changed, 235 insertions(+), 172 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index f5540a7d8..84f0fac90 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -62,3 +62,4 @@ jobs: touch .venv/lib/python${{ matrix.python-version }}/site-packages/ruamel/py.typed touch .venv/lib/python${{ matrix.python-version }}/site-packages/networkx/py.typed poetry run mypy --namespace-packages -p hammer + poetry run mypy --namespace-packages -p tests diff --git a/.readthedocs.yml b/.readthedocs.yml index e85ac8e00..e1ce84e00 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -7,10 +7,12 @@ build: tools: python: '3.10' jobs: - post_install: + post_create_environment: - pip install poetry myst-parser - - poetry config virtualenvs.create false - - poetry install + post_install: + # VIRTUAL_ENV needs to be set manually for now. + # See https://github.com/readthedocs/readthedocs.org/pull/11152/ + - VIRTUAL_ENV=$READTHEDOCS_VIRTUALENV_PATH poetry install - python3 -c "from hammer.tech import TechJSON; print(TechJSON.schema_json(indent=2))" > doc/Technology/schema.json # Build documentation with Sphinx diff --git a/doc/Hammer-Basics/Hammer-Setup.md b/doc/Hammer-Basics/Hammer-Setup.md index 33ae2b464..809ed3126 100644 --- a/doc/Hammer-Basics/Hammer-Setup.md +++ b/doc/Hammer-Basics/Hammer-Setup.md @@ -137,10 +137,11 @@ pytest tests/test_build_systems.py -k "flat_makefile" -rA -v ### Type Checking with mypy -There is a [small issue with the ruamel.yaml package typechecking](https://github.com/python/mypy/issues/12664) which can be hacked around with: +There is a [small issue with the ruamel.yaml package typechecking](https://github.com/python/mypy/issues/12664) which can be hacked around with (replace the python version with your own): ```shell touch .venv/lib/python3.10/site-packages/ruamel/py.typed +touch .venv/lib/python3.10/site-packages/networkx/py.typed ``` Inside your poetry virtualenv, from the root of Hammer, run: @@ -218,7 +219,14 @@ Run `poetry update` and `poetry install` and commit `poetry.lock`. ### Building Documentation -- Within your poetry virutualenv, `cd doc` +First, generate the `schema.json` file from within your poetry virtualenv: + +```shell +python3 -c "from hammer.tech import TechJSON; print(TechJSON.schema_json(indent=2))" > doc/Technology/schema.json +``` + +Then: +- `cd doc` - Modify any documentation files. You can migrate any rst file to Markdown if desired. - Run `sphinx-build . build` - The generated HTML files are placed in `build/` diff --git a/hammer/tech/__init__.py b/hammer/tech/__init__.py index 4d4ad48b7..5044745de 100644 --- a/hammer/tech/__init__.py +++ b/hammer/tech/__init__.py @@ -45,7 +45,7 @@ class MinMaxCap(BaseModel): class Provide(BaseModel): lib_type: str - vt: Optional[str] + vt: Optional[str] = None class Supplies(BaseModel): @@ -212,27 +212,27 @@ def from_setting(grid_unit: Decimal, d: Dict[str, Any]) -> "Site": class TechJSON(BaseModel): name: str - grid_unit: Optional[str] - shrink_factor: Optional[str] - installs: Optional[List[PathPrefix]] - libraries: Optional[List[Library]] - gds_map_file: Optional[str] - physical_only_cells_list: Optional[List[Cell]] - dont_use_list: Optional[List[Cell]] - drc_decks: Optional[List[DRCDeck]] - lvs_decks: Optional[List[LVSDeck]] - tarballs: Optional[List[Tarball]] - sites: Optional[List[Site]] - stackups: Optional[List[Stackup]] - special_cells: Optional[List[SpecialCell]] - extra_prefixes: Optional[List[PathPrefix]] - additional_lvs_text: Optional[str] - additional_drc_text: Optional[str] + grid_unit: Optional[str] = None + shrink_factor: Optional[str] = None + installs: Optional[List[PathPrefix]] = None + libraries: Optional[List[Library]] = None + gds_map_file: Optional[str] = None + physical_only_cells_list: Optional[List[Cell]] = None + dont_use_list: Optional[List[Cell]] = None + drc_decks: Optional[List[DRCDeck]] = None + lvs_decks: Optional[List[LVSDeck]] = None + tarballs: Optional[List[Tarball]] = None + sites: Optional[List[Site]] = None + stackups: Optional[List[Stackup]] = None + special_cells: Optional[List[SpecialCell]] = None + extra_prefixes: Optional[List[PathPrefix]] = None + additional_lvs_text: Optional[str] = None + additional_drc_text: Optional[str] = None def copy_library(lib: Library) -> Library: """Perform a deep copy of a Library.""" - return Library.parse_raw(lib.json()) + return Library.model_validate_json(lib.model_dump_json()) def library_from_json(json: str) -> Library: @@ -241,12 +241,12 @@ def library_from_json(json: str) -> Library: :param json: JSON string. :return: hammer_tech library. """ - return Library.parse_raw(json) + return Library.model_validate_json(json) # Struct that holds an extra library and possible prefix. class ExtraLibrary(BaseModel): - prefix: Optional[PathPrefix] + prefix: Optional[PathPrefix] = None library: Library def store_into_library(self) -> Library: @@ -271,7 +271,7 @@ class MacroSize(BaseModel): height: Decimal def to_setting(self) -> dict: - return self.dict() + return self.model_dump() @staticmethod def from_setting(d: dict) -> "MacroSize": @@ -370,10 +370,10 @@ def load_from_module(cls, tech_module: str) -> Optional["HammerTechnology"]: tech_yaml = importlib.resources.files(tech_module) / f"{technology_name}.tech.yml" if tech_json.is_file(): - tech.config = TechJSON.parse_raw(tech_json.read_text()) + tech.config = TechJSON.model_validate_json(tech_json.read_text()) return tech elif tech_yaml.is_file(): - tech.config = TechJSON.parse_raw(json.dumps(load_yaml(tech_yaml.read_text()))) + tech.config = TechJSON.model_validate_json(json.dumps(load_yaml(tech_yaml.read_text()))) return tech else: #TODO - from Pydantic model instance return None @@ -535,7 +535,7 @@ def parse_library(lib: dict) -> Library: raise TypeError("lib must be a dict") # Convert the dict to JSON... - return Library.parse_raw(json.dumps(lib, cls=HammerJSONEncoder)) + return Library.model_validate_json(json.dumps(lib, cls=HammerJSONEncoder)) @property def tech_defined_libraries(self) -> List[Library]: @@ -582,7 +582,7 @@ def extraction_func(lib: Library, paths: List[str]) -> List[str]: name = str(lib_name) return [json.dumps([paths[0], name], cls=HammerJSONEncoder)] - lef_filter_plus = filters.lef_filter.copy(deep=True) + lef_filter_plus = filters.lef_filter.model_copy(deep=True) lef_filter_plus.extraction_func = extraction_func lef_names_filenames_serialized = self.process_library_filter(filt=lef_filter_plus, @@ -779,7 +779,7 @@ def get_extra_libraries(self) -> List[ExtraLibrary]: if not isinstance(extra_libs, list): raise ValueError("extra_libraries was not a list") else: - return [ExtraLibrary.parse_obj(lib) for lib in extra_libs] + return [ExtraLibrary.model_validate(lib) for lib in extra_libs] def get_available_libraries(self) -> List[Library]: """ @@ -945,7 +945,7 @@ def filter_for_supplies(self, lib: Library) -> bool: for provided in lib.provides: if provided.lib_type is not None and provided.lib_type == "technology": return True - self.logger.warning("Lib %s has no supplies annotation! Using anyway." % (lib.json())) + self.logger.warning("Lib %s has no supplies annotation! Using anyway." % (lib.model_dump_json())) return True return self.get_setting("vlsi.inputs.supplies.VDD") == lib.supplies.VDD and self.get_setting( "vlsi.inputs.supplies.GND") == lib.supplies.GND diff --git a/hammer/tech/specialcells.py b/hammer/tech/specialcells.py index 0168fb6e7..77de6bc1a 100644 --- a/hammer/tech/specialcells.py +++ b/hammer/tech/specialcells.py @@ -5,7 +5,7 @@ from enum import Enum from typing import List, Optional -from pydantic import BaseModel +from pydantic import ConfigDict, BaseModel class CellType(str, Enum): @@ -29,10 +29,7 @@ class SpecialCell(BaseModel): # Endcap, filler, etc. cell_type: CellType name: List[str] - size: Optional[List[str]] - input_ports: Optional[List[str]] - output_ports: Optional[List[str]] - - class Config: - # https://stackoverflow.com/questions/65209934/pydantic-enum-field-does-not-get-converted-to-string - use_enum_values = True + size: Optional[List[str]] = None + input_ports: Optional[List[str]] = None + output_ports: Optional[List[str]] = None + model_config = ConfigDict(use_enum_values=True) diff --git a/hammer/tech/stackup.py b/hammer/tech/stackup.py index e8b81a596..cdc625888 100644 --- a/hammer/tech/stackup.py +++ b/hammer/tech/stackup.py @@ -7,7 +7,7 @@ from functools import partial from typing import Any, List, Tuple, Optional -from pydantic import BaseModel, root_validator +from pydantic import model_validator, ConfigDict, BaseModel from hammer.utils import coerce_to_grid from hammer.logging import HammerVLSILoggingContext @@ -51,8 +51,8 @@ class WidthSpacingTuple(BaseModel): @staticmethod def from_setting(grid_unit: Decimal, d: dict) -> "WidthSpacingTuple": - width_at_least = coerce_to_grid(d["width_at_least"], grid_unit) - min_spacing = coerce_to_grid(d["min_spacing"], grid_unit) + width_at_least = coerce_to_grid(Decimal(str(d["width_at_least"])), grid_unit) + min_spacing = coerce_to_grid(Decimal(str(d["min_spacing"])), grid_unit) assert width_at_least >= 0 assert min_spacing > 0 return WidthSpacingTuple( @@ -110,11 +110,10 @@ class Metal(BaseModel): # Note: grid_unit is not currently parsed as part of the Metal data structure! # See #379 grid_unit: Decimal + model_config = ConfigDict(use_enum_values=True) - class Config: - use_enum_values = True - - @root_validator(pre=True) + @model_validator(mode="before") + @classmethod def widths_must_snap_to_grid(cls, values): grid_unit = Decimal(str(values.get("grid_unit"))) for field in ["min_width", "pitch", "offset"]: @@ -148,10 +147,10 @@ def from_setting(grid_unit: Decimal, d: dict) -> "Metal": name=str(d["name"]), index=int(d["index"]), direction=RoutingDirection(d["direction"]), - min_width=coerce_to_grid(d["min_width"], grid_unit), - max_width=coerce_to_grid(d["max_width"], grid_unit) if "max_width" in d and d["max_width"] is not None else None, - pitch=coerce_to_grid(d["pitch"], grid_unit), - offset=coerce_to_grid(d["offset"], grid_unit), + min_width=coerce_to_grid(Decimal(str(d["min_width"])), grid_unit), + max_width=coerce_to_grid(Decimal(str(d["max_width"])), grid_unit) if "max_width" in d and d["max_width"] is not None else None, + pitch=coerce_to_grid(Decimal(str(d["pitch"])), grid_unit), + offset=coerce_to_grid(Decimal(str(d["offset"])), grid_unit), power_strap_widths_and_spacings=WidthSpacingTuple.from_list(grid_unit, d["power_strap_widths_and_spacings"]), power_strap_width_table=Metal.power_strap_widths_from_list(grid_unit, d["power_strap_width_table"] if "power_strap_width_table" in d and d["power_strap_width_table"] else []) ) diff --git a/hammer/vlsi/hammer_vlsi_impl.py b/hammer/vlsi/hammer_vlsi_impl.py index 7c7088f47..2a0795031 100644 --- a/hammer/vlsi/hammer_vlsi_impl.py +++ b/hammer/vlsi/hammer_vlsi_impl.py @@ -214,7 +214,7 @@ def export_config_outputs(self) -> Dict[str, Any]: outputs = deepdict(super().export_config_outputs()) simple_ex = [] for ex in self.output_libraries: # type: ExtraLibrary - simple_lib = json.loads(ex.library.json()) + simple_lib = json.loads(ex.library.model_dump_json()) if(ex.prefix == None): new_ex = {"library": simple_lib} else: diff --git a/poetry.lock b/poetry.lock index 5cc7905a2..53d8aabe6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. [[package]] name = "alabaster" @@ -11,6 +11,17 @@ files = [ {file = "alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65"}, ] +[[package]] +name = "annotated-types" +version = "0.6.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"}, + {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"}, +] + [[package]] name = "astroid" version = "2.15.8" @@ -771,55 +782,113 @@ files = [ [[package]] name = "pydantic" -version = "1.10.14" -description = "Data validation and settings management using python type hints" +version = "2.6.3" +description = "Data validation using Python type hints" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pydantic-1.10.14-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7f4fcec873f90537c382840f330b90f4715eebc2bc9925f04cb92de593eae054"}, - {file = "pydantic-1.10.14-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e3a76f571970fcd3c43ad982daf936ae39b3e90b8a2e96c04113a369869dc87"}, - {file = "pydantic-1.10.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82d886bd3c3fbeaa963692ef6b643159ccb4b4cefaf7ff1617720cbead04fd1d"}, - {file = "pydantic-1.10.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:798a3d05ee3b71967844a1164fd5bdb8c22c6d674f26274e78b9f29d81770c4e"}, - {file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:23d47a4b57a38e8652bcab15a658fdb13c785b9ce217cc3a729504ab4e1d6bc9"}, - {file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f9f674b5c3bebc2eba401de64f29948ae1e646ba2735f884d1594c5f675d6f2a"}, - {file = "pydantic-1.10.14-cp310-cp310-win_amd64.whl", hash = "sha256:24a7679fab2e0eeedb5a8924fc4a694b3bcaac7d305aeeac72dd7d4e05ecbebf"}, - {file = "pydantic-1.10.14-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9d578ac4bf7fdf10ce14caba6f734c178379bd35c486c6deb6f49006e1ba78a7"}, - {file = "pydantic-1.10.14-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa7790e94c60f809c95602a26d906eba01a0abee9cc24150e4ce2189352deb1b"}, - {file = "pydantic-1.10.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aad4e10efa5474ed1a611b6d7f0d130f4aafadceb73c11d9e72823e8f508e663"}, - {file = "pydantic-1.10.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1245f4f61f467cb3dfeced2b119afef3db386aec3d24a22a1de08c65038b255f"}, - {file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:21efacc678a11114c765eb52ec0db62edffa89e9a562a94cbf8fa10b5db5c046"}, - {file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:412ab4a3f6dbd2bf18aefa9f79c7cca23744846b31f1d6555c2ee2b05a2e14ca"}, - {file = "pydantic-1.10.14-cp311-cp311-win_amd64.whl", hash = "sha256:e897c9f35281f7889873a3e6d6b69aa1447ceb024e8495a5f0d02ecd17742a7f"}, - {file = "pydantic-1.10.14-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d604be0f0b44d473e54fdcb12302495fe0467c56509a2f80483476f3ba92b33c"}, - {file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a42c7d17706911199798d4c464b352e640cab4351efe69c2267823d619a937e5"}, - {file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:596f12a1085e38dbda5cbb874d0973303e34227b400b6414782bf205cc14940c"}, - {file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bfb113860e9288d0886e3b9e49d9cf4a9d48b441f52ded7d96db7819028514cc"}, - {file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bc3ed06ab13660b565eed80887fcfbc0070f0aa0691fbb351657041d3e874efe"}, - {file = "pydantic-1.10.14-cp37-cp37m-win_amd64.whl", hash = "sha256:ad8c2bc677ae5f6dbd3cf92f2c7dc613507eafe8f71719727cbc0a7dec9a8c01"}, - {file = "pydantic-1.10.14-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c37c28449752bb1f47975d22ef2882d70513c546f8f37201e0fec3a97b816eee"}, - {file = "pydantic-1.10.14-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:49a46a0994dd551ec051986806122767cf144b9702e31d47f6d493c336462597"}, - {file = "pydantic-1.10.14-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53e3819bd20a42470d6dd0fe7fc1c121c92247bca104ce608e609b59bc7a77ee"}, - {file = "pydantic-1.10.14-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fbb503bbbbab0c588ed3cd21975a1d0d4163b87e360fec17a792f7d8c4ff29f"}, - {file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:336709883c15c050b9c55a63d6c7ff09be883dbc17805d2b063395dd9d9d0022"}, - {file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4ae57b4d8e3312d486e2498d42aed3ece7b51848336964e43abbf9671584e67f"}, - {file = "pydantic-1.10.14-cp38-cp38-win_amd64.whl", hash = "sha256:dba49d52500c35cfec0b28aa8b3ea5c37c9df183ffc7210b10ff2a415c125c4a"}, - {file = "pydantic-1.10.14-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c66609e138c31cba607d8e2a7b6a5dc38979a06c900815495b2d90ce6ded35b4"}, - {file = "pydantic-1.10.14-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d986e115e0b39604b9eee3507987368ff8148222da213cd38c359f6f57b3b347"}, - {file = "pydantic-1.10.14-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:646b2b12df4295b4c3148850c85bff29ef6d0d9621a8d091e98094871a62e5c7"}, - {file = "pydantic-1.10.14-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282613a5969c47c83a8710cc8bfd1e70c9223feb76566f74683af889faadc0ea"}, - {file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:466669501d08ad8eb3c4fecd991c5e793c4e0bbd62299d05111d4f827cded64f"}, - {file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:13e86a19dca96373dcf3190fcb8797d40a6f12f154a244a8d1e8e03b8f280593"}, - {file = "pydantic-1.10.14-cp39-cp39-win_amd64.whl", hash = "sha256:08b6ec0917c30861e3fe71a93be1648a2aa4f62f866142ba21670b24444d7fd8"}, - {file = "pydantic-1.10.14-py3-none-any.whl", hash = "sha256:8ee853cd12ac2ddbf0ecbac1c289f95882b2d4482258048079d13be700aa114c"}, - {file = "pydantic-1.10.14.tar.gz", hash = "sha256:46f17b832fe27de7850896f3afee50ea682220dd218f7e9c88d436788419dca6"}, + {file = "pydantic-2.6.3-py3-none-any.whl", hash = "sha256:72c6034df47f46ccdf81869fddb81aade68056003900a8724a4f160700016a2a"}, + {file = "pydantic-2.6.3.tar.gz", hash = "sha256:e07805c4c7f5c6826e33a1d4c9d47950d7eaf34868e2690f8594d2e30241f11f"}, ] [package.dependencies] -typing-extensions = ">=4.2.0" +annotated-types = ">=0.4.0" +pydantic-core = "2.16.3" +typing-extensions = ">=4.6.1" [package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] +email = ["email-validator (>=2.0.0)"] + +[[package]] +name = "pydantic-core" +version = "2.16.3" +description = "" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_core-2.16.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:75b81e678d1c1ede0785c7f46690621e4c6e63ccd9192af1f0bd9d504bbb6bf4"}, + {file = "pydantic_core-2.16.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9c865a7ee6f93783bd5d781af5a4c43dadc37053a5b42f7d18dc019f8c9d2bd1"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:162e498303d2b1c036b957a1278fa0899d02b2842f1ff901b6395104c5554a45"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f583bd01bbfbff4eaee0868e6fc607efdfcc2b03c1c766b06a707abbc856187"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b926dd38db1519ed3043a4de50214e0d600d404099c3392f098a7f9d75029ff8"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:716b542728d4c742353448765aa7cdaa519a7b82f9564130e2b3f6766018c9ec"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc4ad7f7ee1a13d9cb49d8198cd7d7e3aa93e425f371a68235f784e99741561f"}, + {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bd87f48924f360e5d1c5f770d6155ce0e7d83f7b4e10c2f9ec001c73cf475c99"}, + {file = "pydantic_core-2.16.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0df446663464884297c793874573549229f9eca73b59360878f382a0fc085979"}, + {file = "pydantic_core-2.16.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4df8a199d9f6afc5ae9a65f8f95ee52cae389a8c6b20163762bde0426275b7db"}, + {file = "pydantic_core-2.16.3-cp310-none-win32.whl", hash = "sha256:456855f57b413f077dff513a5a28ed838dbbb15082ba00f80750377eed23d132"}, + {file = "pydantic_core-2.16.3-cp310-none-win_amd64.whl", hash = "sha256:732da3243e1b8d3eab8c6ae23ae6a58548849d2e4a4e03a1924c8ddf71a387cb"}, + {file = "pydantic_core-2.16.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:519ae0312616026bf4cedc0fe459e982734f3ca82ee8c7246c19b650b60a5ee4"}, + {file = "pydantic_core-2.16.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b3992a322a5617ded0a9f23fd06dbc1e4bd7cf39bc4ccf344b10f80af58beacd"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d62da299c6ecb04df729e4b5c52dc0d53f4f8430b4492b93aa8de1f541c4aac"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2acca2be4bb2f2147ada8cac612f8a98fc09f41c89f87add7256ad27332c2fda"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1b662180108c55dfbf1280d865b2d116633d436cfc0bba82323554873967b340"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e7c6ed0dc9d8e65f24f5824291550139fe6f37fac03788d4580da0d33bc00c97"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1bb0827f56654b4437955555dc3aeeebeddc47c2d7ed575477f082622c49e"}, + {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e56f8186d6210ac7ece503193ec84104da7ceb98f68ce18c07282fcc2452e76f"}, + {file = "pydantic_core-2.16.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:936e5db01dd49476fa8f4383c259b8b1303d5dd5fb34c97de194560698cc2c5e"}, + {file = "pydantic_core-2.16.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:33809aebac276089b78db106ee692bdc9044710e26f24a9a2eaa35a0f9fa70ba"}, + {file = "pydantic_core-2.16.3-cp311-none-win32.whl", hash = "sha256:ded1c35f15c9dea16ead9bffcde9bb5c7c031bff076355dc58dcb1cb436c4721"}, + {file = "pydantic_core-2.16.3-cp311-none-win_amd64.whl", hash = "sha256:d89ca19cdd0dd5f31606a9329e309d4fcbb3df860960acec32630297d61820df"}, + {file = "pydantic_core-2.16.3-cp311-none-win_arm64.whl", hash = "sha256:6162f8d2dc27ba21027f261e4fa26f8bcb3cf9784b7f9499466a311ac284b5b9"}, + {file = "pydantic_core-2.16.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:0f56ae86b60ea987ae8bcd6654a887238fd53d1384f9b222ac457070b7ac4cff"}, + {file = "pydantic_core-2.16.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9bd22a2a639e26171068f8ebb5400ce2c1bc7d17959f60a3b753ae13c632975"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4204e773b4b408062960e65468d5346bdfe139247ee5f1ca2a378983e11388a2"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f651dd19363c632f4abe3480a7c87a9773be27cfe1341aef06e8759599454120"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf09e615a0bf98d406657e0008e4a8701b11481840be7d31755dc9f97c44053"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8e47755d8152c1ab5b55928ab422a76e2e7b22b5ed8e90a7d584268dd49e9c6b"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:500960cb3a0543a724a81ba859da816e8cf01b0e6aaeedf2c3775d12ee49cade"}, + {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cf6204fe865da605285c34cf1172879d0314ff267b1c35ff59de7154f35fdc2e"}, + {file = "pydantic_core-2.16.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d33dd21f572545649f90c38c227cc8631268ba25c460b5569abebdd0ec5974ca"}, + {file = "pydantic_core-2.16.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:49d5d58abd4b83fb8ce763be7794d09b2f50f10aa65c0f0c1696c677edeb7cbf"}, + {file = "pydantic_core-2.16.3-cp312-none-win32.whl", hash = "sha256:f53aace168a2a10582e570b7736cc5bef12cae9cf21775e3eafac597e8551fbe"}, + {file = "pydantic_core-2.16.3-cp312-none-win_amd64.whl", hash = "sha256:0d32576b1de5a30d9a97f300cc6a3f4694c428d956adbc7e6e2f9cad279e45ed"}, + {file = "pydantic_core-2.16.3-cp312-none-win_arm64.whl", hash = "sha256:ec08be75bb268473677edb83ba71e7e74b43c008e4a7b1907c6d57e940bf34b6"}, + {file = "pydantic_core-2.16.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:b1f6f5938d63c6139860f044e2538baeee6f0b251a1816e7adb6cbce106a1f01"}, + {file = "pydantic_core-2.16.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2a1ef6a36fdbf71538142ed604ad19b82f67b05749512e47f247a6ddd06afdc7"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:704d35ecc7e9c31d48926150afada60401c55efa3b46cd1ded5a01bdffaf1d48"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d937653a696465677ed583124b94a4b2d79f5e30b2c46115a68e482c6a591c8a"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9803edf8e29bd825f43481f19c37f50d2b01899448273b3a7758441b512acf8"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:72282ad4892a9fb2da25defeac8c2e84352c108705c972db82ab121d15f14e6d"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f752826b5b8361193df55afcdf8ca6a57d0232653494ba473630a83ba50d8c9"}, + {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4384a8f68ddb31a0b0c3deae88765f5868a1b9148939c3f4121233314ad5532c"}, + {file = "pydantic_core-2.16.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a4b2bf78342c40b3dc830880106f54328928ff03e357935ad26c7128bbd66ce8"}, + {file = "pydantic_core-2.16.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:13dcc4802961b5f843a9385fc821a0b0135e8c07fc3d9949fd49627c1a5e6ae5"}, + {file = "pydantic_core-2.16.3-cp38-none-win32.whl", hash = "sha256:e3e70c94a0c3841e6aa831edab1619ad5c511199be94d0c11ba75fe06efe107a"}, + {file = "pydantic_core-2.16.3-cp38-none-win_amd64.whl", hash = "sha256:ecdf6bf5f578615f2e985a5e1f6572e23aa632c4bd1dc67f8f406d445ac115ed"}, + {file = "pydantic_core-2.16.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:bda1ee3e08252b8d41fa5537413ffdddd58fa73107171a126d3b9ff001b9b820"}, + {file = "pydantic_core-2.16.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:21b888c973e4f26b7a96491c0965a8a312e13be108022ee510248fe379a5fa23"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be0ec334369316fa73448cc8c982c01e5d2a81c95969d58b8f6e272884df0074"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5b6079cc452a7c53dd378c6f881ac528246b3ac9aae0f8eef98498a75657805"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ee8d5f878dccb6d499ba4d30d757111847b6849ae07acdd1205fffa1fc1253c"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7233d65d9d651242a68801159763d09e9ec96e8a158dbf118dc090cd77a104c9"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6119dc90483a5cb50a1306adb8d52c66e447da88ea44f323e0ae1a5fcb14256"}, + {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:578114bc803a4c1ff9946d977c221e4376620a46cf78da267d946397dc9514a8"}, + {file = "pydantic_core-2.16.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d8f99b147ff3fcf6b3cc60cb0c39ea443884d5559a30b1481e92495f2310ff2b"}, + {file = "pydantic_core-2.16.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4ac6b4ce1e7283d715c4b729d8f9dab9627586dafce81d9eaa009dd7f25dd972"}, + {file = "pydantic_core-2.16.3-cp39-none-win32.whl", hash = "sha256:e7774b570e61cb998490c5235740d475413a1f6de823169b4cf94e2fe9e9f6b2"}, + {file = "pydantic_core-2.16.3-cp39-none-win_amd64.whl", hash = "sha256:9091632a25b8b87b9a605ec0e61f241c456e9248bfdcf7abdf344fdb169c81cf"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:36fa178aacbc277bc6b62a2c3da95226520da4f4e9e206fdf076484363895d2c"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:dcca5d2bf65c6fb591fff92da03f94cd4f315972f97c21975398bd4bd046854a"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a72fb9963cba4cd5793854fd12f4cfee731e86df140f59ff52a49b3552db241"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b60cc1a081f80a2105a59385b92d82278b15d80ebb3adb200542ae165cd7d183"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cbcc558401de90a746d02ef330c528f2e668c83350f045833543cd57ecead1ad"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:fee427241c2d9fb7192b658190f9f5fd6dfe41e02f3c1489d2ec1e6a5ab1e04a"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f4cb85f693044e0f71f394ff76c98ddc1bc0953e48c061725e540396d5c8a2e1"}, + {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b29eeb887aa931c2fcef5aa515d9d176d25006794610c264ddc114c053bf96fe"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a425479ee40ff021f8216c9d07a6a3b54b31c8267c6e17aa88b70d7ebd0e5e5b"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5c5cbc703168d1b7a838668998308018a2718c2130595e8e190220238addc96f"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99b6add4c0b39a513d323d3b93bc173dac663c27b99860dd5bf491b240d26137"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f76ee558751746d6a38f89d60b6228fa174e5172d143886af0f85aa306fd89"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:287073c66748f624be4cef893ef9174e3eb88fe0b8a78dc22e88eca4bc357ca6"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ed25e1835c00a332cb10c683cd39da96a719ab1dfc08427d476bce41b92531fc"}, + {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:86b3d0033580bd6bbe07590152007275bd7af95f98eaa5bd36f3da219dcd93da"}, + {file = "pydantic_core-2.16.3.tar.gz", hash = "sha256:1cac689f80a3abab2d3c0048b29eea5751114054f032a941a32de4c852c59cad"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pygments" @@ -912,7 +981,6 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -995,24 +1063,24 @@ python-versions = ">=3.6" files = [ {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:d92f81886165cb14d7b067ef37e142256f1c6a90a65cd156b063a43da1708cfd"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412"}, - {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:aa2267c6a303eb483de8d02db2871afb5c5fc15618d894300b88958f729ad74f"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:b5edda50e5e9e15e54a6a8a0070302b00c518a9d32accc2346ad6c984aacd279"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b"}, - {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_24_aarch64.whl", hash = "sha256:1707814f0d9791df063f8c19bb51b0d1278b8e9a2353abbb676c2f685dee6afe"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:7048c338b6c86627afb27faecf418768acb6331fc24cfa56c93e8c9780f815fa"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92"}, - {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_24_aarch64.whl", hash = "sha256:1dc67314e7e1086c9fdf2680b7b6c2be1c0d8e3a8279f2e993ca2a7545fecf62"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-win32.whl", hash = "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa"}, @@ -1020,7 +1088,7 @@ files = [ {file = "ruamel.yaml.clib-0.2.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875"}, - {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_24_aarch64.whl", hash = "sha256:77159f5d5b5c14f7c34073862a6b7d34944075d9f93e681638f6d753606c6ce6"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:3fcc54cb0c8b811ff66082de1680b4b14cf8a81dce0d4fbf665c2265a81e07a1"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4ecbf9c3e19f9562c7fdd462e8d18dd902a47ca046a2e64dba80699f0b6c09b7"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:87ea5ff66d8064301a154b3933ae406b0863402a799b16e4a1d24d9fbbcbe0d3"}, @@ -1028,7 +1096,7 @@ files = [ {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win_amd64.whl", hash = "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337"}, - {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_24_aarch64.whl", hash = "sha256:305889baa4043a09e5b76f8e2a51d4ffba44259f6b4c72dec8ca56207d9c6fe1"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:665f58bfd29b167039f714c6998178d27ccd83984084c286110ef26b230f259f"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e2b4c44b60eadec492926a7270abb100ef9f72798e18743939bdbf037aab8c28"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e79e5db08739731b0ce4850bed599235d601701d5694c36570a99a0c5ca41a9d"}, @@ -1036,7 +1104,7 @@ files = [ {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win_amd64.whl", hash = "sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf"}, - {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_24_aarch64.whl", hash = "sha256:a1a45e0bb052edf6a1d3a93baef85319733a888363938e1fc9924cb00c8df24c"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:9eb5dee2772b0f704ca2e45b1713e4e5198c18f515b52743576d196348f374d3"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:184565012b60405d93838167f425713180b949e9d8dd0bbc7b49f074407c5a8b"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a75879bacf2c987c003368cf14bed0ffe99e8e85acfa6c0bfffc21a090f16880"}, @@ -1477,4 +1545,4 @@ asap7-gdstk = ["gdstk"] [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "ef4abec4b808a19b2c40e6838c29e52cf32eb02738d1677bc3d569a0a4d70f1e" +content-hash = "fc96db85aeddccee3d71f794a484e0f4f4d17ba4f860ce0fd0be1dc0b1ec9d69" diff --git a/pyproject.toml b/pyproject.toml index 12f5de155..e1cab30b1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ asap7_gds_scale = "hammer.technology.asap7.gds_scale:main" [tool.poetry.dependencies] python = "^3.9" -pydantic = "^1.9.2" +pydantic = "^2.6.3" PyYAML = "^6.0" "ruamel.yaml" = "^0.17.21" networkx = "^3.0" diff --git a/tests/test_hooks.py b/tests/test_hooks.py index 295cbcdc2..b03b80f76 100644 --- a/tests/test_hooks.py +++ b/tests/test_hooks.py @@ -2,7 +2,7 @@ import os from typing import Optional, Callable, Iterator -from pydantic import BaseModel +from pydantic import ConfigDict, BaseModel import pytest from hammer import vlsi as hammer_vlsi @@ -13,10 +13,8 @@ class HooksTestContext(BaseModel): temp_dir: str - driver: Optional[hammer_vlsi.HammerDriver] - - class Config: - arbitrary_types_allowed = True + driver: Optional[hammer_vlsi.HammerDriver] = None + model_config = ConfigDict(arbitrary_types_allowed=True) @pytest.fixture() diff --git a/tests/test_pcb_tool.py b/tests/test_pcb_tool.py index 77becf340..1366cb326 100644 --- a/tests/test_pcb_tool.py +++ b/tests/test_pcb_tool.py @@ -2,7 +2,7 @@ import os from typing import Dict, Any, Iterator -from pydantic import BaseModel +from pydantic import ConfigDict, BaseModel import pytest import hammer.pcb.generic @@ -15,9 +15,7 @@ class PCBToolTextContext(BaseModel): driver: hammer_vlsi.HammerDriver temp_dir: str env: Dict[Any, Any] = {} - - class Config: - arbitrary_types_allowed = True + model_config = ConfigDict(arbitrary_types_allowed=True) @pytest.fixture() diff --git a/tests/test_power_straps.py b/tests/test_power_straps.py index 165af1c28..507e8a8d4 100644 --- a/tests/test_power_straps.py +++ b/tests/test_power_straps.py @@ -1,30 +1,28 @@ import json import os from decimal import Decimal -from typing import Dict, cast, List, Any, Iterator +from typing import Dict, cast, List, Any, Iterator, ClassVar import sys -from pydantic import BaseModel +from pydantic import ConfigDict, BaseModel import pytest from hammer import vlsi as hammer_vlsi from hammer.config import HammerJSONEncoder -from hammer.logging import HammerVLSILogging +from hammer.logging import HammerVLSILogging, HammerVLSILoggingContext from hammer.utils import deepdict, add_dicts from hammer.tech.specialcells import CellType, SpecialCell -from utils.stackup import StackupTestHelper -from utils.tech import HasGetTech -from utils.tool import HammerToolTestHelpers +from tests.utils.stackup import StackupTestHelper +from tests.utils.tech import HasGetTech +from tests.utils.tool import HammerToolTestHelpers class PowerStrapsTestContext(BaseModel): #straps_options: Dict[str, Any] temp_dir: str driver: hammer_vlsi.HammerDriver - logger = HammerVLSILogging.context("") - - class Config: - arbitrary_types_allowed = True + logger: ClassVar[HammerVLSILoggingContext] = HammerVLSILogging.context("") + model_config = ConfigDict(arbitrary_types_allowed=True) @pytest.fixture() @@ -38,10 +36,10 @@ def power_straps_test_context(tmp_path, tech_name: str, straps_options: Dict[str def add_stackup_and_site(in_dict: Dict[str, Any]) -> Dict[str, Any]: out_dict = deepdict(in_dict) - out_dict["stackups"] = [StackupTestHelper.create_test_stackup(8, StackupTestHelper.mfr_grid()).dict()] - out_dict["sites"] = [StackupTestHelper.create_test_site(StackupTestHelper.mfr_grid()).dict()] + out_dict["stackups"] = [StackupTestHelper.create_test_stackup(8, StackupTestHelper.mfr_grid()).model_dump()] + out_dict["sites"] = [StackupTestHelper.create_test_site(StackupTestHelper.mfr_grid()).model_dump()] out_dict["grid_unit"] = str(StackupTestHelper.mfr_grid()) - out_dict["special_cells"] = [SpecialCell(cell_type=CellType.TapCell, name=["FakeTapCell"]).dict()] + out_dict["special_cells"] = [SpecialCell(cell_type=CellType.TapCell, name=["FakeTapCell"]).model_dump()] return out_dict HammerToolTestHelpers.write_tech_json(tech_json_filename, tech_name, add_stackup_and_site) diff --git a/tests/test_sdc.py b/tests/test_sdc.py index 9e5c5eca1..f6736755f 100644 --- a/tests/test_sdc.py +++ b/tests/test_sdc.py @@ -2,7 +2,7 @@ from hammer import vlsi as hammer_vlsi, config as hammer_config from hammer import technology as hammer_techs -from utils.tool import DummyTool +from tests.utils.tool import DummyTool class SDCDummyTool(hammer_vlsi.HasSDCSupport, DummyTool): diff --git a/tests/test_signoff_tools.py b/tests/test_signoff_tools.py index 0e05be114..9bbf6e374 100644 --- a/tests/test_signoff_tools.py +++ b/tests/test_signoff_tools.py @@ -2,7 +2,7 @@ import os from typing import Dict, Any, Iterator -from pydantic import BaseModel, validator +from pydantic import field_validator, ConfigDict, BaseModel import pytest from hammer import vlsi as hammer_vlsi @@ -15,11 +15,10 @@ class SignoffToolTestContext(BaseModel): driver: hammer_vlsi.HammerDriver tool_type: str temp_dir: str + model_config = ConfigDict(arbitrary_types_allowed=True) - class Config: - arbitrary_types_allowed = True - - @validator("tool_type") + @field_validator("tool_type") + @classmethod def check_tool_type(cls, tool_type): if tool_type not in ["drc", "lvs"]: raise NotImplementedError("Have not created a test for %s yet" % tool_type) diff --git a/tests/test_sim_tool.py b/tests/test_sim_tool.py index 0da7c0e14..902dfeef7 100644 --- a/tests/test_sim_tool.py +++ b/tests/test_sim_tool.py @@ -2,7 +2,7 @@ import os from typing import Dict, Iterator, Any -from pydantic import BaseModel +from pydantic import ConfigDict, BaseModel import pytest from hammer import vlsi as hammer_vlsi @@ -13,9 +13,7 @@ class SimToolTestContext(BaseModel): driver: hammer_vlsi.HammerDriver temp_dir: str env: Dict[Any, Any] = {} - - class Config: - arbitrary_types_allowed = True + model_config = ConfigDict(arbitrary_types_allowed=True) @pytest.fixture() diff --git a/tests/test_sram_generator.py b/tests/test_sram_generator.py index a8a769a7c..f2b535af6 100644 --- a/tests/test_sram_generator.py +++ b/tests/test_sram_generator.py @@ -2,7 +2,7 @@ import os from typing import Dict, Any, List, Iterator -from pydantic import BaseModel +from pydantic import ConfigDict, BaseModel import pytest from hammer import vlsi as hammer_vlsi @@ -14,9 +14,7 @@ class SRAMGeneratorTestContext(BaseModel): env: Dict[Any, Any] = {} driver: hammer_vlsi.HammerDriver temp_dir: str - - class Config: - arbitrary_types_allowed = True + model_config = ConfigDict(arbitrary_types_allowed=True) @pytest.fixture() diff --git a/tests/test_stackup.py b/tests/test_stackup.py index 9b411d55b..7dd03f0fb 100644 --- a/tests/test_stackup.py +++ b/tests/test_stackup.py @@ -1,7 +1,7 @@ from decimal import Decimal from hammer.tech.stackup import Metal -from utils.stackup import StackupTestHelper +from tests.utils.stackup import StackupTestHelper import json import pytest @@ -18,8 +18,8 @@ def test_wire_parsing_from_json(self) -> None: """ grid_unit = StackupTestHelper.mfr_grid() metal = StackupTestHelper.create_test_metal(3, grid_unit) - direct_metal = Metal.from_setting(grid_unit, StackupTestHelper.create_test_metal(3, grid_unit).dict()) - json_string: str = metal.json() + direct_metal = Metal.from_setting(grid_unit, StackupTestHelper.create_test_metal(3, grid_unit).model_dump()) + json_string: str = metal.model_dump_json() json_metal = Metal.from_setting(grid_unit, json.loads(json_string)) # type: Metal assert direct_metal == json_metal @@ -128,8 +128,8 @@ def test_quantize_to_width_table(self) -> None: grid_unit = StackupTestHelper.mfr_grid() metal = StackupTestHelper.create_test_metal(1, grid_unit) metal.power_strap_width_table = StackupTestHelper.create_w_tbl(1, 5, grid_unit) - q_metal = Metal.from_setting(StackupTestHelper.mfr_grid(), metal.dict()) - nq_metal = Metal.from_setting(StackupTestHelper.mfr_grid(), StackupTestHelper.create_test_metal(1, grid_unit).dict()) + q_metal = Metal.from_setting(StackupTestHelper.mfr_grid(), metal.model_dump()) + nq_metal = Metal.from_setting(StackupTestHelper.mfr_grid(), StackupTestHelper.create_test_metal(1, grid_unit).model_dump()) for num_tracks in range(1, 20): # twt case wq, sq, oq = q_metal.get_width_spacing_start_twt(num_tracks, logger=None) diff --git a/tests/test_submit_command.py b/tests/test_submit_command.py index 9c96977ce..8d3872921 100644 --- a/tests/test_submit_command.py +++ b/tests/test_submit_command.py @@ -1,34 +1,33 @@ import json import os -from typing import Dict, Any, List, Iterator +from typing import Dict, Any, List, Iterator, ClassVar import importlib.resources as resources -from pydantic import BaseModel, validator +from pydantic import field_validator, ConfigDict, BaseModel import pytest from hammer import vlsi as hammer_vlsi from hammer.config import HammerJSONEncoder -from hammer.logging import HammerVLSILogging +from hammer.logging import HammerVLSILogging, HammerVLSILoggingContext from hammer.utils import get_or_else class SubmitCommandTestContext(BaseModel): echo_command_args: List[str] = ["go", "bears", "!"] echo_command: List[str] = ["echo", "go", "bears", "!"] - logger = HammerVLSILogging.context("") + logger: ClassVar[HammerVLSILoggingContext] = HammerVLSILogging.context("") env: Dict[Any, Any] = {} driver: hammer_vlsi.HammerDriver cmd_type: str submit_command: hammer_vlsi.HammerSubmitCommand temp_dir: str - @validator("cmd_type") + @field_validator("cmd_type") + @classmethod def cmd_type_validator(cls, cmd_type): if cmd_type not in ["lsf", "local"]: raise NotImplementedError("Have not built a test for %s yet" % cmd_type) - - class Config: - arbitrary_types_allowed = True + model_config = ConfigDict(arbitrary_types_allowed=True) @pytest.fixture() diff --git a/tests/test_tech.py b/tests/test_tech.py index 9389668b8..963475efd 100644 --- a/tests/test_tech.py +++ b/tests/test_tech.py @@ -20,9 +20,9 @@ from hammer.config import HammerJSONEncoder from decimal import Decimal -from utils.tool import HammerToolTestHelpers, DummyTool -from utils.tech import HasGetTech -from utils.stackup import StackupTestHelper +from tests.utils.tool import HammerToolTestHelpers, DummyTool +from tests.utils.tech import HasGetTech +from tests.utils.stackup import StackupTestHelper # Tests for the Hammer technology library (hammer_tech). @@ -768,7 +768,7 @@ def test_get_stackups(self, tmpdir, request) -> None: def add_stackup(in_dict: Dict[str, Any]) -> Dict[str, Any]: out_dict = deepdict(in_dict) - out_dict.update({"stackups": [test_stackup.dict()]}) + out_dict.update({"stackups": [test_stackup.model_dump()]}) return out_dict HammerToolTestHelpers.write_tech_json(tech_json_filename, tech_name, add_stackup) @@ -781,4 +781,4 @@ def add_stackup(in_dict: Dict[str, Any]) -> Dict[str, Any]: database = hammer_config.HammerDatabase() tool.set_database(database) - assert tech.get_stackup_by_name(test_stackup.name) == Stackup.from_setting(tech.get_grid_unit(), test_stackup.dict()) + assert tech.get_stackup_by_name(test_stackup.name) == Stackup.from_setting(tech.get_grid_unit(), test_stackup.model_dump()) diff --git a/tests/test_tool.py b/tests/test_tool.py index 15aed2d62..7b20dddf0 100644 --- a/tests/test_tool.py +++ b/tests/test_tool.py @@ -12,9 +12,9 @@ from hammer.logging import HammerVLSILogging, HammerVLSIFileLogger from hammer.logging.test import HammerLoggingCaptureContext from hammer.utils import deeplist, deepdict -from utils.stackup import StackupTestHelper -from utils.tech import HasGetTech -from utils.tool import HammerToolTestHelpers, SingleStepTool, DummyTool +from tests.utils.stackup import StackupTestHelper +from tests.utils.tech import HasGetTech +from tests.utils.tool import HammerToolTestHelpers, SingleStepTool, DummyTool class TestHammerTool(HasGetTech): @@ -102,7 +102,7 @@ def test_timing_lib_with_preference_filter(self, tmp_path, request) -> None: "ccs_liberty_file": "cookies.ccs" } ] - + } with open(tech_json_filename, "w") as f: f.write(json.dumps(tech_json, cls=HammerJSONEncoder, indent=4)) @@ -122,13 +122,13 @@ def test_timing_lib_with_preference_filter(self, tmp_path, request) -> None: logger = HammerVLSILogging.context("") logger.logging_class.clear_callbacks() tech.logger = logger - + class Tool(hammer_vlsi.DummyHammerTool, metaclass=ABCMeta): - + def __init__(self, removal=False): self.geek = "GeekforGeeks" - + lib_outputs = [] # type: List[str] @property def steps(self) -> List[hammer_vlsi.HammerToolStep]: @@ -164,7 +164,7 @@ def step_three(self) -> bool: test.technology = tech test.set_database(hammer_config.HammerDatabase()) tech.set_database(hammer_config.HammerDatabase()) - + # Test the default case: test.run(hook_actions=[ hammer_vlsi.HammerTool.make_removal_hook("step_two"), @@ -195,7 +195,7 @@ def step_three(self) -> bool: test.run(hook_actions=[ hammer_vlsi.HammerTool.make_removal_hook("step_one"), hammer_vlsi.HammerTool.make_removal_hook("step_two")]) - + assert set(Tool.lib_outputs) == { "{0}/eggs.ccs".format(tech_dir), "{0}/custard.ccs".format(tech_dir), @@ -204,7 +204,7 @@ def step_three(self) -> bool: "{0}/cookies.ccs".format(tech_dir) } - + def test_timing_lib_ecsm_filter(self, tmp_path, request) -> None: """ Test that the ECSM-first filter works as expected. @@ -561,7 +561,7 @@ def test_good_pins(self, tmp_path, request) -> None: def add_stackup(in_dict: Dict[str, Any]) -> Dict[str, Any]: out_dict = deepdict(in_dict) - out_dict["stackups"] = [StackupTestHelper.create_test_stackup(8, StackupTestHelper.mfr_grid()).dict()] + out_dict["stackups"] = [StackupTestHelper.create_test_stackup(8, StackupTestHelper.mfr_grid()).model_dump()] return out_dict HammerToolTestHelpers.write_tech_json(tech_json_filename, tech_name, add_stackup) @@ -619,7 +619,7 @@ def test_pin_modes(self, tmp_path, request) -> None: def add_stackup(in_dict: Dict[str, Any]) -> Dict[str, Any]: out_dict = deepdict(in_dict) - out_dict["stackups"] = [StackupTestHelper.create_test_stackup(8, StackupTestHelper.mfr_grid()).dict()] + out_dict["stackups"] = [StackupTestHelper.create_test_stackup(8, StackupTestHelper.mfr_grid()).model_dump()] return out_dict HammerToolTestHelpers.write_tech_json(tech_json_filename, tech_name, add_stackup) @@ -741,7 +741,7 @@ def test_pins(self, tmp_path, request) -> None: def add_stackup(in_dict: Dict[str, Any]) -> Dict[str, Any]: out_dict = deepdict(in_dict) - out_dict["stackups"] = [StackupTestHelper.create_test_stackup(8, StackupTestHelper.mfr_grid()).dict()] + out_dict["stackups"] = [StackupTestHelper.create_test_stackup(8, StackupTestHelper.mfr_grid()).model_dump()] return out_dict HammerToolTestHelpers.write_tech_json(tech_json_filename, tech_name, add_stackup) @@ -817,7 +817,7 @@ def test_hierarchical_width_height(self, tmp_path, request) -> None: def add_stackup(in_dict: Dict[str, Any]) -> Dict[str, Any]: out_dict = deepdict(in_dict) - out_dict["stackups"] = [StackupTestHelper.create_test_stackup(8, StackupTestHelper.mfr_grid()).dict()] + out_dict["stackups"] = [StackupTestHelper.create_test_stackup(8, StackupTestHelper.mfr_grid()).model_dump()] return out_dict HammerToolTestHelpers.write_tech_json(tech_json_filename, tech_name, add_stackup)