|
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 | | - |
27 | | -# __all__ = [ |
28 | | -# 'ENV_NUM_THREADS', |
29 | | -# ] |
30 | | - |
31 | 17 | ENV_NUM_THREADS = "PETAB_NUM_THREADS" |
32 | | - |
33 | | - |
34 | | -def _deprecated_v1(func): |
35 | | - """Decorator for deprecation warnings for functions.""" |
36 | | - |
37 | | - @functools.wraps(func) |
38 | | - def new_func(*args, **kwargs): |
39 | | - warnings.warn( |
40 | | - f"petab.{func.__name__} is deprecated, " |
41 | | - f"please use petab.v1.{func.__name__} instead.", |
42 | | - category=DeprecationWarning, |
43 | | - stacklevel=2, |
| 18 | +__all__ = ["ENV_NUM_THREADS"] |
| 19 | + |
| 20 | + |
| 21 | +def __getattr__(name): |
| 22 | + if attr := globals().get(name): |
| 23 | + return attr |
| 24 | + if name == "v1": |
| 25 | + return importlib.import_module("petab.v1") |
| 26 | + if name != "__path__": |
| 27 | + warn( |
| 28 | + f"Accessing `petab.{name}` is deprecated and will be removed in " |
| 29 | + f"the next major release. Please use `petab.v1.{name}` instead.", |
| 30 | + DeprecationWarning, |
| 31 | + stacklevel=3, |
44 | 32 | ) |
45 | | - return func(*args, **kwargs) |
| 33 | + return getattr(importlib.import_module("petab.v1"), name) |
46 | 34 |
|
47 | | - return new_func |
48 | 35 |
|
49 | | - |
50 | | -def _deprecated_import_v1(module_name: str): |
51 | | - """Decorator for deprecation warnings for modules.""" |
52 | | - warn( |
53 | | - f"The '{module_name}' module is deprecated and will be removed " |
54 | | - f"in the next major release. Please use " |
55 | | - f"'petab.v1.{module_name.removeprefix('petab.')}' " |
56 | | - "instead.", |
57 | | - DeprecationWarning, |
58 | | - stacklevel=2, |
59 | | - ) |
60 | | - |
61 | | - |
62 | | -__all__ = [ |
63 | | - x |
64 | | - for x in dir(sys.modules[__name__]) |
65 | | - if not x.startswith("_") |
66 | | - and x not in {"sys", "warnings", "functools", "warn", "inspect"} |
67 | | -] |
68 | | - |
69 | | - |
70 | | -# apply decorator to all functions in the module |
71 | | -for name in __all__: |
72 | | - obj = globals().get(name) |
73 | | - if callable(obj) and inspect.isfunction(obj): |
74 | | - globals()[name] = _deprecated_v1(obj) |
75 | | -del name, obj |
| 36 | +def v1getattr(name, module): |
| 37 | + if name != "__path__": |
| 38 | + warn( |
| 39 | + f"Accessing `petab.{name}` is deprecated and will be removed in " |
| 40 | + f"the next major release. Please use `petab.v1.{name}` instead.", |
| 41 | + DeprecationWarning, |
| 42 | + stacklevel=3, |
| 43 | + ) |
| 44 | + try: |
| 45 | + return module.__dict__[name] |
| 46 | + except KeyError: |
| 47 | + raise AttributeError(name) from None |
| 48 | + |
| 49 | + |
| 50 | +# Create dummy modules for all old modules |
| 51 | +v1_root = Path(__file__).resolve().parent / "v1" |
| 52 | +v1_objects = [f.relative_to(v1_root) for f in v1_root.rglob("*")] |
| 53 | +for v1_object in v1_objects: |
| 54 | + if "__pycache__" in str(v1_object): |
| 55 | + continue |
| 56 | + if v1_object.suffix not in ["", ".py"]: |
| 57 | + continue |
| 58 | + if not (v1_root / v1_object).exists(): |
| 59 | + raise ValueError(v1_root / v1_object) |
| 60 | + v1_object_parts = [*v1_object.parts[:-1], v1_object.stem] |
| 61 | + module_name = ".".join(["petab", *v1_object_parts]) |
| 62 | + |
| 63 | + try: |
| 64 | + real_module = importlib.import_module( |
| 65 | + f"petab.v1.{'.'.join(v1_object_parts)}" |
| 66 | + ) |
| 67 | + real_module.__getattr__ = partial(v1getattr, module=real_module) |
| 68 | + sys.modules[module_name] = real_module |
| 69 | + except ModuleNotFoundError: |
| 70 | + pass |
0 commit comments