-
-
Save drconopoima/281b917f7a2a0814d7f70aed1cbaacd5 to your computer and use it in GitHub Desktop.
create venv within venv (with_pip=True)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """ | |
| Normally to create a virtual environment, we can do so from the command prompt with:: | |
| C:\Users\me>python -m venv venv | |
| This doesn't work when we are within a virtual environment though:: | |
| (venv) C:Users\me>python -m venv venv2 | |
| Error: Command '['C:\\Users\\me\\venv2\\Scripts\\python.exe', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 3221226505. | |
| The issue seems to stem from the home variable in the pyvenv.cfg created from creating the virtual environment within the virtual environment:: | |
| home = C:\Users\me\venv\Scripts | |
| include-system-site-packages = false | |
| version = 3.7.0 | |
| We need to override this home variable so that it points to a non-virtual enviroment Python. | |
| Below is a shows how to create a virtual environment even if you have a virtual environment activated. | |
| """ | |
| import os | |
| import re | |
| import subprocess | |
| import venv | |
| class EnvB(venv.EnvBuilder): | |
| """ Subclassing venv.EnvBuilder so we can customize the pyvenv.cfg file """ | |
| def create_configuration(self, context: SimpleNamespace) -> None: | |
| """ | |
| Create a configuration file indicating where the environment's Python | |
| was copied from, and whether the system site-packages should be made | |
| available in the environment. | |
| :param context: The information for the environment creation request | |
| being processed. | |
| """ | |
| context.cfg_path = path = os.path.join(context.env_dir, 'pyvenv.cfg') | |
| try: # this part is different from the superclass | |
| # we want the correct home python rather than the one from within a potential virtual environment | |
| with open(os.path.join(os.path.dirname(context.python_dir), 'pyvenv.cfg'), 'r', encoding='utf-8') as f: | |
| context.python_dir = re.search(r'home\s=\s(.+)', f.read().split('\n')[0]).group(1) | |
| except FileNotFoundError: | |
| pass # the rest is the same | |
| with open(path, 'w', encoding='utf-8') as f: | |
| f.write('home = %s\n' % context.python_dir) | |
| if self.system_site_packages: | |
| incl = 'true' | |
| else: | |
| incl = 'false' | |
| f.write('include-system-site-packages = %s\n' % incl) | |
| f.write('version = %d.%d.%d\n' % sys.version_info[:3]) | |
| def create_env(venv_dir_): | |
| venv_py = os.path.join(venv_dir_, 'Scripts', 'python.exe') | |
| v = EnvB() | |
| v.create(venv_dir_) | |
| r = subprocess.run([venv_py, '-c', 'import ensurepip;ensurepip.bootstrap(upgrade=True,default_pip=True)'], | |
| capture_output=True) | |
| if r.stderr and not r.stdout: | |
| raise Exception(r.stderr.decode('utf-8')) | |
| if __name__ == '__main__': | |
| # activate your virtual environment before running | |
| create_env(r'C:\Users\me\venv2') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment