diff --git a/.github/workflows/core.yml b/.github/workflows/core.yml index 66e8ced53..a60e002d9 100644 --- a/.github/workflows/core.yml +++ b/.github/workflows/core.yml @@ -10,7 +10,7 @@ jobs: matrix: os: [ubuntu-latest] # CPython 3.9 is in quick-test - python-version: ['3.6', '3.7', '3.10', 3.11-dev, pypy-3.6, pypy-3.7, pypy-3.8] + python-version: ['3.7', '3.10', 3.11-dev, pypy-3.7, pypy-3.8] run-tests-ext: [sh] include: # atleast one of each CPython/PyPy tests must be in windows diff --git a/.github/workflows/download.yml b/.github/workflows/download.yml index 7fdc5595a..e8eb1fd12 100644 --- a/.github/workflows/download.yml +++ b/.github/workflows/download.yml @@ -25,7 +25,7 @@ jobs: fail-fast: true matrix: os: [ubuntu-latest] - python-version: ['3.6', '3.7', '3.10', 3.11-dev, pypy-3.6, pypy-3.7, pypy-3.8] + python-version: ['3.7', '3.10', 3.11-dev, pypy-3.7, pypy-3.8] run-tests-ext: [sh] include: # atleast one of each CPython/PyPy tests must be in windows diff --git a/setup.py b/setup.py index ef9d3e91b..dab09c268 100644 --- a/setup.py +++ b/setup.py @@ -136,7 +136,7 @@ setup( url='https://github.com/yt-dlp/yt-dlp', packages=packages(), install_requires=REQUIREMENTS, - python_requires='>=3.6', + python_requires='>=3.7', project_urls={ 'Documentation': 'https://github.com/yt-dlp/yt-dlp#readme', 'Source': 'https://github.com/yt-dlp/yt-dlp', @@ -148,7 +148,6 @@ setup( 'Development Status :: 5 - Production/Stable', 'Environment :: Console', 'Programming Language :: Python', - 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', diff --git a/test/test_compat.py b/test/test_compat.py index c6a8f4ecb..e3d775bc1 100644 --- a/test/test_compat.py +++ b/test/test_compat.py @@ -28,7 +28,8 @@ class TestCompat(unittest.TestCase): with self.assertWarns(DeprecationWarning): compat.WINDOWS_VT_MODE - compat.asyncio.events # Must not raise error + # TODO: Test submodule + # compat.asyncio.events # Must not raise error def test_compat_expanduser(self): old_home = os.environ.get('HOME') diff --git a/yt_dlp/YoutubeDL.py b/yt_dlp/YoutubeDL.py index 31fbbdb54..70897d492 100644 --- a/yt_dlp/YoutubeDL.py +++ b/yt_dlp/YoutubeDL.py @@ -584,7 +584,8 @@ class YoutubeDL: for type_, stream in self._out_files.items_ if type_ != 'console' }) - MIN_SUPPORTED, MIN_RECOMMENDED = (3, 6), (3, 7) + # The code is left like this to be reused for future deprecations + MIN_SUPPORTED, MIN_RECOMMENDED = (3, 7), (3, 7) current_version = sys.version_info[:2] if current_version < MIN_RECOMMENDED: msg = ('Support for Python version %d.%d has been deprecated. ' diff --git a/yt_dlp/__init__.py b/yt_dlp/__init__.py index 7caf41c60..5b9b3541c 100644 --- a/yt_dlp/__init__.py +++ b/yt_dlp/__init__.py @@ -1,4 +1,4 @@ -f'You are using an unsupported version of Python. Only Python versions 3.6 and above are supported by yt-dlp' # noqa: F541 +f'You are using an unsupported version of Python. Only Python versions 3.7 and above are supported by yt-dlp' # noqa: F541 __license__ = 'Public Domain' diff --git a/yt_dlp/compat/__init__.py b/yt_dlp/compat/__init__.py index df1d4e671..6d85a6a1f 100644 --- a/yt_dlp/compat/__init__.py +++ b/yt_dlp/compat/__init__.py @@ -3,13 +3,12 @@ import sys 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)) + DeprecationWarning(f'{__name__}.{attr} is deprecated'), stacklevel=3)) # HTMLParseError has been deprecated in Python 3.3 and removed in @@ -33,6 +32,7 @@ compat_os_name = os._name if os.name == 'java' else os.name if compat_os_name == 'nt': def compat_shlex_quote(s): + import re return s if re.match(r'^[-_\w./]+$', s) else '"%s"' % s.replace('"', '\\"') else: from shlex import quote as compat_shlex_quote # noqa: F401 diff --git a/yt_dlp/compat/_legacy.py b/yt_dlp/compat/_legacy.py index e75f79bbf..09259c988 100644 --- a/yt_dlp/compat/_legacy.py +++ b/yt_dlp/compat/_legacy.py @@ -22,10 +22,14 @@ import urllib.request import xml.etree.ElementTree as etree from subprocess import DEVNULL -from .compat_utils import passthrough_module # isort: split -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 +# isort: split +import asyncio # noqa: F401 +import re # noqa: F401 +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 + +from .compat_utils import passthrough_module from ..dependencies import Cryptodome_AES as compat_pycrypto_AES # noqa: F401 from ..dependencies import brotli as compat_brotli # noqa: F401 from ..dependencies import websockets as compat_websockets # noqa: F401 diff --git a/yt_dlp/compat/asyncio.py b/yt_dlp/compat/asyncio.py deleted file mode 100644 index c61e5c8fd..000000000 --- a/yt_dlp/compat/asyncio.py +++ /dev/null @@ -1,23 +0,0 @@ -# flake8: noqa: F405 -from asyncio import * # noqa: F403 - -from .compat_utils import passthrough_module - -passthrough_module(__name__, 'asyncio') -del passthrough_module - -try: - run # >= 3.7 -except NameError: - def run(coro): - try: - loop = get_event_loop() - except RuntimeError: - loop = new_event_loop() - set_event_loop(loop) - loop.run_until_complete(coro) - -try: - all_tasks # >= 3.7 -except NameError: - all_tasks = Task.all_tasks diff --git a/yt_dlp/compat/re.py b/yt_dlp/compat/re.py deleted file mode 100644 index e1d3a2645..000000000 --- a/yt_dlp/compat/re.py +++ /dev/null @@ -1,18 +0,0 @@ -# flake8: noqa: F405 -from re import * # F403 - -from .compat_utils import passthrough_module - -passthrough_module(__name__, 're') -del passthrough_module - -try: - Pattern # >= 3.7 -except NameError: - Pattern = type(compile('')) - - -try: - Match # >= 3.7 -except NameError: - Match = type(compile('').match('')) diff --git a/yt_dlp/downloader/websocket.py b/yt_dlp/downloader/websocket.py index 727a15828..6837ff1da 100644 --- a/yt_dlp/downloader/websocket.py +++ b/yt_dlp/downloader/websocket.py @@ -1,3 +1,4 @@ +import asyncio import contextlib import os import signal @@ -5,7 +6,6 @@ import threading from .common import FileDownloader from .external import FFmpegFD -from ..compat import asyncio from ..dependencies import websockets diff --git a/yt_dlp/extractor/common.py b/yt_dlp/extractor/common.py index f0eddcf26..1c751870c 100644 --- a/yt_dlp/extractor/common.py +++ b/yt_dlp/extractor/common.py @@ -11,13 +11,14 @@ import math import netrc import os import random +import re import sys import time import urllib.parse import urllib.request import xml.etree.ElementTree -from ..compat import functools, re # isort: split +from ..compat import functools # isort: split from ..compat import compat_etree_fromstring, compat_expanduser, compat_os_name from ..downloader import FileDownloader from ..downloader.f4m import get_base_url, remove_encrypted_media diff --git a/yt_dlp/utils.py b/yt_dlp/utils.py index 7648b6fce..f0e9ee8c4 100644 --- a/yt_dlp/utils.py +++ b/yt_dlp/utils.py @@ -1,3 +1,4 @@ +import asyncio import atexit import base64 import binascii @@ -46,7 +47,7 @@ import urllib.request import xml.etree.ElementTree import zlib -from .compat import asyncio, functools # isort: split +from .compat import functools # isort: split from .compat import ( compat_etree_fromstring, compat_expanduser, diff --git a/yt_dlp/webvtt.py b/yt_dlp/webvtt.py index b8974f883..cc2353436 100644 --- a/yt_dlp/webvtt.py +++ b/yt_dlp/webvtt.py @@ -9,8 +9,8 @@ in RFC 8216 ยง3.5 . """ import io +import re -from .compat import re from .utils import int_or_none, timetuple_from_msec