Skip to content

Commit ed7adce

Browse files
committed
Split initpkg implementation to keep flake8 happy with complexity
1 parent 1be7d47 commit ed7adce

File tree

1 file changed

+56
-37
lines changed

1 file changed

+56
-37
lines changed

src/apipkg/__init__.py

+56-37
Original file line numberDiff line numberDiff line change
@@ -63,37 +63,63 @@ def initpkg(pkgname, exportdefs, attr=None, eager=False):
6363
attr = attr or {}
6464
mod = sys.modules.get(pkgname)
6565

66-
# In Python 2 we can't update __class__ for an instance of types.Module, and
67-
# imports are protected by the global import lock anyway, so it is safe for a
68-
# module to replace itself during import. Python 3.3+ uses finer grained locking
69-
# for imports, and checks sys.modules before acquiring the lock to avoid the
70-
# overhead of the fine-grained locking. This introduces a race condition when a
71-
# module is imported by multiple threads concurrently - some threads will see the
72-
# initial module and some the replacement ApiModule. We avoid this by updating the
73-
# existing module in-place.
7466
if _PY2:
75-
d = {}
76-
f = getattr(mod, "__file__", None)
77-
if f:
78-
f = _py_abspath(f)
79-
d["__file__"] = f
80-
if hasattr(mod, "__version__"):
81-
d["__version__"] = mod.__version__
82-
if hasattr(mod, "__loader__"):
83-
d["__loader__"] = mod.__loader__
84-
if hasattr(mod, "__path__"):
85-
d["__path__"] = [_py_abspath(p) for p in mod.__path__]
86-
if hasattr(mod, "__package__"):
87-
d["__package__"] = mod.__package__
88-
if "__doc__" not in exportdefs and getattr(mod, "__doc__", None):
89-
d["__doc__"] = mod.__doc__
90-
d["__spec__"] = getattr(mod, "__spec__", None)
91-
d.update(attr)
92-
if hasattr(mod, "__dict__"):
93-
mod.__dict__.update(d)
94-
mod = ApiModule(pkgname, exportdefs, implprefix=pkgname, attr=d)
95-
sys.modules[pkgname] = mod
96-
elif mod is None:
67+
mod = _initpkg_py2(mod, pkgname, exportdefs, attr=attr)
68+
else:
69+
mod = _initpkg_py3(mod, pkgname, exportdefs, attr=attr)
70+
71+
# eagerload in bypthon to avoid their monkeypatching breaking packages
72+
if "bpython" in sys.modules or eager:
73+
for module in list(sys.modules.values()):
74+
if isinstance(module, ApiModule):
75+
module.__dict__
76+
77+
return mod
78+
79+
80+
def _initpkg_py2(mod, pkgname, exportdefs, attr=None):
81+
"""Python 2 helper for initpkg.
82+
83+
In Python 2 we can't update __class__ for an instance of types.Module, and
84+
imports are protected by the global import lock anyway, so it is safe for a
85+
module to replace itself during import.
86+
87+
"""
88+
d = {}
89+
f = getattr(mod, "__file__", None)
90+
if f:
91+
f = _py_abspath(f)
92+
d["__file__"] = f
93+
if hasattr(mod, "__version__"):
94+
d["__version__"] = mod.__version__
95+
if hasattr(mod, "__loader__"):
96+
d["__loader__"] = mod.__loader__
97+
if hasattr(mod, "__path__"):
98+
d["__path__"] = [_py_abspath(p) for p in mod.__path__]
99+
if hasattr(mod, "__package__"):
100+
d["__package__"] = mod.__package__
101+
if "__doc__" not in exportdefs and getattr(mod, "__doc__", None):
102+
d["__doc__"] = mod.__doc__
103+
d["__spec__"] = getattr(mod, "__spec__", None)
104+
d.update(attr)
105+
if hasattr(mod, "__dict__"):
106+
mod.__dict__.update(d)
107+
mod = ApiModule(pkgname, exportdefs, implprefix=pkgname, attr=d)
108+
sys.modules[pkgname] = mod
109+
return mod
110+
111+
112+
def _initpkg_py3(mod, pkgname, exportdefs, attr=None):
113+
"""Python 3 helper for initpkg.
114+
115+
Python 3.3+ uses finer grained locking for imports, and checks sys.modules before
116+
acquiring the lock to avoid the overhead of the fine-grained locking. This
117+
introduces a race condition when a module is imported by multiple threads
118+
concurrently - some threads will see the initial module and some the replacement
119+
ApiModule. We avoid this by updating the existing module in-place.
120+
121+
"""
122+
if mod is None:
97123
d = {"__file__": None, "__spec__": None}
98124
d.update(attr)
99125
mod = ApiModule(pkgname, exportdefs, implprefix=pkgname, attr=d)
@@ -114,13 +140,6 @@ def initpkg(pkgname, exportdefs, attr=None, eager=False):
114140
# Updating class of existing module as per importlib.util.LazyLoader
115141
mod.__class__ = ApiModule
116142
mod.__init__(pkgname, exportdefs, implprefix=pkgname, attr=attr)
117-
118-
# eagerload in bypthon to avoid their monkeypatching breaking packages
119-
if "bpython" in sys.modules or eager:
120-
for module in list(sys.modules.values()):
121-
if isinstance(module, ApiModule):
122-
module.__dict__
123-
124143
return mod
125144

126145

0 commit comments

Comments
 (0)