Skip to content

Pydantic v2 #2433

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ documentation = "https://docs.flexcompute.com/projects/tidy3d/en/latest/"

[tool.poetry.dependencies]
python = ">=3.9,<3.14"
typing-extensions = { version = "*", python = "<3.11" }
pyroots = ">=0.5.0"
xarray = ">=2023.08"
importlib-metadata = ">=6.0.0"
Expand All @@ -33,7 +34,8 @@ numpy = "*"
matplotlib = "*"
shapely = "^2.0"
pandas = "*"
pydantic = "^2.0"
pydantic = ">=2,<3"
pydantic-settings=">=2,<3"
PyYAML = "*"
dask = "*"
toml = "*"
Expand Down
29 changes: 16 additions & 13 deletions tests/test_components/test_IO.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

# Store an example of every minor release simulation to test updater in the future
SIM_DIR = "tests/sims"
SIM_STATIC = SIM.to_static()


@pytest.fixture
Expand Down Expand Up @@ -66,14 +67,14 @@ def test_simulation_load_export(split_string, tmp_path):
major, minor, patch = __version__.split(".")
path = os.path.join(tmp_path, f"simulation_{major}_{minor}_{patch}.json")
path_hdf5 = os.path.join(tmp_path, f"simulation_{major}_{minor}_{patch}.h5")
SIM.to_file(path)
SIM.to_hdf5(path_hdf5)
SIM_STATIC.to_file(path)
SIM_STATIC.to_hdf5(path_hdf5)
SIM2 = td.Simulation.from_file(path)
SIM_HDF5 = td.Simulation.from_hdf5(path_hdf5)
assert (
set_datasets_to_none(SIM)._json_string == SIM2._json_string
set_datasets_to_none(SIM_STATIC)._json_string == SIM2._json_string
), "original and loaded simulations are not the same"
assert SIM == SIM_HDF5, "original and loaded from hdf5 simulations are not the same"
assert SIM_STATIC == SIM_HDF5, "original and loaded from hdf5 simulations are not the same"


def test_simulation_load_export_yaml(tmp_path):
Expand Down Expand Up @@ -101,30 +102,30 @@ def test_component_load_export_yaml(tmp_path):

def test_simulation_load_export_hdf5(split_string, tmp_path):
path = str(tmp_path / "simulation.hdf5")
SIM.to_file(path)
SIM_STATIC.to_file(path)
SIM2 = td.Simulation.from_file(path)
assert SIM == SIM2, "original and loaded simulations are not the same"
assert SIM_STATIC == SIM2, "original and loaded simulations are not the same"


def test_simulation_load_export_hdf5_gz(split_string, tmp_path):
path = str(tmp_path / "simulation.hdf5.gz")
SIM.to_file(path)
SIM_STATIC.to_file(path)
SIM2 = td.Simulation.from_file(path)
assert SIM == SIM2, "original and loaded simulations are not the same"
assert SIM_STATIC == SIM2, "original and loaded simulations are not the same"


def test_simulation_load_export_hdf5_explicit(split_string, tmp_path):
path = str(tmp_path / "simulation.hdf5")
SIM.to_hdf5(path)
SIM_STATIC.to_hdf5(path)
SIM2 = td.Simulation.from_hdf5(path)
assert SIM == SIM2, "original and loaded simulations are not the same"
assert SIM_STATIC == SIM2, "original and loaded simulations are not the same"


def test_simulation_load_export_hdf5_gz_explicit(split_string, tmp_path):
path = str(tmp_path / "simulation.hdf5.gz")
SIM.to_hdf5_gz(path)
SIM_STATIC.to_hdf5_gz(path)
SIM2 = td.Simulation.from_hdf5_gz(path)
assert SIM == SIM2, "original and loaded simulations are not the same"
assert SIM_STATIC == SIM2, "original and loaded simulations are not the same"


def test_simulation_load_export_pckl(tmp_path):
Expand Down Expand Up @@ -189,7 +190,7 @@ def test_validation_speed(tmp_path):
for i in range(n):
new_structure = SIM.structures[0].copy(update={"name": str(i)})
new_structures.append(new_structure)
S = SIM.copy(update=dict(structures=new_structures))
S = SIM.copy(update=dict(structures=tuple(new_structures)))

S.to_file(path)
time_start = time()
Expand Down Expand Up @@ -220,7 +221,9 @@ def test_simulation_updater(sim_file):
def test_yaml(tmp_path):
path = str(tmp_path / "simulation.json")
SIM.to_file(path)
SIM.to_file("simulation.json")
sim = td.Simulation.from_file(path)

