473,569 Members | 2,799 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Metaclass with name overloading.

I would like to write a metaclass which would allow me to overload
names in the definition of its instances, like this

class Foo(object):

__metaclass__ = OverloadingClas s

att = 1
att = 3

def meth(self):
pass

def meth(self, arg):
return arg
I would then like the dictionary received by OverloadingClas s.__new__
to look something like this:

{'att': (1,3),
'meth: (<function meth at 0x4018e56c>, <function meth at 0x4018e80c>) }

IOW, each name bound in the class definition should have associated
with it, a tuple containing all the objects which were bound to that
name, rather merely keeping the most recent binding for any given
name.

I was wondering whether it would be possible to achieve this by
forcing Python to use some dicitonary proxy (which accumulates values,
rather that keeping just the last value to be associated with a key),
instead of dict, when executing the class definiton?

Is something like this at all possible in pure Python? or does in
require fiddling around in the guts of the parser?
Jul 18 '05 #1
33 2503
Jacek Generowicz <ja************ **@cern.ch> wrote:
...
I would like to write a metaclass which would allow me to overload
names in the definition of its instances, like this ... I was wondering whether it would be possible to achieve this by
forcing Python to use some dicitonary proxy (which accumulates values,
rather that keeping just the last value to be associated with a key),
instead of dict, when executing the class definiton?

Is something like this at all possible in pure Python? or does in
require fiddling around in the guts of the parser?


It's not possible in pure Python -- Python will always use a real dict
rather than any other type as you'd wish. The parser OTOH shouldn't
really be involved, either. In the end it boils down to a series of
STORE_NAME pseudocode instructions, which currently do:

case STORE_NAME:
w = GETITEM(names, oparg);
v = POP();
if ((x = f->f_locals) != NULL) {
if (PyDict_CheckEx act(x))
err = PyDict_SetItem( x, w, v);
else
err = PyObject_SetIte m(x, w, v);
Py_DECREF(v);

so they'd be able to work with f_locals being either a dict, or any
other mapping -- so that part should be OK. But having frame f's
f_locals be anything but a dict, now THAT is the problem...
Alex

Jul 18 '05 #2
On 27 Sep 2004 13:33:33 +0200, Jacek Generowicz
<ja************ **@cern.ch> wrote:
<snip>
I would then like the dictionary received by OverloadingClas s.__new__
to look something like this:

{'att': (1,3),
'meth: (<function meth at 0x4018e56c>, <function meth at 0x4018e80c>) }

IOW, each name bound in the class definition should have associated
with it, a tuple containing all the objects which were bound to that
name, rather merely keeping the most recent binding for any given
name.

I was wondering whether it would be possible to achieve this by
forcing Python to use some dicitonary proxy (which accumulates values,
rather that keeping just the last value to be associated with a key),
instead of dict, when executing the class definiton?

Is something like this at all possible in pure Python? or does in
require fiddling around in the guts of the parser?


No, you can't, and it's not just a parser issue. Python uses direct C
calls to the native dict type. It's hard coded, and I don't see any
obvious or easy way to override it except by rewriting all such code.
The metaclass receives the dictionary after all declarations were
collected, and then it's too late to act upon it.

Now that we're talking about it, I would like to discuss how this type
of hack could possibly be done in a future version of Python (probaly
Python 3.0, I don't think it's anywhere close to possible for Python
2.x).

1) One such idea is to provide the metaclass with a __dict__ factory.
For example:

class MyMetaclass(typ e):
def __new__(...):
...
def __dict__(cls):
return CustomDict()

.... where CustomDict is a user-defined mapping type that can store
more information about the entries than the native dict:

-- CustomDict[name] would retrieve a tuple containing all entries, in
reverse order. CustomDict[name][0] would retrieve the last definition.

-- The order of the definitions would be preserved, and the iterators
(iterkeys, iteritems, itervalues) would all iterate over the entries
in the order of the definition.

By using a user-defined dict, we would still use the default dict most
of the time without any noticeable performance hit, but would be able
to change the guts of the class declaration system whenever needed.

2) Another (crazy) idea is to have the possibility to declare
anonymous class members, such as in:

class MyClass:
"""the first anonymous member is the doc string"""
"""the second anonymous member is __anon__[0]"""
1.5 # __anon__[1] = 1.5

By anonymous members, I mean anything that is not a def, a nested
class, or a value that wasn't assigned or bound to name. That's would
be nice to have too :-)

