From 3c5386cd711a5a0480a0b8d72e9df5007b10ac92 Mon Sep 17 00:00:00 2001 From: pukkandan Date: Fri, 24 Jun 2022 15:40:13 +0530 Subject: [PATCH] [compat] Fix `compat.WINDOWS_VT_MODE` --- test/test_compat.py | 3 +++ yt_dlp/compat/_legacy.py | 11 ++++------- yt_dlp/compat/compat_utils.py | 26 +++++++++++++++++--------- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/test/test_compat.py b/test/test_compat.py index 224175c65..ce95a6afa 100644 --- a/test/test_compat.py +++ b/test/test_compat.py @@ -26,6 +26,9 @@ class TestCompat(unittest.TestCase): with self.assertWarns(DeprecationWarning): compat.compat_basestring + with self.assertWarns(DeprecationWarning): + compat.WINDOWS_VT_MODE + compat.asyncio.events # Must not raise error def test_compat_getenv(self): diff --git a/yt_dlp/compat/_legacy.py b/yt_dlp/compat/_legacy.py index c4d95e1fb..79461617d 100644 --- a/yt_dlp/compat/_legacy.py +++ b/yt_dlp/compat/_legacy.py @@ -14,6 +14,7 @@ import urllib import xml.etree.ElementTree as etree from subprocess import DEVNULL +from .compat_utils import passthrough_module from .asyncio import run as compat_asyncio_run # noqa: F401 from .re import Pattern as compat_Pattern # noqa: F401 from .re import match as compat_Match # noqa: F401 @@ -22,6 +23,9 @@ from ..dependencies import brotli as compat_brotli # noqa: F401 from ..dependencies import websockets as compat_websockets # noqa: F401 +passthrough_module(__name__, '...utils', ('WINDOWS_VT_MODE', 'windows_enable_vt_mode')) + + # compat_ctypes_WINFUNCTYPE = ctypes.WINFUNCTYPE # will not work since ctypes.WINFUNCTYPE does not exist in UNIX machines def compat_ctypes_WINFUNCTYPE(*args, **kwargs): @@ -55,10 +59,3 @@ compat_xml_parse_error = etree.ParseError compat_xpath = lambda xpath: xpath compat_zip = zip workaround_optparse_bug9161 = lambda: None - - -def __getattr__(name): - if name in ('WINDOWS_VT_MODE', 'windows_enable_vt_mode'): - from .. import utils - return getattr(utils, name) - raise AttributeError(name) diff --git a/yt_dlp/compat/compat_utils.py b/yt_dlp/compat/compat_utils.py index 8da4fcc0a..79e253056 100644 --- a/yt_dlp/compat/compat_utils.py +++ b/yt_dlp/compat/compat_utils.py @@ -31,7 +31,7 @@ def _is_package(module): return True -def passthrough_module(parent, child, *, callback=lambda _: None): +def passthrough_module(parent, child, allowed_attributes=None, *, callback=lambda _: None): parent_module = importlib.import_module(parent) child_module = None # Import child module only as needed @@ -41,22 +41,30 @@ def passthrough_module(parent, child, *, callback=lambda _: None): with contextlib.suppress(ImportError): return importlib.import_module(f'.{attr}', parent) + ret = self.__from_child(attr) + if ret is _NO_ATTRIBUTE: + raise AttributeError(f'module {parent} has no attribute {attr}') + callback(attr) + return ret + + def __from_child(self, attr): + if allowed_attributes is None: + if attr.startswith('__') and attr.endswith('__'): + return _NO_ATTRIBUTE + elif attr not in allowed_attributes: + return _NO_ATTRIBUTE + nonlocal child_module child_module = child_module or importlib.import_module(child, parent) - ret = _NO_ATTRIBUTE with contextlib.suppress(AttributeError): - ret = getattr(child_module, attr) + return getattr(child_module, attr) if _is_package(child_module): with contextlib.suppress(ImportError): - ret = importlib.import_module(f'.{attr}', child) + return importlib.import_module(f'.{attr}', child) - if ret is _NO_ATTRIBUTE: - raise AttributeError(f'module {parent} has no attribute {attr}') - - callback(attr) - return ret + return _NO_ATTRIBUTE # Python 3.6 does not have module level __getattr__ # https://peps.python.org/pep-0562/