From c685de9803cbad4f1ba6d41b413726807e16d64a Mon Sep 17 00:00:00 2001 From: Gordon Ball Date: Mon, 17 Oct 2016 15:17:05 +0200 Subject: [PATCH] Add support for path literals --- xonsh/built_ins.py | 6 ++++++ xonsh/parsers/base.py | 11 ++++++++--- xonsh/tokenize.py | 2 +- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/xonsh/built_ins.py b/xonsh/built_ins.py index 39bd68735..79c98ef0e 100644 --- a/xonsh/built_ins.py +++ b/xonsh/built_ins.py @@ -14,6 +14,7 @@ import shlex import signal import atexit import inspect +import pathlib import builtins import itertools import subprocess @@ -138,6 +139,9 @@ def reglob(path, parts=None, i=None): return paths +def path_literal(s): + return pathlib.Path(s) + def regexsearch(s): s = expand_path(s) return reglob(s) @@ -1124,6 +1128,7 @@ def load_builtins(execer=None, config=None, login=False, ctx=None): builtins.__xonsh_completers__ = xonsh.completers.init.default_completers() builtins.__xonsh_call_macro__ = call_macro builtins.__xonsh_enter_macro__ = enter_macro + builtins.__xonsh_path_literal__ = path_literal # public built-ins builtins.XonshError = XonshError builtins.XonshBlockError = XonshBlockError @@ -1192,6 +1197,7 @@ def unload_builtins(): '__xonsh_completers__', '__xonsh_call_macro__', '__xonsh_enter_macro__', + '__xonsh_path_literal__', 'XonshError', 'XonshBlockError', 'XonshCalledProcessError', diff --git a/xonsh/parsers/base.py b/xonsh/parsers/base.py index d3180d383..265de58fc 100644 --- a/xonsh/parsers/base.py +++ b/xonsh/parsers/base.py @@ -1973,9 +1973,14 @@ class BaseParser(object): def p_string_literal(self, p): """string_literal : string_tok""" p1 = p[1] - s = ast.literal_eval(p1.value) - cls = ast.Bytes if p1.value.startswith('b') else ast.Str - p[0] = cls(s=s, lineno=p1.lineno, col_offset=p1.lexpos) + if p1.value.startswith('p'): + s = ast.literal_eval(p1.value[1:]) + p[0] = xonsh_call('__xonsh_path_literal__', [s], + lineno=p1.lineno, col=p1.lexpos) + else: + s = ast.literal_eval(p1.value) + cls = ast.Bytes if p1.value.startswith('b') else ast.Str + p[0] = cls(s=s, lineno=p1.lineno, col_offset=p1.lexpos) def p_string_literal_list(self, p): """string_literal_list : string_literal diff --git a/xonsh/tokenize.py b/xonsh/tokenize.py index 974e778f9..e70d0ea3c 100644 --- a/xonsh/tokenize.py +++ b/xonsh/tokenize.py @@ -205,7 +205,7 @@ Floatnumber = group(Pointfloat, Expfloat) Imagnumber = group(r'[0-9]+[jJ]', Floatnumber + r'[jJ]') Number = group(Imagnumber, Floatnumber, Intnumber) -StringPrefix = r'(?:[bB][rR]?|[rR][bB]?|[uU])?' +StringPrefix = r'(?:[bB][rR]?|[rR][bB]?|[uU]|[p])?' # Tail end of ' string. Single = r"[^'\\]*(?:\\.[^'\\]*)*'"