mirror of
				https://github.com/yt-dlp/yt-dlp.git
				synced 2025-11-04 08:30:46 +00:00 
			
		
		
		
	[compat] Ensure submodules are correctly wrapped
This commit is contained in:
		@@ -2,11 +2,18 @@ import contextlib
 | 
			
		||||
import os
 | 
			
		||||
import subprocess
 | 
			
		||||
import sys
 | 
			
		||||
import types
 | 
			
		||||
import warnings
 | 
			
		||||
import xml.etree.ElementTree as etree
 | 
			
		||||
 | 
			
		||||
from . import re
 | 
			
		||||
from ._deprecated import *  # noqa: F401, F403
 | 
			
		||||
from .compat_utils import passthrough_module
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# XXX: Implement this the same way as other DeprecationWarnings without circular import
 | 
			
		||||
passthrough_module(__name__, '._legacy', callback=lambda attr: warnings.warn(
 | 
			
		||||
    DeprecationWarning(f'{__name__}.{attr} is deprecated'), stacklevel=2))
 | 
			
		||||
del passthrough_module
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# HTMLParseError has been deprecated in Python 3.3 and removed in
 | 
			
		||||
@@ -85,24 +92,3 @@ def windows_enable_vt_mode():  # TODO: Do this the proper way https://bugs.pytho
 | 
			
		||||
    with contextlib.suppress(Exception):
 | 
			
		||||
        subprocess.Popen('', shell=True, startupinfo=startupinfo).wait()
 | 
			
		||||
        WINDOWS_VT_MODE = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class _PassthroughLegacy(types.ModuleType):
 | 
			
		||||
    def __getattr__(self, attr):
 | 
			
		||||
        import importlib
 | 
			
		||||
        with contextlib.suppress(ImportError):
 | 
			
		||||
            return importlib.import_module(f'.{attr}', __name__)
 | 
			
		||||
 | 
			
		||||
        legacy = importlib.import_module('._legacy', __name__)
 | 
			
		||||
        if not hasattr(legacy, attr):
 | 
			
		||||
            raise AttributeError(f'module {__name__} has no attribute {attr}')
 | 
			
		||||
 | 
			
		||||
        # XXX: Implement this the same way as other DeprecationWarnings without circular import
 | 
			
		||||
        import warnings
 | 
			
		||||
        warnings.warn(DeprecationWarning(f'{__name__}.{attr} is deprecated'), stacklevel=2)
 | 
			
		||||
        return getattr(legacy, attr)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Python 3.6 does not have module level __getattr__
 | 
			
		||||
# https://peps.python.org/pep-0562/
 | 
			
		||||
sys.modules[__name__].__class__ = _PassthroughLegacy
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,10 @@
 | 
			
		||||
from asyncio import *  # noqa: F403
 | 
			
		||||
 | 
			
		||||
from . import tasks  # noqa: F401
 | 
			
		||||
from ..compat_utils import passthrough_module
 | 
			
		||||
 | 
			
		||||
passthrough_module(__name__, 'asyncio')
 | 
			
		||||
del passthrough_module
 | 
			
		||||
 | 
			
		||||
try:
 | 
			
		||||
    run  # >= 3.7
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,11 @@
 | 
			
		||||
 | 
			
		||||
from asyncio.tasks import *  # noqa: F403
 | 
			
		||||
 | 
			
		||||
from ..compat_utils import passthrough_module
 | 
			
		||||
 | 
			
		||||
passthrough_module(__name__, 'asyncio.tasks')
 | 
			
		||||
del passthrough_module
 | 
			
		||||
 | 
			
		||||
try:  # >= 3.7
 | 
			
		||||
    all_tasks
 | 
			
		||||
except NameError:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										44
									
								
								yt_dlp/compat/compat_utils.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								yt_dlp/compat/compat_utils.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
import contextlib
 | 
			
		||||
import importlib
 | 
			
		||||
import sys
 | 
			
		||||
import types
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _is_package(module):
 | 
			
		||||
    try:
 | 
			
		||||
        module.__getattribute__('__path__')
 | 
			
		||||
    except AttributeError:
 | 
			
		||||
        return False
 | 
			
		||||
    return True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
_NO_ATTRIBUTE = object()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def passthrough_module(parent, child, *, callback=lambda _: None):
 | 
			
		||||
    parent_module = importlib.import_module(parent)
 | 
			
		||||
    child_module = importlib.import_module(child, parent)
 | 
			
		||||
 | 
			
		||||
    class PassthroughModule(types.ModuleType):
 | 
			
		||||
        def __getattr__(self, attr):
 | 
			
		||||
            if _is_package(parent_module):
 | 
			
		||||
                with contextlib.suppress(ImportError):
 | 
			
		||||
                    return importlib.import_module(f'.{attr}', parent)
 | 
			
		||||
 | 
			
		||||
            ret = _NO_ATTRIBUTE
 | 
			
		||||
            with contextlib.suppress(AttributeError):
 | 
			
		||||
                ret = getattr(child_module, attr)
 | 
			
		||||
 | 
			
		||||
            if _is_package(child_module):
 | 
			
		||||
                with contextlib.suppress(ImportError):
 | 
			
		||||
                    ret = importlib.import_module(f'.{attr}', child)
 | 
			
		||||
 | 
			
		||||
            if ret is _NO_ATTRIBUTE:
 | 
			
		||||
                raise AttributeError(f'module {parent} has no attribute {attr}')
 | 
			
		||||
 | 
			
		||||
            callback(attr)
 | 
			
		||||
            return ret
 | 
			
		||||
 | 
			
		||||
    # Python 3.6 does not have module level __getattr__
 | 
			
		||||
    # https://peps.python.org/pep-0562/
 | 
			
		||||
    sys.modules[parent].__class__ = PassthroughModule
 | 
			
		||||
@@ -2,6 +2,11 @@
 | 
			
		||||
 | 
			
		||||
from re import *  # F403
 | 
			
		||||
 | 
			
		||||
from .compat_utils import passthrough_module
 | 
			
		||||
 | 
			
		||||
passthrough_module(__name__, 're')
 | 
			
		||||
del passthrough_module
 | 
			
		||||
 | 
			
		||||
try:
 | 
			
		||||
    Pattern  # >= 3.7
 | 
			
		||||
except NameError:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user