subclassing a module: misleading(?) error message

Discussion in 'Python' started by Erik Johnson, Jan 4, 2007.

  1. Erik Johnson

    Erik Johnson Guest

    I ran into a problem I didn't understand at first. I got part of it figured
    out. Let me first demonstrate the original problem:

    > cat Super.py


    class Super(object):
    def __init__(self):
    self._class = 'Super'
    def hello(self):
    print "%s says 'Hello'" % self._class
    > cat Sub.py


    import Super

    class Sub(Super):
    def __init__(self):
    self._class = 'Sub'
    >
    > python

    Python 2.3.4 (#1, Feb 7 2005, 15:50:45)
    [GCC 3.3.4 (pre 3.3.5 20040809)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> from Super import Super
    >>> from Sub import Sub

    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    File "Sub.py", line 4, in ?
    class Sub(Super):
    TypeError: function takes at most 2 arguments (3 given)
    >>>


    My question is NOT "What's wrong here?"
    (The answer to that is that the import in Sub.py should be: from Super
    import Super
    i.e., I tried to use the module itself where I meant to subclass the class
    defined in that module).

    My questions are:

    Why does python complain about a function here? (it's a class definition
    statement, right?)
    Is there really a function being called here?
    If so:
    What function was called?
    What two arguments is it expecting?
    What three were given?

    Thanks,
    -ej
     
    Erik Johnson, Jan 4, 2007
    #1
    1. Advertising

  2. Erik Johnson

    Carl Banks Guest

    Erik Johnson wrote:
    > My questions are:
    >
    > Why does python complain about a function here? (it's a class definition
    > statement, right?)


    Because you're calling the function with the wrong number of arguments.

    > Is there really a function being called here?


    Yes. (Well, it's not exactly a function, but you are calling
    something.)

    > If so:
    > What function was called?


    types.ModuleType

    > What two arguments is it expecting?


    The name of the module and a docstring.

    > What three were given?


    1. The name of the class
    2. The tuple of bases
    3. A dict containing the symbols defined inside the class statement.

    You are aware, I presume, that types (be it classes or built-in types)
    are callable. For example, to create an instance of class of class X,
    you would call X(). And to create a list, you can call list(). Well,
    in the same way, you can call type(), with the three arguments above,
    to create classes. And that's just what the class statement does under
    the covers (usually).

    The following class definition:

    class A(object):
    b = 1

    is exactly equivalent to this explicit call to type:

    A = type("A",(object,),{"b":1})

    However, there are some cases where, instead of creating the class
    object itself, type will instead call some other function to create it.
    One way is if you define __metaclass__ in the class namespace: then
    type will call the object spec. Another way is if there are any bases
    which have a type other than type. (Remember, bases are supposed to be
    type objects.)

    That's what happened to you. type saw that type(Super) was
    types.ModuleType, not type, so it called that instead of creating the
    class itself. However, types.ModuleType doesn't accept that same
    arguments that a normal type constructor does, so you get the error.

    Does that clear things up? Probably not. For a detailed explanation
    of how this all works, look for some resources on learning
    "metaclasses" or "metatypes" in Python.


    Carl Banks
     
    Carl Banks, Jan 4, 2007
    #2
    1. Advertising

  3. Erik Johnson

    Huayang Xia Guest

    So you know you are subclassing a module.

    There is an answer @
    http://www.velocityreviews.com/forums/showpost.php?p=1819038&postcount=2

    On Jan 4, 3:49 pm, "Erik Johnson" <ej at somewhere.com> wrote:
    > I ran into a problem I didn't understand at first. I got part of it figured
    > out. Let me first demonstrate the original problem:
    >
    > > cat Super.pyclass Super(object):

    > def __init__(self):
    > self._class = 'Super'
    > def hello(self):
    > print "%s says 'Hello'" % self._class
    >
    > > cat Sub.pyimport Super

    >
    > class Sub(Super):
    > def __init__(self):
    > self._class = 'Sub'
    >
    > > pythonPython 2.3.4 (#1, Feb 7 2005, 15:50:45)

    > [GCC 3.3.4 (pre 3.3.5 20040809)] on linux2
    > Type "help", "copyright", "credits" or "license" for more information.>>> from Super import Super
    > >>> from Sub import SubTraceback (most recent call last):

    > File "<stdin>", line 1, in ?
    > File "Sub.py", line 4, in ?
    > class Sub(Super):
    > TypeError: function takes at most 2 arguments (3 given)
    >
    > My question is NOT "What's wrong here?"
    > (The answer to that is that the import in Sub.py should be: from Super
    > import Super
    > i.e., I tried to use the module itself where I meant to subclass the class
    > defined in that module).
    >
    > My questions are:
    >
    > Why does python complain about a function here? (it's a class definition
    > statement, right?)
    > Is there really a function being called here?
    > If so:
    > What function was called?
    > What two arguments is it expecting?
    > What three were given?
    >
    > Thanks,
    > -ej
     
    Huayang Xia, Jan 4, 2007
    #3
  4. At Thursday 4/1/2007 17:49, Erik Johnson wrote:

    >Python 2.3.4 (#1, Feb 7 2005, 15:50:45)
    >Traceback (most recent call last):
    > File "<stdin>", line 1, in ?
    > File "Sub.py", line 4, in ?
    > class Sub(Super):
    >TypeError: function takes at most 2 arguments (3 given)
    >
    >Why does python complain about a function here? (it's a class definition
    >statement, right?)
    >Is there really a function being called here?
    >If so:
    > What function was called?
    > What two arguments is it expecting?
    > What three were given?


    The same thing on Python 2.4.2 (at least) prints a much more meaningful error:

    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    TypeError: Error when calling the metaclass bases
    module.__init__() takes at most 2 arguments (3 given)


    --
    Gabriel Genellina
    Softlab SRL






    __________________________________________________
    Preguntá. Respondé. Descubrí.
    Todo lo que querías saber, y lo que ni imaginabas,
    está en Yahoo! Respuestas (Beta).
    ¡Probalo ya!
    http://www.yahoo.com.ar/respuestas
     
    Gabriel Genellina, Jan 5, 2007
    #4
  5. Erik Johnson

    ej Guest

    Carl Banks wrote:

    <snip> A good explanation

    I have not been able to get back to news lately - lot going on, but
    thank you for your time to explain that to me. It mostly makes pretty
    good sense to me, but I will have to study metaclasses further. ;)

    Thanks,
    -ej
     
    ej, Jan 11, 2007
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. j
    Replies:
    5
    Views:
    420
    Samuel Barber
    Jul 27, 2003
  2. Brian Kelley

    Misleading Python error message

    Brian Kelley, Nov 19, 2003, in forum: Python
    Replies:
    4
    Views:
    376
    Dennis Lee Bieber
    Nov 21, 2003
  3. Claudio Grondi
    Replies:
    8
    Views:
    805
    Georg Brandl
    Aug 28, 2006
  4. Roy Smith

    Misleading error message of the day

    Roy Smith, Dec 8, 2011, in forum: Python
    Replies:
    37
    Views:
    560
    Lie Ryan
    Dec 10, 2011
  5. Vít Ondruch

    Subclassing in module from top module?

    Vít Ondruch, Oct 12, 2009, in forum: Ruby
    Replies:
    3
    Views:
    119
    Vít Ondruch
    Oct 12, 2009
Loading...

Share This Page