Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Trouble with metaclass

Reply
Thread Tools

Trouble with metaclass

 
 
Fernando Rodriguez
Guest
Posts: n/a
 
      11-13-2003
Hi,

I'm having trouble with a metaclass suposed to check the method signature of
its classes.

Here's the metaclass:

class MetaChecker(type):
def __new__(cls, name, bases, attribs):
for name, value in attribs.iteritems():
if inspect.ismethod(value):
if not isSingleArg(value):
raise "%s is not a thunk method!"%name
return type.__new__(cls, name, bases, attribs)


def isSingleArg(fn):

args = inspect.getargspec(fn)[0]
if len(args) == 1:
return 1
else:
return None


And here's a class with this metaclass:

class Preconditions (object):

__metaclass__ = MetaChecker



If I define a descendant of Preprocesor with a method with 2 arguments, I
don't get any error:
class P (Preprocessor):
def f(self, x):
return x


What am I doing wrong? O

 
Reply With Quote
 
 
 
 
anton muhin
Guest
Posts: n/a
 
      11-13-2003
Fernando Rodriguez wrote:
> Hi,
>
> I'm having trouble with a metaclass suposed to check the method signature of
> its classes.
>
> Here's the metaclass:
>
> class MetaChecker(type):
> def __new__(cls, name, bases, attribs):
> for name, value in attribs.iteritems():
> if inspect.ismethod(value):
> if not isSingleArg(value):
> raise "%s is not a thunk method!"%name
> return type.__new__(cls, name, bases, attribs)
>
>
> def isSingleArg(fn):
>
> args = inspect.getargspec(fn)[0]
> if len(args) == 1:
> return 1
> else:
> return None
>
>
> And here's a class with this metaclass:
>
> class Preconditions (object):
>
> __metaclass__ = MetaChecker
>
>
>
> If I define a descendant of Preprocesor with a method with 2 arguments, I
> don't get any error:
> class P (Preprocessor):
> def f(self, x):
> return x
>
>
> What am I doing wrong? O
>


The problem seems to be with ismethod function. Cf.:

import inspect

class MetaFoo(type):
def __new__(cls, name, bases, attribs):
for name, value in attribs.iteritems():
if inspect.isfunction(value):
print '%s(%s)' % (name, ',
'.join(inspect.getargspec(value)[0])) // Sorry, it's wrapped

return type.__new__(cls, name, bases, attribs)

class Base(object):
__metaclass__ = MetaFoo

class Foo(Base):
def method0(self): pass
def method1(self, x): pass
def method2(self, x, y): pass

And compare:

class Foo(object):
def method(self): pass
print 'inside', inspect.ismethod(method)
print 'inside', type(method)

print 'outside', inspect.ismethod(Foo.method)
print 'outside', type(Foo.method)

Python2.3 prints:
inside False
inside <type 'function'>
outside True
outside <type 'instancemethod'>


regards,
anton.

 
Reply With Quote
 
 
 
 
Alex Martelli
Guest
Posts: n/a
 
      11-13-2003
anton muhin wrote:

> Fernando Rodriguez wrote:

...
>> class MetaChecker(type):
>> def __new__(cls, name, bases, attribs):
>> for name, value in attribs.iteritems():
>> if inspect.ismethod(value):

...
> The problem seems to be with ismethod function. Cf.:


Right, or, more precisely, there is no problem with ismethod -- it
correctly reports that the values in the attribs dictionary are not
method objects (they're function objects).

Summarizing and simplifying only a little bit...:

1. The def statement always and exclusively creates a function object.

2. A function object is also a descriptor: when you call f.__get__(x),
you get back a method object with im_func == f and im_self == x.

3. The attribute lookup process calls x.__get__(self) on any attribute
it may find in the class's dictionary.

But at this point in the execution of the metaclass's __new__, there
is no "class dictionary" yet -- there isn't even a _class_ -- just a
plain dictionary of attributes which will BECOME the class dictionary
once you call type.__new-_ with that dict as the 4th argument.


Alex

 
Reply With Quote
 
Michele Simionato
Guest
Posts: n/a
 
      11-13-2003
Fernando Rodriguez <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>. ..
> Hi,
>
> I'm having trouble with a metaclass suposed to check the method signature of
> its classes.
>
> Here's the metaclass:
>
> class MetaChecker(type):
> def __new__(cls, name, bases, attribs):
> for name, value in attribs.iteritems():
> if inspect.ismethod(value):
> if not isSingleArg(value):
> raise "%s is not a thunk method!"%name
> return type.__new__(cls, name, bases, attribs)
>
>
> def isSingleArg(fn):
>
> args = inspect.getargspec(fn)[0]
> if len(args) == 1:
> return 1
> else:
> return None
>
>
> And here's a class with this metaclass:
>
> class Preconditions (object):
>
> __metaclass__ = MetaChecker
>
>
>
> If I define a descendant of Preprocesor with a method with 2 arguments, I
> don't get any error:
> class P (Preprocessor):
> def f(self, x):
> return x
>
>
> What am I doing wrong? O


The metaclass is right and actually the names you are using (Preconditions/
Preprocessors) suggest to me that you are using the right tool for the job;
the only problem is that you must use 'inspect.isfunction' and not
'inspect.ismethod', because of the methods <=> functions mismatch I am
sure you know everything about If not, please feel free to ask.

Also, I would use

return super(mcl,MetaChecker).__new__(mcl,name,bases,attr ibs)

instead of type.__new__, anticipating the need for multiple inheritance
of metaclasses.


Michele
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Metaclass of a metaclass Steven D'Aprano Python 1 06-05-2012 03:30 PM
metaclass that inherits a class of that metaclass? ironfroggy Python 16 06-03-2005 10:00 AM
Metaclass and __slots__ anabell@sh163.net Python 1 11-06-2003 08:09 AM
Slight metaclass confusion ben@transversal.com Python 9 09-10-2003 06:02 PM
Metaclass discussons Gustavo Niemeyer Python 5 08-25-2003 12:56 AM



Advertisments