From b883971180a38d2b1f5da60632406a5f0634357c Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Wed, 1 Feb 2023 13:07:43 +0100 Subject: [PATCH 01/16] Build: expose `READTHEDOCS_VIRTUALENV_PATH` variable This variable points to where Read the Docs created the virtualenv. Closes #9629 --- docs/user/environment-variables.rst | 6 ++++++ readthedocs/doc_builder/director.py | 3 +++ 2 files changed, 9 insertions(+) diff --git a/docs/user/environment-variables.rst b/docs/user/environment-variables.rst index 83db28d5762..41dd241c3d8 100644 --- a/docs/user/environment-variables.rst +++ b/docs/user/environment-variables.rst @@ -50,6 +50,12 @@ Read the Docs builders set the following environment variables automatically for :Examples: ``en``, ``it``, ``de_AT``, ``es``, ``pt_BR`` +.. envvar:: READTHEDOCS_VIRTUALENV_PATH + + Path where Read the Docs created the virtualenv for this build. + + :Example: ``/home/docs/checkouts/readthedocs.org/user_builds/project/envs/version`` + User-defined environment variables ---------------------------------- diff --git a/readthedocs/doc_builder/director.py b/readthedocs/doc_builder/director.py index fedd6ed7f63..29681749e87 100644 --- a/readthedocs/doc_builder/director.py +++ b/readthedocs/doc_builder/director.py @@ -577,6 +577,9 @@ def get_build_env_vars(self): self.data.version.slug, "bin", ), + "READTHEDOCS_VIRTUALENV_PATH": os.path.join( + self.data.project.doc_path, "envs", self.data.version.slug + ), } ) From da64970aa92799f92b6fd1021894b54133aabea6 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Wed, 1 Feb 2023 13:33:05 +0100 Subject: [PATCH 02/16] Build: use our own variable `$READTHEDOCS_VIRTUALENV_PATH` This variable contains the path we need to call the Python executable. --- readthedocs/api/v2/serializers.py | 3 +++ readthedocs/doc_builder/environments.py | 10 +++++++++- .../doc_builder/python_environments.py | 19 +++++-------------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/readthedocs/api/v2/serializers.py b/readthedocs/api/v2/serializers.py index 37c58e06c6d..45b064ba0ea 100644 --- a/readthedocs/api/v2/serializers.py +++ b/readthedocs/api/v2/serializers.py @@ -172,6 +172,9 @@ def get_command(self, obj): regex = f"{docroot}{container_hash}{project_slug}/envs/{version_slug}(/bin/)?" command = re.sub(regex, "", obj.command, count=1) + + regex = f"^\\$READTHEDOCS_VIRTUALENV_PATH/bin/" + command = re.sub(regex, "", obj.command, count=1) return command diff --git a/readthedocs/doc_builder/environments.py b/readthedocs/doc_builder/environments.py index 979fc18dda8..b2472ae5abc 100644 --- a/readthedocs/doc_builder/environments.py +++ b/readthedocs/doc_builder/environments.py @@ -380,7 +380,15 @@ def get_wrapped_command(self): def _escape_command(self, cmd): r"""Escape the command by prefixing suspicious chars with `\`.""" - return self.bash_escape_re.sub(r'\\\1', cmd) + command = self.bash_escape_re.sub(r"\\\1", cmd) + + # HACK: avoid escaping `$READTHEDOCS_OUTPUT` variable + command = command.replace("\\$READTHEDOCS_OUTPUT", "$READTHEDOCS_OUTPUT") + # HACK: avoid escaping `$READTHEDOCS_VIRTUALENV_PATH` variable + command = command.replace( + "\\$READTHEDOCS_VIRTUALENV_PATH", "$READTHEDOCS_VIRTUALENV_PATH" + ) + return command class BaseEnvironment: diff --git a/readthedocs/doc_builder/python_environments.py b/readthedocs/doc_builder/python_environments.py index 193b9494d53..748eee88e2f 100644 --- a/readthedocs/doc_builder/python_environments.py +++ b/readthedocs/doc_builder/python_environments.py @@ -96,7 +96,7 @@ def venv_bin(self, filename=None): :param filename: If specified, add this filename to the path return :returns: Path to virtualenv bin or filename in virtualenv bin """ - parts = [self.venv_path(), 'bin'] + parts = ["$READTHEDOCS_VIRTUALENV_PATH", "bin"] if filename is not None: parts.append(filename) return os.path.join(*parts) @@ -110,9 +110,6 @@ class Virtualenv(PythonEnvironment): .. _virtualenv: https://virtualenv.pypa.io/ """ - def venv_path(self): - return os.path.join(self.project.doc_path, 'envs', self.version.slug) - def setup_base(self): """ Create a virtualenv, invoking ``python -mvirtualenv``. @@ -133,9 +130,7 @@ def setup_base(self): cli_args.append('--system-site-packages') # Append the positional destination argument - cli_args.append( - self.venv_path(), - ) + cli_args.append("$READTHEDOCS_VIRTUALENV_PATH") self.build_env.run( self.config.python_interpreter, @@ -167,7 +162,9 @@ def install_core_requirements(self): ) cmd = pip_install_cmd + [pip_version, 'setuptools<58.3.0'] self.build_env.run( - *cmd, bin_path=self.venv_bin(), cwd=self.checkout_path + *cmd, + bin_path=self.venv_bin(), + cwd=self.checkout_path, ) requirements = [] @@ -318,9 +315,6 @@ class Conda(PythonEnvironment): .. _Conda: https://conda.io/docs/ """ - def venv_path(self): - return os.path.join(self.project.doc_path, 'conda', self.version.slug) - def conda_bin_name(self): """ Decide whether use ``mamba`` or ``conda`` to create the environment. @@ -354,9 +348,6 @@ def _update_conda_startup(self): ) def setup_base(self): - conda_env_path = os.path.join(self.project.doc_path, 'conda') - os.path.join(conda_env_path, self.version.slug) - if self.project.has_feature(Feature.UPDATE_CONDA_STARTUP): self._update_conda_startup() From 709062bdf33c538c0ea801b78ed5cdd6dc471789 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Wed, 1 Feb 2023 13:53:00 +0100 Subject: [PATCH 03/16] Build: use environment variables for Conda as well --- readthedocs/api/v2/serializers.py | 5 ++++- readthedocs/doc_builder/director.py | 1 + readthedocs/doc_builder/environments.py | 13 ++++++++----- readthedocs/doc_builder/python_environments.py | 8 +++++++- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/readthedocs/api/v2/serializers.py b/readthedocs/api/v2/serializers.py index 45b064ba0ea..83f3d1ce71a 100644 --- a/readthedocs/api/v2/serializers.py +++ b/readthedocs/api/v2/serializers.py @@ -173,7 +173,10 @@ def get_command(self, obj): regex = f"{docroot}{container_hash}{project_slug}/envs/{version_slug}(/bin/)?" command = re.sub(regex, "", obj.command, count=1) - regex = f"^\\$READTHEDOCS_VIRTUALENV_PATH/bin/" + regex = "^\\$READTHEDOCS_VIRTUALENV_PATH/bin/" + command = re.sub(regex, "", obj.command, count=1) + + regex = "^\\$CONDA_ENVS_PATH/\\$CONDA_DEFAULT_ENV/bin/" command = re.sub(regex, "", obj.command, count=1) return command diff --git a/readthedocs/doc_builder/director.py b/readthedocs/doc_builder/director.py index 29681749e87..0485169ba05 100644 --- a/readthedocs/doc_builder/director.py +++ b/readthedocs/doc_builder/director.py @@ -556,6 +556,7 @@ def get_build_env_vars(self): if self.data.config.conda is not None: env.update( { + # NOTE: should these be prefixed with "READTHEDOCS_"? "CONDA_ENVS_PATH": os.path.join( self.data.project.doc_path, "conda" ), diff --git a/readthedocs/doc_builder/environments.py b/readthedocs/doc_builder/environments.py index b2472ae5abc..63198f9d403 100644 --- a/readthedocs/doc_builder/environments.py +++ b/readthedocs/doc_builder/environments.py @@ -382,12 +382,15 @@ def _escape_command(self, cmd): r"""Escape the command by prefixing suspicious chars with `\`.""" command = self.bash_escape_re.sub(r"\\\1", cmd) - # HACK: avoid escaping `$READTHEDOCS_OUTPUT` variable - command = command.replace("\\$READTHEDOCS_OUTPUT", "$READTHEDOCS_OUTPUT") - # HACK: avoid escaping `$READTHEDOCS_VIRTUALENV_PATH` variable - command = command.replace( - "\\$READTHEDOCS_VIRTUALENV_PATH", "$READTHEDOCS_VIRTUALENV_PATH" + # HACK: avoid escaping variables that we need to use in the commands + not_escape_variables = ( + "READTHEDOCS_OUTPUT", + "READTHEDOCS_VIRTUALENV_PATH", + "CONDA_ENVS_PATH", + "CONDA_DEFAULT_ENV", ) + for variable in not_escape_variables: + command = command.replace(f"\\${variable}", f"${variable}") return command diff --git a/readthedocs/doc_builder/python_environments.py b/readthedocs/doc_builder/python_environments.py index 748eee88e2f..6ec90da8e0e 100644 --- a/readthedocs/doc_builder/python_environments.py +++ b/readthedocs/doc_builder/python_environments.py @@ -89,7 +89,7 @@ def install_package(self, install): bin_path=self.venv_bin(), ) - def venv_bin(self, filename=None): + def venv_bin(self, filename=None, conda=False): """ Return path to the virtualenv bin path, or a specific binary. @@ -97,6 +97,9 @@ def venv_bin(self, filename=None): :returns: Path to virtualenv bin or filename in virtualenv bin """ parts = ["$READTHEDOCS_VIRTUALENV_PATH", "bin"] + if conda: + parts = ["$CONDA_ENVS_PATH", "$CONDA_DEFAULT_ENV", "bin"] + if filename is not None: parts.append(filename) return os.path.join(*parts) @@ -315,6 +318,9 @@ class Conda(PythonEnvironment): .. _Conda: https://conda.io/docs/ """ + def venv_bin(self, filename=None): + return super().venv_bin(filename=filename, conda=True) + def conda_bin_name(self): """ Decide whether use ``mamba`` or ``conda`` to create the environment. From 6997939bb646027bb4009827adbddd3103c5b937 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Wed, 1 Feb 2023 13:56:06 +0100 Subject: [PATCH 04/16] Tests: add missing variable --- readthedocs/projects/tests/test_build_tasks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/readthedocs/projects/tests/test_build_tasks.py b/readthedocs/projects/tests/test_build_tasks.py index e1b2d28e973..b71f1959158 100644 --- a/readthedocs/projects/tests/test_build_tasks.py +++ b/readthedocs/projects/tests/test_build_tasks.py @@ -275,6 +275,7 @@ def test_get_env_vars(self, load_yaml_config, build_environment, config, externa "READTHEDOCS_VERSION_NAME": self.version.verbose_name, "READTHEDOCS_PROJECT": self.project.slug, "READTHEDOCS_LANGUAGE": self.project.language, + "READTHEDOCS_VIRTUALENV_PATH": "/usr/src/app/checkouts/readthedocs.org/user_builds/project/envs/latest", } self._trigger_update_docs_task() From 3e766c3962bb10f8985e5ad26c87bc2a2830e006 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Wed, 1 Feb 2023 14:03:53 +0100 Subject: [PATCH 05/16] Lint --- readthedocs/doc_builder/python_environments.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readthedocs/doc_builder/python_environments.py b/readthedocs/doc_builder/python_environments.py index 6ec90da8e0e..457c62ebd53 100644 --- a/readthedocs/doc_builder/python_environments.py +++ b/readthedocs/doc_builder/python_environments.py @@ -318,7 +318,7 @@ class Conda(PythonEnvironment): .. _Conda: https://conda.io/docs/ """ - def venv_bin(self, filename=None): + def venv_bin(self, filename=None): # pylint disable=arguments-differ return super().venv_bin(filename=filename, conda=True) def conda_bin_name(self): From e2d647af0a2cb9c7e35b88419d013f2308ddcdbc Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Wed, 1 Feb 2023 14:11:06 +0100 Subject: [PATCH 06/16] Lint again --- readthedocs/doc_builder/python_environments.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/readthedocs/doc_builder/python_environments.py b/readthedocs/doc_builder/python_environments.py index 457c62ebd53..66885019df0 100644 --- a/readthedocs/doc_builder/python_environments.py +++ b/readthedocs/doc_builder/python_environments.py @@ -318,7 +318,8 @@ class Conda(PythonEnvironment): .. _Conda: https://conda.io/docs/ """ - def venv_bin(self, filename=None): # pylint disable=arguments-differ + # pylint disable=arguments-differ + def venv_bin(self, filename=None): return super().venv_bin(filename=filename, conda=True) def conda_bin_name(self): From ffe29deb3e26e4ff7859577269974e00c5f787c6 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Wed, 1 Feb 2023 14:11:38 +0100 Subject: [PATCH 07/16] Missing : --- readthedocs/doc_builder/python_environments.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readthedocs/doc_builder/python_environments.py b/readthedocs/doc_builder/python_environments.py index 66885019df0..a3193407cc9 100644 --- a/readthedocs/doc_builder/python_environments.py +++ b/readthedocs/doc_builder/python_environments.py @@ -318,7 +318,7 @@ class Conda(PythonEnvironment): .. _Conda: https://conda.io/docs/ """ - # pylint disable=arguments-differ + # pylint: disable=arguments-differ def venv_bin(self, filename=None): return super().venv_bin(filename=filename, conda=True) From 097eb4e7335452af62c5fc80ecab6435bbb8f10a Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Wed, 1 Feb 2023 15:20:30 +0100 Subject: [PATCH 08/16] Test: update env variables --- readthedocs/projects/tests/test_build_tasks.py | 2 +- readthedocs/rtd_tests/tests/test_api.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/readthedocs/projects/tests/test_build_tasks.py b/readthedocs/projects/tests/test_build_tasks.py index b71f1959158..166bd4ba146 100644 --- a/readthedocs/projects/tests/test_build_tasks.py +++ b/readthedocs/projects/tests/test_build_tasks.py @@ -275,7 +275,6 @@ def test_get_env_vars(self, load_yaml_config, build_environment, config, externa "READTHEDOCS_VERSION_NAME": self.version.verbose_name, "READTHEDOCS_PROJECT": self.project.slug, "READTHEDOCS_LANGUAGE": self.project.language, - "READTHEDOCS_VIRTUALENV_PATH": "/usr/src/app/checkouts/readthedocs.org/user_builds/project/envs/latest", } self._trigger_update_docs_task() @@ -295,6 +294,7 @@ def test_get_env_vars(self, load_yaml_config, build_environment, config, externa "bin", ), PUBLIC_TOKEN="a1b2c3", + READTHEDOCS_VIRTUALENV_PATH=f"/usr/src/app/checkouts/readthedocs.org/user_builds/{self.project.slug}/envs/{self.version.slug}", ) if not external: expected_build_env_vars["PRIVATE_TOKEN"] = "a1b2c3" diff --git a/readthedocs/rtd_tests/tests/test_api.py b/readthedocs/rtd_tests/tests/test_api.py index de34a19f104..33d28050048 100644 --- a/readthedocs/rtd_tests/tests/test_api.py +++ b/readthedocs/rtd_tests/tests/test_api.py @@ -334,7 +334,7 @@ def test_response_finished_and_success(self): buildcommandresult = get( BuildCommandResult, build=build, - command="/home/docs/checkouts/readthedocs.org/user_builds/myproject/envs/myversion/bin/python -m pip install --upgrade --no-cache-dir pip setuptools<58.3.0", + command="python -m pip install --upgrade --no-cache-dir pip setuptools<58.3.0", exit_code=0, ) resp = client.get('/api/v2/build/{build}/'.format(build=build.pk)) From 3dc547aa351f0cd9ae92a54cba7d60391a840cbe Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Wed, 1 Feb 2023 17:57:20 +0100 Subject: [PATCH 09/16] Test: make it work locally and CicleCI --- readthedocs/projects/tests/test_build_tasks.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/readthedocs/projects/tests/test_build_tasks.py b/readthedocs/projects/tests/test_build_tasks.py index 166bd4ba146..9eb7f4e5915 100644 --- a/readthedocs/projects/tests/test_build_tasks.py +++ b/readthedocs/projects/tests/test_build_tasks.py @@ -294,7 +294,9 @@ def test_get_env_vars(self, load_yaml_config, build_environment, config, externa "bin", ), PUBLIC_TOKEN="a1b2c3", - READTHEDOCS_VIRTUALENV_PATH=f"/usr/src/app/checkouts/readthedocs.org/user_builds/{self.project.slug}/envs/{self.version.slug}", + # Local and Circle are different values. + # We only check it's present, but not its value. + READTHEDOCS_VIRTUALENV_PATH=mock.ANY, ) if not external: expected_build_env_vars["PRIVATE_TOKEN"] = "a1b2c3" From fb83a4e4c9b8bf3b960020420e57a7c4457ea3d6 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Thu, 2 Feb 2023 12:28:32 +0100 Subject: [PATCH 10/16] Docs: add link to the builds page --- docs/user/environment-variables.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/user/environment-variables.rst b/docs/user/environment-variables.rst index 41dd241c3d8..7833c6a0ad8 100644 --- a/docs/user/environment-variables.rst +++ b/docs/user/environment-variables.rst @@ -52,7 +52,8 @@ Read the Docs builders set the following environment variables automatically for .. envvar:: READTHEDOCS_VIRTUALENV_PATH - Path where Read the Docs created the virtualenv for this build. + Path for the :ref:`virtualenv that was created for this build `. + Only exists for builds using Virtualenv and not Conda. :Example: ``/home/docs/checkouts/readthedocs.org/user_builds/project/envs/version`` From 66fe0a7d93fde5b1f093ac52abcb23ed6927d9b0 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Thu, 2 Feb 2023 12:28:54 +0100 Subject: [PATCH 11/16] Refactor: make `venv_bin` more concrete to match venv/conda --- .../doc_builder/python_environments.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/readthedocs/doc_builder/python_environments.py b/readthedocs/doc_builder/python_environments.py index a3193407cc9..2dfaac0cacb 100644 --- a/readthedocs/doc_builder/python_environments.py +++ b/readthedocs/doc_builder/python_environments.py @@ -89,20 +89,17 @@ def install_package(self, install): bin_path=self.venv_bin(), ) - def venv_bin(self, filename=None, conda=False): + def venv_bin(self, prefixes, filename=None): """ Return path to the virtualenv bin path, or a specific binary. :param filename: If specified, add this filename to the path return + :param prefix: List of path prefixes to include in the resulting path :returns: Path to virtualenv bin or filename in virtualenv bin """ - parts = ["$READTHEDOCS_VIRTUALENV_PATH", "bin"] - if conda: - parts = ["$CONDA_ENVS_PATH", "$CONDA_DEFAULT_ENV", "bin"] - if filename is not None: - parts.append(filename) - return os.path.join(*parts) + prefixes.append(filename) + return os.path.join(*prefixes) class Virtualenv(PythonEnvironment): @@ -113,6 +110,11 @@ class Virtualenv(PythonEnvironment): .. _virtualenv: https://virtualenv.pypa.io/ """ + # pylint: disable=arguments-differ + def venv_bin(self, filename=None): + prefixes = ["$READTHEDOCS_VIRTUALENV_PATH", "bin"] + super().venv_bin(prefixes, filename=filename) + def setup_base(self): """ Create a virtualenv, invoking ``python -mvirtualenv``. @@ -320,7 +322,8 @@ class Conda(PythonEnvironment): # pylint: disable=arguments-differ def venv_bin(self, filename=None): - return super().venv_bin(filename=filename, conda=True) + prefixes = ["$CONDA_ENVS_PATH", "$CONDA_DEFAULT_ENV", "bin"] + return super().venv_bin(prefixes, filename=filename) def conda_bin_name(self): """ From 378fcef87c62a9bef0d6615eb9e62ef26994b3ef Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Thu, 2 Feb 2023 12:34:14 +0100 Subject: [PATCH 12/16] Build: missing return --- readthedocs/doc_builder/python_environments.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readthedocs/doc_builder/python_environments.py b/readthedocs/doc_builder/python_environments.py index 2dfaac0cacb..b8a8e5f8c5d 100644 --- a/readthedocs/doc_builder/python_environments.py +++ b/readthedocs/doc_builder/python_environments.py @@ -113,7 +113,7 @@ class Virtualenv(PythonEnvironment): # pylint: disable=arguments-differ def venv_bin(self, filename=None): prefixes = ["$READTHEDOCS_VIRTUALENV_PATH", "bin"] - super().venv_bin(prefixes, filename=filename) + return super().venv_bin(prefixes, filename=filename) def setup_base(self): """ From cc39779565d779782b8cfa891a0df8700e35ec23 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Thu, 2 Feb 2023 12:37:43 +0100 Subject: [PATCH 13/16] API: sanitize build command properly --- readthedocs/api/v2/serializers.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/readthedocs/api/v2/serializers.py b/readthedocs/api/v2/serializers.py index 83f3d1ce71a..ec26092e3a3 100644 --- a/readthedocs/api/v2/serializers.py +++ b/readthedocs/api/v2/serializers.py @@ -170,14 +170,15 @@ def get_command(self, obj): docroot = re.sub("/[0-9a-z]+/?$", "", settings.DOCROOT, count=1) container_hash = "/([0-9a-z]+/)?" + command = obj.command regex = f"{docroot}{container_hash}{project_slug}/envs/{version_slug}(/bin/)?" - command = re.sub(regex, "", obj.command, count=1) + command = re.sub(regex, "", command, count=1) - regex = "^\\$READTHEDOCS_VIRTUALENV_PATH/bin/" - command = re.sub(regex, "", obj.command, count=1) + regex = r"^\$READTHEDOCS_VIRTUALENV_PATH/bin/" + command = re.sub(regex, "", command, count=1) - regex = "^\\$CONDA_ENVS_PATH/\\$CONDA_DEFAULT_ENV/bin/" - command = re.sub(regex, "", obj.command, count=1) + regex = r"^\$CONDA_ENVS_PATH/\\$CONDA_DEFAULT_ENV/bin/" + command = re.sub(regex, "", command, count=1) return command From 5617c700d1b52bccc6cd3e6c81812805a9eb3a46 Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Thu, 2 Feb 2023 19:24:58 +0100 Subject: [PATCH 14/16] Update readthedocs/api/v2/serializers.py Co-authored-by: Eric Holscher <25510+ericholscher@users.noreply.github.com> --- readthedocs/api/v2/serializers.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/readthedocs/api/v2/serializers.py b/readthedocs/api/v2/serializers.py index ec26092e3a3..a48d83207c5 100644 --- a/readthedocs/api/v2/serializers.py +++ b/readthedocs/api/v2/serializers.py @@ -174,6 +174,8 @@ def get_command(self, obj): regex = f"{docroot}{container_hash}{project_slug}/envs/{version_slug}(/bin/)?" command = re.sub(regex, "", command, count=1) + # Remove explicit variable names we use to run commands, + # since users don't care about these. regex = r"^\$READTHEDOCS_VIRTUALENV_PATH/bin/" command = re.sub(regex, "", command, count=1) From eecd917ae37a8650e6aba26ce9d5579793874a3a Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Thu, 2 Feb 2023 19:28:17 +0100 Subject: [PATCH 15/16] Lint --- readthedocs/api/v2/serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readthedocs/api/v2/serializers.py b/readthedocs/api/v2/serializers.py index a48d83207c5..0e14572c372 100644 --- a/readthedocs/api/v2/serializers.py +++ b/readthedocs/api/v2/serializers.py @@ -175,7 +175,7 @@ def get_command(self, obj): command = re.sub(regex, "", command, count=1) # Remove explicit variable names we use to run commands, - # since users don't care about these. + # since users don't care about these. regex = r"^\$READTHEDOCS_VIRTUALENV_PATH/bin/" command = re.sub(regex, "", command, count=1) From 1be646ef0d9d1ac38bd052ceff6b31819cda5d7d Mon Sep 17 00:00:00 2001 From: Manuel Kaufmann Date: Tue, 7 Feb 2023 10:48:49 +0100 Subject: [PATCH 16/16] Lint --- readthedocs/doc_builder/python_environments.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/readthedocs/doc_builder/python_environments.py b/readthedocs/doc_builder/python_environments.py index b8a8e5f8c5d..15713ae4b94 100644 --- a/readthedocs/doc_builder/python_environments.py +++ b/readthedocs/doc_builder/python_environments.py @@ -53,6 +53,12 @@ def install_package(self, install): :param install: A install object from the config module. :type install: readthedocs.config.models.PythonInstall """ + # NOTE: `venv_bin` requires `prefixes`. + # However, it's overwritten in the subclasses and + # it forces passing the `prefixes=` attribute. + # I'm not sure how to solve this, so I'm skipping this check for now. + # pylint: disable=no-value-for-parameter + if install.method == PIP: # Prefix ./ so pip installs from a local path rather than pypi local_path = ( @@ -94,7 +100,7 @@ def venv_bin(self, prefixes, filename=None): Return path to the virtualenv bin path, or a specific binary. :param filename: If specified, add this filename to the path return - :param prefix: List of path prefixes to include in the resulting path + :param prefixes: List of path prefixes to include in the resulting path :returns: Path to virtualenv bin or filename in virtualenv bin """ if filename is not None: