Skip to content

Commit 9255958

Browse files
committed
feature(virtualenv): add 'system-site-packages' option
1 parent 6eaa298 commit 9255958

File tree

7 files changed

+46
-15
lines changed

7 files changed

+46
-15
lines changed

docs/docs/configuration.md

+6
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ cache-dir = "/path/to/cache/directory"
3535
virtualenvs.create = true
3636
virtualenvs.in-project = null
3737
virtualenvs.options.always-copy = true
38+
virtualenvs.options.system-site-packages = false
3839
virtualenvs.path = "{cache-dir}/virtualenvs" # /path/to/cache/directory/virtualenvs
3940
```
4041

@@ -143,6 +144,11 @@ Defaults to `{cache-dir}/virtualenvs` (`{cache-dir}\virtualenvs` on Windows).
143144
If set to `true` the `--always-copy` parameter is passed to `virtualenv` on creation of the venv. Thus all needed files are copied into the venv instead of symlinked.
144145
Defaults to `false`.
145146

147+
### `virtualenvs.options.system-site-packages`: boolean
148+
149+
Give the virtual environment access to the system site-packages directory.
150+
Applies on virtualenv creation.
151+
Defaults to `false`.
146152

147153
### `repositories.<name>`: string
148154

poetry/config/config.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class Config(object):
3535
"create": True,
3636
"in-project": None,
3737
"path": os.path.join("{cache-dir}", "virtualenvs"),
38-
"options": {"always-copy": False},
38+
"options": {"always-copy": False, "system-site-packages": False},
3939
},
4040
"experimental": {"new-installer": True},
4141
"installer": {"parallel": True},
@@ -140,6 +140,7 @@ def _get_normalizer(self, name: str) -> Callable:
140140
"virtualenvs.create",
141141
"virtualenvs.in-project",
142142
"virtualenvs.options.always-copy",
143+
"virtualenvs.options.system-site-packages",
143144
"installer.parallel",
144145
}:
145146
return boolean_normalizer

poetry/console/commands/config.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,16 @@ def unique_config_values(self) -> Dict[str, Tuple[Any, Any, Any]]:
6666
),
6767
"virtualenvs.create": (boolean_validator, boolean_normalizer, True),
6868
"virtualenvs.in-project": (boolean_validator, boolean_normalizer, False),
69+
"virtualenvs.options.always-copy": (
70+
boolean_validator,
71+
boolean_normalizer,
72+
False,
73+
),
74+
"virtualenvs.options.system-site-packages": (
75+
boolean_validator,
76+
boolean_normalizer,
77+
False,
78+
),
6979
"virtualenvs.path": (
7080
str,
7181
lambda val: str(Path(val)),
@@ -76,11 +86,6 @@ def unique_config_values(self) -> Dict[str, Tuple[Any, Any, Any]]:
7686
boolean_normalizer,
7787
True,
7888
),
79-
"virtualenvs.options.always-copy": (
80-
boolean_validator,
81-
boolean_normalizer,
82-
False,
83-
),
8489
"installer.parallel": (
8590
boolean_validator,
8691
boolean_normalizer,

poetry/utils/env.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -637,8 +637,8 @@ def create_venv(
637637

638638
create_venv = self._poetry.config.get("virtualenvs.create")
639639
root_venv = self._poetry.config.get("virtualenvs.in-project")
640-
641640
venv_path = self._poetry.config.get("virtualenvs.path")
641+
642642
if root_venv:
643643
venv_path = cwd / ".venv"
644644
elif venv_path is None:

tests/console/commands/test_config.py

+3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def test_list_displays_default_value_if_not_set(tester, config, config_cache_dir
3232
virtualenvs.create = true
3333
virtualenvs.in-project = null
3434
virtualenvs.options.always-copy = false
35+
virtualenvs.options.system-site-packages = false
3536
virtualenvs.path = {path} # {virtualenvs}
3637
""".format(
3738
cache=json.dumps(str(config_cache_dir)),
@@ -53,6 +54,7 @@ def test_list_displays_set_get_setting(tester, config, config_cache_dir):
5354
virtualenvs.create = false
5455
virtualenvs.in-project = null
5556
virtualenvs.options.always-copy = false
57+
virtualenvs.options.system-site-packages = false
5658
virtualenvs.path = {path} # {virtualenvs}
5759
""".format(
5860
cache=json.dumps(str(config_cache_dir)),
@@ -96,6 +98,7 @@ def test_list_displays_set_get_local_setting(tester, config, config_cache_dir):
9698
virtualenvs.create = false
9799
virtualenvs.in-project = null
98100
virtualenvs.options.always-copy = false
101+
virtualenvs.options.system-site-packages = false
99102
virtualenvs.path = {path} # {virtualenvs}
100103
""".format(
101104
cache=json.dumps(str(config_cache_dir)),

tests/test_factory.py

+2
Original file line numberDiff line numberDiff line change
@@ -222,3 +222,5 @@ def test_create_poetry_with_local_config(fixture_dir):
222222

223223
assert not poetry.config.get("virtualenvs.in-project")
224224
assert not poetry.config.get("virtualenvs.create")
225+
assert not poetry.config.get("virtualenvs.options.always-copy")
226+
assert not poetry.config.get("virtualenvs.options.system-site-packages")

tests/utils/test_env.py

+22-8
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ def test_activate_activates_non_existing_virtualenv_no_envs_file(
159159
m.assert_called_with(
160160
Path(tmp_dir) / "{}-py3.7".format(venv_name),
161161
executable="python3.7",
162-
flags={"always-copy": False},
162+
flags={"always-copy": False, "system-site-packages": False},
163163
)
164164

165165
envs_file = TOMLFile(Path(tmp_dir) / "envs.toml")
@@ -279,7 +279,7 @@ def test_activate_activates_different_virtualenv_with_envs_file(
279279
m.assert_called_with(
280280
Path(tmp_dir) / "{}-py3.6".format(venv_name),
281281
executable="python3.6",
282-
flags={"always-copy": False},
282+
flags={"always-copy": False, "system-site-packages": False},
283283
)
284284

285285
assert envs_file.exists()
@@ -333,7 +333,7 @@ def test_activate_activates_recreates_for_different_patch(
333333
build_venv_m.assert_called_with(
334334
Path(tmp_dir) / "{}-py3.7".format(venv_name),
335335
executable="python3.7",
336-
flags={"always-copy": False},
336+
flags={"always-copy": False, "system-site-packages": False},
337337
)
338338
remove_venv_m.assert_called_with(Path(tmp_dir) / "{}-py3.7".format(venv_name))
339339

@@ -661,7 +661,7 @@ def test_create_venv_tries_to_find_a_compatible_python_executable_using_generic_
661661
m.assert_called_with(
662662
config_virtualenvs_path / "{}-py3.7".format(venv_name),
663663
executable="python3",
664-
flags={"always-copy": False},
664+
flags={"always-copy": False, "system-site-packages": False},
665665
)
666666

667667

@@ -685,7 +685,7 @@ def test_create_venv_tries_to_find_a_compatible_python_executable_using_specific
685685
m.assert_called_with(
686686
config_virtualenvs_path / "{}-py3.9".format(venv_name),
687687
executable="python3.9",
688-
flags={"always-copy": False},
688+
flags={"always-copy": False, "system-site-packages": False},
689689
)
690690

691691

@@ -769,7 +769,7 @@ def test_create_venv_uses_patch_version_to_detect_compatibility(
769769
config_virtualenvs_path
770770
/ "{}-py{}.{}".format(venv_name, version.major, version.minor),
771771
executable=None,
772-
flags={"always-copy": False},
772+
flags={"always-copy": False, "system-site-packages": False},
773773
)
774774

775775

@@ -804,7 +804,7 @@ def test_create_venv_uses_patch_version_to_detect_compatibility_with_executable(
804804
config_virtualenvs_path
805805
/ "{}-py{}.{}".format(venv_name, version.major, version.minor - 1),
806806
executable="python{}.{}".format(version.major, version.minor - 1),
807-
flags={"always-copy": False},
807+
flags={"always-copy": False, "system-site-packages": False},
808808
)
809809

810810

@@ -838,7 +838,7 @@ def test_activate_with_in_project_setting_does_not_fail_if_no_venvs_dir(
838838
m.assert_called_with(
839839
poetry.file.parent / ".venv",
840840
executable="python3.7",
841-
flags={"always-copy": False},
841+
flags={"always-copy": False, "system-site-packages": False},
842842
)
843843

844844
envs_file = TOMLFile(Path(tmp_dir) / "virtualenvs" / "envs.toml")
@@ -875,3 +875,17 @@ def test_venv_has_correct_paths(tmp_venv):
875875
assert paths.get("platlib") is not None
876876
assert paths.get("scripts") is not None
877877
assert tmp_venv.site_packages.path == Path(paths["purelib"])
878+
879+
880+
def test_env_system_packages(tmp_path, config):
881+
venv_path = tmp_path / "venv"
882+
pyvenv_cfg = venv_path / "pyvenv.cfg"
883+
884+
EnvManager(config).build_venv(path=venv_path, flags={"system-site-packages": True})
885+
886+
if sys.version_info >= (3, 3):
887+
assert "include-system-site-packages = true" in pyvenv_cfg.read_text()
888+
elif (2, 6) < sys.version_info < (3, 0):
889+
assert not venv_path.joinpath(
890+
"lib", "python2.7", "no-global-site-packages.txt"
891+
).exists()

0 commit comments

Comments
 (0)