MogensR commited on
Commit
d394724
·
1 Parent(s): 43b448c

Update utils/__init__.py

Browse files
Files changed (1) hide show
  1. utils/__init__.py +54 -28
utils/__init__.py CHANGED
@@ -1,12 +1,5 @@
1
  """
2
- Lightweight lazy compatibility shim for `utilities` -> forwards to `utils`.
3
-
4
- Behavior:
5
- - Avoids importing/probing `utils` at import time (prevents recursion).
6
- - On first attribute access, imports the real `utils`, replaces sys.modules["utilities"]
7
- with that real module (so subsequent imports resolve normally), and aliases any
8
- already-loaded utils submodules under utilities.* for backward compatibility.
9
- - Minimal and non-destructive.
10
  """
11
 
12
  from __future__ import annotations
@@ -19,29 +12,64 @@
19
  __all__ = ["__getattr__", "__dir__"]
20
 
21
  _swapped: bool = False
 
22
 
23
  def _swap_with_utils() -> ModuleType:
24
- global _swapped
 
 
 
 
 
 
25
  if _swapped:
26
- mod = sys.modules.get("utilities")
27
- if isinstance(mod, ModuleType):
28
- return mod
29
- return importlib.import_module("utils")
30
-
31
- real_utils = importlib.import_module("utils")
32
- sys.modules["utilities"] = real_utils
33
-
34
- for modname, module in list(sys.modules.items()):
35
- if modname.startswith("utils.") and isinstance(module, ModuleType):
36
- suffix = modname.partition(".")[2]
37
- sys.modules[f"utilities.{suffix}"] = module
38
-
39
- _swapped = True
40
- return real_utils
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
  def __getattr__(name: str) -> Any:
43
- real = _swap_with_utils()
44
- return getattr(real, name)
 
 
 
 
 
 
 
 
 
 
 
 
45
 
46
  def __dir__() -> Iterable[str]:
47
  try:
@@ -49,5 +77,3 @@ def __dir__() -> Iterable[str]:
49
  return dir(real)
50
  except Exception:
51
  return ["__getattr__", "__dir__"]
52
-
53
- __doc__ = __doc__
 
1
  """
2
+ Fixed utils/__init__.py - Prevents recursion in __getattr__
 
 
 
 
 
 
 
3
  """
4
 
5
  from __future__ import annotations
 
12
  __all__ = ["__getattr__", "__dir__"]
13
 
14
  _swapped: bool = False
15
+ _real_utils: ModuleType | None = None
16
 
17
  def _swap_with_utils() -> ModuleType:
18
+ global _swapped, _real_utils
19
+
20
+ # Return cached module if already swapped
21
+ if _swapped and _real_utils is not None:
22
+ return _real_utils
23
+
24
+ # Prevent recursion by checking if we're already in the process
25
  if _swapped:
26
+ # If we're here, something went wrong - return a dummy module
27
+ dummy = ModuleType("utils_dummy")
28
+ return dummy
29
+
30
+ try:
31
+ _swapped = True # Set this BEFORE importing to prevent recursion
32
+ _real_utils = importlib.import_module("utils")
33
+
34
+ # Replace utilities in sys.modules
35
+ sys.modules["utilities"] = _real_utils
36
+
37
+ # Alias submodules
38
+ for modname, module in list(sys.modules.items()):
39
+ if modname.startswith("utils.") and isinstance(module, ModuleType):
40
+ suffix = modname.partition(".")[2]
41
+ sys.modules[f"utilities.{suffix}"] = module
42
+
43
+ return _real_utils
44
+
45
+ except Exception as e:
46
+ # Reset state on failure
47
+ _swapped = False
48
+ _real_utils = None
49
+ # Create a minimal fallback module to prevent further errors
50
+ fallback = ModuleType("utils_fallback")
51
+ fallback.__dict__.update({
52
+ 'device': ModuleType('device'),
53
+ 'logging': ModuleType('logging'),
54
+ 'config': ModuleType('config')
55
+ })
56
+ return fallback
57
 
58
  def __getattr__(name: str) -> Any:
59
+ # Prevent infinite recursion by checking if we're already trying to get this attribute
60
+ if hasattr(__getattr__, '_in_progress'):
61
+ raise AttributeError(f"Recursion detected while getting attribute '{name}'")
62
+
63
+ try:
64
+ __getattr__._in_progress = True
65
+ real = _swap_with_utils()
66
+ if hasattr(real, name):
67
+ return getattr(real, name)
68
+ else:
69
+ raise AttributeError(f"module 'utilities' has no attribute '{name}'")
70
+ finally:
71
+ if hasattr(__getattr__, '_in_progress'):
72
+ delattr(__getattr__, '_in_progress')
73
 
74
  def __dir__() -> Iterable[str]:
75
  try:
 
77
  return dir(real)
78
  except Exception:
79
  return ["__getattr__", "__dir__"]