mirror of
				https://github.com/yt-dlp/yt-dlp.git
				synced 2025-10-31 14:45:14 +00:00 
			
		
		
		
	[compat_utils] Improve passthrough_module
				
					
				
			This commit is contained in:
		
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @@ -74,7 +74,7 @@ offlinetest: codetest | ||||
| 	$(PYTHON) -m pytest -k "not download" | ||||
|  | ||||
| # XXX: This is hard to maintain | ||||
| CODE_FOLDERS = yt_dlp yt_dlp/downloader yt_dlp/extractor yt_dlp/postprocessor yt_dlp/compat | ||||
| CODE_FOLDERS = yt_dlp yt_dlp/downloader yt_dlp/extractor yt_dlp/postprocessor yt_dlp/compat yt_dlp/dependencies | ||||
| yt-dlp: yt_dlp/*.py yt_dlp/*/*.py | ||||
| 	mkdir -p zip | ||||
| 	for d in $(CODE_FOLDERS) ; do \ | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| import collections | ||||
| import contextlib | ||||
| import functools | ||||
| import importlib | ||||
| import sys | ||||
| import types | ||||
| @@ -22,6 +23,10 @@ def _is_package(module): | ||||
|     return '__path__' in vars(module) | ||||
| 
 | ||||
| 
 | ||||
| def _is_dunder(name): | ||||
|     return name.startswith('__') and name.endswith('__') | ||||
| 
 | ||||
| 
 | ||||
| class EnhancedModule(types.ModuleType): | ||||
|     def __new__(cls, name, *args, **kwargs): | ||||
|         if name not in sys.modules: | ||||
| @@ -44,7 +49,7 @@ class EnhancedModule(types.ModuleType): | ||||
|         try: | ||||
|             ret = super().__getattribute__(attr) | ||||
|         except AttributeError: | ||||
|             if attr.startswith('__') and attr.endswith('__'): | ||||
|             if _is_dunder(attr): | ||||
|                 raise | ||||
|             getter = getattr(self, '__getattr__', None) | ||||
|             if not getter: | ||||
| @@ -53,7 +58,7 @@ class EnhancedModule(types.ModuleType): | ||||
|         return ret.fget() if isinstance(ret, property) else ret | ||||
| 
 | ||||
| 
 | ||||
| def passthrough_module(parent, child, allowed_attributes=None, *, callback=lambda _: None): | ||||
| def passthrough_module(parent, child, allowed_attributes=(..., ), *, callback=lambda _: None): | ||||
|     """Passthrough parent module into a child module, creating the parent if necessary""" | ||||
|     parent = EnhancedModule(parent) | ||||
| 
 | ||||
| @@ -68,24 +73,23 @@ def passthrough_module(parent, child, allowed_attributes=None, *, callback=lambd | ||||
|         callback(attr) | ||||
|         return ret | ||||
| 
 | ||||
|     @functools.lru_cache(maxsize=None) | ||||
|     def from_child(attr): | ||||
|         nonlocal child | ||||
| 
 | ||||
|         if allowed_attributes is None: | ||||
|             if attr.startswith('__') and attr.endswith('__'): | ||||
|                 return _NO_ATTRIBUTE | ||||
|         elif attr not in allowed_attributes: | ||||
|         if attr not in allowed_attributes: | ||||
|             if ... not in allowed_attributes or _is_dunder(attr): | ||||
|                 return _NO_ATTRIBUTE | ||||
| 
 | ||||
|         if isinstance(child, str): | ||||
|             child = importlib.import_module(child, parent.__name__) | ||||
| 
 | ||||
|         with contextlib.suppress(AttributeError): | ||||
|             return getattr(child, attr) | ||||
| 
 | ||||
|         if _is_package(child): | ||||
|             with contextlib.suppress(ImportError): | ||||
|                 return importlib.import_module(f'.{attr}', child.__name__) | ||||
|                 return passthrough_module(f'{parent.__name__}.{attr}', | ||||
|                                           importlib.import_module(f'.{attr}', child.__name__)) | ||||
| 
 | ||||
|         with contextlib.suppress(AttributeError): | ||||
|             return getattr(child, attr) | ||||
| 
 | ||||
|         return _NO_ATTRIBUTE | ||||
| 
 | ||||
|   | ||||
| @@ -1,10 +1,6 @@ | ||||
| import importlib | ||||
| 
 | ||||
| from ..compat import functools | ||||
| from ..compat.compat_utils import EnhancedModule, passthrough_module | ||||
| 
 | ||||
| EnhancedModule(__name__) | ||||
| 
 | ||||
| try: | ||||
|     import Cryptodome as _parent | ||||
| except ImportError: | ||||
| @@ -14,14 +10,8 @@ except ImportError: | ||||
|         _parent = EnhancedModule('Cryptodome') | ||||
|         __bool__ = lambda: False | ||||
| 
 | ||||
| 
 | ||||
| @functools.cache | ||||
| def __getattr__(name): | ||||
|     try: | ||||
|         submodule = importlib.import_module(f'.{name}', _parent.__name__) | ||||
|     except ImportError: | ||||
|         return getattr(_parent, name) | ||||
|     return passthrough_module(f'{__name__}.{name}', submodule) | ||||
| passthrough_module(__name__, _parent, (..., '__version__')) | ||||
| del passthrough_module, EnhancedModule | ||||
| 
 | ||||
| 
 | ||||
| @property | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 pukkandan
					pukkandan