By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,621 Members | 1,104 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,621 IT Pros & Developers. It's quick & easy.

subclassing a module: misleading(?) error message

P: n/a
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
Jan 4 '07 #1
Share this Question
Share on Google+
4 Replies


P: n/a
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

Jan 4 '07 #2

P: n/a
So you know you are subclassing a module.

There is an answer @
http://www.velocityreviews.com/forum...38&postcount=2

On Jan 4, 3:49 pm, "Erik Johnson" <ej at somewhere.comwrote:
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
Jan 4 '07 #3

P: n/a
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

Jan 5 '07 #4

P: n/a
ej

Carl Banks wrote:

<snipA 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

Jan 11 '07 #5

This discussion thread is closed

Replies have been disabled for this discussion.