Skip to content

Commit 7c103c8

Browse files
authored
Add substitution {/} to os.sep (#1701)
Closes #1700
1 parent 8d40707 commit 7c103c8

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
@@ -1826,6 +1826,8 @@ def _replace_match(self, match):
18261826
"Malformed substitution; no substitution type provided",
18271827
)
18281828

1829+
if not sub_type and not g["default_value"] and sub_value == "/":
1830+
return os.sep
18291831
if sub_type == "env":
18301832
return self._replace_env(match)
18311833
if sub_type == "tty":

tests/unit/config/test_config.py

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

28052805
class TestConfigConstSubstitutions:
28062806
@pytest.mark.parametrize("pathsep", [":", ";"])
2807-
def test_replace_pathsep_unix(self, monkeypatch, newconfig, pathsep):
2807+
def test_replace_pathsep(self, monkeypatch, newconfig, pathsep):
2808+
"""Replace {:} with OS path separator."""
28082809
monkeypatch.setattr("os.pathsep", pathsep)
28092810
config = newconfig(
28102811
"""
@@ -2825,6 +2826,29 @@ def test_pathsep_regex(self):
28252826
assert mdict["substitution_value"] == ""
28262827
assert mdict["default_value"] == ""
28272828

2829+
@pytest.mark.parametrize("dirsep", ["\\", "\\\\"])
2830+
def test_dirsep_replace(self, monkeypatch, newconfig, dirsep):
2831+
"""Replace {/} with OS directory separator."""
2832+
monkeypatch.setattr("os.sep", dirsep)
2833+
config = newconfig(
2834+
"""
2835+
[testenv]
2836+
setenv =
2837+
VAR = dira{/}subdirb{/}subdirc
2838+
""",
2839+
)
2840+
envconfig = config.envconfigs["python"]
2841+
assert envconfig.setenv["VAR"] == dirsep.join(["dira", "subdirb", "subdirc"])
2842+
2843+
def test_dirsep_regex(self):
2844+
"""Sanity check for regex behavior for directory separator."""
2845+
regex = tox.config.Replacer.RE_ITEM_REF
2846+
match = next(regex.finditer("{/}"))
2847+
mdict = match.groupdict()
2848+
assert mdict["sub_type"] is None
2849+
assert mdict["substitution_value"] == "/"
2850+
assert mdict["default_value"] is None
2851+
28282852

28292853
class TestParseEnv:
28302854
def test_parse_recreate(self, newconfig):

0 commit comments

Comments
 (0)