Merge lp:~florian-vichot/bzr/861008-normpath-2-leading-slashes into lp:bzr/2.4

Proposed by Florian Vichot
Status: Merged
Approved by: Martin Packman
Approved revision: no longer in the source branch.
Merged at revision: 6050
Proposed branch: lp:~florian-vichot/bzr/861008-normpath-2-leading-slashes
Merge into: lp:bzr/2.4
Diff against target: 144 lines (+38/-9)
7 files modified
bzrlib/osutils.py (+17/-2)
bzrlib/tests/stub_sftp.py (+2/-2)
bzrlib/tests/test_osutils.py (+10/-0)
bzrlib/transport/local.py (+1/-1)
bzrlib/urlutils.py (+2/-3)
bzrlib/version.py (+1/-1)
doc/en/release-notes/bzr-2.4.txt (+5/-0)
To merge this branch: bzr merge lp:~florian-vichot/bzr/861008-normpath-2-leading-slashes
Reviewer Review Type Date Requested Status
Martin Packman (community) Approve
Martin Pool Approve
Review via email: mp+78143@code.launchpad.net

Commit message

Add posixpath.normpath wrapper in osutils to remove double leading slash weirdness

Description of the change

To post a comment you must log in.
Revision history for this message
Martin Pool (mbp) wrote :

  review approve

I think that's reasonable though I'd like a second opinion.

review: Approve
Revision history for this message
Martin Packman (gz) wrote :

This is fantastic Florian! I'll go ahead and send this to be merged.

review: Approve
Revision history for this message
Martin Packman (gz) wrote :

sent to pqm by email

Revision history for this message
Florian Vichot (florian-vichot) wrote :

Actually thank you, you were all very helpful, it was greatly appreciated :)

Revision history for this message
Martin Packman (gz) wrote :

There was a single test failure on PQM:

error: bzrlib.tests.test_transport.TestWin32LocalTransport.test_unc_clone_to_root

