Mercurial > hg
annotate tests/test-hgcia.t @ 14007:d764463b433e
atomictempfile: avoid infinite recursion in __del__().
The problem is that a programmer using atomictempfile directly can
make an innocent everyday mistake -- not enough args to the
constructor -- which escalates badly. You would expect a simple
TypeError crash in that case, but you actually get an infinite
recursion that is surprisingly difficult to kill: it happens between
__del__() and __getattr__(), and Python does not handle infinite
recursion from __del__() well.
The fix is to not implement __getattr__(), but instead assign instance
attributes for the methods we wish to delegate to the builtin file
type: write() and fileno(). I've audited mercurial.* and hgext.* and
found no users of atomictempfile using methods other than write() and
rename(). I audited third-party extensions and found one (snap)
passing an atomictempfile to util.fstat(), so I also threw in
fileno().
The last time I submitted a similar patch, Matt proposed that we make
atomictempfile a subclass of file instead of wrapping it. Rejected on
grounds of unnecessary complexity: for one thing, it would make the
Windows implementation of posixfile quite a bit more complex. It would
have to become a subclass of file rather than a simple function -- but
since it's written in C, this is non-obvious and non-trivial.
Furthermore, there's nothing wrong with wrapping objects and
delegating methods: it's a well-established pattern that works just
fine in many cases. Subclassing is not the answer to all of life's
problems.
author | Greg Ward <greg@gerg.ca> |
---|---|
date | Sun, 24 Apr 2011 19:25:10 -0400 |
parents | 01c6be8361df |
children | c322890b03e6 |
rev | line source |
---|---|
12429 | 1 Test the CIA extension |
7438 | 2 |
12429 | 3 $ cat >> $HGRCPATH <<EOF |
4 > [extensions] | |
5 > hgcia= | |
6 > | |
7 > [hooks] | |
8 > changegroup.cia = python:hgext.hgcia.hook | |
9 > | |
10 > [cia] | |
11 > user = testuser | |
12 > project = testproject | |
13 > test = True | |
14 > EOF | |
7438 | 15 |
12429 | 16 $ hg init src |
17 $ hg init cia | |
18 $ cd src | |
19 $ echo foo > foo | |
20 $ hg ci -Amfoo | |
21 adding foo | |
22 $ hg push ../cia | |
23 pushing to ../cia | |
24 searching for changes | |
25 adding changesets | |
26 adding manifests | |
27 adding file changes | |
28 added 1 changesets with 1 changes to 1 files | |
29 | |
30 <message> | |
31 <generator> | |
32 <name>Mercurial (hgcia)</name> | |
33 <version>0.1</version> | |
34 <url>http://hg.kublai.com/mercurial/hgcia</url> | |
35 <user>testuser</user> | |
36 </generator> | |
37 <source> | |
38 <project>testproject</project> | |
39 <branch>default</branch> | |
40 </source> | |
41 <body> | |
42 <commit> | |
43 <author>test</author> | |
44 <version>0:e63c23eaa88a</version> | |
45 <log>foo</log> | |
46 | |
47 <files><file action="add">foo</file></files> | |
48 </commit> | |
49 </body> | |
50 <timestamp>0</timestamp> | |
51 </message> |