diff options
-rw-r--r-- | .github/workflows/build.yml | 15 | ||||
-rw-r--r-- | .github/workflows/core.yml | 6 | ||||
-rw-r--r-- | .github/workflows/download.yml | 8 | ||||
-rw-r--r-- | .github/workflows/quick-test.yml | 2 | ||||
-rw-r--r-- | CONTRIBUTING.md | 2 | ||||
-rw-r--r-- | README.md | 6 | ||||
-rw-r--r-- | setup.cfg | 4 | ||||
-rw-r--r-- | setup.py | 4 | ||||
-rw-r--r-- | test/test_update.py | 110 | ||||
-rw-r--r-- | yt_dlp/__init__.py | 11 | ||||
-rw-r--r-- | yt_dlp/compat/functools.py | 14 | ||||
-rw-r--r-- | yt_dlp/update.py | 14 |
12 files changed, 101 insertions, 95 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a52973ea2..d944659b8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -377,8 +377,8 @@ jobs: steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v4 - with: # 3.7 is used for Vista support. See https://github.com/yt-dlp/yt-dlp/issues/390 - python-version: "3.7" + with: + python-version: "3.8" architecture: "x86" - name: Install Requirements run: | @@ -436,7 +436,16 @@ jobs: run: | cat >> _update_spec << EOF # This file is used for regulating self-update - lock 2022.08.18.36 .+ Python 3.6 + lock 2022.08.18.36 .+ Python 3\.6 + lock 2023.11.16 (?!win_x86_exe).+ Python 3\.7 + lock 2023.11.16 win_x86_exe .+ Windows-(?:Vista|2008Server) + lockV2 yt-dlp/yt-dlp 2022.08.18.36 .+ Python 3\.6 + lockV2 yt-dlp/yt-dlp 2023.11.16 (?!win_x86_exe).+ Python 3\.7 + lockV2 yt-dlp/yt-dlp 2023.11.16 win_x86_exe .+ Windows-(?:Vista|2008Server) + lockV2 yt-dlp/yt-dlp-nightly-builds 2023.11.15.232826 (?!win_x86_exe).+ Python 3\.7 + lockV2 yt-dlp/yt-dlp-nightly-builds 2023.11.15.232826 win_x86_exe .+ Windows-(?:Vista|2008Server) + lockV2 yt-dlp/yt-dlp-master-builds 2023.11.15.232812 (?!win_x86_exe).+ Python 3\.7 + lockV2 yt-dlp/yt-dlp-master-builds 2023.11.15.232812 win_x86_exe .+ Windows-(?:Vista|2008Server) EOF - name: Sign checksum files diff --git a/.github/workflows/core.yml b/.github/workflows/core.yml index e5a976de5..3c10fc17e 100644 --- a/.github/workflows/core.yml +++ b/.github/workflows/core.yml @@ -13,12 +13,12 @@ jobs: matrix: os: [ubuntu-latest] # CPython 3.11 is in quick-test - python-version: ['3.8', '3.9', '3.10', '3.12', pypy-3.7, pypy-3.8, pypy-3.10] + python-version: ['3.8', '3.9', '3.10', '3.12', pypy-3.8, pypy-3.10] run-tests-ext: [sh] include: # atleast one of each CPython/PyPy tests must be in windows - os: windows-latest - python-version: '3.7' + python-version: '3.8' run-tests-ext: bat - os: windows-latest python-version: '3.12' @@ -32,7 +32,7 @@ jobs: uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - - name: Install dependencies + - name: Install test requirements run: pip install pytest -r requirements.txt - name: Run tests continue-on-error: False diff --git a/.github/workflows/download.yml b/.github/workflows/download.yml index 7302a93bc..73b2f9ca3 100644 --- a/.github/workflows/download.yml +++ b/.github/workflows/download.yml @@ -15,7 +15,7 @@ jobs: with: python-version: 3.9 - name: Install test requirements - run: pip install pytest + run: pip install pytest -r requirements.txt - name: Run tests continue-on-error: true run: ./devscripts/run_tests.sh download @@ -28,7 +28,7 @@ jobs: fail-fast: true matrix: os: [ubuntu-latest] - python-version: ['3.7', '3.10', '3.12', pypy-3.7, pypy-3.8, pypy-3.10] + python-version: ['3.10', '3.11', '3.12', pypy-3.8, pypy-3.10] run-tests-ext: [sh] include: # atleast one of each CPython/PyPy tests must be in windows @@ -44,8 +44,8 @@ jobs: uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - - name: Install pytest - run: pip install pytest + - name: Install test requirements + run: pip install pytest -r requirements.txt - name: Run tests continue-on-error: true run: ./devscripts/run_tests.${{ matrix.run-tests-ext }} download diff --git a/.github/workflows/quick-test.yml b/.github/workflows/quick-test.yml index e4fd89551..edbdaffd7 100644 --- a/.github/workflows/quick-test.yml +++ b/.github/workflows/quick-test.yml @@ -15,7 +15,7 @@ jobs: with: python-version: '3.11' - name: Install test requirements - run: pip install pytest pycryptodomex + run: pip install pytest -r requirements.txt - name: Run tests run: | python3 -m yt_dlp -v || true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 90e7faf7c..c472f3251 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -222,7 +222,7 @@ After you have ensured this site is distributing its content legally, you can fo $ flake8 yt_dlp/extractor/yourextractor.py -1. Make sure your code works under all [Python](https://www.python.org/) versions supported by yt-dlp, namely CPython and PyPy for Python 3.7 and above. Backward compatibility is not required for even older versions of Python. +1. Make sure your code works under all [Python](https://www.python.org/) versions supported by yt-dlp, namely CPython and PyPy for Python 3.8 and above. Backward compatibility is not required for even older versions of Python. 1. When the tests pass, [add](https://git-scm.com/docs/git-add) the new files, [commit](https://git-scm.com/docs/git-commit) them and [push](https://git-scm.com/docs/git-push) the result, like this: $ git add yt_dlp/extractor/_extractors.py @@ -131,7 +131,7 @@ Features marked with a **\*** have been back-ported to youtube-dl Some of yt-dlp's default options are different from that of youtube-dl and youtube-dlc: -* yt-dlp supports only [Python 3.7+](## "Windows 7"), and *may* remove support for more versions as they [become EOL](https://devguide.python.org/versions/#python-release-cycle); while [youtube-dl still supports Python 2.6+ and 3.2+](https://github.com/ytdl-org/youtube-dl/issues/30568#issue-1118238743) +* yt-dlp supports only [Python 3.8+](## "Windows 7"), and *may* remove support for more versions as they [become EOL](https://devguide.python.org/versions/#python-release-cycle); while [youtube-dl still supports Python 2.6+ and 3.2+](https://github.com/ytdl-org/youtube-dl/issues/30568#issue-1118238743) * The options `--auto-number` (`-A`), `--title` (`-t`) and `--literal` (`-l`), no longer work. See [removed options](#Removed) for details * `avconv` is not supported as an alternative to `ffmpeg` * yt-dlp stores config files in slightly different locations to youtube-dl. See [CONFIGURATION](#configuration) for a list of correct locations @@ -266,7 +266,7 @@ gpg --verify SHA2-512SUMS.sig SHA2-512SUMS **Note**: The manpages, shell completion (autocomplete) files etc. are available inside the [source tarball](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp.tar.gz) ## DEPENDENCIES -Python versions 3.7+ (CPython and PyPy) are supported. Other versions and implementations may or may not work correctly. +Python versions 3.8+ (CPython and PyPy) are supported. Other versions and implementations may or may not work correctly. <!-- Python 3.5+ uses VC++14 and it is already embedded in the binary created <!x-- https://www.microsoft.com/en-us/download/details.aspx?id=26999 --x> @@ -334,7 +334,7 @@ On some systems, you may need to use `py` or `python` instead of `python3`. **Important**: Running `pyinstaller` directly **without** using `pyinst.py` is **not** officially supported. This may or may not work correctly. ### Platform-independent Binary (UNIX) -You will need the build tools `python` (3.7+), `zip`, `make` (GNU), `pandoc`\* and `pytest`\*. +You will need the build tools `python` (3.8+), `zip`, `make` (GNU), `pandoc`\* and `pytest`\*. After installing these, simply run `make`. @@ -26,7 +26,7 @@ markers = [tox:tox] skipsdist = true -envlist = py{36,37,38,39,310,311},pypy{36,37,38,39} +envlist = py{38,39,310,311,312},pypy{38,39,310} skip_missing_interpreters = true [testenv] # tox @@ -39,7 +39,7 @@ setenv = [isort] -py_version = 37 +py_version = 38 multi_line_output = VERTICAL_HANGING_INDENT line_length = 80 reverse_relative = true @@ -152,7 +152,7 @@ def main(): url='https://github.com/yt-dlp/yt-dlp', packages=packages(), install_requires=REQUIREMENTS, - python_requires='>=3.7', + python_requires='>=3.8', project_urls={ 'Documentation': 'https://github.com/yt-dlp/yt-dlp#readme', 'Source': 'https://github.com/yt-dlp/yt-dlp', @@ -164,11 +164,11 @@ def main(): 'Development Status :: 5 - Production/Stable', 'Environment :: Console', 'Programming Language :: Python', - 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', 'Programming Language :: Python :: Implementation', 'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: PyPy', diff --git a/test/test_update.py b/test/test_update.py index 134424a31..2a5647e44 100644 --- a/test/test_update.py +++ b/test/test_update.py @@ -68,25 +68,34 @@ TEST_API_DATA = { }, } -TEST_LOCKFILE_V1 = '''# This file is used for regulating self-update -lock 2022.08.18.36 .+ Python 3.6 -lock 2023.11.13 .+ Python 3.7 +TEST_LOCKFILE_COMMENT = '# This file is used for regulating self-update' + +TEST_LOCKFILE_V1 = r'''%s +lock 2022.08.18.36 .+ Python 3\.6 +lock 2023.11.16 (?!win_x86_exe).+ Python 3\.7 +lock 2023.11.16 win_x86_exe .+ Windows-(?:Vista|2008Server) +''' % TEST_LOCKFILE_COMMENT + +TEST_LOCKFILE_V2_TMPL = r'''%s +lockV2 yt-dlp/yt-dlp 2022.08.18.36 .+ Python 3\.6 +lockV2 yt-dlp/yt-dlp 2023.11.16 (?!win_x86_exe).+ Python 3\.7 +lockV2 yt-dlp/yt-dlp 2023.11.16 win_x86_exe .+ Windows-(?:Vista|2008Server) +lockV2 yt-dlp/yt-dlp-nightly-builds 2023.11.15.232826 (?!win_x86_exe).+ Python 3\.7 +lockV2 yt-dlp/yt-dlp-nightly-builds 2023.11.15.232826 win_x86_exe .+ Windows-(?:Vista|2008Server) +lockV2 yt-dlp/yt-dlp-master-builds 2023.11.15.232812 (?!win_x86_exe).+ Python 3\.7 +lockV2 yt-dlp/yt-dlp-master-builds 2023.11.15.232812 win_x86_exe .+ Windows-(?:Vista|2008Server) ''' -TEST_LOCKFILE_V2 = '''# This file is used for regulating self-update -lockV2 yt-dlp/yt-dlp 2022.08.18.36 .+ Python 3.6 -lockV2 yt-dlp/yt-dlp 2023.11.13 .+ Python 3.7 -''' +TEST_LOCKFILE_V2 = TEST_LOCKFILE_V2_TMPL % TEST_LOCKFILE_COMMENT + +TEST_LOCKFILE_ACTUAL = TEST_LOCKFILE_V2_TMPL % TEST_LOCKFILE_V1.rstrip('\n') -TEST_LOCKFILE_V1_V2 = '''# This file is used for regulating self-update -lock 2022.08.18.36 .+ Python 3.6 -lock 2023.11.13 .+ Python 3.7 -lockV2 yt-dlp/yt-dlp 2022.08.18.36 .+ Python 3.6 -lockV2 yt-dlp/yt-dlp 2023.11.13 .+ Python 3.7 +TEST_LOCKFILE_FORK = r'''%s# Test if a fork blocks updates to non-numeric tags lockV2 fork/yt-dlp pr0000 .+ Python 3.6 -lockV2 fork/yt-dlp pr1234 .+ Python 3.7 +lockV2 fork/yt-dlp pr1234 (?!win_x86_exe).+ Python 3\.7 +lockV2 fork/yt-dlp pr1234 win_x86_exe .+ Windows-(?:Vista|2008Server) lockV2 fork/yt-dlp pr9999 .+ Python 3.11 -''' +''' % TEST_LOCKFILE_ACTUAL class FakeUpdater(Updater): @@ -97,7 +106,7 @@ class FakeUpdater(Updater): _origin = 'yt-dlp/yt-dlp' def _download_update_spec(self, *args, **kwargs): - return TEST_LOCKFILE_V1_V2 + return TEST_LOCKFILE_ACTUAL def _call_api(self, tag): tag = f'tags/{tag}' if tag != 'latest' else tag @@ -112,7 +121,7 @@ class TestUpdate(unittest.TestCase): def test_update_spec(self): ydl = FakeYDL() - updater = FakeUpdater(ydl, 'stable@latest') + updater = FakeUpdater(ydl, 'stable') def test(lockfile, identifier, input_tag, expect_tag, exact=False, repo='yt-dlp/yt-dlp'): updater._identifier = identifier @@ -124,35 +133,46 @@ class TestUpdate(unittest.TestCase): f'{identifier!r} requesting {repo}@{input_tag} (exact={exact}) ' f'returned {result!r} instead of {expect_tag!r}') - test(TEST_LOCKFILE_V1, 'zip Python 3.11.0', '2023.11.13', '2023.11.13') - test(TEST_LOCKFILE_V1, 'zip stable Python 3.11.0', '2023.11.13', '2023.11.13', exact=True) - test(TEST_LOCKFILE_V1, 'zip Python 3.6.0', '2023.11.13', '2022.08.18.36') - test(TEST_LOCKFILE_V1, 'zip stable Python 3.6.0', '2023.11.13', None, exact=True) - test(TEST_LOCKFILE_V1, 'zip Python 3.7.0', '2023.11.13', '2023.11.13') - test(TEST_LOCKFILE_V1, 'zip stable Python 3.7.1', '2023.11.13', '2023.11.13') - test(TEST_LOCKFILE_V1, 'zip Python 3.7.1', '2023.12.31', '2023.11.13') - test(TEST_LOCKFILE_V1, 'zip stable Python 3.7.1', '2023.12.31', '2023.11.13') - - test(TEST_LOCKFILE_V2, 'zip Python 3.11.1', '2023.11.13', '2023.11.13') - test(TEST_LOCKFILE_V2, 'zip stable Python 3.11.1', '2023.12.31', '2023.12.31') - test(TEST_LOCKFILE_V2, 'zip Python 3.6.1', '2023.11.13', '2022.08.18.36') - test(TEST_LOCKFILE_V2, 'zip stable Python 3.7.2', '2023.11.13', '2023.11.13') - test(TEST_LOCKFILE_V2, 'zip Python 3.7.2', '2023.12.31', '2023.11.13') - - test(TEST_LOCKFILE_V1_V2, 'zip Python 3.11.2', '2023.11.13', '2023.11.13') - test(TEST_LOCKFILE_V1_V2, 'zip stable Python 3.11.2', '2023.12.31', '2023.12.31') - test(TEST_LOCKFILE_V1_V2, 'zip Python 3.6.2', '2023.11.13', '2022.08.18.36') - test(TEST_LOCKFILE_V1_V2, 'zip stable Python 3.7.3', '2023.11.13', '2023.11.13') - test(TEST_LOCKFILE_V1_V2, 'zip Python 3.7.3', '2023.12.31', '2023.11.13') - test(TEST_LOCKFILE_V1_V2, 'zip Python 3.6.3', 'pr0000', None, repo='fork/yt-dlp') - test(TEST_LOCKFILE_V1_V2, 'zip stable Python 3.7.4', 'pr0000', 'pr0000', repo='fork/yt-dlp') - test(TEST_LOCKFILE_V1_V2, 'zip Python 3.6.4', 'pr0000', None, repo='fork/yt-dlp') - test(TEST_LOCKFILE_V1_V2, 'zip Python 3.7.4', 'pr1234', None, repo='fork/yt-dlp') - test(TEST_LOCKFILE_V1_V2, 'zip stable Python 3.8.1', 'pr1234', 'pr1234', repo='fork/yt-dlp') - test(TEST_LOCKFILE_V1_V2, 'zip Python 3.7.5', 'pr1234', None, repo='fork/yt-dlp') - test(TEST_LOCKFILE_V1_V2, 'zip Python 3.11.3', 'pr9999', None, repo='fork/yt-dlp') - test(TEST_LOCKFILE_V1_V2, 'zip stable Python 3.12.0', 'pr9999', 'pr9999', repo='fork/yt-dlp') - test(TEST_LOCKFILE_V1_V2, 'zip Python 3.11.4', 'pr9999', None, repo='fork/yt-dlp') + for lockfile in (TEST_LOCKFILE_V1, TEST_LOCKFILE_V2, TEST_LOCKFILE_ACTUAL, TEST_LOCKFILE_FORK): + # Normal operation + test(lockfile, 'zip Python 3.12.0', '2023.12.31', '2023.12.31') + test(lockfile, 'zip stable Python 3.12.0', '2023.12.31', '2023.12.31', exact=True) + # Python 3.6 --update should update only to its lock + test(lockfile, 'zip Python 3.6.0', '2023.11.16', '2022.08.18.36') + # --update-to an exact version later than the lock should return None + test(lockfile, 'zip stable Python 3.6.0', '2023.11.16', None, exact=True) + # Python 3.7 should be able to update to its lock + test(lockfile, 'zip Python 3.7.0', '2023.11.16', '2023.11.16') + test(lockfile, 'zip stable Python 3.7.1', '2023.11.16', '2023.11.16', exact=True) + # Non-win_x86_exe builds on py3.7 must be locked + test(lockfile, 'zip Python 3.7.1', '2023.12.31', '2023.11.16') + test(lockfile, 'zip stable Python 3.7.1', '2023.12.31', None, exact=True) + test( # Windows Vista w/ win_x86_exe must be locked + lockfile, 'win_x86_exe stable Python 3.7.9 (CPython x86 32bit) - Windows-Vista-6.0.6003-SP2', + '2023.12.31', '2023.11.16') + test( # Windows 2008Server w/ win_x86_exe must be locked + lockfile, 'win_x86_exe Python 3.7.9 (CPython x86 32bit) - Windows-2008Server', + '2023.12.31', None, exact=True) + test( # Windows 7 w/ win_x86_exe py3.7 build should be able to update beyond lock + lockfile, 'win_x86_exe stable Python 3.7.9 (CPython x86 32bit) - Windows-7-6.1.7601-SP1', + '2023.12.31', '2023.12.31') + test( # Windows 8.1 w/ '2008Server' in platform string should be able to update beyond lock + lockfile, 'win_x86_exe Python 3.7.9 (CPython x86 32bit) - Windows-post2008Server-6.2.9200', + '2023.12.31', '2023.12.31', exact=True) + + # Forks can block updates to non-numeric tags rather than lock + test(TEST_LOCKFILE_FORK, 'zip Python 3.6.3', 'pr0000', None, repo='fork/yt-dlp') + test(TEST_LOCKFILE_FORK, 'zip stable Python 3.7.4', 'pr0000', 'pr0000', repo='fork/yt-dlp') + test(TEST_LOCKFILE_FORK, 'zip stable Python 3.7.4', 'pr1234', None, repo='fork/yt-dlp') + test(TEST_LOCKFILE_FORK, 'zip Python 3.8.1', 'pr1234', 'pr1234', repo='fork/yt-dlp', exact=True) + test( + TEST_LOCKFILE_FORK, 'win_x86_exe stable Python 3.7.9 (CPython x86 32bit) - Windows-Vista-6.0.6003-SP2', + 'pr1234', None, repo='fork/yt-dlp') + test( + TEST_LOCKFILE_FORK, 'win_x86_exe stable Python 3.7.9 (CPython x86 32bit) - Windows-7-6.1.7601-SP1', + '2023.12.31', '2023.12.31', repo='fork/yt-dlp') + test(TEST_LOCKFILE_FORK, 'zip Python 3.11.2', 'pr9999', None, repo='fork/yt-dlp', exact=True) + test(TEST_LOCKFILE_FORK, 'zip stable Python 3.12.0', 'pr9999', 'pr9999', repo='fork/yt-dlp') def test_query_update(self): ydl = FakeYDL() diff --git a/yt_dlp/__init__.py b/yt_dlp/__init__.py index 991dbcda7..446f0c47b 100644 --- a/yt_dlp/__init__.py +++ b/yt_dlp/__init__.py @@ -1,8 +1,8 @@ -try: - import contextvars # noqa: F401 -except Exception: - raise Exception( - f'You are using an unsupported version of Python. Only Python versions 3.7 and above are supported by yt-dlp') # noqa: F541 +import sys + +if sys.version_info < (3, 8): + raise ImportError( + f'You are using an unsupported version of Python. Only Python versions 3.8 and above are supported by yt-dlp') # noqa: F541 __license__ = 'Public Domain' @@ -12,7 +12,6 @@ import itertools import optparse import os import re -import sys import traceback from .compat import compat_shlex_quote diff --git a/yt_dlp/compat/functools.py b/yt_dlp/compat/functools.py index ec003ea90..36c983642 100644 --- a/yt_dlp/compat/functools.py +++ b/yt_dlp/compat/functools.py @@ -10,17 +10,3 @@ try: cache # >= 3.9 except NameError: cache = lru_cache(maxsize=None) - -try: - cached_property # >= 3.8 -except NameError: - class cached_property: - def __init__(self, func): - update_wrapper(self, func) - self.func = func - - def __get__(self, instance, _): - if instance is None: - return self - setattr(instance, self.func.__name__, self.func(instance)) - return getattr(instance, self.func.__name__) diff --git a/yt_dlp/update.py b/yt_dlp/update.py index 85c9bb962..f99583b08 100644 --- a/yt_dlp/update.py +++ b/yt_dlp/update.py @@ -131,7 +131,7 @@ def _get_binary_name(): def _get_system_deprecation(): - MIN_SUPPORTED, MIN_RECOMMENDED = (3, 7), (3, 8) + MIN_SUPPORTED, MIN_RECOMMENDED = (3, 8), (3, 8) if sys.version_info > MIN_RECOMMENDED: return None @@ -140,16 +140,8 @@ def _get_system_deprecation(): if sys.version_info < MIN_SUPPORTED: msg = f'Python version {major}.{minor} is no longer supported' else: - msg = f'Support for Python version {major}.{minor} has been deprecated. ' - # Temporary until `win_x86_exe` uses 3.8, which will deprecate Vista and Server 2008 - if detect_variant() == 'win_x86_exe': - platform_name = platform.platform() - if any(platform_name.startswith(f'Windows-{name}') for name in ('Vista', '2008Server')): - msg = 'Support for Windows Vista/Server 2008 has been deprecated. ' - else: - return None - msg += ('See https://github.com/yt-dlp/yt-dlp/issues/7803 for details.' - '\nYou may stop receiving updates on this version at any time') + msg = (f'Support for Python version {major}.{minor} has been deprecated. ' + '\nYou may stop receiving updates on this version at any time') major, minor = MIN_RECOMMENDED return f'{msg}! Please update to Python {major}.{minor} or above' |