-------
p.s. In the particular case of the original poster, I'm wondering what
kind of application did he had in mind. I had similar needs while
studying some alternatives to declare some types of data structure in
Python -- forms, reports, webpages, etc -- stuff where the order of
the entries is potentially as important than the actual member names.
I'm really curious about it...

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmai l.com
mail: ca********@yaho o.com
Jul 18 '05 #3
Carlos Ribeiro <ca********@gma il.com> wrote:
...
No, you can't, and it's not just a parser issue. Python uses direct C
calls to the native dict type. It's hard coded, and I don't see any
obvious or easy way to override it except by rewriting all such code.
The STORE_NAME used within the code object to which the class body gets
compiled is quite ready for a non-native-dict f_locals of the frame.
The problem is how to get your own favourite object into that f_locals
in the first place, and THAT one is hard -- can't think of any way...
The metaclass receives the dictionary after all declarations were
collected, and then it's too late to act upon it.
Yep, far too late. You'd have to somehow tweak the CALL_FUNCTION
bytecode that's compiled as part of the class statement, so that it
makes a frame whose f_locals is some strange object of your choice.
Now that we're talking about it, I would like to discuss how this type
of hack could possibly be done in a future version of Python (probaly
Python 3.0, I don't think it's anywhere close to possible for Python
2.x).
I think it might be quite feasible in 2.5 (too late for 2.4).

1) One such idea is to provide the metaclass with a __dict__ factory.
If you go that route, then it may indeed require changes too deep for
2.5 or 2.anything. The metaclass gets determined later, at the time
CALL_FUNCTION executes the metaclass ain't in play yet.
By using a user-defined dict, we would still use the default dict most
of the time without any noticeable performance hit, but would be able
to change the guts of the class declaration system whenever needed.
Yeah, but if you make it a metaclass's job, then you're indeed asking
for deep changes from today's architecture.
2) Another (crazy) idea is to have the possibility to declare
anonymous class members, such as in:

class MyClass:
"""the first anonymous member is the doc string"""
"""the second anonymous member is __anon__[0]"""
1.5 # __anon__[1] = 1.5

By anonymous members, I mean anything that is not a def, a nested
class, or a value that wasn't assigned or bound to name. That's would
be nice to have too :-)


Maybe, and maybe not, but it would not help in the least with dealing
with two def's for the same name, as the OP wanted.

One thing that might work: have a sys._set_locals _factory(...) which
lets you change (maybe per-thread...?) how a frame's f_locals are made.
Alex
Jul 18 '05 #4
On Mon, 27 Sep 2004 15:27:31 +0200, Alex Martelli <al*****@yahoo. com> wrote:
1) One such idea is to provide the metaclass with a __dict__ factory.


If you go that route, then it may indeed require changes too deep for
2.5 or 2.anything. The metaclass gets determined later, at the time
CALL_FUNCTION executes the metaclass ain't in play yet.
By using a user-defined dict, we would still use the default dict most
of the time without any noticeable performance hit, but would be able
to change the guts of the class declaration system whenever needed.


Yeah, but if you make it a metaclass's job, then you're indeed asking
for deep changes from today's architecture.


Yes, that's why I said that I don't think this is possible in a short
time frame. But for now, I have only one question. You said that the
metaclass is determined later. I'm not familiar with Python's
internals, but I (naively?) assumed that the metaclass is known very
early in the class declaration process. Is that wrong?

obs 1: If it's possible to determine the metaclass *early*, then it's
no problem to call any extra function to provide the f_locals dict, or
to provide an augmented dict.
--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmai l.com
mail: ca********@yaho o.com
Jul 18 '05 #5
Carlos Ribeiro <ca********@gma il.com> wrote:
...
On Mon, 27 Sep 2004 15:27:31 +0200, Alex Martelli <al*****@yahoo. com> wrote:
1) One such idea is to provide the metaclass with a __dict__ factory.
If you go that route, then it may indeed require changes too deep for
2.5 or 2.anything. The metaclass gets determined later, at the time
CALL_FUNCTION executes the metaclass ain't in play yet.

