Skip to content

Commit 60cda3c

Browse files
committed
Add substitution {/} to os.sep
Closes #1700
1 parent e4d0d60 commit 60cda3c

File tree

4 files changed

+34
-1
lines changed

4 files changed

+34
-1
lines changed

docs/changelog/1700.feature.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Allow {/} to refer to os.sep. - by :user:`jayvdb`

docs/config.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,12 @@ Globally available substitutions
669669
OS-specific path separator (``:`` os \*nix family, ``;`` on Windows). May be used in ``setenv``,
670670
when target variable is path variable (e.g. PATH or PYTHONPATH).
671671

672+
``{/}``
673+
OS-specific directory separator (``/`` os \*nix family, ``\\`` on Windows).
674+
Useful for deriving filenames from preset paths, as arguments for commands
675+
that requires ``\\`` on Windows. e.g. ``{distdir}{/}file.txt``.
676+
It is not usually needed when using commands written in Python.
677+
672678
Substitutions for virtualenv-related sections
673679
+++++++++++++++++++++++++++++++++++++++++++++
674680

src/tox/config/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,6 +1811,8 @@ def _replace_match(self, match):
18111811
"Malformed substitution; no substitution type provided",
18121812
)
18131813

1814+
if not sub_type and not g["default_value"] and sub_value == "/":
1815+
return os.sep
18141816
if sub_type == "env":
18151817
return self._replace_env(match)
18161818
if sub_type == "tty":

tests/unit/config/test_config.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2792,7 +2792,8 @@ def test_multiple_homedir_relative_local_indexservers(self, newconfig):
27922792

27932793
class TestConfigConstSubstitutions:
27942794
@pytest.mark.parametrize("pathsep", [":", ";"])
2795-
def test_replace_pathsep_unix(self, monkeypatch, newconfig, pathsep):
2795+
def test_replace_pathsep(self, monkeypatch, newconfig, pathsep):
2796+
"""Replace {:} with OS path separator."""
27962797
monkeypatch.setattr("os.pathsep", pathsep)
27972798
config = newconfig(
27982799
"""
@@ -2813,6 +2814,29 @@ def test_pathsep_regex(self):
28132814
assert mdict["substitution_value"] == ""
28142815
assert mdict["default_value"] == ""
28152816

2817+
@pytest.mark.parametrize("dirsep", ["\\", "\\\\"])
2818+
def test_dirsep_replace(self, monkeypatch, newconfig, dirsep):
2819+
"""Replace {/} with OS directory separator."""
2820+
monkeypatch.setattr("os.sep", dirsep)
2821+
config = newconfig(
2822+
"""
2823+
[testenv]
2824+
setenv =
2825+
VAR = dira{/}subdirb{/}subdirc
2826+
""",
2827+
)
2828+
envconfig = config.envconfigs["python"]
2829+
assert envconfig.setenv["VAR"] == dirsep.join(["dira", "subdirb", "subdirc"])
2830+
2831+
def test_dirsep_regex(self):
2832+
"""Sanity check for regex behavior for directory separator."""
2833+
regex = tox.config.Replacer.RE_ITEM_REF
2834+
match = next(regex.finditer("{/}"))
2835+
mdict = match.groupdict()
2836+
assert mdict["sub_type"] is None
2837+
assert mdict["substitution_value"] == "/"
2838+
assert mdict["default_value"] is None
2839+
28162840

28172841
class TestParseEnv:
28182842
def test_parse_recreate(self, newconfig):

0 commit comments

Comments
 (0)