]>
jfr.im git - yt-dlp.git/blob - yt_dlp/compat/compat_utils.py
7 _NO_ATTRIBUTE
= object()
9 _Package
= collections
.namedtuple('Package', ('name', 'version'))
12 def get_package_info(module
):
13 parent
= module
.__name
__.split('.')[0]
15 with contextlib
.suppress(ImportError):
16 parent_module
= importlib
.import_module(parent
)
18 for attr
in ('__version__', 'version_string', 'version'):
19 version
= getattr(parent_module
, attr
, None)
20 if version
is not None:
22 return _Package(getattr(module
, '_yt_dlp__identifier', parent
), str(version
))
25 def _is_package(module
):
27 module
.__getattribute
__('__path__')
28 except AttributeError:
33 def passthrough_module(parent
, child
, allowed_attributes
=None, *, callback
=lambda _
: None):
34 parent_module
= importlib
.import_module(parent
)
35 child_module
= None # Import child module only as needed
37 class PassthroughModule(types
.ModuleType
):
38 def __getattr__(self
, attr
):
39 if _is_package(parent_module
):
40 with contextlib
.suppress(ImportError):
41 return importlib
.import_module(f
'.{attr}', parent
)
43 ret
= self
.__from
_child
(attr
)
44 if ret
is _NO_ATTRIBUTE
:
45 raise AttributeError(f
'module {parent} has no attribute {attr}')
49 def __from_child(self
, attr
):
50 if allowed_attributes
is None:
51 if attr
.startswith('__') and attr
.endswith('__'):
53 elif attr
not in allowed_attributes
:
57 child_module
= child_module
or importlib
.import_module(child
, parent
)
59 with contextlib
.suppress(AttributeError):
60 return getattr(child_module
, attr
)
62 if _is_package(child_module
):
63 with contextlib
.suppress(ImportError):
64 return importlib
.import_module(f
'.{attr}', child
)
68 # Python 3.6 does not have module level __getattr__
69 # https://peps.python.org/pep-0562/
70 sys
.modules
[parent
].__class
__ = PassthroughModule