mirror of
https://github.com/ytdl-org/youtube-dl.git
synced 2024-12-20 23:52:07 +00:00
Compare commits
No commits in common. "f24bc9272e9b74efc4c4af87c862f5f78921d424" and "fa7f0effbe4e14fcf70e1dc4496371c9862b64b9" have entirely different histories.
f24bc9272e
...
fa7f0effbe
352
.github/workflows/ci.yml
vendored
352
.github/workflows/ci.yml
vendored
@ -1,376 +1,75 @@
|
|||||||
name: CI
|
name: CI
|
||||||
|
on: [push, pull_request]
|
||||||
env:
|
|
||||||
# add 3.10+ after patching nose (https://github.com/nose-devs/nose/issues/1099)
|
|
||||||
# or switching to fork of https://github.com/mdmintz/pynose
|
|
||||||
all-cpython-versions: 2.6, 2.7, 3.2, 3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9
|
|
||||||
main-cpython-versions: 2.7, 3.2, 3.5, 3.9
|
|
||||||
pypy-versions: pypy-2.7, pypy-3.6, pypy-3.7
|
|
||||||
cpython-versions: main
|
|
||||||
test-set: both
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
pull_request:
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
cpython-versions:
|
|
||||||
type: choice
|
|
||||||
description: CPython versions (main = 2.7, 3.2, 3.5, 3.9)
|
|
||||||
options:
|
|
||||||
- all
|
|
||||||
- main
|
|
||||||
required: true
|
|
||||||
default: main
|
|
||||||
test-set:
|
|
||||||
type: choice
|
|
||||||
description: core, download
|
|
||||||
options:
|
|
||||||
- both
|
|
||||||
- core
|
|
||||||
- download
|
|
||||||
required: true
|
|
||||||
default: core
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
select:
|
|
||||||
name: Select tests from inputs
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
cpython-versions: ${{ steps.run.outputs.cpython-versions }}
|
|
||||||
test-set: ${{ steps.run.outputs.test-set }}
|
|
||||||
own-pip-versions: ${{ steps.run.outputs.own-pip-versions }}
|
|
||||||
steps:
|
|
||||||
- id: run
|
|
||||||
run: |
|
|
||||||
# Make a JSON Array from comma/space-separated string (no extra escaping)
|
|
||||||
json_list() { \
|
|
||||||
ret=""; IFS="${IFS},"; set -- $*; \
|
|
||||||
for a in "$@"; do \
|
|
||||||
ret=$(printf '%s"%s"' "${ret}${ret:+, }" "$a"); \
|
|
||||||
done; \
|
|
||||||
printf '[%s]' "$ret"; }
|
|
||||||
tests="${{ inputs.test-set || env.test-set }}"
|
|
||||||
[ $tests = both ] && tests="core download"
|
|
||||||
printf 'test-set=%s\n' "$(json_list $tests)" >> "$GITHUB_OUTPUT"
|
|
||||||
versions="${{ inputs.cpython-versions || env.cpython-versions }}"
|
|
||||||
if [ "$versions" = all ]; then \
|
|
||||||
versions="${{ env.all-cpython-versions }}"; else \
|
|
||||||
versions="${{ env.main-cpython-versions }}"; \
|
|
||||||
fi
|
|
||||||
printf 'cpython-versions=%s\n' \
|
|
||||||
"$(json_list ${versions}${versions:+, }${{ env.pypy-versions }})" >> "$GITHUB_OUTPUT"
|
|
||||||
# versions with a special get-pip.py in a per-version subdirectory
|
|
||||||
printf 'own-pip-versions=%s\n' \
|
|
||||||
"$(json_list 2.6, 2.7, 3.2, 3.3, 3.4, 3.5, 3.6)" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
tests:
|
tests:
|
||||||
name: Run tests
|
name: Tests
|
||||||
needs: select
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
packages: write
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
env:
|
|
||||||
PIP: python -m pip
|
|
||||||
PIP_DISABLE_PIP_VERSION_CHECK: true
|
|
||||||
PIP_NO_PYTHON_VERSION_WARNING: true
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: true
|
fail-fast: true
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-20.04]
|
os: [ubuntu-20.04]
|
||||||
# outside steps, use github.env...., not env....
|
# TODO: python 2.6
|
||||||
python-version: ${{ fromJSON(needs.select.outputs.cpython-versions) }}
|
# TODO: restore support for 3.3, 3.4
|
||||||
|
python-version: [2.7, 3.5, 3.6, 3.7, 3.8, 3.9, pypy-2.7, pypy-3.6, pypy-3.7]
|
||||||
python-impl: [cpython]
|
python-impl: [cpython]
|
||||||
ytdl-test-set: ${{ fromJSON(needs.select.outputs.test-set) }}
|
ytdl-test-set: [core, download]
|
||||||
run-tests-ext: [sh]
|
run-tests-ext: [sh]
|
||||||
include:
|
include:
|
||||||
|
# python 3.2 is only available on windows via setup-python
|
||||||
- os: windows-2019
|
- os: windows-2019
|
||||||
python-version: 3.2
|
python-version: 3.2
|
||||||
python-impl: cpython
|
python-impl: cpython
|
||||||
ytdl-test-set: ${{ contains(needs.select.outputs.test-set, 'core') && 'core' || 'nocore' }}
|
ytdl-test-set: core
|
||||||
run-tests-ext: bat
|
run-tests-ext: bat
|
||||||
- os: windows-2019
|
- os: windows-2019
|
||||||
python-version: 3.2
|
python-version: 3.2
|
||||||
python-impl: cpython
|
python-impl: cpython
|
||||||
ytdl-test-set: ${{ contains(needs.select.outputs.test-set, 'download') && 'download' || 'nodownload' }}
|
ytdl-test-set: download
|
||||||
run-tests-ext: bat
|
run-tests-ext: bat
|
||||||
# jython
|
# jython
|
||||||
- os: ubuntu-20.04
|
- os: ubuntu-20.04
|
||||||
python-impl: jython
|
python-impl: jython
|
||||||
ytdl-test-set: ${{ contains(needs.select.outputs.test-set, 'core') && 'core' || 'nocore' }}
|
ytdl-test-set: core
|
||||||
run-tests-ext: sh
|
run-tests-ext: sh
|
||||||
- os: ubuntu-20.04
|
- os: ubuntu-20.04
|
||||||
python-impl: jython
|
python-impl: jython
|
||||||
ytdl-test-set: ${{ contains(needs.select.outputs.test-set, 'download') && 'download' || 'nodownload' }}
|
ytdl-test-set: download
|
||||||
run-tests-ext: sh
|
run-tests-ext: sh
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- uses: actions/checkout@v3
|
||||||
uses: actions/checkout@v3
|
|
||||||
#-------- Python 3 -----
|
|
||||||
- name: Set up supported Python ${{ matrix.python-version }}
|
- name: Set up supported Python ${{ matrix.python-version }}
|
||||||
id: setup-python
|
|
||||||
if: ${{ matrix.python-impl == 'cpython' && matrix.python-version != '2.6' && matrix.python-version != '2.7'}}
|
|
||||||
# wrap broken actions/setup-python@v4
|
# wrap broken actions/setup-python@v4
|
||||||
uses: ytdl-org/setup-python@v1
|
uses: ytdl-org/setup-python@v1
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
cache-build: true
|
cache-build: true
|
||||||
allow-build: info
|
allow-build: info
|
||||||
- name: Locate supported Python ${{ matrix.python-version }}
|
|
||||||
if: ${{ env.pythonLocation }}
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "PYTHONHOME=${pythonLocation}" >> "$GITHUB_ENV"
|
|
||||||
export expected="${{ steps.setup-python.outputs.python-path }}"
|
|
||||||
dirname() { printf '%s\n' \
|
|
||||||
'import os, sys' \
|
|
||||||
'print(os.path.dirname(sys.argv[1]))' \
|
|
||||||
| ${expected} - "$1"; }
|
|
||||||
expd="$(dirname "$expected")"
|
|
||||||
export python="$(command -v python)"
|
|
||||||
[ "$expd" = "$(dirname "$python")" ] || echo "PATH=$expd:${PATH}" >> "$GITHUB_ENV"
|
|
||||||
[ -x "$python" ] || printf '%s\n' \
|
|
||||||
'import os' \
|
|
||||||
'exp = os.environ["expected"]' \
|
|
||||||
'python = os.environ["python"]' \
|
|
||||||
'exps = os.path.split(exp)' \
|
|
||||||
'if python and (os.path.dirname(python) == exp[0]):' \
|
|
||||||
' exit(0)' \
|
|
||||||
'exps[1] = "python" + os.path.splitext(exps[1])[1]' \
|
|
||||||
'python = os.path.join(*exps)' \
|
|
||||||
'try:' \
|
|
||||||
' os.symlink(exp, python)' \
|
|
||||||
'except AttributeError:' \
|
|
||||||
' os.rename(exp, python)' \
|
|
||||||
| ${expected} -
|
|
||||||
printf '%s\n' \
|
|
||||||
'import sys' \
|
|
||||||
'print(sys.path)' \
|
|
||||||
| ${expected} -
|
|
||||||
#-------- Python 2.7 --
|
|
||||||
- name: Set up Python 2.7
|
|
||||||
if: ${{ matrix.python-version == '2.7' }}
|
|
||||||
# install 2.7
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
sudo apt-get install -y python2 python-is-python2
|
|
||||||
echo "PYTHONHOME=/usr" >> "$GITHUB_ENV"
|
|
||||||
#-------- Python 2.6 --
|
|
||||||
- name: Set up Python 2.6 environment
|
|
||||||
if: ${{ matrix.python-version == '2.6' }}
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
openssl_name=openssl-1.0.2u
|
|
||||||
echo "openssl_name=${openssl_name}" >> "$GITHUB_ENV"
|
|
||||||
openssl_dir=$HOME/.local/opt/$openssl_name
|
|
||||||
echo "openssl_dir=${openssl_dir}" >> "$GITHUB_ENV"
|
|
||||||
PYENV_ROOT=$HOME/.local/share/pyenv
|
|
||||||
echo "PYENV_ROOT=${PYENV_ROOT}" >> "$GITHUB_ENV"
|
|
||||||
sudo apt-get install -y openssl ca-certificates
|
|
||||||
- name: Cache Python 2.6
|
|
||||||
id: cache26
|
|
||||||
if: ${{ matrix.python-version == '2.6' }}
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
key: python-2.6.9
|
|
||||||
path: |
|
|
||||||
${{ env.openssl_dir }}
|
|
||||||
${{ env.PYENV_ROOT }}
|
|
||||||
- name: Build and set up Python 2.6
|
|
||||||
if: ${{ matrix.python-version == '2.6' && ! steps.cache26.outputs.cache-hit }}
|
|
||||||
# dl and build locally
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
# Install build environment
|
|
||||||
sudo apt-get install -y build-essential llvm libssl-dev tk-dev \
|
|
||||||
libncursesw5-dev libreadline-dev libsqlite3-dev \
|
|
||||||
libffi-dev xz-utils zlib1g-dev libbz2-dev liblzma-dev
|
|
||||||
# Download and install OpenSSL 1.0.2, back in time
|
|
||||||
openssl_name=${{ env.openssl_name }}
|
|
||||||
openssl_targz=${openssl_name}.tar.gz
|
|
||||||
openssl_dir=${{ env.openssl_dir }}
|
|
||||||
openssl_inc=$openssl_dir/include
|
|
||||||
openssl_lib=$openssl_dir/lib
|
|
||||||
openssl_ssl=$openssl_dir/ssl
|
|
||||||
curl -L "https://www.openssl.org/source/$openssl_targz" -o $openssl_targz
|
|
||||||
tar -xf $openssl_targz
|
|
||||||
( cd $openssl_name; \
|
|
||||||
./config --prefix=$openssl_dir --openssldir=${openssl_dir}/ssl \
|
|
||||||
--libdir=lib -Wl,-rpath=${openssl_dir}/lib shared zlib-dynamic && \
|
|
||||||
make && \
|
|
||||||
make install )
|
|
||||||
rm -rf $openssl_name
|
|
||||||
rmdir $openssl_ssl/certs && ln -s /etc/ssl/certs $openssl_ssl/certs
|
|
||||||
|
|
||||||
# Download PyEnv from its GitHub repository.
|
|
||||||
export PYENV_ROOT=${{ env.PYENV_ROOT }}
|
|
||||||
export PATH=$PYENV_ROOT/bin:$PATH
|
|
||||||
git clone "https://github.com/pyenv/pyenv.git" "$PYENV_ROOT"
|
|
||||||
|
|
||||||
# Prevent pyenv build trying (and failing) to update pip
|
|
||||||
export GET_PIP=get-pip-2.6.py
|
|
||||||
echo 'import sys; sys.exit(0)' > ${GET_PIP}
|
|
||||||
GET_PIP=$(realpath $GET_PIP)
|
|
||||||
|
|
||||||
# Build and install Python
|
|
||||||
export CFLAGS="-I$openssl_inc"
|
|
||||||
export LDFLAGS="-L$openssl_lib"
|
|
||||||
export LD_LIBRARY_PATH="$openssl_lib"
|
|
||||||
pyenv install 2.6.9
|
|
||||||
- name: Locate Python 2.6
|
|
||||||
if: ${{ matrix.python-version == '2.6' }}
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
PYTHONHOME="${{ env.PYENV_ROOT }}/versions/2.6.9"
|
|
||||||
echo "PYTHONHOME=$PYTHONHOME" >> "$GITHUB_ENV"
|
|
||||||
echo "PATH=${PYTHONHOME}/bin:$PATH" >> "$GITHUB_ENV"
|
|
||||||
echo "LD_LIBRARY_PATH=${{ env.openssl_dir }}/lib${LD_LIBRARY_PATH:+:}${LD_LIBRARY_PATH}" >> "$GITHUB_ENV"
|
|
||||||
#-------- Jython ------
|
|
||||||
- name: Set up Java 8
|
- name: Set up Java 8
|
||||||
if: ${{ matrix.python-impl == 'jython' }}
|
if: ${{ matrix.python-impl == 'jython' }}
|
||||||
uses: actions/setup-java@v2
|
uses: actions/setup-java@v2
|
||||||
with:
|
with:
|
||||||
java-version: 8
|
java-version: 8
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
- name: Setup Jython environment
|
|
||||||
if: ${{ matrix.python-impl == 'jython' }}
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "JYTHON_ROOT=${HOME}/jython" >> "$GITHUB_ENV"
|
|
||||||
echo "PIP=pip" >> "$GITHUB_ENV"
|
|
||||||
- name: Cache Jython
|
|
||||||
id: cachejy
|
|
||||||
if: ${{ matrix.python-impl == 'jython' }}
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
# 2.7.3 now available, may solve SNI issue
|
|
||||||
key: jython-2.7.1
|
|
||||||
path: |
|
|
||||||
${{ env.JYTHON_ROOT }}
|
|
||||||
- name: Install Jython
|
- name: Install Jython
|
||||||
if: ${{ matrix.python-impl == 'jython' && ! steps.cachejy.outputs.cache-hit }}
|
if: ${{ matrix.python-impl == 'jython' }}
|
||||||
shell: bash
|
|
||||||
run: |
|
run: |
|
||||||
JYTHON_ROOT="${{ env.JYTHON_ROOT }}"
|
wget https://repo1.maven.org/maven2/org/python/jython-installer/2.7.1/jython-installer-2.7.1.jar -O jython-installer.jar
|
||||||
curl -L "https://repo1.maven.org/maven2/org/python/jython-installer/2.7.1/jython-installer-2.7.1.jar" -o jython-installer.jar
|
java -jar jython-installer.jar -s -d "$HOME/jython"
|
||||||
java -jar jython-installer.jar -s -d "${JYTHON_ROOT}"
|
echo "$HOME/jython/bin" >> $GITHUB_PATH
|
||||||
echo "${JYTHON_ROOT}/bin" >> "$GITHUB_PATH"
|
- name: Install nose
|
||||||
- name: Set up cached Jython
|
if: ${{ matrix.python-impl != 'jython' }}
|
||||||
if: ${{ steps.cachejy.outputs.cache-hit }}
|
run: pip install nose
|
||||||
shell: bash
|
- name: Install nose (Jython)
|
||||||
|
if: ${{ matrix.python-impl == 'jython' }}
|
||||||
|
# Working around deprecation of support for non-SNI clients at PyPI CDN (see https://status.python.org/incidents/hzmjhqsdjqgb)
|
||||||
run: |
|
run: |
|
||||||
JYTHON_ROOT="${{ env.JYTHON_ROOT }}"
|
wget https://files.pythonhosted.org/packages/99/4f/13fb671119e65c4dce97c60e67d3fd9e6f7f809f2b307e2611f4701205cb/nose-1.3.7-py2-none-any.whl
|
||||||
echo "${JYTHON_ROOT}/bin" >> $GITHUB_PATH
|
pip install nose-1.3.7-py2-none-any.whl
|
||||||
#-------- pip ---------
|
|
||||||
- name: Set up supported Python ${{ matrix.python-version }} pip
|
|
||||||
if: ${{ (matrix.python-version != '3.2' && steps.setup-python.outputs.python-path) || matrix.python-version == '2.7' }}
|
|
||||||
# This step may run in either Linux or Windows
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "$PATH"
|
|
||||||
echo "$PYTHONHOME"
|
|
||||||
# curl is available on both Windows and Linux, -L follows redirects, -O gets name
|
|
||||||
python -m ensurepip || python -m pip --version || { \
|
|
||||||
get_pip="${{ contains(needs.select.outputs.own-pip-versions, matrix.python-version) && format('{0}/', matrix.python-version) || '' }}"; \
|
|
||||||
curl -L -O "https://bootstrap.pypa.io/pip/${get_pip}get-pip.py"; \
|
|
||||||
python get-pip.py; }
|
|
||||||
- name: Set up Python 2.6 pip
|
|
||||||
if: ${{ matrix.python-version == '2.6' }}
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
python -m pip --version || { \
|
|
||||||
curl -L -O "https://bootstrap.pypa.io/pip/2.6/get-pip.py"; \
|
|
||||||
curl -L -O "https://files.pythonhosted.org/packages/ac/95/a05b56bb975efa78d3557efa36acaf9cf5d2fd0ee0062060493687432e03/pip-9.0.3-py2.py3-none-any.whl"; \
|
|
||||||
python get-pip.py --no-setuptools --no-wheel pip-9.0.3-py2.py3-none-any.whl; }
|
|
||||||
# work-around to invoke pip module on 2.6: https://bugs.python.org/issue2751
|
|
||||||
echo "PIP=python -m pip.__main__" >> "$GITHUB_ENV"
|
|
||||||
- name: Set up other Python ${{ matrix.python-version }} pip
|
|
||||||
if: ${{ matrix.python-version == '3.2' && steps.setup-python.outputs.python-path }}
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
python -m pip --version || { \
|
|
||||||
curl -L -O "https://bootstrap.pypa.io/pip/3.2/get-pip.py"; \
|
|
||||||
curl -L -O "https://files.pythonhosted.org/packages/b2/d0/cd115fe345dd6f07ec1c780020a7dfe74966fceeb171e0f20d1d4905b0b7/pip-7.1.2-py2.py3-none-any.whl"; \
|
|
||||||
python get-pip.py --no-setuptools --no-wheel pip-7.1.2-py2.py3-none-any.whl; }
|
|
||||||
#-------- unittest ----
|
|
||||||
- name: Upgrade Unittest for Python 2.6
|
|
||||||
if: ${{ matrix.python-version == '2.6' }}
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
# see pip for Jython
|
|
||||||
$PIP -qq show unittest2 || { \
|
|
||||||
for u in "65/26/32b8464df2a97e6dd1b656ed26b2c194606c16fe163c695a992b36c11cdf/six-1.13.0-py2.py3-none-any.whl" \
|
|
||||||
"f2/94/3af39d34be01a24a6e65433d19e107099374224905f1e0cc6bbe1fd22a2f/argparse-1.4.0-py2.py3-none-any.whl" \
|
|
||||||
"c7/a3/c5da2a44c85bfbb6eebcfc1dde24933f8704441b98fdde6528f4831757a6/linecache2-1.0.0-py2.py3-none-any.whl" \
|
|
||||||
"17/0a/6ac05a3723017a967193456a2efa0aa9ac4b51456891af1e2353bb9de21e/traceback2-1.4.0-py2.py3-none-any.whl" \
|
|
||||||
"72/20/7f0f433060a962200b7272b8c12ba90ef5b903e218174301d0abfd523813/unittest2-1.1.0-py2.py3-none-any.whl"; do \
|
|
||||||
curl -L -O "https://files.pythonhosted.org/packages/${u}"; \
|
|
||||||
$PIP install ${u##*/}; \
|
|
||||||
done; }
|
|
||||||
# make tests use unittest2
|
|
||||||
for test in ./test/test_*.py; do
|
|
||||||
sed -r -i -e '/^import unittest$/s/test/test2 as unittest/' "$test"
|
|
||||||
done
|
|
||||||
#-------- nose --------
|
|
||||||
- name: Install nose for Python ${{ matrix.python-version }}
|
|
||||||
if: ${{ (matrix.python-version != '3.2' && steps.setup-python.outputs.python-path) || matrix.python-version == '2.7' }}
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "$PATH"
|
|
||||||
echo "$PYTHONHOME"
|
|
||||||
$PIP -qq show nose || $PIP install nose
|
|
||||||
- name: Install nose for other Python 2
|
|
||||||
if: ${{ matrix.python-impl == 'jython' || matrix.python-version == '2.6' }}
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
# Work around deprecation of support for non-SNI clients at PyPI CDN (see https://status.python.org/incidents/hzmjhqsdjqgb)
|
|
||||||
$PIP -qq show nose || { \
|
|
||||||
curl -L -O "https://files.pythonhosted.org/packages/99/4f/13fb671119e65c4dce97c60e67d3fd9e6f7f809f2b307e2611f4701205cb/nose-1.3.7-py2-none-any.whl"; \
|
|
||||||
$PIP install nose-1.3.7-py2-none-any.whl; }
|
|
||||||
- name: Install nose for other Python 3
|
|
||||||
if: ${{ matrix.python-version == '3.2' && steps.setup-python.outputs.python-path }}
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
$PIP -qq show nose || { \
|
|
||||||
curl -L -O "https://files.pythonhosted.org/packages/15/d8/dd071918c040f50fa1cf80da16423af51ff8ce4a0f2399b7bf8de45ac3d9/nose-1.3.7-py3-none-any.whl"; \
|
|
||||||
$PIP install nose-1.3.7-py3-none-any.whl; }
|
|
||||||
- name: Set up nosetest test
|
|
||||||
if: ${{ contains(needs.select.outputs.test-set, matrix.ytdl-test-set ) }}
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
# define a test to validate the Python version used by nosetests
|
|
||||||
printf '%s\n' \
|
|
||||||
'from __future__ import unicode_literals' \
|
|
||||||
'import sys, os, platform' \
|
|
||||||
'try:' \
|
|
||||||
' import unittest2 as unittest' \
|
|
||||||
'except ImportError:' \
|
|
||||||
' import unittest' \
|
|
||||||
'class TestPython(unittest.TestCase):' \
|
|
||||||
' def setUp(self):' \
|
|
||||||
' self.ver = os.environ["PYTHON_VER"].split("-")' \
|
|
||||||
' def test_python_ver(self):' \
|
|
||||||
' self.assertEqual(sys.version[:3], self.ver[-1])' \
|
|
||||||
' self.assertTrue(sys.version.startswith(self.ver[-1]))' \
|
|
||||||
' self.assertIn(self.ver[0], sys.version.lower())' \
|
|
||||||
' def test_python_impl(self):' \
|
|
||||||
' self.assertIn(platform.python_implementation().lower(), (os.environ["PYTHON_IMPL"], self.ver[0]))' \
|
|
||||||
> test/test_python.py
|
|
||||||
#-------- TESTS -------
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
if: ${{ contains(needs.select.outputs.test-set, matrix.ytdl-test-set ) }}
|
|
||||||
continue-on-error: ${{ matrix.ytdl-test-set == 'download' || matrix.python-impl == 'jython' }}
|
continue-on-error: ${{ matrix.ytdl-test-set == 'download' || matrix.python-impl == 'jython' }}
|
||||||
env:
|
env:
|
||||||
YTDL_TEST_SET: ${{ matrix.ytdl-test-set }}
|
YTDL_TEST_SET: ${{ matrix.ytdl-test-set }}
|
||||||
PYTHON_VER: ${{ matrix.python-version }}
|
run: ./devscripts/run_tests.${{ matrix.run-tests-ext }}
|
||||||
PYTHON_IMPL: ${{ matrix.python-impl }}
|
|
||||||
run: |
|
|
||||||
./devscripts/run_tests.${{ matrix.run-tests-ext }}
|
|
||||||
|
|
||||||
flake8:
|
flake8:
|
||||||
name: Linter
|
name: Linter
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@ -384,4 +83,3 @@ jobs:
|
|||||||
run: pip install flake8
|
run: pip install flake8
|
||||||
- name: Run flake8
|
- name: Run flake8
|
||||||
run: flake8 .
|
run: flake8 .
|
||||||
|
|
||||||
|
@ -19,10 +19,6 @@ try:
|
|||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
from youtube_dl.compat import compat_register_utf8
|
|
||||||
|
|
||||||
compat_register_utf8()
|
|
||||||
|
|
||||||
from youtube_dl.extractor import _ALL_CLASSES
|
from youtube_dl.extractor import _ALL_CLASSES
|
||||||
from youtube_dl.extractor.common import InfoExtractor, SearchInfoExtractor
|
from youtube_dl.extractor.common import InfoExtractor, SearchInfoExtractor
|
||||||
|
|
||||||
|
@ -10,13 +10,11 @@ import os
|
|||||||
import subprocess
|
import subprocess
|
||||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||||
|
|
||||||
from youtube_dl.compat import compat_register_utf8
|
|
||||||
from youtube_dl.utils import encodeArgument
|
from youtube_dl.utils import encodeArgument
|
||||||
|
|
||||||
compat_register_utf8()
|
|
||||||
|
|
||||||
rootDir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
rootDir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
_DEV_NULL = subprocess.DEVNULL
|
_DEV_NULL = subprocess.DEVNULL
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
@ -27,27 +25,25 @@ class TestExecution(unittest.TestCase):
|
|||||||
def test_import(self):
|
def test_import(self):
|
||||||
subprocess.check_call([sys.executable, '-c', 'import youtube_dl'], cwd=rootDir)
|
subprocess.check_call([sys.executable, '-c', 'import youtube_dl'], cwd=rootDir)
|
||||||
|
|
||||||
@unittest.skipIf(sys.version_info < (2, 7), 'Python 2.6 doesn\'t support package execution')
|
|
||||||
def test_module_exec(self):
|
def test_module_exec(self):
|
||||||
subprocess.check_call([sys.executable, '-m', 'youtube_dl', '--version'], cwd=rootDir, stdout=_DEV_NULL)
|
if sys.version_info >= (2, 7): # Python 2.6 doesn't support package execution
|
||||||
|
subprocess.check_call([sys.executable, '-m', 'youtube_dl', '--version'], cwd=rootDir, stdout=_DEV_NULL)
|
||||||
|
|
||||||
def test_main_exec(self):
|
def test_main_exec(self):
|
||||||
subprocess.check_call([sys.executable, os.path.normpath('youtube_dl/__main__.py'), '--version'], cwd=rootDir, stdout=_DEV_NULL)
|
subprocess.check_call([sys.executable, 'youtube_dl/__main__.py', '--version'], cwd=rootDir, stdout=_DEV_NULL)
|
||||||
|
|
||||||
@unittest.skipIf(sys.version_info < (2, 7), 'Python 2.6 doesn\'t support package execution')
|
|
||||||
def test_cmdline_umlauts(self):
|
def test_cmdline_umlauts(self):
|
||||||
os.environ['PYTHONIOENCODING'] = 'utf-8'
|
|
||||||
p = subprocess.Popen(
|
p = subprocess.Popen(
|
||||||
[sys.executable, os.path.normpath('youtube_dl/__main__.py'), encodeArgument('ä'), '--version'],
|
[sys.executable, 'youtube_dl/__main__.py', encodeArgument('ä'), '--version'],
|
||||||
cwd=rootDir, stdout=_DEV_NULL, stderr=subprocess.PIPE)
|
cwd=rootDir, stdout=_DEV_NULL, stderr=subprocess.PIPE)
|
||||||
_, stderr = p.communicate()
|
_, stderr = p.communicate()
|
||||||
self.assertFalse(stderr)
|
self.assertFalse(stderr)
|
||||||
|
|
||||||
def test_lazy_extractors(self):
|
def test_lazy_extractors(self):
|
||||||
lazy_extractors = os.path.normpath('youtube_dl/extractor/lazy_extractors.py')
|
lazy_extractors = 'youtube_dl/extractor/lazy_extractors.py'
|
||||||
try:
|
try:
|
||||||
subprocess.check_call([sys.executable, os.path.normpath('devscripts/make_lazy_extractors.py'), lazy_extractors], cwd=rootDir, stdout=_DEV_NULL)
|
subprocess.check_call([sys.executable, 'devscripts/make_lazy_extractors.py', lazy_extractors], cwd=rootDir, stdout=_DEV_NULL)
|
||||||
subprocess.check_call([sys.executable, os.path.normpath('test/test_all_urls.py')], cwd=rootDir, stdout=_DEV_NULL)
|
subprocess.check_call([sys.executable, 'test/test_all_urls.py'], cwd=rootDir, stdout=_DEV_NULL)
|
||||||
finally:
|
finally:
|
||||||
for x in ['', 'c'] if sys.version_info[0] < 3 else ['']:
|
for x in ['', 'c'] if sys.version_info[0] < 3 else ['']:
|
||||||
try:
|
try:
|
||||||
|
@ -492,12 +492,10 @@ class TestJSInterpreter(unittest.TestCase):
|
|||||||
jsi = JSInterpreter('''
|
jsi = JSInterpreter('''
|
||||||
function x() { let a=/,,[/,913,/](,)}/; "".replace(a, ""); return a; }
|
function x() { let a=/,,[/,913,/](,)}/; "".replace(a, ""); return a; }
|
||||||
''')
|
''')
|
||||||
attrs = set(('findall', 'finditer', 'match', 'scanner', 'search',
|
attrs = set(('findall', 'finditer', 'flags', 'groupindex',
|
||||||
'split', 'sub', 'subn'))
|
'groups', 'match', 'pattern', 'scanner',
|
||||||
if sys.version_info >= (2, 7):
|
'search', 'split', 'sub', 'subn'))
|
||||||
# documented for 2.6 but may not be found
|
self.assertTrue(set(dir(jsi.call_function('x'))) > attrs)
|
||||||
attrs.update(('flags', 'groupindex', 'groups', 'pattern'))
|
|
||||||
self.assertSetEqual(set(dir(jsi.call_function('x'))) & attrs, attrs)
|
|
||||||
|
|
||||||
jsi = JSInterpreter('''
|
jsi = JSInterpreter('''
|
||||||
function x() { let a=/,,[/,913,/](,)}/i; return a; }
|
function x() { let a=/,,[/,913,/](,)}/i; return a; }
|
||||||
|
@ -15,7 +15,6 @@ IGNORED_FILES = [
|
|||||||
'setup.py', # http://bugs.python.org/issue13943
|
'setup.py', # http://bugs.python.org/issue13943
|
||||||
'conf.py',
|
'conf.py',
|
||||||
'buildserver.py',
|
'buildserver.py',
|
||||||
'get-pip.py',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
IGNORED_DIRS = [
|
IGNORED_DIRS = [
|
||||||
|
@ -1612,7 +1612,7 @@ Line 1
|
|||||||
self.assertEqual(traverse_obj(_TEST_DATA, lambda x, y: x == 'urls' and isinstance(y, list)),
|
self.assertEqual(traverse_obj(_TEST_DATA, lambda x, y: x == 'urls' and isinstance(y, list)),
|
||||||
[_TEST_DATA['urls']],
|
[_TEST_DATA['urls']],
|
||||||
msg='function as query key should perform a filter based on (key, value)')
|
msg='function as query key should perform a filter based on (key, value)')
|
||||||
self.assertCountEqual(traverse_obj(_TEST_DATA, lambda _, x: isinstance(x[0], compat_str)), ('str',),
|
self.assertCountEqual(traverse_obj(_TEST_DATA, lambda _, x: isinstance(x[0], compat_str)), {'str'},
|
||||||
msg='exceptions in the query function should be caught')
|
msg='exceptions in the query function should be caught')
|
||||||
|
|
||||||
# Test alternative paths
|
# Test alternative paths
|
||||||
|
@ -25,11 +25,7 @@ import tokenize
|
|||||||
import traceback
|
import traceback
|
||||||
import random
|
import random
|
||||||
|
|
||||||
try:
|
from ssl import OPENSSL_VERSION
|
||||||
from ssl import OPENSSL_VERSION
|
|
||||||
except ImportError:
|
|
||||||
# Must be Python 2.6, should be built against 1.0.2
|
|
||||||
OPENSSL_VERSION = 'OpenSSL 1.0.2(?)'
|
|
||||||
from string import ascii_letters
|
from string import ascii_letters
|
||||||
|
|
||||||
from .compat import (
|
from .compat import (
|
||||||
|
@ -5,6 +5,7 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
__license__ = 'Public Domain'
|
__license__ = 'Public Domain'
|
||||||
|
|
||||||
|
import codecs
|
||||||
import io
|
import io
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
@ -16,7 +17,6 @@ from .options import (
|
|||||||
)
|
)
|
||||||
from .compat import (
|
from .compat import (
|
||||||
compat_getpass,
|
compat_getpass,
|
||||||
compat_register_utf8,
|
|
||||||
compat_shlex_split,
|
compat_shlex_split,
|
||||||
workaround_optparse_bug9161,
|
workaround_optparse_bug9161,
|
||||||
)
|
)
|
||||||
@ -46,8 +46,10 @@ from .YoutubeDL import YoutubeDL
|
|||||||
|
|
||||||
|
|
||||||
def _real_main(argv=None):
|
def _real_main(argv=None):
|
||||||
# Compatibility fix for Windows
|
# Compatibility fixes for Windows
|
||||||
compat_register_utf8()
|
if sys.platform == 'win32':
|
||||||
|
# https://github.com/ytdl-org/youtube-dl/issues/820
|
||||||
|
codecs.register(lambda name: codecs.lookup('utf-8') if name == 'cp65001' else None)
|
||||||
|
|
||||||
workaround_optparse_bug9161()
|
workaround_optparse_bug9161()
|
||||||
|
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from __future__ import division
|
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
import binascii
|
import binascii
|
||||||
import collections
|
import collections
|
||||||
import ctypes
|
import ctypes
|
||||||
import datetime
|
|
||||||
import email
|
import email
|
||||||
import getpass
|
import getpass
|
||||||
import io
|
import io
|
||||||
@ -33,17 +31,13 @@ try:
|
|||||||
compat_str, compat_basestring, compat_chr = (
|
compat_str, compat_basestring, compat_chr = (
|
||||||
unicode, basestring, unichr
|
unicode, basestring, unichr
|
||||||
)
|
)
|
||||||
|
from .casefold import casefold as compat_casefold
|
||||||
|
|
||||||
except NameError:
|
except NameError:
|
||||||
compat_str, compat_basestring, compat_chr = (
|
compat_str, compat_basestring, compat_chr = (
|
||||||
str, str, chr
|
str, str, chr
|
||||||
)
|
)
|
||||||
|
|
||||||
# casefold
|
|
||||||
try:
|
|
||||||
compat_str.casefold
|
|
||||||
compat_casefold = lambda s: s.casefold()
|
compat_casefold = lambda s: s.casefold()
|
||||||
except AttributeError:
|
|
||||||
from .casefold import casefold as compat_casefold
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import collections.abc as compat_collections_abc
|
import collections.abc as compat_collections_abc
|
||||||
@ -3143,24 +3137,6 @@ else:
|
|||||||
compat_open = open
|
compat_open = open
|
||||||
|
|
||||||
|
|
||||||
# compat_register_utf8
|
|
||||||
def compat_register_utf8():
|
|
||||||
if sys.platform == 'win32':
|
|
||||||
# https://github.com/ytdl-org/youtube-dl/issues/820
|
|
||||||
from codecs import register, lookup
|
|
||||||
register(
|
|
||||||
lambda name: lookup('utf-8') if name == 'cp65001' else None)
|
|
||||||
|
|
||||||
|
|
||||||
# compat_datetime_timedelta_total_seconds
|
|
||||||
try:
|
|
||||||
compat_datetime_timedelta_total_seconds = datetime.timedelta.total_seconds
|
|
||||||
except AttributeError:
|
|
||||||
# Py 2.6
|
|
||||||
def compat_datetime_timedelta_total_seconds(td):
|
|
||||||
return (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6
|
|
||||||
|
|
||||||
|
|
||||||
legacy = [
|
legacy = [
|
||||||
'compat_HTMLParseError',
|
'compat_HTMLParseError',
|
||||||
'compat_HTMLParser',
|
'compat_HTMLParser',
|
||||||
@ -3198,7 +3174,6 @@ __all__ = [
|
|||||||
'compat_chr',
|
'compat_chr',
|
||||||
'compat_collections_abc',
|
'compat_collections_abc',
|
||||||
'compat_collections_chain_map',
|
'compat_collections_chain_map',
|
||||||
'compat_datetime_timedelta_total_seconds',
|
|
||||||
'compat_http_cookiejar',
|
'compat_http_cookiejar',
|
||||||
'compat_http_cookiejar_Cookie',
|
'compat_http_cookiejar_Cookie',
|
||||||
'compat_http_cookies',
|
'compat_http_cookies',
|
||||||
@ -3228,7 +3203,6 @@ __all__ = [
|
|||||||
'compat_print',
|
'compat_print',
|
||||||
'compat_re_Match',
|
'compat_re_Match',
|
||||||
'compat_re_Pattern',
|
'compat_re_Pattern',
|
||||||
'compat_register_utf8',
|
|
||||||
'compat_setenv',
|
'compat_setenv',
|
||||||
'compat_shlex_quote',
|
'compat_shlex_quote',
|
||||||
'compat_shlex_split',
|
'compat_shlex_split',
|
||||||
|
@ -277,20 +277,9 @@ class JSInterpreter(object):
|
|||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
self.__instantiate()
|
self.__instantiate()
|
||||||
# make Py 2.6 conform to its lying documentation
|
|
||||||
if name == 'flags':
|
|
||||||
self.flags = self.__flags
|
|
||||||
elif name == 'pattern':
|
|
||||||
self.pattern = self.__pattern_txt
|
|
||||||
elif name in ('groupindex', 'groups'):
|
|
||||||
# in case these get set after a match?
|
|
||||||
if hasattr(self.__self, name):
|
|
||||||
setattr(self, name, getattr(self.__self, name))
|
|
||||||
else:
|
|
||||||
return 0 if name == 'groupindex' else {}
|
|
||||||
if hasattr(self, name):
|
if hasattr(self, name):
|
||||||
return getattr(self, name)
|
return getattr(self, name)
|
||||||
raise AttributeError('{0} has no attribute named {1}'.format(self, name))
|
return super(JSInterpreter.JS_RegExp, self).__getattr__(name)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def regex_flags(cls, expr):
|
def regex_flags(cls, expr):
|
||||||
|
@ -47,7 +47,6 @@ from .compat import (
|
|||||||
compat_collections_abc,
|
compat_collections_abc,
|
||||||
compat_cookiejar,
|
compat_cookiejar,
|
||||||
compat_ctypes_WINFUNCTYPE,
|
compat_ctypes_WINFUNCTYPE,
|
||||||
compat_datetime_timedelta_total_seconds,
|
|
||||||
compat_etree_fromstring,
|
compat_etree_fromstring,
|
||||||
compat_expanduser,
|
compat_expanduser,
|
||||||
compat_html_entities,
|
compat_html_entities,
|
||||||
@ -3103,7 +3102,7 @@ def unified_timestamp(date_str, day_first=True):
|
|||||||
pass
|
pass
|
||||||
timetuple = email.utils.parsedate_tz(date_str)
|
timetuple = email.utils.parsedate_tz(date_str)
|
||||||
if timetuple:
|
if timetuple:
|
||||||
return calendar.timegm(timetuple) + pm_delta * 3600 - compat_datetime_timedelta_total_seconds(timezone)
|
return calendar.timegm(timetuple) + pm_delta * 3600 - timezone.total_seconds()
|
||||||
|
|
||||||
|
|
||||||
def determine_ext(url, default_ext='unknown_video'):
|
def determine_ext(url, default_ext='unknown_video'):
|
||||||
|
Loading…
Reference in New Issue
Block a user