|
2 | 2 | PEtab global |
3 | 3 | ============ |
4 | 4 |
|
5 | | -.. warning:: |
6 | | -
|
7 | | - All functions in here are deprecated. Use the respective functions from |
8 | | - :mod:`petab.v1` instead. |
9 | | -
|
10 | 5 | Attributes: |
11 | 6 | ENV_NUM_THREADS: |
12 | 7 | Name of environment variable to set number of threads or processes |
13 | 8 | PEtab should use for operations that can be performed in parallel. |
14 | 9 | By default, all operations are performed sequentially. |
15 | 10 | """ |
16 | | -import functools |
17 | | -import inspect |
| 11 | +import importlib |
18 | 12 | import sys |
19 | | -import warnings |
| 13 | +from functools import partial |
| 14 | +from pathlib import Path |
20 | 15 | from warnings import warn |
21 | 16 |
|
22 | | -# deprecated imports |
23 | | -from petab.v1 import * # noqa: F403, F401, E402 |
24 | | - |
25 | | -from .v1.format_version import __format_version__ # noqa: F401, E402 |
26 | 17 |
|
27 | 18 | ENV_NUM_THREADS = "PETAB_NUM_THREADS" |
28 | | - |
29 | | - |
30 | | -def _deprecated_v1(func): |
31 | | - """Decorator for deprecation warnings for functions.""" |
32 | | - |
33 | | - @functools.wraps(func) |
34 | | - def new_func(*args, **kwargs): |
35 | | - warnings.warn( |
36 | | - f"petab.{func.__name__} is deprecated, " |
37 | | - f"please use petab.v1.{func.__name__} instead.", |
38 | | - category=DeprecationWarning, |
39 | | - stacklevel=2, |
| 19 | +__all__ = ["ENV_NUM_THREADS"] |
| 20 | + |
| 21 | + |
| 22 | +def __getattr__(name): |
| 23 | + if attr := globals().get(name): |
| 24 | + return attr |
| 25 | + if name == "v1": |
| 26 | + return importlib.import_module("petab.v1") |
| 27 | + if name != "__path__": |
| 28 | + warn( |
| 29 | + f"Accessing `petab.{name}` is deprecated and will be removed in " |
| 30 | + f"the next major release. Please use `petab.v1.{name}` instead.", |
| 31 | + DeprecationWarning, |
| 32 | + stacklevel=3, |
40 | 33 | ) |
41 | | - return func(*args, **kwargs) |
42 | | - |
43 | | - return new_func |
| 34 | + return getattr(importlib.import_module("petab.v1"), name) |
44 | 35 |
|
45 | 36 |
|
46 | | -def _deprecated_import_v1(module_name: str): |
47 | | - """Decorator for deprecation warnings for modules.""" |
48 | | - warn( |
49 | | - f"The '{module_name}' module is deprecated and will be removed " |
50 | | - f"in the next major release. Please use " |
51 | | - f"'petab.v1.{module_name.removeprefix('petab.')}' " |
52 | | - "instead.", |
53 | | - DeprecationWarning, |
54 | | - stacklevel=2, |
55 | | - ) |
56 | | - |
57 | | - |
58 | | -__all__ = [ |
59 | | - x |
60 | | - for x in dir(sys.modules[__name__]) |
61 | | - if not x.startswith("_") |
62 | | - and x not in {"sys", "warnings", "functools", "warn", "inspect"} |
63 | | -] |
64 | | - |
65 | | - |
66 | | -# apply decorator to all functions in the module |
67 | | -for name in __all__: |
68 | | - obj = globals().get(name) |
69 | | - if callable(obj) and inspect.isfunction(obj): |
70 | | - globals()[name] = _deprecated_v1(obj) |
71 | | -del name, obj |
| 37 | +def v1getattr(name, module): |
| 38 | + if name != "__path__": |
| 39 | + warn( |
| 40 | + f"Accessing `petab.{name}` is deprecated and will be removed in " |
| 41 | + f"the next major release. Please use `petab.v1.{name}` instead.", |
| 42 | + DeprecationWarning, |
| 43 | + stacklevel=3, |
| 44 | + ) |
| 45 | + try: |
| 46 | + return module.__dict__[name] |
| 47 | + except KeyError: |
| 48 | + raise AttributeError(name) from None |
| 49 | + |
| 50 | + |
| 51 | +# Create dummy modules for all old modules |
| 52 | +v1_root = Path(__file__).resolve().parent / "v1" |
| 53 | +v1_objects = [f.relative_to(v1_root) for f in v1_root.rglob("*")] |
| 54 | +for v1_object in v1_objects: |
| 55 | + if "__pycache__" in str(v1_object): |
| 56 | + continue |
| 57 | + if v1_object.suffix not in ["", ".py"]: |
| 58 | + continue |
| 59 | + if not (v1_root / v1_object).exists(): |
| 60 | + raise ValueError(v1_root / v1_object) |
| 61 | + v1_object_parts = [*v1_object.parts[:-1], v1_object.stem] |
| 62 | + module_name = ".".join(["petab", *v1_object_parts]) |
| 63 | + |
| 64 | + try: |
| 65 | + real_module = importlib.import_module( |
| 66 | + f"petab.v1.{'.'.join(v1_object_parts)}" |
| 67 | + ) |
| 68 | + real_module.__getattr__ = partial(v1getattr, module=real_module) |
| 69 | + sys.modules[module_name] = real_module |
| 70 | + except ModuleNotFoundError: |
| 71 | + pass |
0 commit comments