... time frame. But for now, I have only one question. You said that the
metaclass is determined later. I'm not familiar with Python's
internals, but I (naively?) assumed that the metaclass is known very
early in the class declaration process. Is that wrong?
I'm confused as to why you would assume that and what you mean by
'declaration'. I'll take it that you mean the _execution_ of the class
_statement_, in which case I really can't see how you could assume any
such thing. You _do_ know that __metaclass__ can be set anywhere in the
class body, for example, right? So how could Python know the metaclass
before it's done executing the class body? Yet it's exactly in order to
execute the class body in the modified way you desire, that Python would
need to set a certain frame's f_locals differently from the usual dict.

In other words, it's not an issue of implementation details that could
be tweaked while leaving current semantics intact: if you insist that it
must be the _metaclass_ which determines what kind of mapping object is
used for the f_locals of the frame where the class's body executes, then
it cannot be possible any more to determine the metaclass with today's
semantics (which I think are pretty fine, btw).

Come to think of it, this might be a great role for class-decorators.
If I had a way to tweak the kind of f_locals for a _function_, the
general semantics of today's function decorators would be fine (the
tweak might be attached after the function object is built, since it's
only needed when that function gets _called_). But for a class, by the
time the class body starts executing, it's too late, because it must be
executing with some kind of f_locals in its frame. So, class decorators
would have to be given a chance _before_ the class body runs.
obs 1: If it's possible to determine the metaclass *early*, then it's
no problem to call any extra function to provide the f_locals dict, or
to provide an augmented dict.


But Python can never be sure what the metaclass will be until the class
body is done executing, far too late. Basically, you'd need to forbid
the current possibility of setting __metaclass_ in the class body, plus,
you'd have to get deep into analyzing the bases before executing the
class body -- and if you look at what types.ClassType does to delegate
the metaclass choice to other bases if it possibly can, you'll probably
agree that this nicety has to be abrogated too.

All in order to have the f_locals' kind be set by the *metaclass* rather
than by other means -- honestly, it seems the price is too high, unless
there are some big advantages connected by the choice of metaclass vs
other means that I fail to see. What's so terrible about my q&d idea of
having a sys._something function do the job, for example? Then once we
have the ability to do the setting we can think of nice syntax to dress
it up. But the mods to ceval.c needed to accept any kind of setting for
f_locals' type seem a pretty big job already, without needing to put up
the hurdle that the metaclass must be determined early, too...
Alex
Jul 18 '05 #6
Jacek Generowicz <ja************ **@cern.ch> writes:
I would like to write a metaclass which would allow me to overload
names in the definition of its instances, like this

class Foo(object):

__metaclass__ = OverloadingClas s

att = 1
att = 3

def meth(self):
pass

def meth(self, arg):
return arg
I would then like the dictionary received by OverloadingClas s.__new__
to look something like this:

