msg58112 - (view) |
Author: ianaré (ianare) |
Date: 2007-12-03 07:08 |
When using shutil.copy2 or copytree where the source is on a filesystem
that has octal permissions (ie ext3) and the destination is on an NTFS
partition mounted rw, the operation fails with
OSError: [Errno 1] Operation not permitted
I am attaching a version of shutil.py where this has been worked around
by calling copystat like so:
try:
copystat(src, dst)
except OSError, (n, str):
# can't change stats on NTFS partition even if
# OS supports it
if n == 1:
pass
else:
raise Error, str
|
msg58117 - (view) |
Author: Christian Heimes (christian.heimes) * |
Date: 2007-12-03 12:35 |
Better patch:
import errno
try:
copystat(src, dst)
except OSError, err:
# can't change stats on NTFS partition even if
# OS supports it
if err.errno != errno.EPERM:
raise
|
msg58123 - (view) |
Author: Facundo Batista (facundobatista) * |
Date: 2007-12-03 13:34 |
But is ok to hide the problem?
I mean, there *is* an error: the operation is not permitted (even if
it's not Python fault), so why to not have the exception?
|
msg58128 - (view) |
Author: Raghuram Devarakonda (draghuram) |
Date: 2007-12-03 15:33 |
I agree with Facundo that it is not good to hide the error. It should be
up to the caller to ignore the error.
|
msg58129 - (view) |
Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * |
Date: 2007-12-03 15:49 |
This reminds me of an option in os.walk:
"""
By default errors from the os.listdir() call are ignored. If optional
argument onerror is specified, it should be a function; it will be
called with one argument, an OSError instance. It can report the error
to continue with the walk, or raise the exception to abort the walk.
Note that the filename is available as the filename attribute of the
exception object.
"""
We could do something similar, except that by default, errors are not
ignored.
|
msg58135 - (view) |
Author: ianaré (ianare) |
Date: 2007-12-03 17:53 |
I agree, the best would be to have the option of ignoring errors.
However, I think there should be a way to differentiate between errors
that prevent a file from being copied, and one that only affects
permissions.
|
msg58136 - (view) |
Author: Facundo Batista (facundobatista) * |
Date: 2007-12-03 17:59 |
os.walk has an error handling mechanism because it goes through a
collection of files, so it's nice to have, for example, a function
applied if errors appear in some of those files.
As this operation is applicable only to one file, this is not useful at
all: if you want to catch the error, just do it.
Regarding the type of error, note that you can use the mechanism tiran
shows below (if err.errno equals errno.EPERM).
In any case, this bug is not applicable any more.
|
msg58142 - (view) |
Author: ianaré (ianare) |
Date: 2007-12-03 19:15 |
I must respectfully disagree. This bug also occurs during the copytree
command, so it can apply to more than one file. And if using from move
then the original file never gets deleted.
As far as working around it, it is obviously doable, however this
requires distributing my own version of shutil with my application,
something which is clearly undesirable.
Furthermore, I think that being able to ignore certain errors is very
much desirable for this library. (maybe this could be filed under a
different report)
|
msg58146 - (view) |
Author: Facundo Batista (facundobatista) * |
Date: 2007-12-03 19:23 |
I'm -1 to the library ignore errors without specific indication from the
user, specially when it's so easy to do it in the calling code.
We agree that copytree could grow an option like the one in os.walk.
Feel free to open an issue for it (this discussion went through other
path here, that's why I prefer a clean issue; you should refer this one
in the text, though). You should first discuss this in the list, also.
Thank you!
|
msg58147 - (view) |
Author: Guido van Rossum (gvanrossum) * |
Date: 2007-12-03 19:31 |
There's already an except clause for copystat() that ignores
WindowsError in copytree(). If copying this same code into copy2() makes
the OP happy I think we can place a similar except clause around the
copystat() call in copy2().
|
msg58158 - (view) |
Author: ianaré (ianare) |
Date: 2007-12-03 21:36 |
The problem with WindowsError is that it is not included in Linux. So if
there is an exception, it fails without showing the actual error. See
here (ubuntu 7.10 default install):
>>> try: print a
... except WindowsError:
... print 'b'
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
NameError: name 'WindowsError' is not defined
It should return "NameError: name 'a' is not defined"
In my workaround, by placing the OSError before the WindowsError, this
problem is taken care of.
Let me see if I can figure out something a little better than always
ignoring this type of error ...
Thanks
|
msg58159 - (view) |
Author: Guido van Rossum (gvanrossum) * |
Date: 2007-12-03 21:45 |
Hm, that means there's a bug in the existing copytree() code too!
Can you check whether WindowsError derives from OSError? If it does,
your proposal won't fly.
|
msg58160 - (view) |
Author: ianaré (ianare) |
Date: 2007-12-03 22:00 |
Yes, it is a sub-class of OSError. So then only catching OSError should
be sufficient? Or am I missing something?
|
msg58161 - (view) |
Author: Guido van Rossum (gvanrossum) * |
Date: 2007-12-03 22:13 |
Not quite, because we only want to ignore WindowsError.
Maybe this would work?
try:
WindowsError
except NameError:
WindowsError = None
try:
....
except os.error, err:
if WindowsError is not None or not isinstance(err, WindowsError):
raise # Pretend we didn't catch it
pass # Ignore it
|
msg58162 - (view) |
Author: Raghuram Devarakonda (draghuram) |
Date: 2007-12-03 22:25 |
> try:
> ....
> except os.error, err:
> if WindowsError is not None or not isinstance(err, WindowsError):
> raise # Pretend we didn't catch it
> pass # Ignore it
All the double negations are hurting when I try to understand above
conditions. How about (in addition to the WindowsError name check):
if WindowsError and isinstance(err, WindowsError):
pass # ignore
raise
|
msg58164 - (view) |
Author: Guido van Rossum (gvanrossum) * |
Date: 2007-12-03 23:18 |
You're right, my code was wrong. Yours will be be correct if you add
"else:" in front of the raise. I also still prefer "WindowsError is
not None" over just "WindowsError".
On Dec 3, 2007 2:25 PM, Raghuram Devarakonda <report@bugs.python.org> wrote:
>
> Raghuram Devarakonda added the comment:
>
> > try:
> > ....
> > except os.error, err:
> > if WindowsError is not None or not isinstance(err, WindowsError):
> > raise # Pretend we didn't catch it
> > pass # Ignore it
>
> All the double negations are hurting when I try to understand above
> conditions. How about (in addition to the WindowsError name check):
>
> if WindowsError and isinstance(err, WindowsError):
> pass # ignore
>
> raise
>
>
> __________________________________
> Tracker <report@bugs.python.org>
> <http://bugs.python.org/issue1545>
> __________________________________
>
|
msg58165 - (view) |
Author: Raghuram Devarakonda (draghuram) |
Date: 2007-12-03 23:22 |
> You're right, my code was wrong. Yours will be be correct if you add
> "else:" in front of the raise. I also still prefer "WindowsError is
Yeah. I was just about to correct my code when I saw your response. I
should not post just before leaving work for home :-)
|
msg58166 - (view) |
Author: ianaré (ianare) |
Date: 2007-12-03 23:39 |
Rather than try in copytree and try again in copy2, why not add this to
the root of the issue - copystat. Something like this?
def copystat(src, dst, ignore_permission_err=False):
"""Copy all stat info (mode bits, atime and mtime) from src to dst"""
st = os.stat(src)
mode = stat.S_IMODE(st.st_mode)
try:
if hasattr(os, 'utime'):
os.utime(dst, (st.st_atime, st.st_mtime))
if hasattr(os, 'chmod'):
os.chmod(dst, mode)
except OSError, err:
if WindowsError is not None and isinstance(err, WindowsError):
pass
elif ignore_permissions_err and err.errno == errno.EPERM:
pass
else:
raise
|
msg58167 - (view) |
Author: Guido van Rossum (gvanrossum) * |
Date: 2007-12-03 23:49 |
Look at the except clause in copytree(); it does a bit more,
collecting the errors and raising them later.
|
msg58192 - (view) |
Author: ianaré (ianare) |
Date: 2007-12-04 16:53 |
OK I see that now. For what it's worth, I tested the code on win2000,
XP, and ubuntu using the shutil.move command on files and folders (so
that it uses either copy2 or copytree). Apart from the original bug in
ubuntu (copy from ext3 to ntfs-3g) it is fine.
I've made further modifications to allow for not showing permission
errors. Should I file these under a new report?
Many thanks.
|
msg58195 - (view) |
Author: ianaré (ianare) |
Date: 2007-12-04 17:12 |
sorry, should have clarified, I tested with this code:
copy2
try:
copystat(src, dst)
except OSError, err:
if WindowsError is not None and isinstance(err, WindowsError):
pass
else:
raise
copytree
try:
copystat(src, dst)
except OSError, err:
if WindowsError is not None and isinstance(err, WindowsError):
pass
else:
errors.extend((src, dst, str(why)))
|
msg58197 - (view) |
Author: Raghuram Devarakonda (draghuram) |
Date: 2007-12-04 17:29 |
The change looks fine as per yesterday's discussion. Can you submit
the actual patch? it needs to include check for WindowsError name.
BTW, I would put a comment when the exception is being ignored on
windows.
|
msg58198 - (view) |
Author: ianaré (ianare) |
Date: 2007-12-04 17:57 |
Sure thing, here it is.
|
msg58202 - (view) |
Author: ianaré (ianare) |
Date: 2007-12-04 20:46 |
hmm, marked me as spam ... the tar.gz posted last message contains the
original shutil, a patched version, and the diff
|
msg58203 - (view) |
Author: Raghuram Devarakonda (draghuram) |
Date: 2007-12-04 21:10 |
Some comments about shutil.diff:
1) This seems to be against 2.5. You would be better off submitting a
patch against trunk. In case of bug fixes, it will usually be back
ported. This particular change is not a bug fix though.
2) patches should be either context diff or preferably unified diffs. In
addition, a patch should be a forward diff (diff <original file>
<changed file>. It is best to simply do "svn diff".
3) Now for the actual content of the patch, it must be noted that
ignoring WindowsError in copy2 breaks compatibility. Not that there is
any reason for any one to be depending on it, but I just thought I would
point it out. In any case, it will require slight doc change.
Lastly, just to be clear, the original problem reported in this bug
would still remain.
|
msg58204 - (view) |
Author: ianaré (ianare) |
Date: 2007-12-04 22:13 |
Sorry about that. Here is the output from $ svn diff
I've also made modifications to allow to ignore the permission errors
(defaults to no) - should I post here or file new report?
|
msg58233 - (view) |
Author: Raghuram Devarakonda (draghuram) |
Date: 2007-12-05 22:39 |
There is a mistake in the patch. The line "if WindowsError is not None
and isinstance(err, WindowsError):" in copytree() should use the name
'why' and not 'err'. Unfortunately I can't test on windows, but you
didn't get NameError when you tested copytree() on windows?
|
msg68460 - (view) |
Author: Raghuram Devarakonda (draghuram) |
Date: 2008-06-20 14:26 |
I have submitted a patch (http://codereview.appspot.com/2384) for
WindowsError issue as it is reported in two other bugs #3134 and #2549.
I have only tested on Linux so I would appreciate if some one who have
access to windows can test it as well. Considering that the fix is
simple and more bugs are being opened for the same problem, it is
worthwhile to check this in quickly.
|
msg71024 - (view) |
Author: Raghuram Devarakonda (draghuram) |
Date: 2008-08-11 17:26 |
WindowsError issue is now fixed in r65644.
|
msg97171 - (view) |
Author: Valentín (Val) |
Date: 2010-01-03 17:50 |
I think this one is solved now. I recommend just to put as solved and kill it from the list ;)
|
|
Date |
User |
Action |
Args |
2022-04-11 14:56:28 | admin | set | github: 45886 |
2010-01-03 18:30:45 | benjamin.peterson | set | status: open -> closed resolution: fixed |
2010-01-03 17:50:09 | Val | set | nosy:
+ Val messages:
+ msg97171
|
2008-08-11 17:26:47 | draghuram | set | messages:
+ msg71024 |
2008-06-20 14:26:21 | draghuram | set | messages:
+ msg68460 |
2007-12-05 22:39:55 | draghuram | set | messages:
+ msg58233 |
2007-12-04 22:13:47 | ianare | set | files:
+ shutil.diff messages:
+ msg58204 |
2007-12-04 21:10:50 | draghuram | set | messages:
+ msg58203 |
2007-12-04 20:46:18 | ianare | set | messages:
+ msg58202 |
2007-12-04 17:57:53 | ianare | set | files:
+ shutil.tar.gz messages:
+ msg58198 |
2007-12-04 17:29:25 | draghuram | set | messages:
+ msg58197 |
2007-12-04 17:12:21 | ianare | set | messages:
+ msg58195 |
2007-12-04 16:53:36 | ianare | set | messages:
+ msg58192 |
2007-12-03 23:49:53 | gvanrossum | set | messages:
+ msg58167 |
2007-12-03 23:39:16 | ianare | set | messages:
+ msg58166 |
2007-12-03 23:22:46 | draghuram | set | messages:
+ msg58165 |
2007-12-03 23:18:59 | gvanrossum | set | messages:
+ msg58164 |
2007-12-03 22:25:22 | draghuram | set | messages:
+ msg58162 |
2007-12-03 22:13:15 | gvanrossum | set | messages:
+ msg58161 |
2007-12-03 22:00:19 | ianare | set | messages:
+ msg58160 |
2007-12-03 21:45:05 | gvanrossum | set | status: closed -> open resolution: rejected -> (no value) messages:
+ msg58159 |
2007-12-03 21:36:24 | ianare | set | messages:
+ msg58158 |
2007-12-03 19:31:09 | gvanrossum | set | nosy:
+ gvanrossum messages:
+ msg58147 |
2007-12-03 19:23:43 | facundobatista | set | messages:
+ msg58146 |
2007-12-03 19:15:41 | ianare | set | messages:
+ msg58142 |
2007-12-03 17:59:52 | facundobatista | set | status: open -> closed resolution: rejected messages:
+ msg58136 |
2007-12-03 17:53:32 | ianare | set | messages:
+ msg58135 |
2007-12-03 15:49:36 | amaury.forgeotdarc | set | nosy:
+ amaury.forgeotdarc messages:
+ msg58129 |
2007-12-03 15:33:36 | draghuram | set | nosy:
+ draghuram messages:
+ msg58128 |
2007-12-03 13:34:37 | facundobatista | set | nosy:
+ facundobatista messages:
+ msg58123 |
2007-12-03 12:35:08 | christian.heimes | set | priority: normal keywords:
+ patch messages:
+ msg58117 nosy:
+ christian.heimes versions:
+ Python 2.6, Python 3.0 |
2007-12-03 07:08:50 | ianare | create | |