Traceback (most recent call last):
  File "/usr/lib/python2.6/dist-packages/testtools/runtest.py", line 144, in _run_user
    return fn(*args)
  File "/usr/lib/python2.6/dist-packages/testtools/testcase.py", line 465, in _run_test_method
    testMethod()
  File "/home/pqm/pqm-workdir/srv/2.4/bzrlib/tests/test_transport.py", line 753, in test_unc_clone_to_root
    t = t.clone('..')
  File "/home/pqm/pqm-workdir/srv/2.4/bzrlib/transport/local.py", line 583, in clone
    return EmulatedWin32LocalTransport(abspath)
  File "/home/pqm/pqm-workdir/srv/2.4/bzrlib/transport/local.py", line 562, in __init__
    self._local_base = urlutils._win32_local_path_from_url(base)
  File "/home/pqm/pqm-workdir/srv/2.4/bzrlib/urlutils.py", line 231, in _win32_local_path_from_url
    raise errors.InvalidURL(url, 'Win32 file urls start with'
InvalidURL: Invalid url supplied to transport: "file:////:OST/path/to/some/": Win32 file urls start with file:///x:/, where x is a valid drive letter

You should find this one pretty easy to resolve. It's a test suite only issue, the EmulatedWin32LocalTransport class is trying to act like win32, but uses osutils path functions. It actually passes on windows, where those functions resolve to the right things.

Revision history for this message
Florian Vichot (florian-vichot) wrote :

I've doubled checked every call to osutils.normpath(), it should be good now.

Revision history for this message
Martin Packman (gz) wrote :

sent to pqm by email

Revision history for this message
Martin Packman (gz) wrote :

sent to pqm by email

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bzrlib/osutils.py'
2--- bzrlib/osutils.py 2011-07-25 07:11:56 +0000
3+++ bzrlib/osutils.py 2011-10-05 00:23:23 +0000
4@@ -277,13 +277,28 @@
5 # copy posixpath.abspath, but use os.getcwdu instead
6 if not posixpath.isabs(path):
7 path = posixpath.join(getcwd(), path)
8- return posixpath.normpath(path)
9+ return _posix_normpath(path)
10
11
12 def _posix_realpath(path):
13 return posixpath.realpath(path.encode(_fs_enc)).decode(_fs_enc)
14
15
16+def _posix_normpath(path):
17+ path = posixpath.normpath(path)
18+ # Bug 861008: posixpath.normpath() returns a path normalized according to
19+ # the POSIX standard, which stipulates (for compatibility reasons) that two
20+ # leading slashes must not be simplified to one, and only if there are 3 or
21+ # more should they be simplified as one. So we treat the leading 2 slashes
22+ # as a special case here by simply removing the first slash, as we consider
23+ # that breaking POSIX compatibility for this obscure feature is acceptable.
24+ # This is not a paranoid precaution, as we notably get paths like this when
25+ # the repo is hosted at the root of the filesystem, i.e. in "/".
26+ if path.startswith('//'):
27+ path = path[1:]
28+ return path
29+
30+
31 def _win32_fixdrive(path):
32 """Force drive letters to be consistent.
33
34@@ -377,7 +392,7 @@
35 abspath = _posix_abspath
36 realpath = _posix_realpath
37 pathjoin = os.path.join
38-normpath = os.path.normpath
39+normpath = _posix_normpath
40 getcwd = os.getcwdu
41 rename = os.rename
42 dirname = os.path.dirname
43
44=== modified file 'bzrlib/tests/stub_sftp.py'
45--- bzrlib/tests/stub_sftp.py 2011-01-12 01:01:53 +0000
46+++ bzrlib/tests/stub_sftp.py 2011-10-05 00:23:23 +0000
47@@ -118,9 +118,9 @@
48 else:
49 def canonicalize(self, path):
50 if os.path.isabs(path):
51- return os.path.normpath(path)
52+ return osutils.normpath(path)
53 else:
54- return os.path.normpath('/' + os.path.join(self.home, path))
55+ return osutils.normpath('/' + os.path.join(self.home, path))
56
57 def chattr(self, path, attr):
58 try:
59
60=== modified file 'bzrlib/tests/test_osutils.py'
61--- bzrlib/tests/test_osutils.py 2011-06-16 18:34:26 +0000
62+++ bzrlib/tests/test_osutils.py 2011-10-05 00:23:23 +0000
63@@ -818,6 +818,16 @@
64 self.assertEqual(None, osutils.safe_file_id(None))
65
66
67+class TestPosixFuncs(tests.TestCase):
68+ """Test that the posix version of normpath returns an appropriate path
69+ when used with 2 leading slashes."""
70+
71+ def test_normpath(self):
72+ self.assertEqual('/etc/shadow', osutils._posix_normpath('/etc/shadow'))
73+ self.assertEqual('/etc/shadow', osutils._posix_normpath('//etc/shadow'))
74+ self.assertEqual('/etc/shadow', osutils._posix_normpath('///etc/shadow'))
75+
76+
77 class TestWin32Funcs(tests.TestCase):
78 """Test that _win32 versions of os utilities return appropriate paths."""
79
80
81=== modified file 'bzrlib/transport/local.py'
82--- bzrlib/transport/local.py 2011-07-05 06:41:37 +0000
83+++ bzrlib/transport/local.py 2011-10-05 00:23:23 +0000
84@@ -562,7 +562,7 @@
85 self._local_base = urlutils._win32_local_path_from_url(base)
86
87 def abspath(self, relpath):
88- path = osutils.normpath(osutils.pathjoin(
89+ path = osutils._win32_normpath(osutils.pathjoin(
90 self._local_base, urlutils.unescape(relpath)))
91 return urlutils._win32_local_path_to_url(path)
92
93
94=== modified file 'bzrlib/urlutils.py'
95--- bzrlib/urlutils.py 2010-10-21 22:27:43 +0000
96+++ bzrlib/urlutils.py 2011-10-05 00:23:23 +0000
97@@ -22,7 +22,7 @@
98
99 from bzrlib.lazy_import import lazy_import
100 lazy_import(globals(), """
101-from posixpath import split as _posix_split, normpath as _posix_normpath
102+from posixpath import split as _posix_split
103 import urllib
104 import urlparse
105
106@@ -200,8 +200,7 @@
107 """
108 # importing directly from posixpath allows us to test this
109 # on non-posix platforms
110- return 'file://' + escape(_posix_normpath(
111- osutils._posix_abspath(path)))
112+ return 'file://' + escape(osutils._posix_abspath(path))
113
114
115 def _win32_local_path_from_url(url):
116
117=== modified file 'bzrlib/version.py'
118--- bzrlib/version.py 2010-04-30 11:03:59 +0000
119+++ bzrlib/version.py 2011-10-05 00:23:23 +0000
120@@ -73,7 +73,7 @@
121 else:
122 to_file.write(bzrlib.__path__[0] + '\n')
123 if show_config:
124- config_dir = os.path.normpath(config.config_dir()) # use native slashes
125+ config_dir = osutils.normpath(config.config_dir()) # use native slashes
126 if not isinstance(config_dir, unicode):
127 config_dir = config_dir.decode(osutils.get_user_encoding())
128 to_file.write(" Bazaar configuration: %s\n" % (config_dir,))
129
130=== modified file 'doc/en/release-notes/bzr-2.4.txt'
131--- doc/en/release-notes/bzr-2.4.txt 2011-09-30 16:36:13 +0000
132+++ doc/en/release-notes/bzr-2.4.txt 2011-10-05 00:23:23 +0000
133@@ -42,6 +42,11 @@
134 * Return early from create_delta_index_from_delta given tiny inputs. This
135 avoids raising a spurious MemoryError on certain platforms such as AIX.
136 (John Arbash Meinel, #856731)
137+
138+* Fixed an infinite loop when creating a repo at the root of the filesystem,
139+ i.e. "/", due to posixpath.normpath() not collapsing 2 leading slashes into
140+ one, thus respecting the POSIX standard, but making relpath() loop infinitely.
141+ (Florian Vichot, #861008)
142
143 Documentation
144 *************

Subscribers

People subscribed via source and target branches