{'att': (1,3),
'meth: (<function meth at 0x4018e56c>, <function meth at 0x4018e80c>) }

IOW, each name bound in the class definition should have associated
with it, a tuple containing all the objects which were bound to that
name, rather merely keeping the most recent binding for any given
name.

I was wondering whether it would be possible to achieve this by
forcing Python to use some dicitonary proxy (which accumulates values,
rather that keeping just the last value to be associated with a key),
instead of dict, when executing the class definiton?

Is something like this at all possible in pure Python? or does in
require fiddling around in the guts of the parser?


It won't work for ordinary attributes, but for overloading methods you
should be able to play some tricks with decorators and sys._getframe() .

Thomas
Jul 18 '05 #7
On Mon, 27 Sep 2004 16:47:31 +0200, Alex Martelli <al*****@yahoo. com> wrote:
I'm confused as to why you would assume that and what you mean by
'declaration'. I'll take it that you mean the _execution_ of the class
_statement_, in which case I really can't see how you could assume any
such thing. You _do_ know that __metaclass__ can be set anywhere in the
class body, for example, right? So how could Python know the metaclass
before it's done executing the class body? Yet it's exactly in order to
execute the class body in the modified way you desire, that Python would
need to set a certain frame's f_locals differently from the usual dict.


Forgive me, because I've made a big confusion. For some reason, I
assumed that the __metaclass__ statement had to be the first one on
the class declaration. I don't know why. Probably because all examples
that I have seen so far have were done like that, and in a way, it
made sense to me -- probably because I wanted it to be that.

I think that I'm trying to do too many thing at once, with more
enthusiasm than solid knowledge. I really feel that I'm on the right
path, but I'm still missing a lot of stuff. I'll try to rest a little,
think carefully about all the ideas that have popped in my mind over
the past week, and try to study it a little better *before* trying to
post again. Real thanks for all the help.

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmai l.com
mail: ca********@yaho o.com
Jul 18 '05 #8
Carlos Ribeiro <ca********@gma il.com> wrote:
...
Forgive me, because I've made a big confusion. For some reason, I
assumed that the __metaclass__ statement had to be the first one on
the class declaration. I don't know why. Probably because all examples
that I have seen so far have were done like that, and in a way, it
made sense to me -- probably because I wanted it to be that.
Ah, I see. There is no such constraint, nor does Python need to 'peek'
into the class body _at all_ trying to find all the ways in which the
name __metaclass__ could be bound, even if it was the first statement to
do that binding. E.g.,

class foo:
class __metaclass__(t ype): ...

or

class bar:
from baz import fee as __metaclass__

and a bazillion other possibilities to bind name '__metaclass__' in the
class body. Python just executes the class body, _then_ checks if
'__metaclass__' is a key in the resulting dictionary -- that's all. WAY
simpler and more general, this way.

I think that I'm trying to do too many thing at once, with more
enthusiasm than solid knowledge. I really feel that I'm on the right
path, but I'm still missing a lot of stuff. I'll try to rest a little,
think carefully about all the ideas that have popped in my mind over
the past week, and try to study it a little better *before* trying to
post again. Real thanks for all the help.


You're welcome! Sure, metaclasses are tempting when one is trying to
shoehorn not-quite-feasible things into Python. And I do appreciate
that one really prefers declarative syntax sometimes... but...

In AB Strakt's CAPS framework, we started out with purely-executable
ways to build Business Logic Modules (calls such as 'blm = MakeBlm(...)'
and 'ent = blm.addEntity(. ..)' etc etc), then we moved to a simple
"interprete r" churning simple data structures (and doing the
executable-ways of BLM creation under the covers), finally designed a
dedicated, purely declarative language (informally known as 'blam'),
with somewhat Pythonesque syntax, to express each BLM (basically the
result of an Entity-Relationship Diagram analysis, plus embedded Python
code for 'trigger'-like actions, and the like) -- so, now, we parse
'blam' modules into AST's, walk the AST's to generate the needed Python
code, etc.

A dedicated declarative "small language" is, I believe, a better idea
than shoehorning a declarative language into Python. It lets us choose
the best syntax more freely, provide clearer error messages when
something is wrong, process a BLM in alternate ways (e.g. to produce ERD
graphics rather than executable forms), etc. However, I understand the
charm of the alternative "embedding" idea.

The ability to use something else than a dict for a frame's f_locals, in
any case, _would_ be neat. Your other ideas about anonymous members
would require more -- executing the 'function' that's built from the
class body's code-object in a special state where expression's results
aren't just thrown away but processed (much like an interactive
interpreter does -- but merging that with function execution is still
somewhat of a challenge...). For all this sort of ideas, a good grasp
of the relevant Python internals would help -- if you know enough C,
it's mostly not THAT hard, as said internals are mostly quite cleanly
coded (with a few exceptions where speed is paramount, or regarding the
parsing itself, which isn't the most readable parser in the world;-)...

Module dis is your friend -- you can disassemble any piece of code that
interests you to see what bytecode it produces. You can then dip into
ceval.c to see exactly what happens on this bytecode or that... it's a
really fun process of learning, really!
Alex
Jul 18 '05 #9
Thomas Heller <th*****@python .net> wrote:
...
It won't work for ordinary attributes, but for overloading methods you
should be able to play some tricks with decorators and sys._getframe() .


Great idea... love it!!! To clarify it a bit for people who may not be
as familiar with internals as Mr Heller...: a decorator 'sees' the
method it's decorating "at once", so it doesn't matter if that method's
name later gets trampled upon... as long as the decorator can stash the
original away somewhere, and the frame in which the class body is
executing is just the right 'somewhere'.

A code snippet may be clearer than words...:

import sys, itertools

_ignore_method = object()

def overloaded(f):
d = sys._getframe(1 ).f_locals
n = '__overloaded__ %s__%%d' % f.func_name
for i in itertools.count ():
nx = n % i
if nx in d: continue
d[nx] = f
break
return _ignore_method

class blop:
@ overloaded
def f(self): return 'first f'
@ overloaded
def f(self): return 'second f'

print blop.__dict__
so, class blop doesn't really have an 'f' (it does have it in the
__dict__, but it's a dummy '_ignore_method ' entry with a suitable custom
metaclass would easily prune!-) but has __overloaded__f __0 and
__overloaded__f __1 methods (which, again, a suitable custom metaclass
could do whatever wonders with!-).

