From a9da2da158dca4238dc385f5619f1a67291010a2 Mon Sep 17 00:00:00 2001 From: gilgamezh Date: Sat, 20 Jun 2026 13:22:24 +0200 Subject: [PATCH 1/5] Allow --rm to remove a virtualenv by its dependencies '--rm' now takes an optional UUID: when passed a UUID it removes that virtualenv as before, but when given as a bare flag it removes the virtualenv matching the indicated dependencies (e.g. 'fades --rm -d django'), saving the round-trip through '--where' to look up the UUID. Add tests for the '--rm' flow in go() (by UUID and by dependencies), and update the man page and README accordingly. Co-Authored-By: Claude Opus 4.8 --- README.rst | 10 ++++++++ fades/main.py | 57 +++++++++++++++++++++++++++------------------- man/fades.1 | 6 ++--- tests/test_main.py | 53 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 99 insertions(+), 27 deletions(-) diff --git a/README.rst b/README.rst index 3e3ff62..b682266 100644 --- a/README.rst +++ b/README.rst @@ -470,6 +470,12 @@ virtual environment matching the provided UUID if such environment exists (one e way to find out the environment's UUID is calling *fades* with the ``--where`` option). +Alternatively, you can pass ``--rm`` without a UUID and indicate the dependencies +instead; *fades* will then remove the virtual environment that matches those +dependencies, just like it would select it to run something:: + + fades --rm -d django + Another way to clean up the cache is to remove all venvs that haven't been used for some time. In order to do this you need to call *fades* with ``--clean-unused-venvs``. When fades it's called with this option, it runs in mantain mode, this means that fades will exit @@ -519,6 +525,10 @@ Remove a virtual environment matching the given uuid from disk and cache index:: fades --rm 89a2bf83-c280-4918-a78d-c35506efd69d +Remove the virtual environment matching the indicated dependencies from disk and cache index:: + + fades --rm -d django + Download the script from the given pastebin and executes it (previously building a virtual environment for the dependencies indicated in that pastebin, of course):: fades http://linkode.org/#4QI4TrPlGf1gK2V7jPBC47 diff --git a/fades/main.py b/fades/main.py index 0a3f47a..671d450 100644 --- a/fades/main.py +++ b/fades/main.py @@ -45,6 +45,10 @@ # the rest of the module just fine logger = logging.getLogger('fades') +# sentinel used as the '--rm' value when it's given as a bare flag (no UUID), meaning +# "remove the virtualenv that matches the indicated dependencies" +REMOVE_BY_DEPS = object() + # the signals to redirect to the child process (note: only these are # allowed in Windows, see 'signal' doc). REDIRECTED_SIGNALS = [ @@ -263,8 +267,10 @@ def go(): '--python-options', action='append', default=[], help="extra options to be supplied to python (this option can be used multiple times)") parser.add_argument( - '--rm', dest='remove', metavar='UUID', - help="remove a virtualenv by UUID; see --where option to easily find out the UUID") + '--rm', dest='remove', metavar='UUID', nargs='?', const=REMOVE_BY_DEPS, default=None, + help="remove a virtualenv: by UUID if one is given (see --where to easily find out the " + "UUID), or by the indicated dependencies if no UUID is passed " + "(e.g. 'fades --rm -d django')") parser.add_argument( '--clean-unused-venvs', action='store', help="remove venvs that haven't been used for more than the indicated days and compact " @@ -363,22 +369,6 @@ def go(): usage_manager.clean_unused_venvs(max_days_to_keep) return 0 - uuid = args.remove - if uuid: - venv_data = venvscache.get_venv(uuid=uuid) - if venv_data: - # remove this venv from the cache - env_path = venv_data.get('env_path') - if env_path: - envbuilder.destroy_venv(env_path, venvscache) - else: - logger.warning( - "Invalid 'env_path' found in virtualenv metadata: %r. " - "Not removing virtualenv.", env_path) - else: - logger.warning('No virtualenv found with uuid: %s.', uuid) - return 0 - # decided which the child program really is analyzable_child_program, child_program = decide_child_program( args.executable, args.module, args.child_program) @@ -387,10 +377,6 @@ def go(): indicated_deps = consolidate_dependencies( args.ipython, analyzable_child_program, args.requirement, args.dependency) - # Check for packages updates - if args.check_updates: - helpers.check_pypi_updates(indicated_deps) - # decide the interpreter to use, considering the one indicated with --python and the # Python version the script declares it needs in its '# /// script' metadata block, if any # (this may find in PATH a different interpreter than fades' own) @@ -408,8 +394,33 @@ def go(): if args.system_site_packages: options['venv_options'].append("--system-site-packages") + # remove a virtualenv, either by the given UUID or by the indicated dependencies + if args.remove is not None: + if args.remove is REMOVE_BY_DEPS: + venv_data = venvscache.get_venv(indicated_deps, interpreter, options=options) + descriptor = "the indicated dependencies" + else: + venv_data = venvscache.get_venv(uuid=args.remove) + descriptor = "uuid: {}".format(args.remove) + if venv_data: + # remove this venv from the cache + env_path = venv_data.get('env_path') + if env_path: + envbuilder.destroy_venv(env_path, venvscache) + else: + logger.warning( + "Invalid 'env_path' found in virtualenv metadata: %r. " + "Not removing virtualenv.", env_path) + else: + logger.warning('No virtualenv found with %s.', descriptor) + return 0 + + # Check for packages updates + if args.check_updates: + helpers.check_pypi_updates(indicated_deps) + create_venv = False - venv_data = venvscache.get_venv(indicated_deps, interpreter, uuid, options) + venv_data = venvscache.get_venv(indicated_deps, interpreter, options=options) if venv_data: env_path = venv_data['env_path'] # A venv was found in the cache check if its valid or re-generate it. diff --git a/man/fades.1 b/man/fades.1 index e9631c7..7b00e92 100644 --- a/man/fades.1 +++ b/man/fades.1 @@ -14,7 +14,7 @@ fades - A system that automatically handles the virtualenvs in the cases normall [\fB-r\fR][\fB--requirement\fR] [\fB-x\fR][\fB--exec\fR] [\fB-p\fR \fIversion\fR][\fB--python\fR=\fIversion\fR] -[\fB--rm\fR=\fIUUID\fR] +[\fB--rm\fR[=\fIUUID\fR]] [\fB--system-site-packages\fR] [\fB--venv-options\fR=\fIoptions\fR] [\fB--pip-options\fR=\fIoptions\fR] @@ -93,8 +93,8 @@ The dependencies can be indicated in multiple places (in the Python source file, Execute the \fIchild_program\fR in the context of the virtual environment. The child_program, which in this case becomes a mandatory parameter, can be just the executable name (relative to the venv's bin directory) or an absolute path. .TP -.BR --rm " " \fIUUID\fR -Remove a virtual environment by UUID. See \fB--get-venv-dir\fR option to easily find out the UUID. +.BR --rm " " [\fIUUID\fR] +Remove a virtual environment. If a UUID is given, the environment with that UUID is removed (see \fB--get-venv-dir\fR option to easily find out the UUID); if no UUID is given, the environment matching the indicated dependencies is removed (e.g. \fBfades --rm -d django\fR). .TP .BR --system-site-packages "" diff --git a/tests/test_main.py b/tests/test_main.py index fd42154..7d2830d 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -19,7 +19,7 @@ import os import unittest from pathlib import Path -from unittest.mock import patch +from unittest.mock import MagicMock, patch from packaging.requirements import Requirement @@ -318,6 +318,57 @@ def test_module(self): self.assertEqual(child, child_path) +class RemoveVenvTestCase(unittest.TestCase): + """Check the '--rm' option, removing by uuid or by the indicated dependencies.""" + + def _run(self, cmdline_args, found_venv): + """Run go() with the given cli args, mocking the cache and the venv destruction. + + 'found_venv' is the metadata returned by the cache lookup (or None when nothing matches). + Returns the mocked cache and destroy_venv so the test can check how they were called. + """ + venvscache = MagicMock() + venvscache.get_venv.return_value = found_venv + with patch('sys.argv', ['fades'] + cmdline_args), \ + patch('fades.main.detect_inside_virtualenv', return_value=False), \ + patch('fades.cache.VEnvsCache', return_value=venvscache), \ + patch('fades.envbuilder.UsageManager'), \ + patch('fades.helpers.get_basedir', return_value=Path('/tmp/fades-test')), \ + patch('fades.envbuilder.destroy_venv') as destroy_venv: + result = main.go() + self.assertEqual(result, 0) + return venvscache, destroy_venv + + def test_by_uuid_found(self): + venvscache, destroy_venv = self._run( + ['--rm', 'some-uuid'], found_venv={'env_path': '/path/to/venv'}) + venvscache.get_venv.assert_called_once_with(uuid='some-uuid') + destroy_venv.assert_called_once_with('/path/to/venv', venvscache) + + def test_by_uuid_not_found(self): + venvscache, destroy_venv = self._run(['--rm', 'some-uuid'], found_venv=None) + venvscache.get_venv.assert_called_once_with(uuid='some-uuid') + destroy_venv.assert_not_called() + + def test_by_uuid_invalid_env_path(self): + _, destroy_venv = self._run(['--rm', 'some-uuid'], found_venv={'env_path': None}) + destroy_venv.assert_not_called() + + def test_by_dependencies_found(self): + venvscache, destroy_venv = self._run( + ['--rm', '-d', 'foo'], found_venv={'env_path': '/path/to/venv'}) + # the lookup is done by the indicated dependencies, not by uuid + (_, kwargs) = venvscache.get_venv.call_args + self.assertNotIn('uuid', kwargs) + deps = venvscache.get_venv.call_args[0][0] + self.assertIn('foo', [req.name for req in deps[REPO_PYPI]]) + destroy_venv.assert_called_once_with('/path/to/venv', venvscache) + + def test_by_dependencies_not_found(self): + venvscache, destroy_venv = self._run(['--rm', '-d', 'foo'], found_venv=None) + destroy_venv.assert_not_called() + + # --------------------------------------- # autoimport tests From aa0afbef7273288c6616d4fabb50b0d1adad71fb Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 17 Oct 2026 12:46:32 +0000 Subject: [PATCH 2/5] Address review: drop redundant --rm default, use --where in man page Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01M8yxMZWHoMvnGE8biuNrGb --- fades/main.py | 2 +- man/fades.1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fades/main.py b/fades/main.py index 671d450..15750ec 100644 --- a/fades/main.py +++ b/fades/main.py @@ -267,7 +267,7 @@ def go(): '--python-options', action='append', default=[], help="extra options to be supplied to python (this option can be used multiple times)") parser.add_argument( - '--rm', dest='remove', metavar='UUID', nargs='?', const=REMOVE_BY_DEPS, default=None, + '--rm', dest='remove', metavar='UUID', nargs='?', const=REMOVE_BY_DEPS, help="remove a virtualenv: by UUID if one is given (see --where to easily find out the " "UUID), or by the indicated dependencies if no UUID is passed " "(e.g. 'fades --rm -d django')") diff --git a/man/fades.1 b/man/fades.1 index 7b00e92..c684c79 100644 --- a/man/fades.1 +++ b/man/fades.1 @@ -94,7 +94,7 @@ Execute the \fIchild_program\fR in the context of the virtual environment. The c .TP .BR --rm " " [\fIUUID\fR] -Remove a virtual environment. If a UUID is given, the environment with that UUID is removed (see \fB--get-venv-dir\fR option to easily find out the UUID); if no UUID is given, the environment matching the indicated dependencies is removed (e.g. \fBfades --rm -d django\fR). +Remove a virtual environment. If a UUID is given, the environment with that UUID is removed (see \fB--where\fR option to easily find out the UUID); if no UUID is given, the environment matching the indicated dependencies is removed (e.g. \fBfades --rm -d django\fR). .TP .BR --system-site-packages "" From 0be0a06ec947ef3af5392524051c801914b5cabd Mon Sep 17 00:00:00 2001 From: gilgamezh Date: Sat, 17 Oct 2026 16:21:33 +0200 Subject: [PATCH 3/5] Make 'fades --rm script.py' remove the venv of the script As '--rm' takes an optional UUID, argparse grabs the script as its value. Venv UUIDs are always valid UUIDs, so a value that isn't one is taken as the child program, removing the venv by its dependencies. The bare '--rm' value is now an empty string instead of an object() sentinel, so the value is always None or a str. Co-Authored-By: Claude Opus 5.5 --- fades/main.py | 27 ++++++++++++------ tests/test_main.py | 68 ++++++++++++++++++++++++++++++++++++---------- 2 files changed, 72 insertions(+), 23 deletions(-) diff --git a/fades/main.py b/fades/main.py index 15750ec..20dcc4b 100644 --- a/fades/main.py +++ b/fades/main.py @@ -25,6 +25,7 @@ import sys import subprocess import tempfile +import uuid from pathlib import Path import fades @@ -45,10 +46,6 @@ # the rest of the module just fine logger = logging.getLogger('fades') -# sentinel used as the '--rm' value when it's given as a bare flag (no UUID), meaning -# "remove the virtualenv that matches the indicated dependencies" -REMOVE_BY_DEPS = object() - # the signals to redirect to the child process (note: only these are # allowed in Windows, see 'signal' doc). REDIRECTED_SIGNALS = [ @@ -267,7 +264,7 @@ def go(): '--python-options', action='append', default=[], help="extra options to be supplied to python (this option can be used multiple times)") parser.add_argument( - '--rm', dest='remove', metavar='UUID', nargs='?', const=REMOVE_BY_DEPS, + '--rm', dest='remove', metavar='UUID', nargs='?', const='', help="remove a virtualenv: by UUID if one is given (see --where to easily find out the " "UUID), or by the indicated dependencies if no UUID is passed " "(e.g. 'fades --rm -d django')") @@ -317,6 +314,18 @@ def go(): # update args from config file (if needed). args = file_options.options_from_file(cli_args) + # '--rm' takes an optional UUID, so in 'fades --rm script.py' argparse grabs the script as + # its value; venv UUIDs are always valid UUIDs, so anything else is really the child program + if args.remove is not None: + try: + uuid.UUID(args.remove) + except ValueError: + if args.remove: + if args.child_program is not None: + args.child_options.insert(0, args.child_program) + args.child_program = args.remove + args.remove = '' + # validate input, parameters, and support some special options if args.version: print("Running 'fades' version", fades.__version__) @@ -396,12 +405,12 @@ def go(): # remove a virtualenv, either by the given UUID or by the indicated dependencies if args.remove is not None: - if args.remove is REMOVE_BY_DEPS: - venv_data = venvscache.get_venv(indicated_deps, interpreter, options=options) - descriptor = "the indicated dependencies" - else: + if args.remove: venv_data = venvscache.get_venv(uuid=args.remove) descriptor = "uuid: {}".format(args.remove) + else: + venv_data = venvscache.get_venv(indicated_deps, interpreter, options=options) + descriptor = "the indicated dependencies" if venv_data: # remove this venv from the cache env_path = venv_data.get('env_path') diff --git a/tests/test_main.py b/tests/test_main.py index 7d2830d..24591c5 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -18,12 +18,15 @@ import os import unittest +import uuid from pathlib import Path from unittest.mock import MagicMock, patch from packaging.requirements import Requirement -from fades import VERSION, FadesError, __version__, helpers, main, parsing, REPO_PYPI, REPO_VCS +from fades import ( + VERSION, FadesError, __version__, file_options, helpers, main, parsing, REPO_PYPI, + REPO_VCS) from tests import create_tempfile @@ -325,7 +328,8 @@ def _run(self, cmdline_args, found_venv): """Run go() with the given cli args, mocking the cache and the venv destruction. 'found_venv' is the metadata returned by the cache lookup (or None when nothing matches). - Returns the mocked cache and destroy_venv so the test can check how they were called. + Returns the mocked cache and destroy_venv so the test can check how they were called, + and the parsed arguments. """ venvscache = MagicMock() venvscache.get_venv.return_value = found_venv @@ -334,40 +338,76 @@ def _run(self, cmdline_args, found_venv): patch('fades.cache.VEnvsCache', return_value=venvscache), \ patch('fades.envbuilder.UsageManager'), \ patch('fades.helpers.get_basedir', return_value=Path('/tmp/fades-test')), \ + patch('fades.file_options.options_from_file', + wraps=file_options.options_from_file) as options_from_file, \ patch('fades.envbuilder.destroy_venv') as destroy_venv: result = main.go() self.assertEqual(result, 0) - return venvscache, destroy_venv + # the parsed arguments are updated in place, so these are the final ones + (args,), _ = options_from_file.call_args + return venvscache, destroy_venv, args def test_by_uuid_found(self): - venvscache, destroy_venv = self._run( - ['--rm', 'some-uuid'], found_venv={'env_path': '/path/to/venv'}) - venvscache.get_venv.assert_called_once_with(uuid='some-uuid') + venv_uuid = str(uuid.uuid4()) + venvscache, destroy_venv, _ = self._run( + ['--rm', venv_uuid], found_venv={'env_path': '/path/to/venv'}) + venvscache.get_venv.assert_called_once_with(uuid=venv_uuid) destroy_venv.assert_called_once_with('/path/to/venv', venvscache) def test_by_uuid_not_found(self): - venvscache, destroy_venv = self._run(['--rm', 'some-uuid'], found_venv=None) - venvscache.get_venv.assert_called_once_with(uuid='some-uuid') + venv_uuid = str(uuid.uuid4()) + venvscache, destroy_venv, _ = self._run(['--rm', venv_uuid], found_venv=None) + venvscache.get_venv.assert_called_once_with(uuid=venv_uuid) destroy_venv.assert_not_called() def test_by_uuid_invalid_env_path(self): - _, destroy_venv = self._run(['--rm', 'some-uuid'], found_venv={'env_path': None}) + _, destroy_venv, _ = self._run( + ['--rm', str(uuid.uuid4())], found_venv={'env_path': None}) destroy_venv.assert_not_called() - def test_by_dependencies_found(self): - venvscache, destroy_venv = self._run( - ['--rm', '-d', 'foo'], found_venv={'env_path': '/path/to/venv'}) + def _assert_removed_by_deps(self, venvscache, destroy_venv, dep_name): + """Check that the venv was looked up by the indicated dependencies and removed.""" # the lookup is done by the indicated dependencies, not by uuid (_, kwargs) = venvscache.get_venv.call_args self.assertNotIn('uuid', kwargs) deps = venvscache.get_venv.call_args[0][0] - self.assertIn('foo', [req.name for req in deps[REPO_PYPI]]) + self.assertIn(dep_name, [req.name for req in deps[REPO_PYPI]]) destroy_venv.assert_called_once_with('/path/to/venv', venvscache) + def test_by_dependencies_found(self): + venvscache, destroy_venv, _ = self._run( + ['--rm', '-d', 'foo'], found_venv={'env_path': '/path/to/venv'}) + self._assert_removed_by_deps(venvscache, destroy_venv, 'foo') + def test_by_dependencies_not_found(self): - venvscache, destroy_venv = self._run(['--rm', '-d', 'foo'], found_venv=None) + venvscache, destroy_venv, _ = self._run(['--rm', '-d', 'foo'], found_venv=None) destroy_venv.assert_not_called() + def test_by_dependencies_after_double_dash(self): + script = create_tempfile(self, ['import foo # fades']) + venvscache, destroy_venv, args = self._run( + ['--rm', '--', script], found_venv={'env_path': '/path/to/venv'}) + self._assert_removed_by_deps(venvscache, destroy_venv, 'foo') + self.assertEqual(args.child_program, script) + + def test_by_script_dependencies(self): + # argparse takes the script as the '--rm' value, but it's not a UUID + script = create_tempfile(self, ['import foo # fades']) + venvscache, destroy_venv, args = self._run( + ['--rm', script], found_venv={'env_path': '/path/to/venv'}) + self._assert_removed_by_deps(venvscache, destroy_venv, 'foo') + self.assertEqual(args.child_program, script) + self.assertEqual(args.child_options, []) + + def test_by_script_dependencies_with_options(self): + # the script options must not be taken as the child program + script = create_tempfile(self, ['import foo # fades']) + venvscache, destroy_venv, args = self._run( + ['--rm', script, 'arg1', '--opt'], found_venv={'env_path': '/path/to/venv'}) + self._assert_removed_by_deps(venvscache, destroy_venv, 'foo') + self.assertEqual(args.child_program, script) + self.assertEqual(args.child_options, ['arg1', '--opt']) + # --------------------------------------- # autoimport tests From 773c534fab9b93131024c4eecd2e81dc52531cb9 Mon Sep 17 00:00:00 2001 From: gilgamezh Date: Thu, 22 Oct 2026 11:40:12 +0200 Subject: [PATCH 4/5] README: use 'fades --rm script.py' in the commands examples Co-Authored-By: Claude Opus 5.5 --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index b682266..7d3748e 100644 --- a/README.rst +++ b/README.rst @@ -525,9 +525,9 @@ Remove a virtual environment matching the given uuid from disk and cache index:: fades --rm 89a2bf83-c280-4918-a78d-c35506efd69d -Remove the virtual environment matching the indicated dependencies from disk and cache index:: +Remove the virtual environment built for the dependencies indicated inside a script, from disk and cache index:: - fades --rm -d django + fades --rm script.py Download the script from the given pastebin and executes it (previously building a virtual environment for the dependencies indicated in that pastebin, of course):: From 073106010603f3a2dbb8a5cfc01f704b797dac3c Mon Sep 17 00:00:00 2001 From: gilgamezh Date: Mon, 26 Oct 2026 14:56:39 +0100 Subject: [PATCH 5/5] Address review: explicit remove_flag for --rm, one import per line Co-Authored-By: Claude Opus 5.5 --- fades/main.py | 35 ++++++++++++++++++++--------------- tests/test_main.py | 12 ++++++++++-- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/fades/main.py b/fades/main.py index 20dcc4b..bfb602c 100644 --- a/fades/main.py +++ b/fades/main.py @@ -57,6 +57,10 @@ signal.SIGTERM, ] +# special value for '--rm' to remove the virtualenv of the indicated dependencies (instead of +# the one with the UUID given by the user) +BY_DEPENDENCIES = object() + HELP_EPILOG = """ The "child program" is the script that fades will execute. It's an optional parameter, it will be the first thing received by fades that @@ -264,7 +268,7 @@ def go(): '--python-options', action='append', default=[], help="extra options to be supplied to python (this option can be used multiple times)") parser.add_argument( - '--rm', dest='remove', metavar='UUID', nargs='?', const='', + '--rm', dest='remove', metavar='UUID', nargs='?', const=BY_DEPENDENCIES, help="remove a virtualenv: by UUID if one is given (see --where to easily find out the " "UUID), or by the indicated dependencies if no UUID is passed " "(e.g. 'fades --rm -d django')") @@ -314,17 +318,18 @@ def go(): # update args from config file (if needed). args = file_options.options_from_file(cli_args) - # '--rm' takes an optional UUID, so in 'fades --rm script.py' argparse grabs the script as - # its value; venv UUIDs are always valid UUIDs, so anything else is really the child program - if args.remove is not None: + # what to remove (if '--rm' was given): the UUID indicated by the user, or BY_DEPENDENCIES + remove_flag = args.remove + if remove_flag is not None and remove_flag is not BY_DEPENDENCIES: + # '--rm' takes an optional UUID, so in 'fades --rm script.py' argparse grabs the script + # as its value; venv UUIDs are always valid UUIDs, so anything else is the child program try: - uuid.UUID(args.remove) + uuid.UUID(remove_flag) except ValueError: - if args.remove: - if args.child_program is not None: - args.child_options.insert(0, args.child_program) - args.child_program = args.remove - args.remove = '' + if args.child_program is not None: + args.child_options.insert(0, args.child_program) + args.child_program = remove_flag + remove_flag = BY_DEPENDENCIES # validate input, parameters, and support some special options if args.version: @@ -404,13 +409,13 @@ def go(): options['venv_options'].append("--system-site-packages") # remove a virtualenv, either by the given UUID or by the indicated dependencies - if args.remove is not None: - if args.remove: - venv_data = venvscache.get_venv(uuid=args.remove) - descriptor = "uuid: {}".format(args.remove) - else: + if remove_flag is not None: + if remove_flag is BY_DEPENDENCIES: venv_data = venvscache.get_venv(indicated_deps, interpreter, options=options) descriptor = "the indicated dependencies" + else: + venv_data = venvscache.get_venv(uuid=remove_flag) + descriptor = "uuid: {}".format(remove_flag) if venv_data: # remove this venv from the cache env_path = venv_data.get('env_path') diff --git a/tests/test_main.py b/tests/test_main.py index 24591c5..f29bfa6 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -25,8 +25,16 @@ from packaging.requirements import Requirement from fades import ( - VERSION, FadesError, __version__, file_options, helpers, main, parsing, REPO_PYPI, - REPO_VCS) + FadesError, + REPO_PYPI, + REPO_VCS, + VERSION, + __version__, + file_options, + helpers, + main, + parsing, +) from tests import create_tempfile