Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Why has 'dir()' changed in Python 2.2?

0 views
Skip to first unread message

Dr. David Mertz

unread,
Feb 1, 2002, 9:47:14 PM2/1/02
to
I just noticed a change in Python 2.2... that turns out to break my
[xml_pickle] module. It shouldn't be hard to fix (although I *do* have
a decision to ponder about the best fix)... but I mostly wonder what the
thoughts behind the change were (it seems like it will break a lot of
code that is moderately introspective).

Here's a test program:

% cat dir_change.py
import sys
class C:
"The docstring for C"
def __init__(self):
self.foo = 3
self.bar = "bar"
def othermethod(self): pass
o = C()
print sys.version
print dir(o)

Running it (2.1):

% python dir_change.py
2.1 (#0, Jun 17 2001, 11:51:05) [EMX GCC 2.8.1]
['bar', 'foo']

compared with (2.2):

% python dir_change.py
2.2 (#0, Dec 24 2001, 18:42:48) [EMX GCC 2.8.1]
['__doc__', '__init__', '__module__', 'bar', 'foo', 'othermethod']

Here's a few others FWIW:

% python dir_change.py
1.5.1 (#0, Sep 21 1998, 08:28:40) [VisualAge C/C++]
['bar', 'foo']

% python dir_change.py
1.5.2 (#0, Jun 27 1999, 11:23:01) [VisualAge C/C++]
['bar', 'foo']

% python dir_change.py
2.0.42-S1.2.23 (#0, Apr 25 2001, 20:59:49) [GNU C/C++]
['bar', 'foo']

% jython dir_change.py
2.0
['bar', 'foo']

Or even:

# python dir_change.py
2.1.1 (#1, Aug 13 2001, 19:37:40)
[GCC 2.96 20000731 (Red Hat Linux 7.1 2.96-96)]
['bar', 'foo']

# python1 dir_change.py
1.5.2 (#1, Jul 5 2001, 03:02:19) [GCC 2.96 20000731 (Red Hat Linux 7.1 2
['bar', 'foo']

Or:

> python dir_change.py
2.2a2+ (#22, Sep 5 2001, 14:10:41) [MSC 32 bit (Intel)]
['__doc__', '__init__', '__module__', 'bar', 'foo', 'othermethod']

Ok, enough versions...

--
mertz@ | The specter of free information is haunting the `Net! All the
gnosis | powers of IP- and crypto-tyranny have entered into an unholy
.cx | alliance...ideas have nothing to lose but their chains. Unite
| against "intellectual property" and anti-privacy regimes!
-------------------------------------------------------------------------


Hans Nowak

unread,
Feb 1, 2002, 11:10:52 PM2/1/02
to
"Dr. David Mertz" wrote:
>
> I just noticed a change in Python 2.2... that turns out to break my
> [xml_pickle] module. It shouldn't be hard to fix (although I *do* have
> a decision to ponder about the best fix)... but I mostly wonder what the
> thoughts behind the change were (it seems like it will break a lot of
> code that is moderately introspective).

The descrinto document explains why:

http://www.python.org/2.2/descrintro.html#introspection

"In classic Python, the method names of lists were available as
the __methods__ attribute of list objects, with the same effect
as using the built-in dir() function. [...] Under the new proposal,
the __methods__ attribute no longer exists. [...] Instead, you can
get the same information from the dir() function, which gives more
information."

Apparently, it was expected that not much code would break.
Personally, I only use dir() in interactive sessions, to quickly
inspect a module or (other) object. For introspection in
programs, I usually inspect the object's __dict__.

--
Hans (base64.decodestring('d3VybXlAZWFydGhsaW5rLm5ldA=='))
# decode for email address ;-)
The Pythonic Quarter:: http://www.awaretek.com/nowak/

Tim Peters

unread,
Feb 1, 2002, 11:28:11 PM2/1/02
to
[Dr. David Mertz]

> I just noticed a change in Python 2.2... that turns out to break my
> [xml_pickle] module. It shouldn't be hard to fix (although I *do* have
> a decision to ponder about the best fix)... but I mostly wonder what the
> thoughts behind the change were

The original intent of dir() was to list the names available from a module
object, for convenience at an interactive prompt. As the years went on,
more gimmicks got added to it in more-or-less random fashion.

For instances of classes, the more-or-less accidental behavior that got
implemented was to list the keys of the instance's dict.

With type/class unification in 2.2, what were instances of builtin types
*became* instances of classes, and then (for example) in the early 2.2 alpha
releases you got

>>> dir([1, 2, 3)]
[]
>>>

Many people complained about that. It "was logical", since [1, 2, 3] is
indeed an instance of a class now, and doesn't have anything in its
"instance dict". It *used* to give a listing of list methods (append, sort,
etc), because dir() dealt with instances of *types* in an entirely different
way.

With 2.2 the usefuless of that distinction vanished, and after public
discussion it was decided to make dir(instance_of_class) reveal much more
info than it used to (read the 2.2 dir.__doc__). People who tried it in the
beta releases appeared to like it, and the complaints stopped regardless.

> (it seems like it will break a lot of code that is moderately
> introspective).

dir() is generally a poor building block for introspection, since what it
does (exactly) has always been unclear. It's more principled in 2.2 than it
was, but since its primary *intended* use is still for convenience at an
interactive prompt, its behavior is still subject to what people claim is
convenient. I don't know what you were using it for exactly, but chances
are good you should be looking at object.__dict__.keys() instead (which is
all dir() often did before 2.2).


Dr. David Mertz

unread,
Feb 2, 2002, 12:58:34 AM2/2/02
to
Me, previously:

|> I just noticed a change in Python 2.2... that turns out to break my
|> [xml_pickle] module. It shouldn't be hard to fix (although I *do* have
|> a decision to ponder about the best fix)

"Tim Peters" <tim...@home.com> wrote previously:


|I don't know what you were using it for exactly, but chances
|are good you should be looking at object.__dict__.keys() instead (which
|is all dir() often did before 2.2).

The timbot, as always, can peer through the surface words on the Usenet
into my deepest, dark thoughts. The obj.__dict__.keys() is probably
what I'll change it to, which should restore the old behavior. As the
name suggests, the [xml_pickle] module serializes Python objects to an
XML format... so dir() was a convenient shortcut for asking "what's this
object got?"

I probably should have known better, and -do- vaguely recall some
discussion about dir() on c.l.py around the time 2.2 alphas were coming
out. The thing I want to think about is whether I actually *want* any
of the extra information that dir() gives me; for example, maybe the
docstring.

Do I understand the new behavior correctly in thinking that the
following function is equivalent to dir(), at least for old-style class
instances:

def dir2(o):
lst = o.__dict__.keys()
lst.extend(o.__class__.__dict__.keys())
return lst

Or is there something else thrown in there that this overlooks?

Yours, David...

0 new messages