How to avoid "f.close" (no parens) bug?

S

Stephen Ferg

I've just spent several very frustrating hours tracking down a bug in
one of my programs. The problem was that I was writing text to a
file, and when I was done I coded

f.close

when I should have been coding

f.close()

with the parentheses.

Although I love Python dearly, the fact that such an easy-to-make
mistake should do nothing useful and do it silently (which, in this
context, means: fail silently) seems to me a bit of a wart.

In any event, does anybody have any suggestions for how a coder could
avoid making such a mistake, or detect it quickly?

I teach the occasional beginning Python class, and I would hate to
have to tell my beginning students to watch out for making this kind
of mistake because it can bite you in a most nasty way.
 
S

Skip Montanaro

Stephen> I've just spent several very frustrating hours tracking down a
Stephen> bug in one of my programs. The problem was that I was writing
Stephen> text to a file, and when I was done I coded

Stephen> f.close

Stephen> when I should have been coding

Stephen> f.close()

Stephen> with the parentheses.

Stephen> In any event, does anybody have any suggestions for how a coder
Stephen> could avoid making such a mistake, or detect it quickly?

Pychecker would probably have warned about this. Given this four-line file:

def bar():
return 5

bar

Pychecker reports:

% pychecker foo.py
name: foo
Processing foo...

Warnings...

foo.py:4: Statement appears to have no effect

Skip
 
P

Peter Otten

Stephen said:
I've just spent several very frustrating hours tracking down a bug in
one of my programs. The problem was that I was writing text to a
file, and when I was done I coded

f.close

when I should have been coding

f.close()

with the parentheses.

Although I love Python dearly, the fact that such an easy-to-make
mistake should do nothing useful and do it silently (which, in this
context, means: fail silently) seems to me a bit of a wart.

In any event, does anybody have any suggestions for how a coder could
avoid making such a mistake, or detect it quickly?

I teach the occasional beginning Python class, and I would hate to
have to tell my beginning students to watch out for making this kind
of mistake because it can bite you in a most nasty way.

Try pychecker.

<pycheckerfodder.py>
if __name__ == "__name__":
f = file("xxx")
print f.readline(),
f.close
</pycheckerfodder.py>

....> pychecker pycheckerfodder.py
Processing pycheckerfodder...

Warnings...

pycheckerfodder.py:4: Statement appears to have no effect

Peter
 
D

DH

Stephen> I've just spent several very frustrating hours tracking down a
Stephen> bug in one of my programs. The problem was that I was writing
Stephen> text to a file, and when I was done I coded

Stephen> f.close

Stephen> when I should have been coding

Stephen> f.close()

Stephen> with the parentheses.

Stephen> In any event, does anybody have any suggestions for how a coder
Stephen> could avoid making such a mistake, or detect it quickly?

Pychecker would probably have warned about this. Given this four-line file:

There are numerous common mistakes people making when coding in Python
that the compiler doesn't catch. Case-sensitive errors, errors in
indenting, etc.

I think PyChecker ( http://pychecker.sf.net/ ) should be mentioned in
every beginner tutorial, and should be integrated with every Python IDE.
Before you type anything, type "import pychecker.checker"
 
J

John Roth

Stephen Ferg said:
I've just spent several very frustrating hours tracking down a bug in
one of my programs. The problem was that I was writing text to a
file, and when I was done I coded

f.close

when I should have been coding

f.close()

with the parentheses.

Although I love Python dearly, the fact that such an easy-to-make
mistake should do nothing useful and do it silently (which, in this
context, means: fail silently) seems to me a bit of a wart.

In any event, does anybody have any suggestions for how a coder could
avoid making such a mistake, or detect it quickly?

I teach the occasional beginning Python class, and I would hate to
have to tell my beginning students to watch out for making this kind
of mistake because it can bite you in a most nasty way.

I don't know about anyone else, but I'd appreciate a run
time error message when it detects an impossible operation
on a function/bound method/unbound method which has no /
one operand on the top of the stack.

Something simple, like: "Unsupported operation on {function
| unbound method | bound method} with {no | one} operand
detected. Did you forget the empty calling parameter list < () >?"

So far, that would have saved me close to a cumulative
person-week of work!

John Roth
 
P

Peter Hansen

