From 50096fc044fd0e5216a6cc23e38c469781f3d959 Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Mon, 12 Oct 2026 11:04:45 +0200 Subject: [PATCH 1/2] Remove deprecated `petab.*` aliases for `petab.v1` Accessing `petab.` or importing `petab.` has been deprecated in favor of `petab.v1` since 0.4.0. Remove the `__getattr__` fallback and the `sys.modules` aliases. The only top-level names left are `petab.v1`, `petab.v2`, `petab.ENV_NUM_THREADS` and `petab.__version__`. Everything else now raises `AttributeError` or `ModuleNotFoundError`. As a side effect, `import petab` no longer imports `petab.v1`. Removing the eager `petab.v1` import exposed a circular import between `petab.versions` and `petab.v1.yaml`. Fix it by importing `petab.v1` lazily in `get_major_version`. Also: * import `ENV_NUM_THREADS` in `petab.v1.parameter_mapping` from `petab` instead of defining it again * update tests, docstring cross-references, messages, README and the visualization notebook to use `petab.v1` * remove `test_problem_with_sbml_model`, which only differed from `test_get_condition_specific_models` by using the deprecated alias * add a changelog section for the unreleased 0.10.0 Generated with AI assistance. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 34 ++++++++++ README.md | 4 +- doc/example/example_visualization.ipynb | 8 +-- petab/__init__.py | 69 ++------------------ petab/v1/composite_problem.py | 2 +- petab/v1/core.py | 6 +- petab/v1/lint.py | 2 +- petab/v1/math/SympyVisitor.py | 2 +- petab/v1/parameter_mapping.py | 17 ++--- petab/v1/parameters.py | 2 +- petab/v1/problem.py | 34 +++++----- petab/v1/sampling.py | 2 +- petab/v1/simulate.py | 22 ++++--- petab/v1/visualize/__init__.py | 2 +- petab/v1/visualize/helper_functions.py | 2 +- petab/versions.py | 9 ++- tests/test_deprecation_warnings.py | 26 -------- tests/v1/test_combine.py | 2 +- tests/v1/test_conditions.py | 6 +- tests/v1/test_deprecated.py | 34 +--------- tests/v1/test_lint.py | 10 +-- tests/v1/test_measurements.py | 4 +- tests/v1/test_model_pysb.py | 3 +- tests/v1/test_observables.py | 6 +- tests/v1/test_parameter_mapping.py | 9 +-- tests/v1/test_parameters.py | 4 +- tests/v1/test_petab.py | 11 ++-- tests/v1/test_sbml.py | 2 +- tests/v1/test_simplify.py | 8 +-- tests/v1/test_simulate.py | 4 +- tests/v1/test_visualization.py | 4 +- tests/v1/test_visualization_data_overview.py | 5 +- tests/v1/test_yaml.py | 3 +- 33 files changed, 140 insertions(+), 218 deletions(-) delete mode 100644 tests/test_deprecation_warnings.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 130c5814..a8cb1c4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,39 @@ # PEtab changelog +## 0.10 series + +### 0.10.0 (unreleased) + +**Breaking changes** +* Removed the deprecated top-level aliases for `petab.v1` (deprecated since + 0.4.0). Accessing `petab.` or importing `petab.` for anything + other than `petab.v1`, `petab.v2`, `petab.ENV_NUM_THREADS` and + `petab.__version__` now raises `AttributeError` / `ModuleNotFoundError`. + Use `petab.v1.` instead, e.g., `import petab.v1 as petab`. + `import petab` no longer imports `petab.v1`. + (by @dweindl) + +**Fixes** +* `get_model_for_condition` no longer turns rate-rule targets that are + overridden in the condition table into constants + (by @dweindl in https://github.com/PEtab-dev/libpetab-python/pull/520) +* Raise a clear error for a PEtab YAML file with an empty `problems` section + (by @dweindl in https://github.com/PEtab-dev/libpetab-python/pull/521) +* Several fixes to the v1-to-v2 converter (`petab1to2`): keep + pre-equilibration for conditions that set nothing, order placeholders by + index instead of lexicographically, rescale noise and priors when + converting `log10` to `log`, and fix the conversion of `logNormal`, + `logLaplace` and `parameterScaleUniform` priors + (by @FFroehlich in + https://github.com/PEtab-dev/libpetab-python/pull/532, + https://github.com/PEtab-dev/libpetab-python/pull/533, + https://github.com/PEtab-dev/libpetab-python/pull/535, and + https://github.com/PEtab-dev/libpetab-python/pull/536) + +**Features** +* `petab1to2` and `petab_files_1to2` can skip validation via `validate=False` + (by @FFroehlich in https://github.com/PEtab-dev/libpetab-python/pull/534) + ## 0.9 series ### 0.9.0 diff --git a/README.md b/README.md index 455ea046..d66d3e7e 100644 --- a/README.md +++ b/README.md @@ -39,11 +39,11 @@ be: entrypoints to be available as a shell command from anywhere, called `petablint` - - [petab.create_parameter_df](https://petab.readthedocs.io/projects/libpetab-python/en/latest/build/_autosummary/petab.parameters.html#petab.parameters.create_parameter_df) + - [petab.v1.create_parameter_df](https://petab.readthedocs.io/projects/libpetab-python/en/latest/build/_autosummary/petab.v1.parameters.html#petab.v1.parameters.create_parameter_df) to create the parameter table, once you have set up the model, condition table, observable table and measurement table - - [petab.create_combine_archive](https://petab.readthedocs.io/projects/libpetab-python/en/latest/build/_autosummary/petab.core.html#petab.core.create_combine_archive) + - [petab.v1.create_combine_archive](https://petab.readthedocs.io/projects/libpetab-python/en/latest/build/_autosummary/petab.v1.core.html#petab.v1.core.create_combine_archive) to create a [COMBINE Archive](https://combinearchive.org/index/) from PEtab files diff --git a/doc/example/example_visualization.ipynb b/doc/example/example_visualization.ipynb index abc97cfa..2bef672b 100644 --- a/doc/example/example_visualization.ipynb +++ b/doc/example/example_visualization.ipynb @@ -26,10 +26,10 @@ "from pathlib import Path\n", "\n", "import matplotlib.pyplot as plt\n", - "from petab.visualize import plot_problem\n", "\n", - "import petab\n", - "from petab import Problem\n", + "import petab.v1 as petab\n", + "from petab.v1 import Problem\n", + "from petab.v1.visualize import plot_problem\n", "\n", "example_dir_fujita = Path(\"example_Fujita\")\n", "petab_yaml_fujita = example_dir_fujita / \"Fujita.yaml\"\n", @@ -62,7 +62,7 @@ "source": [ "### Plotting measurements\n", "\n", - "For the most basic visualization, we can use the [plot_problem()](https://petab.readthedocs.io/projects/libpetab-python/en/latest/build/_autosummary/petab.visualize.html#petab.visualize.plot_problem) function." + "For the most basic visualization, we can use the [plot_problem()](https://petab.readthedocs.io/projects/libpetab-python/en/latest/build/_autosummary/petab.v1.visualize.html#petab.v1.visualize.plot_problem) function." ] }, { diff --git a/petab/__init__.py b/petab/__init__.py index 23b376c2..2bf36d57 100644 --- a/petab/__init__.py +++ b/petab/__init__.py @@ -10,72 +10,15 @@ """ import importlib -import sys -from functools import partial -from pathlib import Path -from warnings import warn + +from .version import __version__ # noqa: F401 ENV_NUM_THREADS = "PETAB_NUM_THREADS" __all__ = ["ENV_NUM_THREADS"] def __getattr__(name): - if attr := globals().get(name): - return attr - if name == "v1": - return importlib.import_module("petab.v1") - if name == "v2": - return importlib.import_module("petab.v2") - if name not in ( - "__path__", - "__all__", - "__wrapped__", - # accessed under pytest - "_pytestfixturefunction", - "__test__", - "__bases__", - ): - warn( - f"Accessing `petab.{name}` is deprecated and will be removed in " - f"the next major release. Please use `petab.v1.{name}` instead.", - DeprecationWarning, - stacklevel=3, - ) - return getattr(importlib.import_module("petab.v1"), name) - - -def _v1getattr(name, module): - if name not in ("__path__", "__all__", "__wrapped__"): - warn( - f"Accessing `petab.{name}` is deprecated and will be removed in " - f"the next major release. Please use `petab.v1.{name}` instead.", - DeprecationWarning, - stacklevel=3, - ) - try: - return module.__dict__[name] - except KeyError: - raise AttributeError(name) from None - - -# Create dummy modules for all old modules -v1_root = Path(__file__).resolve().parent / "v1" -v1_objects = [f.relative_to(v1_root) for f in v1_root.rglob("*")] -for v1_object in v1_objects: - if "__pycache__" in str(v1_object): - continue - if v1_object.suffix not in ["", ".py"]: - continue - if not (v1_root / v1_object).exists(): - raise ValueError(v1_root / v1_object) - v1_object_parts = [*v1_object.parts[:-1], v1_object.stem] - module_name = ".".join(["petab", *v1_object_parts]) - - try: - real_module = importlib.import_module( - f"petab.v1.{'.'.join(v1_object_parts)}" - ) - real_module.__getattr__ = partial(_v1getattr, module=real_module) - sys.modules[module_name] = real_module - except ModuleNotFoundError: - pass + """Lazily import the `petab.v1` and `petab.v2` subpackages.""" + if name in ("v1", "v2"): + return importlib.import_module(f"petab.{name}") + raise AttributeError(f"module 'petab' has no attribute '{name}'") diff --git a/petab/v1/composite_problem.py b/petab/v1/composite_problem.py index 1cdab0b0..bdc376ae 100644 --- a/petab/v1/composite_problem.py +++ b/petab/v1/composite_problem.py @@ -15,7 +15,7 @@ class CompositeProblem: Attributes: problems: - List of :py:class:`petab.Problem` s + List of :py:class:`petab.v1.Problem` s parameter_df: PEtab parameter DataFrame """ diff --git a/petab/v1/core.py b/petab/v1/core.py index 4ca10b7d..9de03cfa 100644 --- a/petab/v1/core.py +++ b/petab/v1/core.py @@ -185,7 +185,7 @@ def get_hyperparameter_replacement_id( def get_flattened_id_mappings( - petab_problem: "petab.problem.Problem", + petab_problem: "petab.v1.problem.Problem", ) -> dict[str, dict[str, str]]: """Get mapping from unflattened to flattened observable IDs. @@ -240,7 +240,7 @@ def get_flattened_id_mappings( def flatten_timepoint_specific_output_overrides( - petab_problem: "petab.problem.Problem", + petab_problem: "petab.v1.problem.Problem", ) -> None: """Flatten timepoint-specific output parameter overrides. @@ -322,7 +322,7 @@ def flatten_timepoint_specific_output_overrides( def unflatten_simulation_df( simulation_df: pd.DataFrame, - petab_problem: "petab.problem.Problem", + petab_problem: "petab.v1.problem.Problem", ) -> pd.DataFrame: """Unflatten simulations from a flattened PEtab problem. diff --git a/petab/v1/lint.py b/petab/v1/lint.py index df9fc6e2..d723f4a2 100644 --- a/petab/v1/lint.py +++ b/petab/v1/lint.py @@ -1172,7 +1172,7 @@ def assert_measurements_numeric( ) if not all_measurements_are_numeric: raise AssertionError( - "Some values in the `petab.C.MEASUREMENT` column of the PEtab " + "Some values in the `petab.v1.C.MEASUREMENT` column of the PEtab " "measurements table are not numeric." ) diff --git a/petab/v1/math/SympyVisitor.py b/petab/v1/math/SympyVisitor.py index 64284e7f..92563d80 100644 --- a/petab/v1/math/SympyVisitor.py +++ b/petab/v1/math/SympyVisitor.py @@ -73,7 +73,7 @@ class MathVisitorSympy(PetabMathExprParserVisitor): Converts PEtab math expressions to sympy expressions. Most users will not need to interact with this class directly, but rather - use :func:`petab.math.sympify_petab`. + use :func:`petab.v1.math.sympify_petab`. Evaluation of any sub-expressions currently relies on sympy's defaults. diff --git a/petab/v1/parameter_mapping.py b/petab/v1/parameter_mapping.py index 9bb09638..66d0a388 100644 --- a/petab/v1/parameter_mapping.py +++ b/petab/v1/parameter_mapping.py @@ -14,6 +14,7 @@ import numpy as np import pandas as pd +from .. import ENV_NUM_THREADS from . import ( core, lint, @@ -25,10 +26,6 @@ from .mapping import resolve_mapping from .models import Model -# FIXME import from petab.ENV_NUM_THREADS -ENV_NUM_THREADS = "PETAB_NUM_THREADS" - - logger = logging.getLogger(__name__) __all__ = [ "ParMappingDict", @@ -89,7 +86,7 @@ def get_optimization_to_simulation_parameter_mapping( The model. simulation_conditions: Table of simulation conditions as created by - ``petab.get_simulation_conditions``. + ``petab.v1.get_simulation_conditions``. warn_unmapped: If ``True``, log warning regarding unmapped parameters scaled_parameters: @@ -124,7 +121,7 @@ def get_optimization_to_simulation_parameter_mapping( if sbml_model: warnings.warn( "Passing a model via the `sbml_model` argument is " - "deprecated, use `model=petab.models.sbml_model." + "deprecated, use `model=petab.v1.models.sbml_model." "SbmlModel(...)` instead.", DeprecationWarning, stacklevel=2, @@ -347,7 +344,7 @@ def get_parameter_mapping_for_condition( The model. simulation_parameters: Model simulation parameter IDs mapped to parameter values (output - of ``petab.sbml.get_model_parameters(.., with_values=True)``). + of ``petab.v1.sbml.get_model_parameters(.., with_values=True)``). Optional, saves time if precomputed. warn_unmapped: If ``True``, log warning regarding unmapped parameters @@ -374,7 +371,7 @@ def get_parameter_mapping_for_condition( if sbml_model: warnings.warn( "Passing a model via the `sbml_model` argument is " - "deprecated, use `model=petab.models.sbml_model." + "deprecated, use `model=petab.v1.models.sbml_model." "SbmlModel(...)` instead.", DeprecationWarning, stacklevel=2, @@ -778,10 +775,10 @@ def merge_preeq_and_sim_pars( Parameters: parameter_mappings: As returned by - :py:func:`petab.get_optimization_to_simulation_parameter_mapping`. + :py:func:`petab.v1.get_optimization_to_simulation_parameter_mapping`. scale_mappings: As returned by - :py:func:`petab.get_optimization_to_simulation_parameter_mapping`. + :py:func:`petab.v1.get_optimization_to_simulation_parameter_mapping`. Returns: The parameter and scale simulation mappings, modified and checked. diff --git a/petab/v1/parameters.py b/petab/v1/parameters.py index 3efdaddb..3ce2593c 100644 --- a/petab/v1/parameters.py +++ b/petab/v1/parameters.py @@ -193,7 +193,7 @@ def create_parameter_df( if sbml_model: warnings.warn( "Passing a model via the `sbml_model` argument is " - "deprecated, use `model=petab.models.sbml_model." + "deprecated, use `model=petab.v1.models.sbml_model." "SbmlModel(...)` instead.", DeprecationWarning, stacklevel=2, diff --git a/petab/v1/problem.py b/petab/v1/problem.py index 96401f9b..643d6cbd 100644 --- a/petab/v1/problem.py +++ b/petab/v1/problem.py @@ -99,8 +99,8 @@ def __init__( ): warn( "Passing `sbml_model`, `sbml_document`, or `sbml_reader` " - "to petab.Problem is deprecated and will be removed in a " - "future version. Use `model=petab.models.sbml_model." + "to petab.v1.Problem is deprecated and will be removed in a " + "future version. Use `model=petab.v1.models.sbml_model." "SbmlModel(...)` instead.", DeprecationWarning, stacklevel=2, @@ -202,8 +202,8 @@ def from_files( extensions_config: Information on the extensions used """ warn( - "petab.Problem.from_files is deprecated and will be removed in a " - "future version. Use `petab.Problem.from_yaml instead.", + "petab.v1.Problem.from_files is deprecated and will be removed " + "in a future version. Use `petab.v1.Problem.from_yaml instead.", DeprecationWarning, stacklevel=2, ) @@ -289,10 +289,10 @@ def get_path(filename): if yaml.is_composite_problem(yaml_config): raise ValueError( - "petab.Problem.from_yaml() can only be used for " + "petab.v1.Problem.from_yaml() can only be used for " "yaml files comprising a single model. " "Consider using " - "petab.CompositeProblem.from_yaml() instead." + "petab.v1.CompositeProblem.from_yaml() instead." ) major_version = get_major_version(yaml_config) @@ -424,13 +424,13 @@ def get_path(filename): def from_combine(filename: Path | str) -> Problem: """Read PEtab COMBINE archive (http://co.mbine.org/documents/archive). - See also :py:func:`petab.create_combine_archive`. + See also :py:func:`petab.v1.create_combine_archive`. Arguments: filename: Path to the PEtab-COMBINE archive Returns: - A :py:class:`petab.Problem` instance. + A :py:class:`petab.v1.Problem` instance. """ # function-level import, because module-level import interfered with # other SWIG interfaces @@ -471,7 +471,7 @@ def to_files_generic( Specify a prefix to all paths, to avoid specifying the prefix for all paths individually. NB: the prefix is added to paths before ``relative_paths`` is handled downstream in - :func:`petab.yaml.create_problem_yaml`. + :func:`petab.v1.yaml.create_problem_yaml`. Returns: The path to the PEtab problem YAML file. @@ -653,7 +653,7 @@ def get_optimization_parameters(self) -> list[str]: """ Return list of optimization parameter IDs. - See :py:func:`petab.parameters.get_optimization_parameters`. + See :py:func:`petab.v1.parameters.get_optimization_parameters`. """ return parameters.get_optimization_parameters(self.parameter_df) @@ -661,14 +661,14 @@ def get_optimization_parameter_scales(self) -> dict[str, str]: """ Return list of optimization parameter scaling strings. - See :py:func:`petab.parameters.get_optimization_parameters`. + See :py:func:`petab.v1.parameters.get_optimization_parameters`. """ return parameters.get_optimization_parameter_scaling(self.parameter_df) def get_model_parameters(self) -> list[str] | dict[str, float]: - """See :py:func:`petab.sbml.get_model_parameters`""" + """See :py:func:`petab.v1.sbml.get_model_parameters`""" warn( - "petab.Problem.get_model_parameters is deprecated and will be " + "petab.v1.Problem.get_model_parameters is deprecated and will be " "removed in a future version.", DeprecationWarning, stacklevel=2, @@ -892,13 +892,13 @@ def x_fixed_indices(self) -> list[int]: return [j for j, val in enumerate(estimated) if val == 0] def get_simulation_conditions_from_measurement_df(self): - """See petab.get_simulation_conditions""" + """See petab.v1.get_simulation_conditions""" return measurements.get_simulation_conditions(self.measurement_df) def get_optimization_to_simulation_parameter_mapping(self, **kwargs): """ See - :py:func:`petab.parameter_mapping.get_optimization_to_simulation_parameter_mapping`, + :py:func:`petab.v1.parameter_mapping.get_optimization_to_simulation_parameter_mapping`, to which all keyword arguments are forwarded. """ return ( @@ -929,7 +929,7 @@ def create_parameter_df(self, **kwargs): def sample_parameter_startpoints(self, n_starts: int = 100, **kwargs): """Create 2D array with starting points for optimization - See :py:func:`petab.sample_parameter_startpoints`. + See :py:func:`petab.v1.sample_parameter_startpoints`. """ return sampling.sample_parameter_startpoints( self.parameter_df, n_starts=n_starts, **kwargs @@ -940,7 +940,7 @@ def sample_parameter_startpoints_dict( ) -> list[dict[str, float]]: """Create dictionaries with starting points for optimization - See also :py:func:`petab.sample_parameter_startpoints`. + See also :py:func:`petab.v1.sample_parameter_startpoints`. Returns: A list of dictionaries with parameter IDs mapping to samples diff --git a/petab/v1/sampling.py b/petab/v1/sampling.py index 5cbdba88..49049099 100644 --- a/petab/v1/sampling.py +++ b/petab/v1/sampling.py @@ -17,7 +17,7 @@ def sample_from_prior( Arguments: prior: A tuple as obtained from - :func:`petab.parameter.get_priors_from_df` + :func:`petab.v1.parameters.get_priors_from_df` n_starts: Number of samples Returns: diff --git a/petab/v1/simulate.py b/petab/v1/simulate.py index 46001a72..a5a762bc 100644 --- a/petab/v1/simulate.py +++ b/petab/v1/simulate.py @@ -21,7 +21,7 @@ class Simulator(abc.ABC): """Base class that specific simulators should inherit. Specific simulators should minimally implement the - :meth:`petab.simulate.Simulator.simulate_without_noise` method. + :meth:`petab.v1.simulate.Simulator.simulate_without_noise` method. Example (AMICI): https://bit.ly/33SUSG4 Attributes: @@ -79,7 +79,7 @@ def __init__( def remove_working_dir(self, force: bool = False, **kwargs) -> None: """Remove the simulator working directory, and all files within. - See the :meth:`petab.simulate.Simulator.__init__` method arguments. + See the :meth:`petab.v1.simulate.Simulator.__init__` method arguments. Arguments: force: @@ -115,9 +115,9 @@ def simulate_without_noise(self) -> pd.DataFrame: Returns: Simulated data, as a PEtab measurements table, which should be equivalent to replacing all values in the - :const:`petab.C.MEASUREMENT` column of the measurements table (of - the PEtab problem supplied to the - :meth:`petab.simulate.Simulator.__init__` method), with + :const:`petab.v1.C.MEASUREMENT` column of the measurements table + (of the PEtab problem supplied to the + :meth:`petab.v1.simulate.Simulator.__init__` method), with simulated values. """ raise NotImplementedError() @@ -136,11 +136,12 @@ def simulate( noise_scaling_factor: A multiplier of the scale of the noise distribution. as_measurement: - Whether the data column is named :const:`petab.C.MEASUREMENT` - (`True`) or :const:`petab.C.SIMULATION` (`False`). + Whether the data column is named + :const:`petab.v1.C.MEASUREMENT` (`True`) or + :const:`petab.v1.C.SIMULATION` (`False`). **kwargs: Additional keyword arguments are passed to - :meth:`petab.simulate.Simulator.simulate_without_noise`. + :meth:`petab.v1.simulate.Simulator.simulate_without_noise`. Returns: Simulated data, as a PEtab measurements table. @@ -206,7 +207,7 @@ def sample_noise( Arguments: petab_problem: The PEtab problem used to generate the simulated value. - Instance of :class:`petab.Problem`. + Instance of :class:`petab.v1.Problem`. measurement_row: The row in the PEtab problem measurement table that corresponds to the simulated value. @@ -214,7 +215,8 @@ def sample_noise( A simulated value without noise. noise_formulas: Processed noise formulas from the PEtab observables table, in the - form output by :func:`petab.calculate.get_symbolic_noise_formulas`. + form output by + :func:`petab.v1.calculate.get_symbolic_noise_formulas`. rng: A NumPy random generator. noise_scaling_factor: diff --git a/petab/v1/visualize/__init__.py b/petab/v1/visualize/__init__.py index f84ac476..c909a68b 100644 --- a/petab/v1/visualize/__init__.py +++ b/petab/v1/visualize/__init__.py @@ -3,7 +3,7 @@ ========= PEtab comes with visualization functionality. Those need to be imported via -``import petab.visualize``. +``import petab.v1.visualize``. """ diff --git a/petab/v1/visualize/helper_functions.py b/petab/v1/visualize/helper_functions.py index 85b5d936..309fe316 100644 --- a/petab/v1/visualize/helper_functions.py +++ b/petab/v1/visualize/helper_functions.py @@ -1,7 +1,7 @@ """ This file should contain the functions, which PEtab internally needs for plotting, but which are not meant to be used by non-developers and should -hence not be directly visible/usable when using `import petab.visualize`. +hence not be directly visible/usable when using `import petab.v1.visualize`. """ import pandas as pd diff --git a/petab/versions.py b/petab/versions.py index b1fdecf4..8644fc1b 100644 --- a/petab/versions.py +++ b/petab/versions.py @@ -4,14 +4,15 @@ import re from pathlib import Path +from typing import TYPE_CHECKING -import petab +if TYPE_CHECKING: + import petab __all__ = [ "get_major_version", "parse_version", ] -from . import v1 # version regex pattern _version_pattern = ( @@ -43,6 +44,8 @@ def get_major_version( problem: str | dict | Path | petab.v1.Problem | petab.v2.Problem, ) -> int: """Get the major version number of the given problem.""" + from . import v1 + version = None if isinstance(problem, str | Path): @@ -57,7 +60,7 @@ def get_major_version( version = str(version) return int(version.split(".")[0]) - if isinstance(problem, petab.v1.Problem): + if isinstance(problem, v1.Problem): return 1 from . import v2 diff --git a/tests/test_deprecation_warnings.py b/tests/test_deprecation_warnings.py deleted file mode 100644 index 7680d14b..00000000 --- a/tests/test_deprecation_warnings.py +++ /dev/null @@ -1,26 +0,0 @@ -import warnings - -import pytest - - -def test_deprecated_global(): - with pytest.warns(DeprecationWarning): - from petab import Problem - - with pytest.warns(DeprecationWarning): # noqa PT031 - import petab - - petab.Problem() - - with pytest.warns(DeprecationWarning): # noqa PT031 - import petab.parameters - - petab.parameters # noqa - - with warnings.catch_warnings(): - warnings.simplefilter("error") - from petab.v1 import Problem - - Problem() - - import petab.v1.parameters diff --git a/tests/v1/test_combine.py b/tests/v1/test_combine.py index 50c87b32..117354d1 100644 --- a/tests/v1/test_combine.py +++ b/tests/v1/test_combine.py @@ -4,9 +4,9 @@ from pathlib import Path import pandas as pd -from petab.C import * import petab.v1 as petab +from petab.v1.C import * from petab.v1.models.sbml_model import SbmlModel # import fixtures diff --git a/tests/v1/test_conditions.py b/tests/v1/test_conditions.py index 6fb75d1f..c594ea8f 100644 --- a/tests/v1/test_conditions.py +++ b/tests/v1/test_conditions.py @@ -7,10 +7,10 @@ import numpy as np import pandas as pd import pytest -from petab.C import * -import petab -from petab import conditions +import petab.v1 as petab +from petab.v1 import conditions +from petab.v1.C import * def test_get_parametric_overrides(): diff --git a/tests/v1/test_deprecated.py b/tests/v1/test_deprecated.py index 46a37fd3..6f00f1a7 100644 --- a/tests/v1/test_deprecated.py +++ b/tests/v1/test_deprecated.py @@ -5,41 +5,9 @@ import pytest -import petab +import petab.v1 as petab from .test_petab import petab_problem # noqa: F401 -from .test_sbml import check_model, create_test_data - - -def test_problem_with_sbml_model(): - """Test that a problem can be correctly created from sbml model.""" - # retrieve test data - ( - model, - condition_df, - _observable_df, - measurement_df, - parameter_df, - ) = create_test_data() - - with pytest.deprecated_call(): - petab_problem = petab.Problem( - model=model, - condition_df=condition_df, - measurement_df=measurement_df, - parameter_df=parameter_df, - ) - - with pytest.warns( - UserWarning, - match="An SBML rule was removed to set the component " - "species_2 to a constant value.", - ): - _, condition_model = petab.get_model_for_condition( - petab_problem, "condition_1" - ) - - check_model(condition_model) def test_to_files_with_sbml_model(petab_problem): # noqa: F811 diff --git a/tests/v1/test_lint.py b/tests/v1/test_lint.py index 5dec74be..64e0dd0c 100644 --- a/tests/v1/test_lint.py +++ b/tests/v1/test_lint.py @@ -5,10 +5,10 @@ import pandas as pd import pytest -from petab.C import * -import petab -from petab import lint +import petab.v1 as petab +from petab.v1 import lint +from petab.v1.C import * # import fixtures pytest_plugins = [ @@ -256,7 +256,7 @@ def test_assert_no_leading_trailing_whitespace(): def test_assert_model_parameters_in_condition_or_parameter_table(): - from petab.models.sbml_model import SbmlModel + from petab.v1.models.sbml_model import SbmlModel ant_model = """ parameter1 = 0.0 @@ -501,7 +501,7 @@ def test_assert_measurement_conditions_present_in_condition_table(): def test_check_condition_df(): """Check that we correctly detect errors in condition table""" - from petab.models.sbml_model import SbmlModel + from petab.v1.models.sbml_model import SbmlModel model = SbmlModel.from_antimony("") diff --git a/tests/v1/test_measurements.py b/tests/v1/test_measurements.py index 14a40954..b89ccfe1 100644 --- a/tests/v1/test_measurements.py +++ b/tests/v1/test_measurements.py @@ -5,9 +5,9 @@ import numpy as np import pandas as pd -from petab.C import * -import petab +import petab.v1 as petab +from petab.v1.C import * def test_get_measurement_df(): diff --git a/tests/v1/test_model_pysb.py b/tests/v1/test_model_pysb.py index 66ba3c9d..a3f9ea77 100644 --- a/tests/v1/test_model_pysb.py +++ b/tests/v1/test_model_pysb.py @@ -2,7 +2,8 @@ import pysb import pytest -from petab.models.pysb_model import ( + +from petab.v1.models.pysb_model import ( PySBModel, parse_species_name, pattern_from_string, diff --git a/tests/v1/test_observables.py b/tests/v1/test_observables.py index 4941f38b..5e094990 100644 --- a/tests/v1/test_observables.py +++ b/tests/v1/test_observables.py @@ -5,9 +5,9 @@ import pandas as pd import pytest -from petab.C import * -import petab +import petab.v1 as petab +from petab.v1.C import * # import fixtures pytest_plugins = [ @@ -70,7 +70,7 @@ def test_write_observable_df(): def test_get_output_parameters(): """Test measurements.get_output_parameters.""" - from petab.models.sbml_model import SbmlModel + from petab.v1.models.sbml_model import SbmlModel model = SbmlModel.from_antimony( "fixedParameter1 = 1.0; observable_1 = 1.0" diff --git a/tests/v1/test_parameter_mapping.py b/tests/v1/test_parameter_mapping.py index e02d349b..0d97b734 100644 --- a/tests/v1/test_parameter_mapping.py +++ b/tests/v1/test_parameter_mapping.py @@ -3,10 +3,11 @@ import numpy as np import pandas as pd -from petab.C import * -from petab.models.sbml_model import SbmlModel -import petab +import petab.v1 as petab +from petab import ENV_NUM_THREADS +from petab.v1.C import * +from petab.v1.models.sbml_model import SbmlModel from petab.v1.parameter_mapping import _apply_parameter_table # import fixtures @@ -336,7 +337,7 @@ def test_all_override(condition_df_2_conditions): # For one case we test parallel execution, which must yield the same # result - os.environ[petab.ENV_NUM_THREADS] = "4" + os.environ[ENV_NUM_THREADS] = "4" actual = petab.get_optimization_to_simulation_parameter_mapping( measurement_df=measurement_df, condition_df=condition_df, diff --git a/tests/v1/test_parameters.py b/tests/v1/test_parameters.py index 7aec946f..da7b420c 100644 --- a/tests/v1/test_parameters.py +++ b/tests/v1/test_parameters.py @@ -6,9 +6,9 @@ import numpy as np import pandas as pd import pytest -from petab.C import * -import petab +import petab.v1 as petab +from petab.v1.C import * def test_get_optimization_parameter_scaling(): diff --git a/tests/v1/test_petab.py b/tests/v1/test_petab.py index b7e36123..194ee6ea 100644 --- a/tests/v1/test_petab.py +++ b/tests/v1/test_petab.py @@ -9,13 +9,12 @@ import numpy as np import pandas as pd import pytest -from petab.C import * -from petab.models.sbml_model import SbmlModel from yaml import safe_load -import petab -import petab.v1 +import petab.v1 as petab from petab.v1 import Problem +from petab.v1.C import * +from petab.v1.models.sbml_model import SbmlModel @pytest.fixture @@ -312,7 +311,7 @@ def test_create_parameter_df( # Test old API with passing libsbml.Model directly with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") - parameter_df = petab.v1.create_parameter_df( + parameter_df = petab.create_parameter_df( sbml_model=model.sbml_model, condition_df=condition_df_2_conditions, observable_df=observable_df, @@ -885,7 +884,7 @@ def test_problem_from_yaml_v1_multiple_files(): petab_problem1 = petab.Problem.from_yaml(yaml_path) # test that we can load the problem from a dict with a custom base path - yaml_config = petab.v1.load_yaml(yaml_path) + yaml_config = petab.load_yaml(yaml_path) petab_problem2 = petab.Problem.from_yaml(yaml_config, base_path=tmpdir) for petab_problem in (petab_problem1, petab_problem2): diff --git a/tests/v1/test_sbml.py b/tests/v1/test_sbml.py index 469524c5..f97381ec 100644 --- a/tests/v1/test_sbml.py +++ b/tests/v1/test_sbml.py @@ -8,7 +8,7 @@ from petab.v1.models.sbml_model import SbmlModel, sympify_sbml sys.path.append(os.getcwd()) -import petab +import petab.v1 as petab def create_test_data(): diff --git a/tests/v1/test_simplify.py b/tests/v1/test_simplify.py index 18779c2a..316cc058 100644 --- a/tests/v1/test_simplify.py +++ b/tests/v1/test_simplify.py @@ -5,11 +5,11 @@ import pandas as pd import pytest from pandas.testing import * -from petab.C import * -from petab.models.sbml_model import SbmlModel -from petab.simplify import * -from petab import Problem +from petab.v1 import Problem +from petab.v1.C import * +from petab.v1.models.sbml_model import SbmlModel +from petab.v1.simplify import * @pytest.fixture diff --git a/tests/v1/test_simulate.py b/tests/v1/test_simulate.py index 7cddc674..643837d8 100644 --- a/tests/v1/test_simulate.py +++ b/tests/v1/test_simulate.py @@ -8,9 +8,9 @@ import pandas as pd import pytest import scipy.stats -from petab.C import MEASUREMENT -import petab +import petab.v1 as petab +from petab.v1.C import MEASUREMENT class TestSimulator(petab.simulate.Simulator): diff --git a/tests/v1/test_visualization.py b/tests/v1/test_visualization.py index eadce3d7..b8d0ef75 100644 --- a/tests/v1/test_visualization.py +++ b/tests/v1/test_visualization.py @@ -5,9 +5,9 @@ import matplotlib.pyplot as plt import pytest -from petab.C import * -import petab +import petab.v1 as petab +from petab.v1.C import * from petab.v1.visualize import ( plot_goodness_of_fit, plot_residuals_vs_simulation, diff --git a/tests/v1/test_visualization_data_overview.py b/tests/v1/test_visualization_data_overview.py index 45e9324e..47382e4e 100644 --- a/tests/v1/test_visualization_data_overview.py +++ b/tests/v1/test_visualization_data_overview.py @@ -1,9 +1,8 @@ from pathlib import Path from tempfile import TemporaryDirectory -from petab.visualize.data_overview import create_report - -import petab +import petab.v1 as petab +from petab.v1.visualize.data_overview import create_report def test_data_overview(): diff --git a/tests/v1/test_yaml.py b/tests/v1/test_yaml.py index 419facd8..8164b828 100644 --- a/tests/v1/test_yaml.py +++ b/tests/v1/test_yaml.py @@ -5,7 +5,8 @@ import pytest from jsonschema.exceptions import ValidationError -from petab.yaml import create_problem_yaml, get_path_prefix, validate + +from petab.v1.yaml import create_problem_yaml, get_path_prefix, validate def test_validate(): From 6e45519e98fe2aa3fd508f19dc5dd7023745ff3a Mon Sep 17 00:00:00 2001 From: Daniel Weindl Date: Mon, 12 Oct 2026 11:33:25 +0200 Subject: [PATCH 2/2] Changelog: link #538 Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8cb1c4e..fd39f282 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ `petab.__version__` now raises `AttributeError` / `ModuleNotFoundError`. Use `petab.v1.` instead, e.g., `import petab.v1 as petab`. `import petab` no longer imports `petab.v1`. - (by @dweindl) + (by @dweindl in https://github.com/PEtab-dev/libpetab-python/pull/538) **Fixes** * `get_model_for_condition` no longer turns rate-rule targets that are