diff --git a/CHANGELOG.md b/CHANGELOG.md index a5b2c93244..099b62f2fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - In `Tidy3dBaseModel` the hash (and cached `.json_string`) are now sensitive to changes in `.attrs`. - More accurate frequency range for ``GaussianPulse`` when DC is removed. - Bug in `TerminalComponentModelerData.get_antenna_metrics_data()` where `WavePort` mode indices were not properly handled. Improved docstrings and type hints to make the usage clearer. +- Improved type hints for `Tidy3dBaseModel`, so that all derived classes will have more accurate return types. ## [v2.10.0rc2] - 2025-10-01 diff --git a/poetry.lock b/poetry.lock index 70db5077ae..d22b7a2235 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1654,40 +1654,61 @@ markers = "extra == \"dev\" or extra == \"docs\" or extra == \"gdstk\"" files = [ {file = "gdstk-0.9.61-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8db8120b5b8864de074ed773d4c0788100b76eecd2bf327a6de338f011745e3f"}, {file = "gdstk-0.9.61-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ad942da613f6274e391371771b8cfef2854eb69f628914f716f518929567dcd4"}, + {file = "gdstk-0.9.61-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3b49ff5e43764783d2053b129fe1eac152910e2d062dfc2fd2408c9b91a043d5"}, {file = "gdstk-0.9.61-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5e53c0f765796b4fc449b72c800924df2e936820087816686e987962b3f0452a"}, {file = "gdstk-0.9.61-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc601258b850595b34e22b5c0fd1d98724a053faa4b1a23517c693b6eb01e275"}, + {file = "gdstk-0.9.61-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ab2644f04a3d91e158bfce7c5dbdc60f09745cf7dc7fc19e9255cb6e6d9547b"}, {file = "gdstk-0.9.61-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:4aa897a629d20bca211cacf36e35a7316a5d6cfe03effb6af19c0eb7fd225421"}, {file = "gdstk-0.9.61-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9d20a09f06596ff2926e6b4ad12f3b0ae0ce545bf60211b96c2f9791f1df37fe"}, {file = "gdstk-0.9.61-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:688cc52aa1a5b9016eb0787a9cea4943a1aa2cc3d8d3cbeeaa44b3203f71e38f"}, {file = "gdstk-0.9.61-cp310-cp310-win_amd64.whl", hash = "sha256:5214c4f89fb9ff60ced79f6d2d28de4c5d5b588c9ef930fe72333edaa5e0bcf2"}, {file = "gdstk-0.9.61-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5fab80fa1e5ac4d956a04fdc78fb6971cb32a43418553939ee4ccf4eba6d4496"}, {file = "gdstk-0.9.61-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:82706a72f37c70340978fb70777cf94119408593f5a8c73c0700c0b84486a3fe"}, + {file = "gdstk-0.9.61-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6857359fc517fa91d6c0cd179cf09290aaebf538869d825585d9a0ed3cec754d"}, {file = "gdstk-0.9.61-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:459b1f28a6283bb61ed28c745aba3d49c5cbd9424fb81f76023d3f44b92c6257"}, {file = "gdstk-0.9.61-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3812aadf36764bb6ca86f1b9f4bdf8f8c41749bcdf1e3b45d6263e48b4f97eab"}, + {file = "gdstk-0.9.61-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6f0df208263039851ac5d3d94fcddbc80029a69918d53c0b7dc392725d8fb"}, {file = "gdstk-0.9.61-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:7e166ef1c26fc0f48fa8194e54683e61ca43b72d3342708d4229855dcad137ed"}, {file = "gdstk-0.9.61-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:79dc9f0f0c5f6860199c9af09564bbfed4c34885d3f5b46ab9514ab0716cff39"}, {file = "gdstk-0.9.61-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4b3e2b367e5962db05845eaaf3f9d8bcfa3914738c6e174455a152a63d78904c"}, {file = "gdstk-0.9.61-cp311-cp311-win_amd64.whl", hash = "sha256:0c3866dc287d657f78ae587e2e10de2747ebbf5d2824dc6ba4f9ece89c36a35a"}, {file = "gdstk-0.9.61-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:61f0ee05cdce9b4163ea812cbf2e2f5d8d01a293fa118ff98348280306bd91d6"}, {file = "gdstk-0.9.61-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fff1b104b6775e4c27ab2751b3f4ac6c1ce86a4e9afd5e5535ac4acefa6a7a07"}, + {file = "gdstk-0.9.61-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5218f8c5ab13b6e979665c0a7dc1272768003a1cb7add0682483837f7485faed"}, {file = "gdstk-0.9.61-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e79f3881d3b3666a600efd5b2c131454507f69d3c9b9eaf383d106cfbd6e7bc"}, {file = "gdstk-0.9.61-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e90a6e24c2145320e53e953a59c6297fd25c17c6ef098fa8602e64e64a5390ea"}, + {file = "gdstk-0.9.61-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3a49401cbd26c5a17a4152d1befa73efb21af694524557bf09d15f4c8a874e6"}, {file = "gdstk-0.9.61-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:8738ac63bbe29dcb5abae6a19d207c4e0857f9dc1bd405c85af8a87f0dcfb348"}, {file = "gdstk-0.9.61-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:23bb023a49f3321673d0e32cdce2e2705a51d9e12328c928723ded49af970520"}, {file = "gdstk-0.9.61-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:81c2f19cab89623d1f56848e7a16e2fab82a93c61c8f7aa73f5ff59840b60c0f"}, {file = "gdstk-0.9.61-cp312-cp312-win_amd64.whl", hash = "sha256:4474f015ecc228b210165287cb7eea65639ea6308f60105cb49e970079bddc2b"}, {file = "gdstk-0.9.61-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:3beeae846fc523c7e3a01c47edcd3b7dd83c29650e56b82a371e528f9cb0ec3e"}, {file = "gdstk-0.9.61-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:575a21639b31e2fab4d9e918468b8b40a58183028db563e5963be594bff1403d"}, + {file = "gdstk-0.9.61-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:90d54b48223dcbb8257769faaa87542d12a749d8486e8d1187a45d06e9422859"}, {file = "gdstk-0.9.61-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35405bed95542a0b10f343b165ce0ad80740bf8127a4507565ec74222e6ec8d3"}, {file = "gdstk-0.9.61-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b311ddf8982995b52ac3bf3b32a6cf6d918afc4e66dea527d531e8af73896231"}, + {file = "gdstk-0.9.61-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6dcbfc60fba92d10f1c7d612b5409c343fcaf2a380640e9fb01c504ca948b412"}, {file = "gdstk-0.9.61-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:fab67ccdd8029ef7eb873f8c98f875dc2665a5e45af7cf3d2a7a0f401826a1d3"}, {file = "gdstk-0.9.61-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5852749e203d6978e06d02f8ef9e29ce4512cb1aedeb62c37b8e8b2c10c4f529"}, {file = "gdstk-0.9.61-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7ee38a54c799e77dbe219266f765bbd3b2906b62bc7b6fb64b1387e6db3dd187"}, {file = "gdstk-0.9.61-cp313-cp313-win_amd64.whl", hash = "sha256:6abb396873b2660dd7863d664b3822f00547bf7f216af27be9f1f812bc5e8027"}, + {file = "gdstk-0.9.61-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:a674af8be5cf1f8ea9f6c5b5f165f797d7e2ed74cbca68b4a22adb92b515fb35"}, + {file = "gdstk-0.9.61-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:38ec0b7285d6c9bf8cbc279731dc0d314633cda2ce9e6f9053554b3e5f004fcd"}, + {file = "gdstk-0.9.61-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3b63a77b57fb441c8017217aaf1e8b13d93cbee822031a8e2826adb716e01dd4"}, + {file = "gdstk-0.9.61-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f7fae6eee627e837d1405b47d381ccd33dbba85473b1bb3822bdc8ae41dbc0dc"}, + {file = "gdstk-0.9.61-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9e396694cac24bd87d0e38c37e6740d9ba0c13f6c9f2211a871d62288430f069"}, + {file = "gdstk-0.9.61-cp314-cp314-win_amd64.whl", hash = "sha256:7ea0c1200dc53b794e9c0cc6fe3ea51e49113dfdd9c3109e1961cda3cc2197c7"}, + {file = "gdstk-0.9.61-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:616dd1c3e7aea4a98aeb03db7cf76a853d134c54690790eaa25c63eede7b869a"}, + {file = "gdstk-0.9.61-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:b0e898202fbb7fd4c39f8404831415a0aa0445656342102c4e77d4a7c2c15a1d"}, + {file = "gdstk-0.9.61-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:29bb862a1a814f5bbd6f8bbc2f99e1163df9e6307071cb6e11251dbe7542feb5"}, + {file = "gdstk-0.9.61-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c6c2a08d82a683aff50dc63f2943ed805d32d46bd984cbd4ac9cf876146d0ef9"}, + {file = "gdstk-0.9.61-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3ba52f95763052a6968583942e6531ceca20c14c762d44fe2bd887445e2f73b6"}, {file = "gdstk-0.9.61-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1033d4ddd2af34461c1133ef62213a4861f23d07d64d66e92fe8d2554a85ba6d"}, {file = "gdstk-0.9.61-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bad94f74dff3efaa5ade7bab5040464e575839fa65b935c8f872a47e1658f535"}, + {file = "gdstk-0.9.61-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c9c8738b57cb6100cb0d4346272af489d05f9b9908e0018a5ecbcb5ee485fa97"}, {file = "gdstk-0.9.61-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7f9dd95da53d3cdbc3dcaed446b7404d8d4dfbdbd68628eeddde6285bc5a5"}, {file = "gdstk-0.9.61-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f73637dc2abe3754906f2911557b563281f868f5d153332edea681d963b2a22"}, + {file = "gdstk-0.9.61-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:56d493bb7fc3fb33de63d8c1107ff3d645b62596d0c2073f1a390d90bef73233"}, {file = "gdstk-0.9.61-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:7905572cc10b2b85a960317eadb5cf95197b5a52b1ef9358336d5cd224e08314"}, {file = "gdstk-0.9.61-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:a4bc70f308653d63c26d15637b27e2435f7bdaa50d072db410c1f573db6d985b"}, {file = "gdstk-0.9.61-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:3794115a278d5a38db5c5a8f0cfeff3e1701263bcfb58b7e1934e199578e14f1"}, @@ -7498,4 +7519,4 @@ vtk = ["vtk"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<3.14" -content-hash = "1511652a03ac30c0f6b48358499a6ff262bcad5240daafd77cd0e225649576a5" +content-hash = "791a0a7b974ef55e1d5529967b508383e91df1754c76e9b2500c7f64b6ba2ad4" diff --git a/pyproject.toml b/pyproject.toml index 4ab08bad25..d11929271c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,6 +46,7 @@ pyjwt = "*" click = "^8.1.0" responses = "*" joblib = "*" +typing-extensions = "*" ### END NOT CORE ### Optional dependencies ### diff --git a/tidy3d/components/base.py b/tidy3d/components/base.py index 1beb15e5fa..5498cf1738 100644 --- a/tidy3d/components/base.py +++ b/tidy3d/components/base.py @@ -23,6 +23,7 @@ from autograd.tracer import isbox from pydantic.v1.fields import ModelField from pydantic.v1.json import custom_pydantic_encoder +from typing_extensions import Self from tidy3d.exceptions import FileError from tidy3d.log import log @@ -271,7 +272,7 @@ def _default(o): return hashlib.sha256(json_str.encode("utf-8")).hexdigest() - def copy(self, deep: bool = True, validate: bool = True, **kwargs) -> Tidy3dBaseModel: + def copy(self, deep: bool = True, validate: bool = True, **kwargs) -> Self: """Copy a Tidy3dBaseModel. With ``deep=True`` and ``validate=True`` as default.""" kwargs.update(deep=deep) new_copy = pydantic.BaseModel.copy(self, **kwargs) @@ -284,7 +285,7 @@ def copy(self, deep: bool = True, validate: bool = True, **kwargs) -> Tidy3dBase def updated_copy( self, path: Optional[str] = None, deep: bool = True, validate: bool = True, **kwargs - ) -> Tidy3dBaseModel: + ) -> Self: """Make copy of a component instance with ``**kwargs`` indicating updated field values. Note @@ -342,7 +343,7 @@ def updated_copy( return self._updated_copy(deep=deep, validate=validate, **{field_name: new_component}) - def _updated_copy(self, deep: bool = True, validate: bool = True, **kwargs) -> Tidy3dBaseModel: + def _updated_copy(self, deep: bool = True, validate: bool = True, **kwargs) -> Self: """Make copy of a component instance with ``**kwargs`` indicating updated field values.""" return self.copy(update=kwargs, deep=deep, validate=validate) @@ -368,7 +369,7 @@ def from_file( lazy: bool = False, on_load: Optional[Callable] = None, **parse_obj_kwargs, - ) -> Tidy3dBaseModel: + ) -> Self: """Loads a :class:`Tidy3dBaseModel` from .yaml, .json, .hdf5, or .hdf5.gz file. Parameters @@ -391,7 +392,7 @@ def from_file( Returns ------- - :class:`Tidy3dBaseModel` + Self An instance of the component class calling ``load``. Example @@ -469,7 +470,7 @@ def to_file(self, fname: str) -> None: return converter(fname=fname) @classmethod - def from_json(cls, fname: str, **parse_obj_kwargs) -> Tidy3dBaseModel: + def from_json(cls, fname: str, **parse_obj_kwargs) -> Self: """Load a :class:`Tidy3dBaseModel` from .json file. Parameters @@ -479,7 +480,7 @@ def from_json(cls, fname: str, **parse_obj_kwargs) -> Tidy3dBaseModel: Returns ------- - :class:`Tidy3dBaseModel` + Self An instance of the component class calling `load`. **parse_obj_kwargs Keyword arguments passed to pydantic's ``parse_obj`` method. @@ -532,7 +533,7 @@ def to_json(self, fname: str) -> None: file_handle.write(json_string) @classmethod - def from_yaml(cls, fname: str, **parse_obj_kwargs) -> Tidy3dBaseModel: + def from_yaml(cls, fname: str, **parse_obj_kwargs) -> Self: """Loads :class:`Tidy3dBaseModel` from .yaml file. Parameters @@ -544,7 +545,7 @@ def from_yaml(cls, fname: str, **parse_obj_kwargs) -> Tidy3dBaseModel: Returns ------- - :class:`Tidy3dBaseModel` + Self An instance of the component class calling `from_yaml`. Example @@ -747,7 +748,7 @@ def from_hdf5( group_path: str = "", custom_decoders: Optional[list[Callable]] = None, **parse_obj_kwargs, - ) -> Tidy3dBaseModel: + ) -> Self: """Loads :class:`Tidy3dBaseModel` instance to .hdf5 file. Parameters @@ -882,7 +883,7 @@ def from_hdf5_gz( group_path: str = "", custom_decoders: Optional[list[Callable]] = None, **parse_obj_kwargs, - ) -> Tidy3dBaseModel: + ) -> Self: """Loads :class:`Tidy3dBaseModel` instance to .hdf5.gz file. Parameters @@ -1084,7 +1085,7 @@ def handle_value(x: Any, path: tuple[str, ...]) -> None: # convert the resulting field_mapping to an autograd-traced dictionary return dict_ag(field_mapping) - def _insert_traced_fields(self, field_mapping: AutogradFieldMap) -> Tidy3dBaseModel: + def _insert_traced_fields(self, field_mapping: AutogradFieldMap) -> Self: """Recursively insert a map of paths to autograd-traced fields into a copy of this obj.""" self_dict = self.dict() @@ -1129,7 +1130,7 @@ def _serialized_traced_field_keys( tracer_keys = TracerKeys.from_field_mapping(field_mapping) return tracer_keys.json(separators=(",", ":"), ensure_ascii=True) - def to_static(self) -> Tidy3dBaseModel: + def to_static(self) -> Self: """Version of object with all autograd-traced fields removed.""" # get dictionary of all traced fields