__getattr__ and __setattr__ troubles

Michael Hudson mwh21 at cam.ac.uk
Wed Jun 7 10:03:11 EDT 2000


=?ISO-8859-1?Q?Fran=E7ois_Pinard?= <pinard at iro.umontreal.ca> writes:

[snip] 

> > > * By the way, and a bit unrelated, why the space before the two
> > >   asterisks?
> 
> > Probably to do with softspace.  Not sure.
> 
> It should go between printed element, not before the first one,
> should it not?

Here's how it works:

when you execute

print C()

the code for PRINT_ITEM pops the object off the stack, and calls

PyFile_SoftSpace(w, 1)

where w is sys.stdout.  This checks to see if a softspace is required,
which it isn't (so it returns 0, and a space isn't printed) and then
sets sys.stdout.softspace to 1 (that's what the "1" parameter above
is).

Then the code in ceval.c calls PyFile_WriteObject with the C() object
which winds up calling your __getattr__ method which calls "print
'__str__'"; this gets to the point just mentioned in the code for
PRINT_ITEM, but this time when it calls PyFile_Softspace,
sys.stdout.softspace *is* 1, so it returns 1 and a space is printed,
followed by the string '__str__'; then the PRINT_NEWLINE that follows
sets sys.stdout.softspace to 0, so if you're __getattr__ method
returned appropriately (ie. with a callable or by raising
AttributeError), the printed representation of C() would appear on a
line on it's own, without a space.  But it returns None, so
PyObject_Print blows up, and you get a traceback instead.

Does that help?

> > Your wish is my command [...]  Not sure it's a sufficiently common error
> > to justify this though.  I'll send it to patches at python.org and see what
> > they think of it.
> 
> I hope they will accept them.  Each and every diagnostic should be as
> clear as possible, and _especially_ those diagnostics which are uncommon!

No word yet.  Not too surprising, really...

> > Overriding __getattr__ is good for "oo, ain't that cool" value, but it
> > is probably best to try to avoid it - if you need it, fine, but consider
> > alternatives first.
> 
> Of course, a "need" is a pretty subjective matter.  We can do a great
> deal with very little, and there are not many so-called needs that would
> really stand scrutiny.  In my case, I have a working program already,
> and implementing __getattr__ is part of an intermediary cleanup, before
> attempting to move further, so to simplify code all over and gain better
> maintainability.  So in a sense, I could say that I considered at least one
> alternative, which is already implemented and working.  I think that the
> increase in legibility is worth the slowdown, which the project can afford.

Fair enough.  
 
> P.S. - I hope that Guido will do his best so future Python stays legible.

Out of curiosity, here do you mean Python source, or the C source of
Python?  Both are almost uniquely readable, but which did you mean?

Cheers,
M.

-- 
  Just point your web browser at http://www.python.org/search/ and
  look for "program", "doesn't", "work", or "my". Whenever you find
  someone else whose program didn't work, don't do what they
  did. Repeat as needed.    -- Tim Peters, on python-help, 16 Jun 1998



More information about the Python-list mailing list