From 1f736c5e778f48c91adbd68b45f15d6400e21b4d Mon Sep 17 00:00:00 2001 From: Xavier Fernandez Date: Fri, 26 Jul 2019 00:30:44 +0200 Subject: [PATCH 01/14] Spread the Windows test load between Azure & Appveyor --- .appveyor.yml | 9 ++++----- .azure-pipelines/jobs/test-windows.yml | 17 ++++------------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 2819e0521..9bd0f595c 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,15 +1,14 @@ environment: matrix: # Unit and integration tests. - - PYTHON: "C:\\Python27" + - PYTHON: "C:\\Python27-x64" RUN_INTEGRATION_TESTS: "True" - PYTHON: "C:\\Python36-x64" RUN_INTEGRATION_TESTS: "True" + - PYTHON: "C:\\Python37-x64" + RUN_INTEGRATION_TESTS: "True" # Unit tests only. - - PYTHON: "C:\\Python27-x64" - - PYTHON: "C:\\Python35" - - PYTHON: "C:\\Python35-x64" - - PYTHON: "C:\\Python36" + # Nothing for the moment matrix: fast_finish: true diff --git a/.azure-pipelines/jobs/test-windows.yml b/.azure-pipelines/jobs/test-windows.yml index 752646247..691c9df13 100644 --- a/.azure-pipelines/jobs/test-windows.yml +++ b/.azure-pipelines/jobs/test-windows.yml @@ -9,11 +9,11 @@ jobs: vmImage: ${{ parameters.vmImage }} strategy: matrix: - Python27-x64: + Python27-x86: python.version: '2.7' - python.architecture: x64 - Python36-x64: - python.version: '3.6' + python.architecture: x86 + Python35-x64: + python.version: '3.5' python.architecture: x64 maxParallel: 2 @@ -32,16 +32,7 @@ jobs: vmImage: ${{ parameters.vmImage }} strategy: matrix: - Python35-x64: - python.version: '3.5' - python.architecture: x64 - Python37-x64: - python.version: '3.7' - python.architecture: x64 # This is for Windows, so test x86 builds - Python27-x86: - python.version: '2.7' - python.architecture: x86 Python35-x86: python.version: '3.5' python.architecture: x86 From 30b7720f4b111051ff130992beba9748892166e0 Mon Sep 17 00:00:00 2001 From: Xavier Fernandez Date: Fri, 26 Jul 2019 13:28:33 +0200 Subject: [PATCH 02/14] Move Python 37-x64 to Azure --- .appveyor.yml | 4 ++-- .azure-pipelines/jobs/test-windows.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 9bd0f595c..4efa91595 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -3,9 +3,9 @@ environment: # Unit and integration tests. - PYTHON: "C:\\Python27-x64" RUN_INTEGRATION_TESTS: "True" - - PYTHON: "C:\\Python36-x64" + - PYTHON: "C:\\Python35-x64" RUN_INTEGRATION_TESTS: "True" - - PYTHON: "C:\\Python37-x64" + - PYTHON: "C:\\Python36-x64" RUN_INTEGRATION_TESTS: "True" # Unit tests only. # Nothing for the moment diff --git a/.azure-pipelines/jobs/test-windows.yml b/.azure-pipelines/jobs/test-windows.yml index 691c9df13..ee869c87c 100644 --- a/.azure-pipelines/jobs/test-windows.yml +++ b/.azure-pipelines/jobs/test-windows.yml @@ -12,8 +12,8 @@ jobs: Python27-x86: python.version: '2.7' python.architecture: x86 - Python35-x64: - python.version: '3.5' + Python37-x64: + python.version: '3.7' python.architecture: x64 maxParallel: 2 From d948f63fe266d275f1f421dbc440b26c7933de70 Mon Sep 17 00:00:00 2001 From: Ivan Pozdeev Date: Sat, 27 Jul 2019 02:46:08 +0300 Subject: [PATCH 03/14] Document that `--ignore-installed` is dangerous --- src/pip/_internal/commands/install.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pip/_internal/commands/install.py b/src/pip/_internal/commands/install.py index 927e7817b..783560671 100644 --- a/src/pip/_internal/commands/install.py +++ b/src/pip/_internal/commands/install.py @@ -187,7 +187,11 @@ class InstallCommand(RequirementCommand): '-I', '--ignore-installed', dest='ignore_installed', action='store_true', - help='Ignore the installed packages (reinstalling instead).') + help='Ignore the installed packages, overwriting them. ' + 'This can break your system if the existing package ' + 'is of a different version or was installed ' + 'with a different package manager!' + ) cmd_opts.add_option(cmdoptions.ignore_requires_python()) cmd_opts.add_option(cmdoptions.no_build_isolation()) From 125aae08efeb9097c48309599fbbe75dbb84dc87 Mon Sep 17 00:00:00 2001 From: Ivan Pozdeev Date: Sat, 27 Jul 2019 03:08:21 +0300 Subject: [PATCH 04/14] add a NEWS entry --- news/6794.doc | 1 + 1 file changed, 1 insertion(+) create mode 100644 news/6794.doc diff --git a/news/6794.doc b/news/6794.doc new file mode 100644 index 000000000..55bc01404 --- /dev/null +++ b/news/6794.doc @@ -0,0 +1 @@ +Document that ``--ignore-installed`` is dangerous. From 6c7d309a1cfb99b8a0ea463de028cf9cd7f9e28a Mon Sep 17 00:00:00 2001 From: Ivan Pozdeev Date: Sat, 27 Jul 2019 03:19:11 +0300 Subject: [PATCH 05/14] fix flake8 violation --- src/pip/_internal/commands/install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pip/_internal/commands/install.py b/src/pip/_internal/commands/install.py index 783560671..e7e168096 100644 --- a/src/pip/_internal/commands/install.py +++ b/src/pip/_internal/commands/install.py @@ -191,7 +191,7 @@ class InstallCommand(RequirementCommand): 'This can break your system if the existing package ' 'is of a different version or was installed ' 'with a different package manager!' - ) + ) cmd_opts.add_option(cmdoptions.ignore_requires_python()) cmd_opts.add_option(cmdoptions.no_build_isolation()) From fc976bb32b99e7e2047c614090ceddc8293dbfc7 Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Mon, 29 Jul 2019 14:27:28 +0530 Subject: [PATCH 06/14] Utilize "pip_install_local" where possible --- tests/functional/test_list.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/tests/functional/test_list.py b/tests/functional/test_list.py index 16b725dde..764d326f7 100644 --- a/tests/functional/test_list.py +++ b/tests/functional/test_list.py @@ -513,11 +513,10 @@ def test_list_path(tmpdir, script, data): Test list with --path. """ result = script.pip('list', '--path', tmpdir, '--format=json') - assert {'name': 'simple', - 'version': '2.0'} not in json.loads(result.stdout) + json_result = json.loads(result.stdout) + assert {'name': 'simple', 'version': '2.0'} not in json_result - script.pip('install', '--find-links', data.find_links, - '--target', tmpdir, 'simple==2.0') + script.pip_install_local('--target', tmpdir, 'simple==2.0') result = script.pip('list', '--path', tmpdir, '--format=json') json_result = json.loads(result.stdout) assert {'name': 'simple', 'version': '2.0'} in json_result @@ -528,10 +527,9 @@ def test_list_path_exclude_user(tmpdir, script, data): Test list with --path and make sure packages from --user are not picked up. """ - script.pip_install_local('--find-links', data.find_links, - '--user', 'simple2') - script.pip('install', '--find-links', data.find_links, - '--target', tmpdir, 'simple==1.0') + script.pip_install_local('--user', 'simple2') + script.pip_install_local('--target', tmpdir, 'simple==1.0') + result = script.pip('list', '--user', '--format=json') json_result = json.loads(result.stdout) assert {'name': 'simple2', 'version': '3.0'} in json_result @@ -549,10 +547,10 @@ def test_list_path_multiple(tmpdir, script, data): os.mkdir(path1) path2 = tmpdir / "path2" os.mkdir(path2) - script.pip('install', '--find-links', data.find_links, - '--target', path1, 'simple==2.0') - script.pip('install', '--find-links', data.find_links, - '--target', path2, 'simple2==3.0') + + script.pip_install_local('--target', path1, 'simple==2.0') + script.pip_install_local('--target', path2, 'simple2==3.0') + result = script.pip('list', '--path', path1, '--format=json') json_result = json.loads(result.stdout) assert {'name': 'simple', 'version': '2.0'} in json_result From 4b8f185fa8db62d06aefd4f55668b720e2cd6e50 Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Mon, 29 Jul 2019 14:27:46 +0530 Subject: [PATCH 07/14] Mark a network dependent test as network --- tests/functional/test_pep517.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/functional/test_pep517.py b/tests/functional/test_pep517.py index 6abbad5d0..c71d1a401 100644 --- a/tests/functional/test_pep517.py +++ b/tests/functional/test_pep517.py @@ -1,3 +1,4 @@ +import pytest from pip._vendor import pytoml from pip._internal.build_env import BuildEnvironment @@ -198,6 +199,7 @@ def test_explicit_setuptools_backend(script, tmpdir, data, common_wheels): result.assert_installed(name, editable=False) +@pytest.mark.network def test_pep517_and_build_options(script, tmpdir, data, common_wheels): """Backend generated requirements are installed in the build env""" project_dir, name = make_pyproject_with_setup(tmpdir) From ebdde3d17d9d9074a4b53453bdb667c87e97c2ad Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Mon, 29 Jul 2019 17:27:52 +0530 Subject: [PATCH 08/14] Bump mypy version --- tools/mypy-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/mypy-requirements.txt b/tools/mypy-requirements.txt index ac69c5ad4..50615d913 100644 --- a/tools/mypy-requirements.txt +++ b/tools/mypy-requirements.txt @@ -1 +1 @@ -mypy == 0.670 +mypy == 0.720 From 3b98423981a4fc60f4dcbf4b0291eb7ee75744ff Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Mon, 29 Jul 2019 20:17:06 +0530 Subject: [PATCH 09/14] Work around mypy quirks --- src/pip/_internal/pep425tags.py | 7 +++++-- src/pip/_internal/utils/appdirs.py | 4 +++- src/pip/_internal/utils/misc.py | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 07dc148ee..4dc381619 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -105,6 +105,8 @@ def get_abi_tag(): (CPython 2, PyPy).""" soabi = get_config_var('SOABI') impl = get_abbr_impl() + abi = None # type: Optional[str] + if not soabi and impl in {'cp', 'pp'} and hasattr(sys, 'maxunicode'): d = '' m = '' @@ -129,8 +131,7 @@ def get_abi_tag(): abi = 'cp' + soabi.split('-')[1] elif soabi: abi = soabi.replace('.', '_').replace('-', '_') - else: - abi = None + return abi @@ -353,6 +354,7 @@ def get_supported( # Current version, current API (built specifically for our Python): for abi in abis: + assert abi for arch in arches: supported.append(('%s%s' % (impl, versions[0]), abi, arch)) @@ -362,6 +364,7 @@ def get_supported( if version in {'31', '30'}: break for abi in abi3s: # empty set if not Python 3 + assert abi for arch in arches: supported.append(("%s%s" % (impl, version), abi, arch)) diff --git a/src/pip/_internal/utils/appdirs.py b/src/pip/_internal/utils/appdirs.py index fb2611104..b0953cab8 100644 --- a/src/pip/_internal/utils/appdirs.py +++ b/src/pip/_internal/utils/appdirs.py @@ -239,7 +239,9 @@ def _get_win_folder_with_ctypes(csidl_name): if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): buf = buf2 - return buf.value + # On Python 2, ctypes.create_unicode_buffer().value returns "unicode", + # which isn't the same as str in the annotation above. + return buf.value # type: ignore if WINDOWS: diff --git a/src/pip/_internal/utils/misc.py b/src/pip/_internal/utils/misc.py index f094cac99..156ae0a96 100644 --- a/src/pip/_internal/utils/misc.py +++ b/src/pip/_internal/utils/misc.py @@ -65,9 +65,9 @@ try: except ImportError: # typing's cast() isn't supported in code comments, so we need to # define a dummy, no-op version. - def cast(typ, val): + def cast(typ, val): # type: ignore return val - VersionInfo = None + VersionInfo = None # type: ignore __all__ = ['rmtree', 'display_path', 'backup_dir', From 80b82b52158f288e97d5b6abe95e0b574ca51d93 Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Tue, 30 Jul 2019 10:10:13 +0530 Subject: [PATCH 10/14] Address review comments --- src/pip/_internal/pep425tags.py | 6 ++---- src/pip/_internal/utils/appdirs.py | 5 +++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/pip/_internal/pep425tags.py b/src/pip/_internal/pep425tags.py index 4dc381619..03a906b94 100644 --- a/src/pip/_internal/pep425tags.py +++ b/src/pip/_internal/pep425tags.py @@ -16,7 +16,7 @@ from pip._internal.utils.typing import MYPY_CHECK_RUNNING if MYPY_CHECK_RUNNING: from typing import ( - Tuple, Callable, List, Optional, Union, Dict + Tuple, Callable, List, Optional, Union, Dict, Set ) Pep425Tag = Tuple[str, str, str] @@ -311,7 +311,7 @@ def get_supported( if abi: abis[0:0] = [abi] - abi3s = set() + abi3s = set() # type: Set[str] for suffix in get_extension_suffixes(): if suffix.startswith('.abi'): abi3s.add(suffix.split('.', 2)[1]) @@ -354,7 +354,6 @@ def get_supported( # Current version, current API (built specifically for our Python): for abi in abis: - assert abi for arch in arches: supported.append(('%s%s' % (impl, versions[0]), abi, arch)) @@ -364,7 +363,6 @@ def get_supported( if version in {'31', '30'}: break for abi in abi3s: # empty set if not Python 3 - assert abi for arch in arches: supported.append(("%s%s" % (impl, version), abi, arch)) diff --git a/src/pip/_internal/utils/appdirs.py b/src/pip/_internal/utils/appdirs.py index b0953cab8..dcd757c7e 100644 --- a/src/pip/_internal/utils/appdirs.py +++ b/src/pip/_internal/utils/appdirs.py @@ -218,6 +218,8 @@ def _get_win_folder_from_registry(csidl_name): def _get_win_folder_with_ctypes(csidl_name): # type: (str) -> str + # On Python 2, ctypes.create_unicode_buffer().value returns "unicode", + # which isn't the same as str in the annotation above. csidl_const = { "CSIDL_APPDATA": 26, "CSIDL_COMMON_APPDATA": 35, @@ -239,8 +241,7 @@ def _get_win_folder_with_ctypes(csidl_name): if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): buf = buf2 - # On Python 2, ctypes.create_unicode_buffer().value returns "unicode", - # which isn't the same as str in the annotation above. + # The type: ignore is explained under the type annotation for this function return buf.value # type: ignore From 2a5c23b3d5c47ebdb8c30aaf84aad36a645a1482 Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Tue, 30 Jul 2019 10:16:57 +0530 Subject: [PATCH 11/14] Simplify the handling of "typing.cast" --- src/pip/_internal/utils/misc.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/pip/_internal/utils/misc.py b/src/pip/_internal/utils/misc.py index 156ae0a96..a08669a4b 100644 --- a/src/pip/_internal/utils/misc.py +++ b/src/pip/_internal/utils/misc.py @@ -53,21 +53,18 @@ else: if MYPY_CHECK_RUNNING: from typing import ( Any, AnyStr, Container, Iterable, List, Mapping, Match, Optional, Text, - Union, + Tuple, Union, cast, ) from pip._vendor.pkg_resources import Distribution from pip._internal.models.link import Link from pip._internal.utils.ui import SpinnerInterface -try: - from typing import cast, Tuple VersionInfo = Tuple[int, int, int] -except ImportError: - # typing's cast() isn't supported in code comments, so we need to - # define a dummy, no-op version. - def cast(typ, val): # type: ignore - return val - VersionInfo = None # type: ignore +else: + # typing's cast() is needed at runtime, but we don't want to import typing. + # Thus, we use a dummy no-op version, which we tell mypy to ignore. + def cast(type_, value): # type: ignore + return value __all__ = ['rmtree', 'display_path', 'backup_dir', @@ -140,7 +137,7 @@ def normalize_version_info(py_version_info): elif len(py_version_info) > 3: py_version_info = py_version_info[:3] - return cast(VersionInfo, py_version_info) + return cast('VersionInfo', py_version_info) def ensure_dir(path): From 9214099f09bed1800bce603d294621641959cb56 Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Tue, 30 Jul 2019 12:28:20 +0530 Subject: [PATCH 12/14] Revert "Ignore new warnings traced on tox invocation." --- .appveyor.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 2819e0521..4aa5e217b 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -65,9 +65,6 @@ test_script: subst T: $env:TEMP $env:TEMP = "T:\" $env:TMP = "T:\" - # Workaround warnings traced in packaging.requirements with pyparsing 2.4.1. - # See pypa/packaging#170 and tox-dev/tox#1375. - $env:PYTHONWARNINGS = "ignore:warn_ungrouped_named_tokens_in_collection" tox -e py -- -m unit if ($LastExitCode -eq 0 -and $env:RUN_INTEGRATION_TESTS -eq "True") { tox -e py -- --use-venv -m integration -n2 --durations=20 From c6da85a6ebde3c6d6a1d0bcc82e994514fe79c72 Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Tue, 30 Jul 2019 17:01:05 +0530 Subject: [PATCH 13/14] Move requirement files to tools/requirements/ --- tools/{docs-requirements.txt => requirements/docs.txt} | 0 tools/{lint-requirements.txt => requirements/lint.txt} | 0 tools/{mypy-requirements.txt => requirements/mypy.txt} | 0 .../tests-common_wheels.txt} | 0 .../{tests-requirements.txt => requirements/tests.txt} | 0 tox.ini | 10 +++++----- 6 files changed, 5 insertions(+), 5 deletions(-) rename tools/{docs-requirements.txt => requirements/docs.txt} (100%) rename tools/{lint-requirements.txt => requirements/lint.txt} (100%) rename tools/{mypy-requirements.txt => requirements/mypy.txt} (100%) rename tools/{tests-common_wheels-requirements.txt => requirements/tests-common_wheels.txt} (100%) rename tools/{tests-requirements.txt => requirements/tests.txt} (100%) diff --git a/tools/docs-requirements.txt b/tools/requirements/docs.txt similarity index 100% rename from tools/docs-requirements.txt rename to tools/requirements/docs.txt diff --git a/tools/lint-requirements.txt b/tools/requirements/lint.txt similarity index 100% rename from tools/lint-requirements.txt rename to tools/requirements/lint.txt diff --git a/tools/mypy-requirements.txt b/tools/requirements/mypy.txt similarity index 100% rename from tools/mypy-requirements.txt rename to tools/requirements/mypy.txt diff --git a/tools/tests-common_wheels-requirements.txt b/tools/requirements/tests-common_wheels.txt similarity index 100% rename from tools/tests-common_wheels-requirements.txt rename to tools/requirements/tests-common_wheels.txt diff --git a/tools/tests-requirements.txt b/tools/requirements/tests.txt similarity index 100% rename from tools/tests-requirements.txt rename to tools/requirements/tests.txt diff --git a/tox.ini b/tox.ini index 512bad52d..879c234e8 100644 --- a/tox.ini +++ b/tox.ini @@ -15,10 +15,10 @@ setenv = # This is required in order to get UTF-8 output inside of the subprocesses # that our tests use. LC_CTYPE = en_US.UTF-8 -deps = -r{toxinidir}/tools/tests-requirements.txt +deps = -r{toxinidir}/tools/requirements/tests.txt commands_pre = python -c 'import shutil, sys; shutil.rmtree(sys.argv[1], ignore_errors=True)' {toxinidir}/tests/data/common_wheels - {[helpers]pip} wheel -w {toxinidir}/tests/data/common_wheels -r {toxinidir}/tools/tests-common_wheels-requirements.txt + {[helpers]pip} wheel -w {toxinidir}/tests/data/common_wheels -r {toxinidir}/tools/requirements/tests-common_wheels.txt commands = pytest --timeout 300 [] install_command = {[helpers]pip} install {opts} {packages} list_dependencies_command = {[helpers]pip} freeze --all @@ -29,7 +29,7 @@ commands = pytest --timeout 300 --cov=pip --cov-report=term-missing --cov-report [testenv:docs] # Don't skip install here since pip_sphinxext uses pip's internals. -deps = -r{toxinidir}/tools/docs-requirements.txt +deps = -r{toxinidir}/tools/requirements/docs.txt basepython = python3.6 commands = sphinx-build -W -d {envtmpdir}/doctrees/html -b html docs/html docs/build/html @@ -50,7 +50,7 @@ commands = python setup.py check -m -r -s [lint] -deps = -r{toxinidir}/tools/lint-requirements.txt +deps = -r{toxinidir}/tools/requirements/lint.txt [testenv:lint-py2] skip_install = True @@ -74,7 +74,7 @@ commands = [testenv:mypy] skip_install = True basepython = python3 -deps = -r{toxinidir}/tools/mypy-requirements.txt +deps = -r{toxinidir}/tools/requirements/mypy.txt commands_pre = commands = mypy src From c9b6d252a8ffbbbe932853192d0187e457eb20cb Mon Sep 17 00:00:00 2001 From: Pradyun Gedam Date: Tue, 30 Jul 2019 17:41:22 +0530 Subject: [PATCH 14/14] Move invoke commands to tools.automation --- tasks/__init__.py | 3 +-- {tasks => tools/automation}/generate.py | 0 {tasks => tools/automation}/vendoring/__init__.py | 0 {tasks => tools/automation}/vendoring/patches/appdirs.patch | 0 {tasks => tools/automation}/vendoring/patches/html5lib.patch | 0 {tasks => tools/automation}/vendoring/patches/requests.patch | 0 6 files changed, 1 insertion(+), 2 deletions(-) rename {tasks => tools/automation}/generate.py (100%) rename {tasks => tools/automation}/vendoring/__init__.py (100%) rename {tasks => tools/automation}/vendoring/patches/appdirs.patch (100%) rename {tasks => tools/automation}/vendoring/patches/html5lib.patch (100%) rename {tasks => tools/automation}/vendoring/patches/requests.patch (100%) diff --git a/tasks/__init__.py b/tasks/__init__.py index 5f1a4aff6..ecde43996 100644 --- a/tasks/__init__.py +++ b/tasks/__init__.py @@ -1,6 +1,5 @@ import invoke -from . import generate -from . import vendoring +from tools.automation import generate, vendoring ns = invoke.Collection(generate, vendoring) diff --git a/tasks/generate.py b/tools/automation/generate.py similarity index 100% rename from tasks/generate.py rename to tools/automation/generate.py diff --git a/tasks/vendoring/__init__.py b/tools/automation/vendoring/__init__.py similarity index 100% rename from tasks/vendoring/__init__.py rename to tools/automation/vendoring/__init__.py diff --git a/tasks/vendoring/patches/appdirs.patch b/tools/automation/vendoring/patches/appdirs.patch similarity index 100% rename from tasks/vendoring/patches/appdirs.patch rename to tools/automation/vendoring/patches/appdirs.patch diff --git a/tasks/vendoring/patches/html5lib.patch b/tools/automation/vendoring/patches/html5lib.patch similarity index 100% rename from tasks/vendoring/patches/html5lib.patch rename to tools/automation/vendoring/patches/html5lib.patch diff --git a/tasks/vendoring/patches/requests.patch b/tools/automation/vendoring/patches/requests.patch similarity index 100% rename from tasks/vendoring/patches/requests.patch rename to tools/automation/vendoring/patches/requests.patch