Skip to content

Commit 70682a3

Browse files
authored
fix: fix backwards compatibility for new namespaces (#2805)
* replace backwards compatibility support with custom importlib loader * suppress warnings for models and infrastructure
1 parent 628a019 commit 70682a3

File tree

6 files changed

+91
-104
lines changed

6 files changed

+91
-104
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ repos:
99
rev: 22.1.0
1010
hooks:
1111
- id: black
12+
additional_dependencies: ['click==8.0.4']
1213
- repo: https://github.com/pycqa/isort
1314
rev: 5.10.1
1415
hooks:

renku/__init__.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,96 @@
1919

2020
from __future__ import absolute_import, print_function
2121

22+
import importlib
23+
import sys
24+
import warnings
25+
2226
from renku.version import __template_version__, __version__
2327

28+
29+
class LoaderWrapper(importlib.abc.Loader):
30+
"""Wrap an importlib loader and add the loaded module to sys.modules with an additional name."""
31+
32+
def __init__(self, wrapped_loader, additional_namespace, original_namespace):
33+
self.wrapped_loader = wrapped_loader
34+
self.original_namespace = original_namespace
35+
self.additional_namespace = additional_namespace
36+
37+
def get_code(self, fullname):
38+
"""Get executable code.
39+
40+
Needs to be patched with target name to bypass check in python for names having to match.
41+
"""
42+
target_name = self.original_namespace + fullname[len(self.additional_namespace) :]
43+
return self.wrapped_loader.get_code(target_name)
44+
45+
def create_module(self, spec):
46+
"""Create a module from spec."""
47+
if spec.name in sys.modules:
48+
# NOTE: Original name was already loaded, no need for going through all of importlib
49+
return sys.modules[spec.name]
50+
return self.wrapped_loader.create_module(spec)
51+
52+
def exec_module(self, module):
53+
"""Load the module using the wrapped loader."""
54+
self.wrapped_loader.exec_module(module)
55+
sys.modules[self.additional_namespace] = module
56+
57+
def __getattr__(self, name):
58+
"""Forward all calls to wrapped loaded except for one implemented here."""
59+
if name in ["exec_module", "create_module", "get_code"]:
60+
object.__getattr__(self, name)
61+
62+
return getattr(self.wrapped_loader, name)
63+
64+
65+
class DeprecatedImportInterceptor(importlib.abc.MetaPathFinder):
66+
"""Replaces imports of deprecated modules on the fly.
67+
68+
Replaces old namespace with new namespace, loads the new one, updates sys.modules with the old namespace
69+
pointing to the new namespace and returns the loaded module.
70+
"""
71+
72+
def __init__(self, package_redirects):
73+
self.package_redirects = package_redirects
74+
75+
def find_spec(self, fullname, path, target=None):
76+
"""Find the spec for a namespace."""
77+
match = next((n for n in self.package_redirects if fullname.startswith(n)), None)
78+
if match is not None:
79+
if match == fullname and self.package_redirects[match][1]:
80+
warnings.warn(
81+
f"The {fullname} module has moved to {self.package_redirects[match][0]} and is deprecated",
82+
DeprecationWarning,
83+
stacklevel=2,
84+
)
85+
try:
86+
subpath = fullname[len(match) :]
87+
target_name = self.package_redirects[match][0] + subpath
88+
89+
sys.meta_path = [x for x in sys.meta_path if x is not self]
90+
spec = importlib.util.find_spec(target_name)
91+
spec.loader = LoaderWrapper(spec.loader, fullname, target_name)
92+
finally:
93+
sys.meta_path.insert(0, self)
94+
return spec
95+
96+
return None
97+
98+
99+
# NOTE: Patch python impoprt machinery with custom loader
100+
sys.meta_path.insert(
101+
0,
102+
DeprecatedImportInterceptor(
103+
{
104+
"renku.core.models": ("renku.domain_model", False),
105+
"renku.core.metadata": ("renku.infrastructure", False),
106+
"renku.core.commands": ("renku.command", True),
107+
"renku.core.plugins": ("renku.core.plugin", True),
108+
"renku.api": ("renku.ui.api", True),
109+
"renku.cli": ("renku.ui.cli", True),
110+
}
111+
),
112+
)
113+
24114
__all__ = ("__template_version__", "__version__")

renku/api.py

Lines changed: 0 additions & 26 deletions
This file was deleted.

renku/cli.py

Lines changed: 0 additions & 26 deletions
This file was deleted.

renku/core/commands.py

Lines changed: 0 additions & 26 deletions
This file was deleted.

renku/core/plugins.py

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)