From ef0f0a5afe15aa725f2a781ec602b058a1f154c0 Mon Sep 17 00:00:00 2001 From: Jeff Newman Date: Thu, 8 Feb 2024 08:59:15 -0600 Subject: [PATCH 1/5] update envs for Pydantic 2 --- conda-environments/activitysim-dev-base.yml | 4 ++-- conda-environments/activitysim-dev.yml | 4 ++-- conda-environments/docbuild.yml | 4 ++-- conda-environments/github-actions-tests.yml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/conda-environments/activitysim-dev-base.yml b/conda-environments/activitysim-dev-base.yml index 7a94ae4e1..ec1f2e0f2 100644 --- a/conda-environments/activitysim-dev-base.yml +++ b/conda-environments/activitysim-dev-base.yml @@ -49,7 +49,7 @@ dependencies: - psutil = 5.9.* - pyarrow = 11.* - pycodestyle -- pydantic = 1.10.* +- pydantic = 2.6.* - pydata-sphinx-theme - pyinstrument = 4.4 - pypyr = 5.8.* @@ -75,4 +75,4 @@ dependencies: - zstandard - pip: - - autodoc_pydantic >=1.9,<2.0 + - autodoc_pydantic diff --git a/conda-environments/activitysim-dev.yml b/conda-environments/activitysim-dev.yml index dd1437581..3e5711a29 100644 --- a/conda-environments/activitysim-dev.yml +++ b/conda-environments/activitysim-dev.yml @@ -44,7 +44,7 @@ dependencies: - psutil = 5.9.* - pyarrow = 11.* - pycodestyle -- pydantic = 1.10.* +- pydantic = 2.6.* - pydata-sphinx-theme - pyinstrument = 4.4 - pypyr = 5.8.* @@ -71,5 +71,5 @@ dependencies: - zstandard - pip: - - autodoc_pydantic >=1.9,<2.0 + - autodoc_pydantic - -e .. diff --git a/conda-environments/docbuild.yml b/conda-environments/docbuild.yml index 2e289fa9f..c738ab3a1 100644 --- a/conda-environments/docbuild.yml +++ b/conda-environments/docbuild.yml @@ -36,7 +36,7 @@ dependencies: - platformdirs - psutil >= 4.1 - pyarrow >= 2.0 -- pydantic = 1.10.* +- pydantic = 2.6.* - pypyr >= 5.3 - pytables >=3.7 - pytest @@ -56,5 +56,5 @@ dependencies: - zarr - pip: - - autodoc_pydantic >=1.9,<2.0 + - autodoc_pydantic - -e .. diff --git a/conda-environments/github-actions-tests.yml b/conda-environments/github-actions-tests.yml index 3636f4bc0..5edb8fef7 100644 --- a/conda-environments/github-actions-tests.yml +++ b/conda-environments/github-actions-tests.yml @@ -22,7 +22,7 @@ dependencies: - platformdirs = 3.2.* - psutil = 5.9.* - pyarrow = 11.* -- pydantic = 1.10.* +- pydantic = 2.6.* - pypyr = 5.8.* - pytables >= 3.7 - pytest = 7.2.* From 2a12e89df7b5f01be8b64110df0640d49d9d4091 Mon Sep 17 00:00:00 2001 From: Jeff Newman Date: Thu, 8 Feb 2024 10:11:37 -0600 Subject: [PATCH 2/5] need nbmake --- conda-environments/activitysim-dev.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/conda-environments/activitysim-dev.yml b/conda-environments/activitysim-dev.yml index 3e5711a29..f805b6e36 100644 --- a/conda-environments/activitysim-dev.yml +++ b/conda-environments/activitysim-dev.yml @@ -31,6 +31,7 @@ dependencies: - myst-parser # allows markdown in sphinx - nbconvert - nbformat +- nbmake - numba = 0.56.* - numexpr - numpy = 1.23.* From 2938fec9611f59c22c62d644e29d5deed7e257c7 Mon Sep 17 00:00:00 2001 From: Jeff Newman Date: Thu, 8 Feb 2024 10:23:50 -0600 Subject: [PATCH 3/5] model_validate not parse_obj --- activitysim/abm/models/util/logsums.py | 4 ++-- activitysim/abm/tables/shadow_pricing.py | 2 +- .../test/test_misc/test_load_cached_accessibility.py | 2 +- activitysim/core/configuration/base.py | 2 +- activitysim/core/configuration/filesystem.py | 4 ++-- activitysim/core/logit.py | 2 +- activitysim/core/simulate.py | 2 +- activitysim/core/test/test_input.py | 12 ++++++------ activitysim/core/util.py | 2 +- activitysim/core/workflow/state.py | 4 ++-- 10 files changed, 18 insertions(+), 18 deletions(-) diff --git a/activitysim/abm/models/util/logsums.py b/activitysim/abm/models/util/logsums.py index b92045fa8..328957965 100644 --- a/activitysim/abm/models/util/logsums.py +++ b/activitysim/abm/models/util/logsums.py @@ -84,9 +84,9 @@ def compute_location_choice_logsums( computed logsums with same index as choosers """ if isinstance(model_settings, dict): - model_settings = TourLocationComponentSettings.parse_obj(model_settings) + model_settings = TourLocationComponentSettings.model_validate(model_settings) if isinstance(logsum_settings, dict): - logsum_settings = TourModeComponentSettings.parse_obj(logsum_settings) + logsum_settings = TourModeComponentSettings.model_validate(logsum_settings) trace_label = tracing.extend_trace_label(trace_label, "compute_logsums") logger.debug(f"Running compute_logsums with {choosers.shape[0]:d} choosers") diff --git a/activitysim/abm/tables/shadow_pricing.py b/activitysim/abm/tables/shadow_pricing.py index 6b06a9d58..1b28883df 100644 --- a/activitysim/abm/tables/shadow_pricing.py +++ b/activitysim/abm/tables/shadow_pricing.py @@ -1233,7 +1233,7 @@ def load_shadow_price_calculator( spc : ShadowPriceCalculator """ if not isinstance(model_settings, TourLocationComponentSettings): - model_settings = TourLocationComponentSettings.parse_obj(model_settings) + model_settings = TourLocationComponentSettings.model_validate(model_settings) num_processes = state.get_injectable("num_processes", 1) diff --git a/activitysim/abm/test/test_misc/test_load_cached_accessibility.py b/activitysim/abm/test/test_misc/test_load_cached_accessibility.py index b19d13646..60288d67c 100644 --- a/activitysim/abm/test/test_misc/test_load_cached_accessibility.py +++ b/activitysim/abm/test/test_misc/test_load_cached_accessibility.py @@ -58,7 +58,7 @@ def test_load_cached_accessibility(): settings = state.settings input_table_list = settings.input_table_list input_table_list.append( - configuration.InputTable.parse_obj( + configuration.InputTable.model_validate( { "tablename": "accessibility", "filename": "cached_accessibility.csv", diff --git a/activitysim/core/configuration/base.py b/activitysim/core/configuration/base.py index 9a3f7b7cd..754865dc1 100644 --- a/activitysim/core/configuration/base.py +++ b/activitysim/core/configuration/base.py @@ -118,7 +118,7 @@ class PreprocessorSettings(PydanticBase): The preprocessor will emit rows to a temporary table that match the rows in this table from the pipeline.""" - TABLES: list[str] | None + TABLES: list[str] | None = None """Names of the additional tables to be merged for the preprocessor. Data from these tables will be merged into the primary table, according diff --git a/activitysim/core/configuration/filesystem.py b/activitysim/core/configuration/filesystem.py index 0f398c8fa..ce50becd4 100644 --- a/activitysim/core/configuration/filesystem.py +++ b/activitysim/core/configuration/filesystem.py @@ -639,7 +639,7 @@ def read_settings_file( include_stack: bool = False, configs_dir_list: tuple[Path] | None = None, validator_class: type[PydanticBase] | None = None, - ) -> dict | PydanticBase: + ) -> PydanticBase | dict: """ Load settings from one or more yaml files. @@ -817,7 +817,7 @@ def backfill_settings(settings, backfill): settings.pop("include_settings", None) if validator_class is not None: - settings = validator_class.parse_obj(settings) + settings = validator_class.model_validate(settings) if include_stack: # if we were called recursively, return an updated list of source_file_paths diff --git a/activitysim/core/logit.py b/activitysim/core/logit.py index 053c46e4a..9d282ddda 100644 --- a/activitysim/core/logit.py +++ b/activitysim/core/logit.py @@ -574,7 +574,7 @@ def each_nest(nest_spec: dict | LogitNestSpec, type=None, post_order=False): raise RuntimeError("Unknown nest type '%s' in call to each_nest" % type) if isinstance(nest_spec, dict): - nest_spec = LogitNestSpec.parse_obj(nest_spec) + nest_spec = LogitNestSpec.model_validate(nest_spec) for _node, nest in _each_nest(nest_spec, parent_nest=Nest(), post_order=post_order): if type is None or (type == nest.type): diff --git a/activitysim/core/simulate.py b/activitysim/core/simulate.py index aff2c53e3..133a8b1dc 100644 --- a/activitysim/core/simulate.py +++ b/activitysim/core/simulate.py @@ -467,7 +467,7 @@ def replace_coefficients(nest: LogitNestSpec): coefficients = coefficients["value"].to_dict() if not isinstance(nest_spec, LogitNestSpec): - nest_spec = LogitNestSpec.parse_obj(nest_spec) + nest_spec = LogitNestSpec.model_validate(nest_spec) replace_coefficients(nest_spec) diff --git a/activitysim/core/test/test_input.py b/activitysim/core/test/test_input.py index d0cfc24e2..bedf100d7 100644 --- a/activitysim/core/test/test_input.py +++ b/activitysim/core/test/test_input.py @@ -69,7 +69,7 @@ def test_csv_reader(seed_households, state): """ settings = yaml.load(settings_yaml, Loader=yaml.SafeLoader) - settings = configuration.Settings.parse_obj(settings) + settings = configuration.Settings.model_validate(settings) state.settings = settings hh_file = state.filesystem.get_data_dir()[0].joinpath("households.csv") @@ -94,7 +94,7 @@ def test_hdf_reader1(seed_households, state): """ settings = yaml.load(settings_yaml, Loader=yaml.SafeLoader) - settings = configuration.Settings.parse_obj(settings) + settings = configuration.Settings.model_validate(settings) state.settings = settings hh_file = state.filesystem.get_data_dir()[0].joinpath("households.h5") @@ -120,7 +120,7 @@ def test_hdf_reader2(seed_households, state): """ settings = yaml.load(settings_yaml, Loader=yaml.SafeLoader) - settings = configuration.Settings.parse_obj(settings) + settings = configuration.Settings.model_validate(settings) state.settings = settings hh_file = state.filesystem.get_data_dir()[0].joinpath("households.h5") @@ -145,7 +145,7 @@ def test_hdf_reader3(seed_households, state): """ settings = yaml.load(settings_yaml, Loader=yaml.SafeLoader) - settings = configuration.Settings.parse_obj(settings) + settings = configuration.Settings.model_validate(settings) state.settings = settings hh_file = state.filesystem.get_data_dir()[0].joinpath("input_data.h5") @@ -169,7 +169,7 @@ def test_missing_filename(seed_households, state): """ settings = yaml.load(settings_yaml, Loader=yaml.SafeLoader) - settings = configuration.Settings.parse_obj(settings) + settings = configuration.Settings.model_validate(settings) state.settings = settings with pytest.raises(AssertionError) as excinfo: @@ -191,7 +191,7 @@ def test_create_input_store(seed_households, state): """ settings = yaml.load(settings_yaml, Loader=yaml.SafeLoader) - settings = configuration.Settings.parse_obj(settings) + settings = configuration.Settings.model_validate(settings) state.settings = settings hh_file = state.filesystem.get_data_dir()[0].joinpath("households.csv") diff --git a/activitysim/core/util.py b/activitysim/core/util.py index ce2439a9b..8a0f29b11 100644 --- a/activitysim/core/util.py +++ b/activitysim/core/util.py @@ -443,7 +443,7 @@ def suffix_tables_in_settings( model_settings = recursive_replace(model_settings, k, suffix + k) if model_settings_type is not None: - model_settings = model_settings_type.parse_obj(model_settings) + model_settings = model_settings_type.model_validate(model_settings) return model_settings diff --git a/activitysim/core/workflow/state.py b/activitysim/core/workflow/state.py index 77c07180f..5689e2e6f 100644 --- a/activitysim/core/workflow/state.py +++ b/activitysim/core/workflow/state.py @@ -437,7 +437,7 @@ def initialize_filesystem( if cache_dir is not None: fs["cache_dir"] = cache_dir try: - self.filesystem: FileSystem = FileSystem.parse_obj(fs) + self.filesystem: FileSystem = FileSystem.model_validate(fs) except Exception as err: print(err) raise @@ -485,7 +485,7 @@ def load_settings(self) -> State: logger.warning(f"settings file changes cache_dir to {cache_dir}") self.filesystem.cache_dir = cache_dir settings_class = self.__class__.settings.member_type - self.settings: Settings = settings_class.parse_obj(raw_settings) + self.settings: Settings = settings_class.model_validate(raw_settings) extra_settings = set(self.settings.__dict__) - set(settings_class.__fields__) From 613126e6ffa0903af59e4efb3817af5b30ae5f85 Mon Sep 17 00:00:00 2001 From: Jeff Newman Date: Thu, 8 Feb 2024 10:28:10 -0600 Subject: [PATCH 4/5] update test to use pydantic 2 --- .github/workflows/core_tests.yml | 12 ++++++------ setup.cfg | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/core_tests.yml b/.github/workflows/core_tests.yml index 61c55299c..2f43642f1 100644 --- a/.github/workflows/core_tests.yml +++ b/.github/workflows/core_tests.yml @@ -49,7 +49,7 @@ jobs: mamba env update -n asim-test -f conda-environments/github-actions-tests.yml mamba install --yes \ "psutil=5.9.5" \ - "pydantic=1.10.13" \ + "pydantic=2.6.1" \ "pypyr=5.8.0" \ "pytables=3.6.1" \ "pytest-cov" \ @@ -149,7 +149,7 @@ jobs: mamba env update -n asim-test -f conda-environments/github-actions-tests.yml mamba install --yes \ "psutil=5.9.5" \ - "pydantic=1.10.13" \ + "pydantic=2.6.1" \ "pypyr=5.8.0" \ "pytables=3.6.1" \ "pytest-cov" \ @@ -247,7 +247,7 @@ jobs: mamba env update -n asim-test -f conda-environments/github-actions-tests.yml mamba install --yes \ "psutil=5.9.5" \ - "pydantic=1.10.13" \ + "pydantic=2.6.1" \ "pypyr=5.8.0" \ "pytables=3.6.1" \ "pytest-cov" \ @@ -344,7 +344,7 @@ jobs: mamba env update -n asim-test -f conda-environments/github-actions-tests.yml mamba install --yes \ "psutil=5.9.5" \ - "pydantic=1.10.13" \ + "pydantic=2.6.1" \ "pypyr=5.8.0" \ "pytables=3.6.1" \ "pytest-cov" \ @@ -411,7 +411,7 @@ jobs: mamba env update -n asim-test -f conda-environments/github-actions-tests.yml mamba install --yes \ "psutil=5.9.5" \ - "pydantic=1.10.13" \ + "pydantic=2.6.1" \ "pypyr=5.8.0" \ "pytables=3.6.1" \ "pytest-cov" \ @@ -477,7 +477,7 @@ jobs: mamba env update -n asim-test -f conda-environments/github-actions-tests.yml mamba install --yes \ "psutil=5.9.5" \ - "pydantic=1.10.13" \ + "pydantic=2.6.1" \ "pypyr=5.8.0" \ "pytables=3.6.1" \ "pytest-cov" \ diff --git a/setup.cfg b/setup.cfg index a33f1b3d8..6051b75af 100644 --- a/setup.cfg +++ b/setup.cfg @@ -33,6 +33,7 @@ install_requires = platformdirs psutil >= 4.1 pyarrow >= 2.0 + pydantic >= 2.6 pypyr >= 5.3 pyyaml >= 5.1 requests >= 2.7 From 2a72c2fa48bbb08603ad81416d28a4141e41accf Mon Sep 17 00:00:00 2001 From: Jeff Newman Date: Thu, 8 Feb 2024 14:40:22 -0600 Subject: [PATCH 5/5] remove outdated commented code --- activitysim/core/mp_tasks.py | 1 - 1 file changed, 1 deletion(-) diff --git a/activitysim/core/mp_tasks.py b/activitysim/core/mp_tasks.py index 7d1ffc30e..db92be1da 100644 --- a/activitysim/core/mp_tasks.py +++ b/activitysim/core/mp_tasks.py @@ -887,7 +887,6 @@ def setup_injectables_and_logging(injectables, locutor: bool = True) -> workflow state = workflow.State() state = state.initialize_filesystem(**injectables) state.settings = injectables.get("settings", Settings()) - # state.settings = Settings.parse_obj(injectables.get("settings_package", {})) # register abm steps and other abm-specific injectables # by default, assume we are running activitysim.abm