Closes #15776: pyvenv now works with existing directories.
This commit is contained in:
parent
24dfdb69ca
commit
bd40d3e144
@ -75,8 +75,8 @@ creation according to their needs, the :class:`EnvBuilder` class.
|
|||||||
* ``system_site_packages`` -- a Boolean value indicating that the system Python
|
* ``system_site_packages`` -- a Boolean value indicating that the system Python
|
||||||
site-packages should be available to the environment (defaults to ``False``).
|
site-packages should be available to the environment (defaults to ``False``).
|
||||||
|
|
||||||
* ``clear`` -- a Boolean value which, if True, will delete any existing target
|
* ``clear`` -- a Boolean value which, if True, will delete the contents of
|
||||||
directory instead of raising an exception (defaults to ``False``).
|
any existing target directory, before creating the environment.
|
||||||
|
|
||||||
* ``symlinks`` -- a Boolean value indicating whether to attempt to symlink the
|
* ``symlinks`` -- a Boolean value indicating whether to attempt to symlink the
|
||||||
Python binary (and any necessary DLLs or other binaries,
|
Python binary (and any necessary DLLs or other binaries,
|
||||||
@ -88,7 +88,6 @@ creation according to their needs, the :class:`EnvBuilder` class.
|
|||||||
upgraded in-place (defaults to ``False``).
|
upgraded in-place (defaults to ``False``).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Creators of third-party virtual environment tools will be free to use the
|
Creators of third-party virtual environment tools will be free to use the
|
||||||
provided ``EnvBuilder`` class as a base class.
|
provided ``EnvBuilder`` class as a base class.
|
||||||
|
|
||||||
|
@ -113,13 +113,68 @@ class BasicTest(BaseTest):
|
|||||||
out, err = p.communicate()
|
out, err = p.communicate()
|
||||||
self.assertEqual(out.strip(), expected.encode())
|
self.assertEqual(out.strip(), expected.encode())
|
||||||
|
|
||||||
|
if sys.platform == 'win32':
|
||||||
|
ENV_SUBDIRS = (
|
||||||
|
('Scripts',),
|
||||||
|
('Include',),
|
||||||
|
('Lib',),
|
||||||
|
('Lib', 'site-packages'),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
ENV_SUBDIRS = (
|
||||||
|
('bin',),
|
||||||
|
('include',),
|
||||||
|
('lib',),
|
||||||
|
('lib', 'python%d.%d' % sys.version_info[:2]),
|
||||||
|
('lib', 'python%d.%d' % sys.version_info[:2], 'site-packages'),
|
||||||
|
)
|
||||||
|
|
||||||
|
def create_contents(self, paths, filename):
|
||||||
|
"""
|
||||||
|
Create some files in the environment which are unrelated
|
||||||
|
to the virtual environment.
|
||||||
|
"""
|
||||||
|
for subdirs in paths:
|
||||||
|
d = os.path.join(self.env_dir, *subdirs)
|
||||||
|
os.mkdir(d)
|
||||||
|
fn = os.path.join(d, filename)
|
||||||
|
with open(fn, 'wb') as f:
|
||||||
|
f.write(b'Still here?')
|
||||||
|
|
||||||
def test_overwrite_existing(self):
|
def test_overwrite_existing(self):
|
||||||
"""
|
"""
|
||||||
Test control of overwriting an existing environment directory.
|
Test creating environment in an existing directory.
|
||||||
"""
|
"""
|
||||||
self.assertRaises(ValueError, venv.create, self.env_dir)
|
self.create_contents(self.ENV_SUBDIRS, 'foo')
|
||||||
|
venv.create(self.env_dir)
|
||||||
|
for subdirs in self.ENV_SUBDIRS:
|
||||||
|
fn = os.path.join(self.env_dir, *(subdirs + ('foo',)))
|
||||||
|
self.assertTrue(os.path.exists(fn))
|
||||||
|
with open(fn, 'rb') as f:
|
||||||
|
self.assertEqual(f.read(), b'Still here?')
|
||||||
|
|
||||||
builder = venv.EnvBuilder(clear=True)
|
builder = venv.EnvBuilder(clear=True)
|
||||||
builder.create(self.env_dir)
|
builder.create(self.env_dir)
|
||||||
|
for subdirs in self.ENV_SUBDIRS:
|
||||||
|
fn = os.path.join(self.env_dir, *(subdirs + ('foo',)))
|
||||||
|
self.assertFalse(os.path.exists(fn))
|
||||||
|
|
||||||
|
def clear_directory(self, path):
|
||||||
|
for fn in os.listdir(path):
|
||||||
|
fn = os.path.join(path, fn)
|
||||||
|
if os.path.islink(fn) or os.path.isfile(fn):
|
||||||
|
os.remove(fn)
|
||||||
|
elif os.path.isdir(fn):
|
||||||
|
shutil.rmtree(fn)
|
||||||
|
|
||||||
|
def test_unoverwritable_fails(self):
|
||||||
|
#create a file clashing with directories in the env dir
|
||||||
|
for paths in self.ENV_SUBDIRS[:3]:
|
||||||
|
fn = os.path.join(self.env_dir, *paths)
|
||||||
|
with open(fn, 'wb') as f:
|
||||||
|
f.write(b'')
|
||||||
|
self.assertRaises((ValueError, OSError), venv.create, self.env_dir)
|
||||||
|
self.clear_directory(self.env_dir)
|
||||||
|
|
||||||
def test_upgrade(self):
|
def test_upgrade(self):
|
||||||
"""
|
"""
|
||||||
|
@ -90,6 +90,14 @@ class EnvBuilder:
|
|||||||
self.setup_scripts(context)
|
self.setup_scripts(context)
|
||||||
self.post_setup(context)
|
self.post_setup(context)
|
||||||
|
|
||||||
|
def clear_directory(self, path):
|
||||||
|
for fn in os.listdir(path):
|
||||||
|
fn = os.path.join(path, fn)
|
||||||
|
if os.path.islink(fn) or os.path.isfile(fn):
|
||||||
|
os.remove(fn)
|
||||||
|
elif os.path.isdir(fn):
|
||||||
|
shutil.rmtree(fn)
|
||||||
|
|
||||||
def ensure_directories(self, env_dir):
|
def ensure_directories(self, env_dir):
|
||||||
"""
|
"""
|
||||||
Create the directories for the environment.
|
Create the directories for the environment.
|
||||||
@ -101,11 +109,11 @@ class EnvBuilder:
|
|||||||
def create_if_needed(d):
|
def create_if_needed(d):
|
||||||
if not os.path.exists(d):
|
if not os.path.exists(d):
|
||||||
os.makedirs(d)
|
os.makedirs(d)
|
||||||
|
elif os.path.islink(d) or os.path.isfile(d):
|
||||||
|
raise ValueError('Unable to create directory %r' % d)
|
||||||
|
|
||||||
if os.path.exists(env_dir) and not (self.clear or self.upgrade):
|
|
||||||
raise ValueError('Directory exists: %s' % env_dir)
|
|
||||||
if os.path.exists(env_dir) and self.clear:
|
if os.path.exists(env_dir) and self.clear:
|
||||||
shutil.rmtree(env_dir)
|
self.clear_directory(env_dir)
|
||||||
context = Context()
|
context = Context()
|
||||||
context.env_dir = env_dir
|
context.env_dir = env_dir
|
||||||
context.env_name = os.path.split(env_dir)[1]
|
context.env_name = os.path.split(env_dir)[1]
|
||||||
@ -369,11 +377,10 @@ def main(args=None):
|
|||||||
'when symlinks are not the default for '
|
'when symlinks are not the default for '
|
||||||
'the platform.')
|
'the platform.')
|
||||||
parser.add_argument('--clear', default=False, action='store_true',
|
parser.add_argument('--clear', default=False, action='store_true',
|
||||||
dest='clear', help='Delete the environment '
|
dest='clear', help='Delete the contents of the '
|
||||||
'directory if it already '
|
'environment directory if it '
|
||||||
'exists. If not specified and '
|
'already exists, before '
|
||||||
'the directory exists, an error'
|
'environment creation.')
|
||||||
' is raised.')
|
|
||||||
parser.add_argument('--upgrade', default=False, action='store_true',
|
parser.add_argument('--upgrade', default=False, action='store_true',
|
||||||
dest='upgrade', help='Upgrade the environment '
|
dest='upgrade', help='Upgrade the environment '
|
||||||
'directory to use this version '
|
'directory to use this version '
|
||||||
|
Loading…
x
Reference in New Issue
Block a user