[PATCH 3 of 3] util.makedirs: cleanup of termination of recursion
Adrian Buehlmann
adrian at cadifra.com
Mon Aug 22 03:07:56 CDT 2011
On 2011-08-22 09:19, Adrian Buehlmann wrote:
> On 2011-08-22 01:07, Mads Kiilerich wrote:
>> # HG changeset patch
>> # User Mads Kiilerich <mads at kiilerich.com>
>> # Date 1313966711 -7200
>> # Branch stable
>> # Node ID e241109d6afd46fb19103b3bbf86bbc9adca53cc
>> # Parent 4191b702114a9bb2b6287ce622060589763ac038
>> util.makedirs: cleanup of termination of recursion
>>
>> The fixes in 2649be11ab0b and adff480db558 for preventing infinite recursion
>> are no longer needed and is removed.
>>
>> Parentdir calculation is now postponed until it is needed.
>>
>> diff --git a/mercurial/util.py b/mercurial/util.py
>> --- a/mercurial/util.py
>> +++ b/mercurial/util.py
>> @@ -757,15 +757,14 @@
>>
>> def makedirs(name, mode=None):
>> """recursive directory creation with parent mode inheritance"""
>> - parent = os.path.abspath(os.path.dirname(name))
>> try:
>> os.mkdir(name)
>> except OSError, err:
>> if err.errno == errno.EEXIST:
>> return
>> - if not name or parent == name or err.errno != errno.ENOENT:
>> + if err.errno != errno.ENOENT:
>> raise
>> - makedirs(parent, mode)
>> + makedirs(os.path.dirname(os.path.abspath(name)), mode)
>> os.mkdir(name)
>> if mode is not None:
>> os.chmod(name, mode)
>
> This one seems to make issue2531 (was previously fixed with my adff480db558)
> failing again:
>
> $ N:\
> The system cannot find the drive specified.
>
> $ n:\
> The system cannot find the drive specified.
>
> $ hgc init n:\test
> --- running hg from C:\Users\adi\hgrepos\hg-crew
> ** unknown exception encountered, please report by visiting
> ** http://mercurial.selenic.com/wiki/BugTracker
> ** Python 2.6.6 (r266:84297, Aug 24 2010, 18:13:38) [MSC v.1500 64 bit (AMD64)]
> ** Mercurial Distributed SCM (version unknown)
> ** Extensions loaded: rebase, mq, graphlog, patchbomb
> Traceback (most recent call last):
> File "C:\Users\adi\hgrepos\hg-crew\hg", line 38, in <module>
> mercurial.dispatch.run()
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\dispatch.py", line 27, in run
> sys.exit(dispatch(request(sys.argv[1:])))
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\dispatch.py", line 64, in dispatch
> return _runcatch(req)
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\dispatch.py", line 87, in _runcatch
> return _dispatch(req)
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\dispatch.py", line 684, in _dispatch
> cmdpats, cmdoptions)
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\dispatch.py", line 466, in runcommand
> ret = _runcommand(ui, options, cmd, d)
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\dispatch.py", line 738, in _runcommand
> return checkargs()
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\dispatch.py", line 692, in checkargs
> return cmdfunc()
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\dispatch.py", line 681, in <lambda>
> d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\util.py", line 441, in check
> return func(*args, **kwargs)
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\extensions.py", line 137, in wrap
> util.checksignature(origfn), *args, **kwargs)
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\util.py", line 441, in check
> return func(*args, **kwargs)
> File "C:\Users\adi\hgrepos\hg-crew\hgext\mq.py", line 3201, in mqinit
> return orig(ui, *args, **kwargs)
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\util.py", line 441, in check
> return func(*args, **kwargs)
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\commands.py", line 3290, in init
> hg.peer(ui, opts, ui.expandpath(dest), create=True)
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\hg.py", line 104, in peer
> return repository(rui, path, create)
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\hg.py", line 93, in repository
> repo = _peerlookup(path).instance(ui, path, create)
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\localrepo.py", line 2055, in instance
> return localrepository(ui, util.urllocalpath(path), create)
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\localrepo.py", line 49, in __init__
> util.makedirs(path)
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\util.py", line 790, in makedirs
> makedirs(os.path.dirname(os.path.abspath(name)), mode)
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\util.py", line 790, in makedirs
> makedirs(os.path.dirname(os.path.abspath(name)), mode)
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\util.py", line 790, in makedirs
> makedirs(os.path.dirname(os.path.abspath(name)), mode)
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\util.py", line 790, in makedirs
> makedirs(os.path.dirname(os.path.abspath(name)), mode)
> ...
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\util.py", line 790, in makedirs
> makedirs(os.path.dirname(os.path.abspath(name)), mode)
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\util.py", line 790, in makedirs
> makedirs(os.path.dirname(os.path.abspath(name)), mode)
> File "C:\Users\adi\hgrepos\hg-crew\mercurial\util.py", line 790, in makedirs
> makedirs(os.path.dirname(os.path.abspath(name)), mode)
> File "C:\Python26_x64\lib\ntpath.py", line 478, in abspath
> return normpath(path)
> File "C:\Python26_x64\lib\ntpath.py", line 401, in normpath
> backslash, dot = (u'\\', u'.') if isinstance(path, unicode) else ('\\', '.')
> RuntimeError: maximum recursion depth exceeded while calling a Python object
I tried this:
$ python
Python 2.6.6 (r266:84297, Aug 24 2010, 18:13:38) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> name = "n:\\test"
>>> os.path.abspath(name)
'n:\\test'
>>> os.path.dirname(os.path.abspath(name))
'n:\\'
>>> os.mkdir('n:\\')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
WindowsError: [Error 3] The system cannot find the path specified: 'n:\\'
compare with:
>>> os.mkdir('C:\\Users\\adi\\notexistingdir\\foo')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
WindowsError: [Error 3] The system cannot find the path specified: 'C:\\Users\\adi\\notexistingdir\\foo'
and with:
$ n:\
The system cannot find the drive specified.
If I insert a print:
def makedirs(name, mode=None):
"""recursive directory creation with parent mode inheritance"""
print name
try:
os.mkdir(name)
except OSError, err:
if err.errno == errno.EEXIST:
return
if err.errno != errno.ENOENT:
raise
makedirs(os.path.dirname(os.path.abspath(name)), mode)
os.mkdir(name)
if mode is not None:
os.chmod(name, mode)
I get:
$ hgc init n:\test
--- running hg from C:\Users\adi\hgrepos\hg-crew
n:\test
n:\
n:\
...
n:\
n:\
n:\
n:\
n:\
n:\
** unknown exception encountered, please report by visiting
** http://mercurial.selenic.com/wiki/BugTracker
** Python 2.6.6 (r266:84297, Aug 24 2010, 18:13:38) [MSC v.1500 64 bit (AMD64)]
** Mercurial Distributed SCM (version unknown)
** Extensions loaded: rebase, mq, graphlog, patchbomb
Traceback (most recent call last):
File "C:\Users\adi\hgrepos\hg-crew\hg", line 38, in <module>
mercurial.dispatch.run()
File "C:\Users\adi\hgrepos\hg-crew\mercurial\dispatch.py", line 27, in run
sys.exit(dispatch(request(sys.argv[1:])))
File "C:\Users\adi\hgrepos\hg-crew\mercurial\dispatch.py", line 64, in dispatch
return _runcatch(req)
File "C:\Users\adi\hgrepos\hg-crew\mercurial\dispatch.py", line 87, in _runcatch
return _dispatch(req)
File "C:\Users\adi\hgrepos\hg-crew\mercurial\dispatch.py", line 684, in _dispatch
cmdpats, cmdoptions)
File "C:\Users\adi\hgrepos\hg-crew\mercurial\dispatch.py", line 466, in runcommand
ret = _runcommand(ui, options, cmd, d)
File "C:\Users\adi\hgrepos\hg-crew\mercurial\dispatch.py", line 738, in _runcommand
return checkargs()
File "C:\Users\adi\hgrepos\hg-crew\mercurial\dispatch.py", line 692, in checkargs
return cmdfunc()
File "C:\Users\adi\hgrepos\hg-crew\mercurial\dispatch.py", line 681, in <lambda>
d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
File "C:\Users\adi\hgrepos\hg-crew\mercurial\util.py", line 441, in check
return func(*args, **kwargs)
File "C:\Users\adi\hgrepos\hg-crew\mercurial\extensions.py", line 137, in wrap
util.checksignature(origfn), *args, **kwargs)
File "C:\Users\adi\hgrepos\hg-crew\mercurial\util.py", line 441, in check
return func(*args, **kwargs)
File "C:\Users\adi\hgrepos\hg-crew\hgext\mq.py", line 3201, in mqinit
return orig(ui, *args, **kwargs)
File "C:\Users\adi\hgrepos\hg-crew\mercurial\util.py", line 441, in check
return func(*args, **kwargs)
File "C:\Users\adi\hgrepos\hg-crew\mercurial\commands.py", line 3290, in init
hg.peer(ui, opts, ui.expandpath(dest), create=True)
File "C:\Users\adi\hgrepos\hg-crew\mercurial\hg.py", line 104, in peer
return repository(rui, path, create)
File "C:\Users\adi\hgrepos\hg-crew\mercurial\hg.py", line 93, in repository
repo = _peerlookup(path).instance(ui, path, create)
File "C:\Users\adi\hgrepos\hg-crew\mercurial\localrepo.py", line 2055, in instance
return localrepository(ui, util.urllocalpath(path), create)
File "C:\Users\adi\hgrepos\hg-crew\mercurial\localrepo.py", line 49, in __init__
util.makedirs(path)
File "C:\Users\adi\hgrepos\hg-crew\mercurial\util.py", line 791, in makedirs
makedirs(os.path.dirname(os.path.abspath(name)), mode)
File "C:\Users\adi\hgrepos\hg-crew\mercurial\util.py", line 791, in makedirs
makedirs(os.path.dirname(os.path.abspath(name)), mode)
File "C:\Users\adi\hgrepos\hg-crew\mercurial\util.py", line 791, in makedirs
makedirs(os.path.dirname(os.path.abspath(name)), mode)
...
File "C:\Users\adi\hgrepos\hg-crew\mercurial\util.py", line 791, in makedirs
makedirs(os.path.dirname(os.path.abspath(name)), mode)
File "C:\Users\adi\hgrepos\hg-crew\mercurial\util.py", line 791, in makedirs
makedirs(os.path.dirname(os.path.abspath(name)), mode)
File "C:\Users\adi\hgrepos\hg-crew\mercurial\util.py", line 791, in makedirs
makedirs(os.path.dirname(os.path.abspath(name)), mode)
File "C:\Users\adi\hgrepos\hg-crew\mercurial\util.py", line 791, in makedirs
makedirs(os.path.dirname(os.path.abspath(name)), mode)
File "C:\Users\adi\hgrepos\hg-crew\mercurial\util.py", line 791, in makedirs
makedirs(os.path.dirname(os.path.abspath(name)), mode)
File "C:\Python26_x64\lib\ntpath.py", line 478, in abspath
return normpath(path)
File "C:\Python26_x64\lib\ntpath.py", line 401, in normpath
backslash, dot = (u'\\', u'.') if isinstance(path, unicode) else ('\\', '.')
RuntimeError: maximum recursion depth exceeded while calling a Python object
If we want to postpone (and reorder) the parent calculation, we could do:
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -780,12 +780,12 @@
def makedirs(name, mode=None):
"""recursive directory creation with parent mode inheritance"""
- parent = os.path.abspath(os.path.dirname(name))
try:
os.mkdir(name)
except OSError, err:
if err.errno == errno.EEXIST:
return
+ parent = os.path.dirname(os.path.abspath(name))
if not name or parent == name or err.errno != errno.ENOENT:
raise
makedirs(parent, mode)
which seems to work for me:
$ n:\
The system cannot find the drive specified.
$ hgc init n:\test
--- running hg from C:\Users\adi\hgrepos\hg-crew
abort: The system cannot find the path specified: n:\
$ hgc clone --pull a a2
--- running hg from C:\Users\adi\hgrepos\hg-crew
requesting all changes
adding changesets
adding manifests
adding file changes
added 15 changesets with 16 changes to 5 files (+1 heads)
updating to branch default
5 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hgc -R a2 verify
--- running hg from C:\Users\adi\hgrepos\hg-crew
checking changesets
checking manifests
crosschecking files in changesets and manifests
checking files
5 files, 15 changesets, 16 total revisions
More information about the Mercurial-devel
mailing list