35
from ntpath import (abspath as _nt_abspath,
37
normpath as _nt_normpath,
38
realpath as _nt_realpath,
36
42
from bzrlib.errors import (BzrError,
173
179
rename_func(tmp_name, new)
182
# In Python 2.4.2 and older, os.path.abspath and os.path.realpath
183
# choke on a Unicode string containing a relative path if
184
# os.getcwd() returns a non-sys.getdefaultencoding()-encoded
186
_fs_enc = sys.getfilesystemencoding()
187
def _posix_abspath(path):
188
return os.path.abspath(path.encode(_fs_enc)).decode(_fs_enc)
189
# jam 20060426 This is another possibility which mimics
190
# os.path.abspath, only uses unicode characters instead
191
# if not os.path.isabs(path):
192
# return os.path.join(os.getcwdu(), path)
196
def _posix_realpath(path):
197
return os.path.realpath(path.encode(_fs_enc)).decode(_fs_enc)
200
def _win32_abspath(path):
201
return _nt_abspath(path.encode(_fs_enc)).decode(_fs_enc).replace('\\', '/')
204
def _win32_realpath(path):
205
return _nt_realpath(path.encode(_fs_enc)).decode(_fs_enc).replace('\\', '/')
208
def _win32_pathjoin(*args):
209
return _nt_join(*args).replace('\\', '/')
212
def _win32_normpath(path):
213
return _nt_normpath(path).replace('\\', '/')
217
return os.getcwdu().replace('\\', '/')
220
def _win32_mkdtemp(*args, **kwargs):
221
return tempfile.mkdtemp(*args, **kwargs).replace('\\', '/')
224
def _win32_rename(old, new):
225
fancy_rename(old, new, rename_func=os.rename, unlink_func=os.unlink)
175
228
# Default is to just use the python builtins, but these can be rebound on
176
229
# particular platforms.
177
abspath = os.path.abspath
178
realpath = os.path.realpath
230
abspath = _posix_abspath
231
realpath = _posix_realpath
179
232
pathjoin = os.path.join
180
233
normpath = os.path.normpath
181
234
getcwd = os.getcwdu
188
241
MIN_ABS_PATHLENGTH = 1
190
if os.name == "posix":
191
# In Python 2.4.2 and older, os.path.abspath and os.path.realpath
192
# choke on a Unicode string containing a relative path if
193
# os.getcwd() returns a non-sys.getdefaultencoding()-encoded
195
_fs_enc = sys.getfilesystemencoding() or 'ascii'
197
return os.path.abspath(path.encode(_fs_enc)).decode(_fs_enc)
200
return os.path.realpath(path.encode(_fs_enc)).decode(_fs_enc)
202
244
if sys.platform == 'win32':
203
# We need to use the Unicode-aware os.path.abspath and
204
# os.path.realpath on Windows systems.
206
return os.path.abspath(path).replace('\\', '/')
209
return os.path.realpath(path).replace('\\', '/')
212
return os.path.join(*args).replace('\\', '/')
215
return os.path.normpath(path).replace('\\', '/')
218
return os.getcwdu().replace('\\', '/')
220
def mkdtemp(*args, **kwargs):
221
return tempfile.mkdtemp(*args, **kwargs).replace('\\', '/')
223
def rename(old, new):
224
fancy_rename(old, new, rename_func=os.rename, unlink_func=os.unlink)
245
abspath = _win32_abspath
246
realpath = _win32_realpath
247
pathjoin = _win32_pathjoin
248
normpath = _win32_normpath
249
getcwd = _win32_getcwd
250
mkdtemp = _win32_mkdtemp
251
rename = _win32_rename
226
253
MIN_ABS_PATHLENGTH = 3
666
692
raise BzrBadParameterNotUnicode(unicode_or_utf8_string)
695
_platform_normalizes_filenames = False
696
if sys.platform == 'darwin':
697
_platform_normalizes_filenames = True
700
def normalizes_filenames():
701
"""Return True if this platform normalizes unicode filenames.
703
Mac OSX does, Windows/Linux do not.
705
return _platform_normalizes_filenames
708
if _platform_normalizes_filenames:
709
def unicode_filename(path):
710
"""Make sure 'path' is a properly normalized filename.
712
On platforms where the system normalizes filenames (Mac OSX),
713
you can access a file by any path which will normalize
715
Internally, bzr only supports NFC/NFKC normalization, since
716
that is the standard for XML documents.
717
So we return an normalized path, and indicate this has been
720
:return: (path, is_normalized) Return a path which can
721
access the file, and whether or not this path is
724
return unicodedata.normalize('NFKC', path), True
726
def unicode_filename(path):
727
"""Make sure 'path' is a properly normalized filename.
729
On platforms where the system does not normalize filenames
730
(Windows, Linux), you have to access a file by its exact path.
731
Internally, bzr only supports NFC/NFKC normalization, since
732
that is the standard for XML documents.
733
So we return the original path, and indicate if this is
736
:return: (path, is_normalized) Return a path which can
737
access the file, and whether or not this path is
740
return path, unicodedata.normalize('NFKC', path) == path
669
743
def terminal_width():
670
744
"""Return estimated terminal width."""
671
745
if sys.platform == 'win32':
693
767
return sys.platform != "win32"
696
def strip_trailing_slash(path):
697
"""Strip trailing slash, except for root paths.
698
The definition of 'root path' is platform-dependent.
700
if len(path) != MIN_ABS_PATHLENGTH and path[-1] == '/':
706
770
_validWin32PathRE = re.compile(r'^([A-Za-z]:[/\\])?[^:<>*"?\|]*$')