]> granicus.if.org Git - python/commitdiff
Issue #21840: Fixed expanding unicode variables of form $var in
authorSerhiy Storchaka <storchaka@gmail.com>
Fri, 13 Feb 2015 10:02:05 +0000 (12:02 +0200)
committerSerhiy Storchaka <storchaka@gmail.com>
Fri, 13 Feb 2015 10:02:05 +0000 (12:02 +0200)
posixpath.expandvars().  Fixed all os.path implementations on
unicode-disabled builds.

Lib/genericpath.py
Lib/macpath.py
Lib/ntpath.py
Lib/os2emxpath.py
Lib/posixpath.py
Lib/test/test_genericpath.py
Lib/test/test_macpath.py
Lib/test/test_ntpath.py
Lib/test/test_posixpath.py
Misc/NEWS

index 7ddb94c08b9261f6c53959b6ab53a884d262fa4a..2648e5457ed730f68d93967e7c16cec834434ed6 100644 (file)
@@ -10,6 +10,14 @@ __all__ = ['commonprefix', 'exists', 'getatime', 'getctime', 'getmtime',
            'getsize', 'isdir', 'isfile']
 
 
+try:
+    _unicode = unicode
+except NameError:
+    # If Python is built without Unicode support, the unicode type
+    # will not exist. Fake one.
+    class _unicode(object):
+        pass
+
 # Does a path exist?
 # This is false for dangling symbolic links on systems that support them.
 def exists(path):
index c31bdaade1f5b4f04a0b8557b8992ad45701ae39..9ebd83cf90db9e43cf88137d2fc906296044447e 100644 (file)
@@ -5,6 +5,7 @@ import warnings
 from stat import *
 import genericpath
 from genericpath import *