path1 = str(tmp_path / "simulation.yaml")
sim.to_yaml(path1)
sim1 = td.Simulation.from_yaml(path1)
Expand Down
16 changes: 8 additions & 8 deletions tests/test_components/test_apodization.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
"""Tests mode objects."""

import matplotlib.pyplot as plt
import pydantic.v1 as pydantic
import pytest
import tidy3d as td
from pydantic import ValidationError


def test_apodization():
Expand All @@ -14,27 +14,27 @@ def test_apodization():


def test_end_lt_start():
with pytest.raises(pydantic.ValidationError):
with pytest.raises(ValidationError):
_ = td.ApodizationSpec(start=2, end=1, width=0.2)


def test_no_width():
with pytest.raises(pydantic.ValidationError):
with pytest.raises(ValidationError):
_ = td.ApodizationSpec(start=1, end=2)
with pytest.raises(pydantic.ValidationError):
with pytest.raises(ValidationError):
_ = td.ApodizationSpec(start=1)
with pytest.raises(pydantic.ValidationError):
with pytest.raises(ValidationError):
_ = td.ApodizationSpec(end=2)


def test_negative_times():
with pytest.raises(pydantic.ValidationError):
with pytest.raises(ValidationError):
_ = td.ApodizationSpec(start=-2, end=-1, width=0.2)

with pytest.raises(pydantic.ValidationError):
with pytest.raises(ValidationError):
_ = td.ApodizationSpec(start=1, end=2, width=-0.2)

with pytest.raises(pydantic.ValidationError):
with pytest.raises(ValidationError):
_ = td.ApodizationSpec(start=1, end=2, width=0)


Expand Down
10 changes: 6 additions & 4 deletions tests/test_components/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import numpy as np
import pytest
import tidy3d as td
from pydantic import ValidationError
from pydantic_core import PydanticSerializationError
from tidy3d.components.base import Tidy3dBaseModel

M = td.Medium()
Expand Down Expand Up @@ -166,7 +168,7 @@ def test_updated_copy_path():
)

# forgot path
with pytest.raises(ValueError):
with pytest.raises(KeyError):
assert sim == sim.updated_copy(permittivity=2.0)

assert sim.updated_copy(size=(6, 6, 6)) == sim.updated_copy(size=(6, 6, 6), path=None)
Expand Down Expand Up @@ -198,7 +200,7 @@ def test_attrs(tmp_path):
assert obj.attrs == {"foo": "attr"}

# this is still not allowed though
with pytest.raises(TypeError):
with pytest.raises(ValidationError):
obj.attrs = {}

# attrs can be modified
Expand All @@ -215,7 +217,7 @@ def test_attrs(tmp_path):

# attrs are in the json strings
obj_json = obj3.json()
assert '{"foo": "bar"}' in obj_json
assert '{"foo":"bar"}' in obj_json

# attrs are in the dict()
obj_dict = obj3.dict()
Expand All @@ -230,7 +232,7 @@ def test_attrs(tmp_path):

# test attrs that can't be serialized
obj.attrs["not_serializable"] = type
with pytest.raises(TypeError):
with pytest.raises(PydanticSerializationError):
obj.json()


Expand Down
4 changes: 2 additions & 2 deletions tests/test_components/test_beam.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""Tests for the various BeamProfile components."""

import numpy as np
import pydantic.v1 as pd
import pytest
from pydantic import ValidationError
from tidy3d.components.beam import (
AstigmaticGaussianBeamProfile,
GaussianBeamProfile,
Expand Down Expand Up @@ -94,7 +94,7 @@ def test_invalid_beam_size():
center = (0, 0, 0)
size = (10, 10, 10)
resolution = 100
with pytest.raises(pd.ValidationError):
with pytest.raises(ValidationError):
GaussianBeamProfile(center=center, size=size, resolution=resolution, freqs=FREQS)


Expand Down
6 changes: 3 additions & 3 deletions tests/test_components/test_boundaries.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""Tests boundary conditions."""

import pydantic.v1 as pydantic
import pytest
import tidy3d as td
from pydantic import ValidationError
from tidy3d.components.boundary import (
PML,
Absorber,
Expand Down Expand Up @@ -78,11 +78,11 @@ def test_boundary_validators():
periodic = Periodic()

# test `bloch_on_both_sides`
with pytest.raises(pydantic.ValidationError):
with pytest.raises(ValidationError):
_ = Boundary(plus=bloch, minus=pec)

# test `periodic_with_pml`
with pytest.raises(pydantic.ValidationError):
with pytest.raises(ValidationError):
_ = Boundary(plus=periodic, minus=pml)


Expand Down
Loading