[PATCH] atomictempfile: avoid infinite recursion in destructor
Nicolas Dumazet
nicdumz at gmail.com
Tue Nov 30 03:00:02 CST 2010
2010/11/30 Greg Ward <greg-hg at gerg.ca>:
> # HG changeset patch
> # User Greg Ward <greg-hg at gerg.ca>
> # Date 1291085861 18000
> # Branch stable
> # Node ID 76a458f91f5baad3dd75a26d445ea51402fc32d1
> # Parent 5fb924ee44d516e2f91bb7f5cfd5c81b0629faa4
> atomictempfile: avoid infinite recursion in destructor.
>
> This is a weird one: if Python sees that the caller is not passing the
> right args to the constructor, it raises TypeError rather than enter
> the constructor. But it still ends up calling the destructor, which
> assumes that self._fp has been set in the constructor. But it hasn't,
> because the constructor wasn't actually executed. So we go into a
> nasty infinite recursion between __del__() and __getattr__(), when we
> should just crash with TypeError so the programmer can see what he did
> wrong.
>
> diff --git a/mercurial/util.py b/mercurial/util.py
> --- a/mercurial/util.py
> +++ b/mercurial/util.py
> @@ -823,7 +823,9 @@
> rename(self.temp, localpath(self.__name))
>
> def __del__(self):
> - if not self._fp:
> + if '_fp' not in self.__dict__: # constructor not executed
> + return
> + if not self._fp: # constructor failed
That's quite interesting! :)
You might want to be verbose on purpose, but what about
if not getattr(self, '_fp', None)
? It doesn't work because we're in __del__? (interesting case...!)
I was about to ask for a test, but fair enough, creating a .py file
just for this detail might be overkill.
Regards,
> return
> if not self._fp.closed:
> try:
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel
>
--
Nicolas Dumazet — NicDumZ
More information about the Mercurial-devel
mailing list