For overload purposes, you might have the decorator actually take as
arguments some _types_ and record them so that the metaclass can arrange
for the dispatching based on actual-argument types...

If you bletch at having to decorate each overloaded version with
'@overloaded', consider C# basically requires that "just BECAUSE",
without even having a good excuse such as "we need to do it that way due
to Python's semantics"...;-)
Alex
Jul 18 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
1808
by: Jp Calderone | last post by:
Due to some bizarre constraints placed on me, I've written the following metaclass: import types def remove(t, o): return tuple() class BizarreMetaclass(type): def __new__(klass, name, bases, attrs):
3
1681
by: Fernando Rodriguez | last post by:
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():
0
1602
by: Robin Becker | last post by:
A colleague wanted to initialize his class __new__ and tried code resembling this #######################1 class Metaclass (type): def __init__(cls, name, bases, *args, **kwargs): super(Metaclass, cls).__init__(cls, name, bases, *args, **kwargs) print 'cls=',cls, cls.__new cls.__new__ = staticmethod(cls.__new) def __new(self,cls,*args):
4
1566
by: Paul Morrow | last post by:
One of the beautiful things about Python is its clear, minimal syntax. So we must resist adding new syntax to the language, especially where there is a reasonable alternative. I believe that Stefen Eischet's suggestion for automatically determining a method's type (class/instance/static) from the name of its first formal parameter is a...
5
2251
by: Irmen de Jong | last post by:
Hi, I've developed the Metaclass below, because I needed a way to make a bunch of classes thread-safe. I didn't want to change every method of the class by adding lock.aqcuire()..lock.release() around the existing code. So I made a metaclass that essentially replaces every method of a class with a 'wrapper' method, that does the locking,...
2
1934
by: zipher | last post by:
After searching through comp.lang.python and the web regarding metaclasses, I could not find an example for customing classes using metaclass parameters. I want to be able to create a class at runtime by calling some function or 'meta-constructor' which returns a customized class and sets a class attribute according a given parameter. ...
14
2020
by: Pedro Werneck | last post by:
Hi I have a class A, with metaclass M_A, and class B, subclass of A, with metaclass M_B, subclass of M_A. A class C, subclass of B must have M_B or a subclass of it as metaclass, but what if I need to 'disable' the code in M_B on C ? The correct way to do that seems to be with a M_C metaclass, subclass of M_B, implementing but not...
9
1650
by: Christian Eder | last post by:
Hi, I think I have discovered a problem in context of metaclasses and multiple inheritance in python 2.4, which I could finally reduce to a simple example: Look at following code: class M_A (type) :
4
3297
by: Pedro Werneck | last post by:
Hi all I noticed something strange here while explaining decorators to someone. Not any real use code, but I think it's worth mentioning. When I access a class attribute, on a class with a custom metaclass with a __getattribute__ method, the method is used when acessing some attribute directly with the class object, but not when you do...
0
7924
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
8120
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
5512
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
5219
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3653
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3640
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2113
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1212
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
937
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.