]>
jfr.im git - yt-dlp.git/blob - yt_dlp/compat/compat_utils.py
8 _NO_ATTRIBUTE
= object()
10 _Package
= collections
.namedtuple('Package', ('name', 'version'))
13 def get_package_info(module
):
14 parent
= module
.__name
__.split('.')[0]
16 with contextlib
.suppress(ImportError):
17 parent_module
= importlib
.import_module(parent
)
19 for attr
in ('__version__', 'version_string', 'version'):
20 version
= getattr(parent_module
, attr
, None)
21 if version
is not None:
23 return _Package(getattr(module
, '_yt_dlp__identifier', parent
), str(version
))
26 def _is_package(module
):
28 module
.__getattribute
__('__path__')
29 except AttributeError:
34 def passthrough_module(parent
, child
, allowed_attributes
=None, *, callback
=lambda _
: None):
35 parent_module
= importlib
.import_module(parent
)
36 child_module
= None # Import child module only as needed
38 class PassthroughModule(types
.ModuleType
):
39 def __getattr__(self
, attr
):
40 if _is_package(parent_module
):
41 with contextlib
.suppress(ImportError):
42 return importlib
.import_module(f
'.{attr}', parent
)
44 ret
= self
.__from
_child
(attr
)
45 if ret
is _NO_ATTRIBUTE
:
46 raise AttributeError(f
'module {parent} has no attribute {attr}')
50 def __from_child(self
, attr
):
51 if allowed_attributes
is None:
52 if attr
.startswith('__') and attr
.endswith('__'):
54 elif attr
not in allowed_attributes
:
58 child_module
= child_module
or importlib
.import_module(child
, parent
)
60 with contextlib
.suppress(AttributeError):
61 return getattr(child_module
, attr
)
63 if _is_package(child_module
):
64 with contextlib
.suppress(ImportError):
65 return importlib
.import_module(f
'.{attr}', child
)
69 # Python 3.6 does not have module level __getattr__
70 # https://peps.python.org/pep-0562/
71 sys
.modules
[parent
].__class
__ = PassthroughModule