a type without a __mro__?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Alex Martelli

    #1

    a type without a __mro__?

    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.InstanceT ype) 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.pytho n...
    thanks in advance for any help!


    Alex
  • Fredrik Lundh

    #2
    Re: a type without a __mro__?

    Alex Martelli wrote:
    [color=blue]
    > 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.InstanceT ype) which are explicitly recorded in
    > the dispatch table copy._deepcopy_ dispatch...?[/color]

    something like this?
    [color=blue][color=green][color=darkred]
    >>> import re
    >>> x = re.compile("")
    >>> x[/color][/color][/color]
    <_sre.SRE_Patte rn object at 0x00B2F7A0>[color=blue][color=green][color=darkred]
    >>> x.__mro__[/color][/color][/color]
    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    AttributeError: __mro__[color=blue][color=green][color=darkred]
    >>> import copy
    >>> type(x) in copy._deepcopy_ dispatch[/color][/color][/color]
    False

    </F>



    Comment

    • Nick Coghlan

      #3
      Re: a type without a __mro__?

      Fredrik Lundh wrote:[color=blue]
      > Alex Martelli wrote:
      >
      >[color=green]
      >>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.InstanceT ype) which are explicitly recorded in
      >>the dispatch table copy._deepcopy_ dispatch...?[/color]
      >
      >
      > something like this?
      >
      >[color=green][color=darkred]
      >>>>import re
      >>>>x = re.compile("")
      >>>>x[/color][/color]
      >
      > <_sre.SRE_Patte rn object at 0x00B2F7A0>
      >[color=green][color=darkred]
      >>>>x.__mro__[/color][/color]
      >
      > Traceback (most recent call last):
      > File "<stdin>", line 1, in ?
      > AttributeError: __mro__
      >[color=green][color=darkred]
      >>>>import copy
      >>>>type(x) in copy._deepcopy_ dispatch[/color][/color]
      >
      > False
      >
      > </F>[/color]

      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\li b\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_Patter n object at 0x00B242C0>

      Cheers,
      Nick.

      --
      Nick Coghlan | ncoghlan@email. com | Brisbane, Australia
      ---------------------------------------------------------------

      Comment

      • Alex Martelli

        #4
        Re: a type without a __mro__?

        Fredrik Lundh <fredrik@python ware.com> wrote:
        [color=blue]
        > Alex Martelli wrote:
        >[color=green]
        > > 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[/color][/color]
        ^^^^^^[color=blue][color=green]
        > > for those (such as types.InstanceT ype) which are explicitly recorded in
        > > the dispatch table copy._deepcopy_ dispatch...?[/color]
        >
        > something like this?
        >[color=green][color=darkred]
        > >>> import re
        > >>> x = re.compile("")
        > >>> x[/color][/color]
        > <_sre.SRE_Patte rn object at 0x00B2F7A0>[color=green][color=darkred]
        > >>> x.__mro__[/color][/color]
        > Traceback (most recent call last):
        > File "<stdin>", line 1, in ?
        > AttributeError: __mro__[/color]

        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:
        [color=blue][color=green][color=darkred]
        >>> type(x).__mro__[/color][/color][/color]
        (<type '_sre.SRE_Patte rn'>, <type 'object'>)[color=blue][color=green][color=darkred]
        >>>[/color][/color][/color]

        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_Patter n, 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

        Comment

        • John Lenton

          #5
          Re: a type without a __mro__?

          On Sat, Feb 05, 2005 at 11:37:10AM +0100, Alex Martelli wrote:[color=blue]
          > 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.InstanceT ype) which are explicitly recorded in
          > the dispatch table copy._deepcopy_ dispatch...?[/color]

          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).__getattr ibute__(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 (john@grulic.or g.ar) -- 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)

          iD8DBQFCBbuNgPq u395ykGsRAiaJAJ 9jAWy3eB2ih8xUX njvWtcXk5qOiACc C+Z5
          BLOF4ECf5gwqiFj 5SqgHwEc=
          =KyH9
          -----END PGP SIGNATURE-----

          Comment

          • Alex Martelli

            #6
            Re: a type without a __mro__?

            John Lenton <john@grulic.or g.ar> wrote:
            [color=blue]
            > class C(type):
            > def __getattribute_ _(self, attr):
            > if attr == '__mro__':
            > raise AttributeError, "What, *me*, a __mro__? Nevah!"
            > return super(C, self).__getattr ibute__(attr)
            >
            > class D(object):
            > __metaclass__ = C[/color]

            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

            Comment

            Working...