+from genericpath import _unicode
 
 __all__ = ["normcase","isabs","join","splitdrive","split","splitext",
            "basename","dirname","commonprefix","getsize","getmtime",
@@ -186,7 +187,7 @@ def walk(top, func, arg):
 def abspath(path):
     """Return an absolute path."""
     if not isabs(path):
-        if isinstance(path, unicode):
+        if isinstance(path, _unicode):
             cwd = os.getcwdu()
         else:
             cwd = os.getcwd()
index fcaf21b6b7830d521581d207129b1f24f5689a99..11e4470a467fd6c48ec1ca61621dfae4d68c4a7e 100644 (file)
@@ -12,6 +12,7 @@ import genericpath
 import warnings
 
 from genericpath import *
+from genericpath import _unicode
 
 __all__ = ["normcase","isabs","join","splitdrive","split","splitext",
            "basename","dirname","commonprefix","getsize","getmtime",
@@ -331,7 +332,7 @@ def expandvars(path):
         return path
     import string
     varchars = string.ascii_letters + string.digits + '_-'
-    if isinstance(path, unicode):
+    if isinstance(path, _unicode):
         encoding = sys.getfilesystemencoding()
         def getenv(var):
             return os.environ[var.encode(encoding)].decode(encoding)
@@ -414,7 +415,7 @@ def expandvars(path):
 def normpath(path):
     """Normalize path, eliminating double slashes, etc."""
     # Preserve unicode (if path is unicode)
-    backslash, dot = (u'\\', u'.') if isinstance(path, unicode) else ('\\', '.')
+    backslash, dot = (u'\\', u'.') if isinstance(path, _unicode) else ('\\', '.')
     if path.startswith(('\\\\.\\', '\\\\?\\')):
         # in the case of paths with these prefixes:
         # \\.\ -> device names
@@ -471,7 +472,7 @@ except ImportError: # not running on Windows - mock up something sensible
     def abspath(path):
         """Return the absolute version of a path."""
         if not isabs(path):
-            if isinstance(path, unicode):
+            if isinstance(path, _unicode):
                 cwd = os.getcwdu()
             else:
                 cwd = os.getcwd()
@@ -487,7 +488,7 @@ else:  # use native Windows method on Windows
                 path = _getfullpathname(path)
             except WindowsError:
                 pass # Bad path - return unchanged.
-        elif isinstance(path, unicode):
+        elif isinstance(path, _unicode):
             path = os.getcwdu()
         else:
             path = os.getcwd()
index 1bed51d4fabbce40cefbba6e66f7add74a9d401c..0b32d636ca83f9db894adc2095241d51c9da778d 100644 (file)
@@ -8,6 +8,7 @@ module as os.path.
 import os
 import stat
 from genericpath import *
+from genericpath import _unicode
 from ntpath import (expanduser, expandvars, isabs, islink, splitdrive,
                     splitext, split, walk)
 
@@ -146,7 +147,7 @@ def normpath(path):
 def abspath(path):
     """Return the absolute version of a path"""
     if not isabs(path):
-        if isinstance(path, unicode):
+        if isinstance(path, _unicode):
             cwd = os.getcwdu()
         else:
             cwd = os.getcwd()
index 037800418df67a990d3a52fe6a36b7d13da51fc0..6578481f7b4923e8bf913025732f4e55baaf2151 100644 (file)
@@ -16,14 +16,7 @@ import stat
 import genericpath
 import warnings
 from genericpath import *
-
-try:
-    _unicode = unicode
-except NameError:
-    # If Python is built without Unicode support, the unicode type
-    # will not exist. Fake one.
-    class _unicode(object):
-        pass
+from genericpath import _unicode
 
 __all__ = ["normcase","isabs","join","splitdrive","split","splitext",
            "basename","dirname","commonprefix","getsize","getmtime",
@@ -294,16 +287,16 @@ def expandvars(path):
     if '$' not in path:
         return path
     if isinstance(path, _unicode):
-        if not _varprog:
+        if not _uvarprog:
             import re
-            _varprog = re.compile(r'\$(\w+|\{[^}]*\})')
-        varprog = _varprog
+            _uvarprog = re.compile(ur'\$(\w+|\{[^}]*\})', re.UNICODE)
+        varprog = _uvarprog
         encoding = sys.getfilesystemencoding()
     else:
-        if not _uvarprog:
+        if not _varprog:
             import re
-            _uvarprog = re.compile(_unicode(r'\$(\w+|\{[^}]*\})'), re.UNICODE)
-        varprog = _uvarprog
+            _varprog = re.compile(r'\$(\w+|\{[^}]*\})')
+        varprog = _varprog
         encoding = None
     i = 0
     while True:
index 94380b1b1ffb49430f6226f6567a1aef163d908f..741b755d795f834f5b60b851ac293effa7803cc1 100644 (file)
@@ -243,11 +243,13 @@ class CommonTest(GenericTest):
     def test_realpath(self):
         self.assertIn("foo", self.pathmodule.realpath("foo"))
 
+    @test_support.requires_unicode
     def test_normpath_issue5827(self):
         # Make sure normpath preserves unicode
         for path in (u'', u'.', u'/', u'\\', u'///foo/.//bar//'):
             self.assertIsInstance(self.pathmodule.normpath(path), unicode)
 
+    @test_support.requires_unicode
     def test_abspath_issue3426(self):
         # Check that abspath returns unicode when the arg is unicode
         # with both ASCII and non-ASCII cwds.
index 96ad61fbe12e22889997de95b470da7c62cdc1d8..be936de224a9e934e230fe0c891c5d3842a4b7c8 100644 (file)
@@ -59,6 +59,7 @@ class MacPathTestCase(unittest.TestCase):
         self.assertEqual(splitext(""), ('', ''))
         self.assertEqual(splitext("foo.bar.ext"), ('foo.bar', '.ext'))
 
+    @test_support.requires_unicode
     def test_normpath(self):
         # Issue 5827: Make sure normpath preserves unicode
         for path in (u'', u'.', u'/', u'\\', u':', u'///foo/.//bar//'):
index 0fbe6a17786aafa84d7c6d6632374b4d8c5eaa53..55da7e1354fd6337294a1c51062d631d50b8dbb0 100644 (file)
@@ -69,8 +69,9 @@ class TestNtpath(unittest.TestCase):
                ('', '\\\\conky\\\\mountpoint\\foo\\bar'))
         tester('ntpath.splitunc("//conky//mountpoint/foo/bar")',
                ('', '//conky//mountpoint/foo/bar'))
-        self.assertEqual(ntpath.splitunc(u'//conky/MOUNTPO\u0130NT/foo/bar'),
-                         (u'//conky/MOUNTPO\u0130NT', u'/foo/bar'))
+        if test_support.have_unicode:
+            self.assertEqual(ntpath.splitunc(u'//conky/MOUNTPO%cNT/foo/bar' % 0x0130),
+                             (u'//conky/MOUNTPO%cNT' % 0x0130, u'/foo/bar'))
 
     def test_split(self):
         tester('ntpath.split("c:\\foo\\bar")', ('c:\\foo', 'bar'))
index f74dc1489938cb9c9910f2d25543a58672b8e7cb..295bf491644959b44f873f1b9305ea4ae138a8c6 100644 (file)
@@ -1,7 +1,9 @@
 import unittest
 from test import test_support, test_genericpath
 
-import posixpath, os
+import posixpath
+import os
+import sys
 from posixpath import realpath, abspath, dirname, basename
 
 # An absolute path to a temporary filename for testing. We can't rely on TESTFN
@@ -409,6 +411,21 @@ class PosixPathTest(unittest.TestCase):
         finally:
             os.getcwd = real_getcwd
 
+    @test_support.requires_unicode
+    def test_expandvars_nonascii_word(self):
+        encoding = sys.getfilesystemencoding()
+        # Non-ASCII word characters
+        letters = test_support.u(r'\xe6\u0130\u0141\u03c6\u041a\u05d0\u062a\u0e01')
+        uwnonascii = letters.encode(encoding, 'ignore').decode(encoding)[:3]
+        swnonascii = uwnonascii.encode(encoding)
+        if not swnonascii:
+            self.skip('Needs non-ASCII word characters')
+        with test_support.EnvironmentVarGuard() as env:
+            env.clear()
+            env[swnonascii] = 'baz' + swnonascii
+            self.assertEqual(posixpath.expandvars(u'$%s bar' % uwnonascii),
+                             u'baz%s bar' % uwnonascii)
+
 
 class PosixCommonTest(test_genericpath.CommonTest):
     pathmodule = posixpath
index 4680a6fd6f83d6594f29007f0988f7d018d58b14..60a44eeb1efb73f2073205cde5fbf2a00943b412 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -18,6 +18,10 @@ Core and Builtins
 Library
 -------
 
+- Issue #21840: Fixed expanding unicode variables of form $var in
+  posixpath.expandvars().  Fixed all os.path implementations on
+  unicode-disabled builds.
+
 - Issue #23363: Fix possible overflow in itertools.permutations.
 
 - Issue #23364: Fix possible overflow in itertools.product.