Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Dollar escape #1025

Merged
merged 3 commits into from

2 participants

@takluyver
Owner

As pointed out by @stefanv and @minrk on #822, it should be possible to use a raw $ in shell commands, e.g. for environment variables. This allows that, with the "$$HOME" syntax.

@minrk
Owner

Looks good to me. Do you want to add a test to cover '${foo}' -> '$bar'? That's one probably quite rare use case that I've had to deal with long ago, where the shell variable name is a Python variable you want to expand. This works just fine right now with the syntax above, but we might add the test case anyway.

@takluyver
Owner

Yep, good idea. Done.

@minrk
Owner

Thanks, I say go ahead and merge.

@takluyver takluyver merged commit aa30a66 into ipython:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
5 IPython/core/tests/test_interactiveshell.py
@@ -201,7 +201,10 @@ def test_drop_by_id(self):
def test_var_expand(self):
ip = get_ipython()
- ip.user_ns['f'] = 'Ca\xc3\xb1o'
+ ip.user_ns['f'] = u'Ca\xf1o'
+ self.assertEqual(ip.var_expand(u'echo $f'), u'echo Ca\xf1o')
+
+ ip.user_ns['f'] = b'Ca\xc3\xb1o'
# This should not raise any exception:
ip.var_expand(u'echo $f')
View
4 IPython/utils/tests/test_text.py
@@ -107,3 +107,7 @@ def test_dollar_formatter():
nt.assert_equals(s, "12")
s = f.format("$n/{stuff[:5]}", **ns)
nt.assert_equals(s, "12/hello")
+ s = f.format("$n $$HOME", **ns)
+ nt.assert_equals(s, "12 $HOME")
+ s = f.format("${foo}", foo="HOME")
+ nt.assert_equals(s, "$HOME")
View
12 IPython/utils/text.py
@@ -663,20 +663,26 @@ class DollarFormatter(FullEvalFormatter):
In [4]: f.format('$a or {b}', a=1, b=2)
Out[4]: u'1 or 2'
"""
- _dollar_pattern = re.compile("(.*)\$([\w\.]+)")
+ _dollar_pattern = re.compile("(.*?)\$(\$?[\w\.]+)")
def parse(self, fmt_string):
for literal_txt, field_name, format_spec, conversion \
in Formatter.parse(self, fmt_string):
# Find $foo patterns in the literal text.
continue_from = 0
+ txt = ""
for m in self._dollar_pattern.finditer(literal_txt):
new_txt, new_field = m.group(1,2)
- yield (new_txt, new_field, "", None)
+ # $$foo --> $foo
+ if new_field.startswith("$"):
+ txt += new_txt + new_field
+ else:
+ yield (txt + new_txt, new_field, "", None)
+ txt = ""
continue_from = m.end()
# Re-yield the {foo} style pattern
- yield (literal_txt[continue_from:], field_name, format_spec, conversion)
+ yield (txt + literal_txt[continue_from:], field_name, format_spec, conversion)
def columnize(items, separator=' ', displaywidth=80):
Something went wrong with that request. Please try again.