diff --git a/CHANGELOG.md b/CHANGELOG.md index a14a8ce6..c43b4de6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Common environment directories (`env, venv, .env, .venv`) are no longer excluded by name. Environments are detected by the presence of a python executable in `bin` or `Scripts` and excluded. +- Lines output from `pip freeze` which start with [notice] are filtered out from the generated `requirements.txt`. ### Added - Added support for the `no_proxy` or `NO_PROXY` environment variables to specify diff --git a/rsconnect/environment.py b/rsconnect/environment.py index 4c47f8ec..75afc1ab 100644 --- a/rsconnect/environment.py +++ b/rsconnect/environment.py @@ -145,7 +145,7 @@ def output_file(dirname, filename, package_manager): def pip_freeze(): - """Inspect the environment using `pip freeze`. + """Inspect the environment using `pip freeze --disable-pip-version-check version`. Returns a dictionary containing the filename (always 'requirements.txt') and contents if successful, @@ -153,7 +153,7 @@ def pip_freeze(): """ try: proc = subprocess.Popen( - [sys.executable, "-m", "pip", "freeze"], + [sys.executable, "-m", "pip", "freeze", "--disable-pip-version-check"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, @@ -168,7 +168,7 @@ def pip_freeze(): msg = pip_stderr or ("exited with code %d" % pip_status) raise EnvironmentException("Error during pip freeze: %s" % msg) - pip_stdout = "\n".join([line for line in pip_stdout.split("\n") if "rsconnect" not in line]) + pip_stdout = filter_pip_freeze_output(pip_stdout) pip_stdout = ( "# requirements.txt generated by rsconnect-python on " + str(datetime.datetime.utcnow()) + "\n" + pip_stdout @@ -182,6 +182,13 @@ def pip_freeze(): } +def filter_pip_freeze_output(pip_stdout): + # Filter out dependency on `rsconnect` and ignore output lines from pip which start with `[notice]` + return "\n".join( + [line for line in pip_stdout.split("\n") if (("rsconnect" not in line) and (line.find("[notice]") != 0))] + ) + + def strip_ref(line): # remove erroneous conda build paths that will break pip install return line.split(" @ file:", 1)[0].strip() diff --git a/rsconnect/main.py b/rsconnect/main.py index aa54d1f7..36347e2b 100644 --- a/rsconnect/main.py +++ b/rsconnect/main.py @@ -744,7 +744,7 @@ def _warn_if_no_requirements_file(directory): """ if not exists(join(directory, "requirements.txt")): click.secho( - " Warning: Capturing the environment using 'pip freeze'.\n" + " Warning: Capturing the environment using 'pip freeze --disable-pip-version-check'.\n" " Consider creating a requirements.txt file instead.", fg="yellow", ) diff --git a/tests/test_environment.py b/tests/test_environment.py index ad4688cb..5ef4f8a3 100644 --- a/tests/test_environment.py +++ b/tests/test_environment.py @@ -8,6 +8,7 @@ detect_environment, get_default_locale, get_python_version, + filter_pip_freeze_output, ) from .utils import get_dir @@ -72,3 +73,24 @@ def test_pip_freeze(self): source="pip_freeze", ) self.assertEqual(expected, result) + + def test_filter_pip_freeze_output(self): + raw_stdout = "numpy\npandas\n[notice] A new release of pip is available: 23.1.2 -> 23.3\n\ +[notice] To update, run: pip install --upgrade pip" + filtered = filter_pip_freeze_output(raw_stdout) + expected = "numpy\npandas" + + self.assertEqual(filtered, expected) + + raw_stdout = "numpy\npandas" + filtered = filter_pip_freeze_output(raw_stdout) + expected = "numpy\npandas" + + self.assertEqual(filtered, expected) + + raw_stdout = "numpy\npandas\nnot at beginning [notice]\n\ +[notice] To update, run: pip install --upgrade pip" + filtered = filter_pip_freeze_output(raw_stdout) + expected = "numpy\npandas\nnot at beginning [notice]" + + self.assertEqual(filtered, expected)