Stephen said:
I've just spent several very frustrating hours tracking down a bug in
one of my programs. The problem was that I was writing text to a
file, and when I was done I coded

f.close

when I should have been coding

f.close()

with the parentheses.

Although I love Python dearly, the fact that such an easy-to-make
mistake should do nothing useful and do it silently (which, in this
context, means: fail silently) seems to me a bit of a wart.

One thing no one has done here yet is to ask about your background
in programming.

Would I be write in guessing that you have used VisualBASIC a lot
in the past? Or perhaps a similar language which allows the type
of function call you would expect with the first form above?

I have *never* made this particular mistake in Python, nor, as
far as I can tell, have any of the several dozen Python programmers
I've hired over the past few years (none of whom have VB backgrounds).

I believe f.close could be a legal call in VB (am I right?) and
I'm guessing that is the reason you are making this mistake.
I doubt it's a common problem for many people, but maybe it is for
those with a particular background.

-Peter
 
D

Dang Griffith

Would I be write in guessing that you have used VisualBASIC a lot
in the past? Or perhaps a similar language which allows the type
of function call you would expect with the first form above?

I believe f.close could be a legal call in VB (am I right?) and
I'm guessing that is the reason you are making this mistake.
I doubt it's a common problem for many people, but maybe it is for
those with a particular background.
Pascal, Delphi also use this convention. Personally, I think that
design for a language is strange, but if the language doesn't support
a "pointer to function" or "function" type, there's no ambiguosity to
the compiler. A casual reader of the code can get confused, not
knowing if the code is referring to a function that returns a value,
or a simple attribute. Delphi complicates it further by having
"attributes", which are sort of like a getter/setter used
(syntactically) as if it were an attribute assignment/reference.
Point being it's not just VisualBasic (and Access and VBA). I
think it's not unreasonable that your thought about someone's
background is relevant. I'm from a C background, and never made this
particular mistake.
--dang
 
P

Paul Prescod

Peter said:
...
I have *never* made this particular mistake in Python, nor, as
far as I can tell, have any of the several dozen Python programmers
I've hired over the past few years (none of whom have VB backgrounds).

I make this mistake from time to time although by now I am more fluent
in Python than any other language (and I was never fluent in a language
where you called functions without parens). I also leave off trailing
colons, quotes, etc. It is just laziness. I suspect I would never write:

f.close

(it does stand out like a sore thumb)

But I might write

foo(bar[0].doSomething)

I can usually diagnose these pretty quickly.

Paul Prescod
 
P

Peter Hansen

Paul said:
But I might write

foo(bar[0].doSomething)

Good point. Given that this is much more likely to be deliberate,
it's also more likely to occur as a mistake for those of us who
would "never" write f.close accidentally.

I also leave off the odd colon, though I believe that's the only
such error I've made more than maybe once with Python. Never left
quotes off anything that was supposed to have them, unless it was
strictly a slip of the finger (instead of the mind).

-Peter
 
J

Jarek Zgoda

Peter Hansen said:
Would I be write in guessing that you have used VisualBASIC a lot
in the past? Or perhaps a similar language which allows the type
of function call you would expect with the first form above?

You call Pascal "similar to VB"?
 
P

Peter Hansen

Jarek said:
You call Pascal "similar to VB"?

Yes, in at least this once sense, obviously. Clearly no other similarity
with VB is needed to suffice as a background for someone who makes such
a mistake "commonly", if my theory is correct.

-Peter
 
I

Isaac To

Dang> I'm from a C background, and never made this particular mistake.

At least in GCC, the compiler will emit a warning when you do that (provided
that you use -Wall), telling you that you've generated a value without using
it. This isn't possible in Python (or did I miss something?), so you never
know how many such subtle problem lies in your program, especially because
forgetting to close a file "normally" won't cause any visible problem (that
is, until you modify the same file somewhere elso and when the program
exits, half of your modifications are gone).

Regards,
Isaac.
 
N

Nick Craig-Wood

Peter Hansen said:
One thing no one has done here yet is to ask about your background
in programming.

As a long time Perl programmer I've found myself making exactly that
mistake in Python. In Perl method calls don't need parens if the call
doesn't take any arguments.

However I've also discovered pychecker ;-)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top