Patchwork D2525: convert: add some utility code for working with shlex on Python 3

login
register
mail settings
Submitter phabricator
Date March 1, 2018, 11:22 p.m.
Message ID <differential-rev-PHID-DREV-gkbx3bfvt4h7ghkddnxs-req@phab.mercurial-scm.org>
Download mbox | patch
Permalink /patch/28617/
State Superseded
Headers show

Comments

phabricator - March 1, 2018, 11:22 p.m.
durin42 created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  This could have gone in pycompat, but it's only needed in convert, so
  I figured it made more sense here. It's got py3 in the name and checks
  pycompat.ispy3, so we'll find it whenever we decide to drop Python 2
  support in 20x6.
  
  1. no-check-commit because of required foo_bar naming on the proxy class

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2525

AFFECTED FILES
  hgext/convert/common.py

CHANGE DETAILS




To: durin42, #hg-reviewers
Cc: mercurial-devel

Patch

diff --git a/hgext/convert/common.py b/hgext/convert/common.py
--- a/hgext/convert/common.py
+++ b/hgext/convert/common.py
@@ -11,6 +11,7 @@ 
 import errno
 import os
 import re
+import shlex
 import subprocess
 
 from mercurial.i18n import _
@@ -25,6 +26,58 @@ 
 pickle = util.pickle
 propertycache = util.propertycache
 
+def _encodeornone(d):
+    if d is None:
+        return
+    return d.encode('latin1')
+
+class _shlexpy3proxy(object):
+
+    def __init__(self, l):
+        self._l = l
+
+    def __iter__(self):
+        return (_encodeornone(v) for v in self._l)
+
+    def get_token(self):
+        return _encodeornone(self._l.get_token())
+
+    @property
+    def infile(self):
+        return self._l.infile or '<unknown>'
+
+    @property
+    def lineno(self):
+        return self._l.lineno
+
+def shlexer(data=None, filepath=None, wordchars=None, whitespace=None):
+    if data is None:
+        if pycompat.ispy3:
+            data = open(filepath, 'r', encoding=r'latin1')
+        else:
+            data = open(filepath, 'r')
+    else:
+        if filepath is not None:
+            raise error.ProgrammingError(
+                'shlexer only accepts data or filepath, not both')
+        if pycompat.ispy3:
+            data = data.decode('latin1')
+    l = shlex.shlex(data, infile=filepath, posix=True)
+    if whitespace is not None:
+        l.whitespace_split = True
+        if pycompat.ispy3:
+            l.whitespace += whitespace.decode('latin1')
+        else:
+            l.whitespace += whitespace
+    if wordchars is not None:
+        if pycompat.ispy3:
+            l.wordchars += wordchars.decode('latin1')
+        else:
+            l.wordchars += wordchars
+    if pycompat.ispy3:
+        return _shlexpy3proxy(l)
+    return l
+
 def encodeargs(args):
     def encodearg(s):
         lines = base64.encodestring(s)