a type without a __mro__?

A

Alex Martelli

Can anybody suggest where to find (within the standard library) or how
to easily make (e.g. in a C extension) a type without a __mro__, except
for those (such as types.InstanceType) which are explicitly recorded in
the dispatch table copy._deepcopy_dispatch...?

Weird request, I know, so let me explain. There's a bug in the
forthcoming 2.3.5's copy.py which can be tickled only by such a type.

Fixing the bug is trivially easy (I'll just use inspect.getmro(cls)
instead of cls.__mro__), but I also want to add to test_copy.py a unit
test that tickles the bug, rather than just commit an ``untested fix''.

I'm stumped at finding a type that's suitable for reproducing the bug;
I've asked the submitter of the original bug report (which comes up with
Zope and some specific application -- unsuitable for a core python unit
test, sigh), I've asked on python-dev, I've even IM'd a couple of
Python-guru friends, but the friends are equally stumped and I'm getting
no answers on python-dev nor from the submitter of the bug report. So,
I thought I'd turn to the collective ingenuity of comp.lang.python...
thanks in advance for any help!


Alex
 
F

Fredrik Lundh

Alex said:
Can anybody suggest where to find (within the standard library) or how
to easily make (e.g. in a C extension) a type without a __mro__, except
for those (such as types.InstanceType) which are explicitly recorded in
the dispatch table copy._deepcopy_dispatch...?

something like this?
Traceback (most recent call last):
False

</F>
 
N

Nick Coghlan

Fredrik said:
Alex Martelli wrote:




something like this?



Traceback (most recent call last):


False

</F>

Unfortunately, it *does* have a __deepcopy__ method, so I don't think it
actually triggers the bug Alex is interested in:

Py> import re
Py> x = re.compile("")
Py> x.__mro__
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: __mro__
Py> from copy import deepcopy
Py> deepcopy(x)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "C:\Python24\lib\copy.py", line 172, in deepcopy
y = copier(memo)
TypeError: cannot deepcopy this pattern object
Py> x.__deepcopy__
<built-in method __deepcopy__ of _sre.SRE_Pattern object at 0x00B242C0>

Cheers,
Nick.
 
A

Alex Martelli

Fredrik Lundh said:
something like this?

Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: __mro__

Alas, no -- wish it were so easy! It does need to be a TYPE, not just
any object, to reproduce the bug that was reported about 2.3.5c1's
copy.py. The relevant code in copy.py does the equivalent of:

not of just x.__mro__, which would easily be made to fail.

How a type(whatever) can end up without a __mro__ in 2.3.* is rather
murky to me; looks like something strange must be happening wrt the
type's flags, or something. Normal types such as _sre.SRE_Pattern, or
the Copyable type I put in _testcapi, just sprout an __mro__ without
even trying. Ah well, thanks anyway -- guess I'll commit the fix (using
inspect.getmro(cls) rather than cls.__mro__) even though I don't have a
unit test to show it's necessary and sufficient:-(


Alex
 
J

John Lenton

Can anybody suggest where to find (within the standard library) or how
to easily make (e.g. in a C extension) a type without a __mro__, except
for those (such as types.InstanceType) which are explicitly recorded in
the dispatch table copy._deepcopy_dispatch...?

would this do what you need?

class C(type):
def __getattribute__(self, attr):
if attr == '__mro__':
raise AttributeError, "What, *me*, a __mro__? Nevah!"
return super(C, self).__getattribute__(attr)

class D(object):
__metaclass__ = C

instances of D have a type that behaves as if it didn't have a
__mro__. This isn't exactly what you asked for, but it might be
enough.

--
John Lenton ([email protected]) -- Random fortune:
El tiempo cura los dolores y las querellas porque cambiamos. Ya no somos la
misma persona.
-- Blaise Pascal. (1600-1662) Filósofo y escritor francés.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (GNU/Linux)

iD8DBQFCBbuNgPqu395ykGsRAiaJAJ9jAWy3eB2ih8xUXnjvWtcXk5qOiACcC+Z5
BLOF4ECf5gwqiFj5SqgHwEc=
=KyH9
-----END PGP SIGNATURE-----
 
A

Alex Martelli

John Lenton said:
class C(type):
def __getattribute__(self, attr):
if attr == '__mro__':
raise AttributeError, "What, *me*, a __mro__? Nevah!"
return super(C, self).__getattribute__(attr)

class D(object):
__metaclass__ = C

Yay -- *exactly*!!! This simple trick reproduces the problem AND shows
that using inspect.getmro fixes it. EXACTLY what we needed. Thanks!!!
Now I can make a proper patch with unittest as well as the fix.


Alex
 

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

Forum statistics

Threads
474,219
Messages
2,571,117
Members
47,730
Latest member
scavoli

Latest Threads

Top