Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Mangle function name with decorator?

232 views
Skip to first unread message

Adam

unread,
Mar 17, 2009, 12:35:05 PM3/17/09
to
I am using Python 2.5, and I would like to write a decorator (or using
some other elegant, declarative approach) to mangle the name of
function in a class. I would like to be able to have two methods
declared with the same name, but one of them will have a decorator (or
whatever) that will change the name of one of them.

Example:

class A(object):
def __init__(self, method, usebar = False):
self.method = method
self.usebar = usebar

def __call__(self):
if self.usebar == True:
mangled_name = "_bar_" + self.method
if hasattr(self, mangled_name):
return getattr(self, mangled_name)()
else:
return getattr(self, self.method)()
else:
if hasattr(self, self.method):
return getattr(self, self.method)()
else:
raise NotImplementedError

@bar
def foo(self):
print "in _bar_foo"

def foo(self):
print "in foo"

Desired output:
>>>y = A("foo", True)
>>>y()
in _bar_foo
>>>z = A("foo")
>>>z()
in foo


andrew cooke

unread,
Mar 17, 2009, 12:52:22 PM3/17/09
to Adam, pytho...@python.org
Adam wrote:
> class A(object):
> def __init__(self, method, usebar = False):
> self.method = method
> self.usebar = usebar
>
> def __call__(self):
> if self.usebar == True:
> mangled_name = "_bar_" + self.method
> if hasattr(self, mangled_name):
> return getattr(self, mangled_name)()
> else:
> return getattr(self, self.method)()
> else:
> if hasattr(self, self.method):
> return getattr(self, self.method)()
> else:
> raise NotImplementedError
>
> @bar
> def foo(self):
> print "in _bar_foo"
>
> def foo(self):
> print "in foo"


this isn't exactly what you ask for, but it gives a similar result. it's
kind of obvious, but it's possible you didn't know methods were first
class entities.

class Foo:

def __init__(self, useBar=False):
if useBar:
self.foo = self.__bar
else:
self.foo = self.__foo

def __foo(self):
print('foo')

def __bar(self):
print('bar')

andrew

Adam

unread,
Mar 17, 2009, 1:20:58 PM3/17/09
to
Thanks, Andrew. I'm trying to accomplish something with a
metaprogramming flavor, where, for the convenience of the programmer
and the clarity of code, I'd like to have a decorator or some other
mechanism do twiddling behind the scenes to make a class do something
it wouldn't normally do.

Here's a less-obfuscated exmaple: I want to build a framework for
creating MVC web applications in Python (I know, I know, there's
already 2^1bazillion of them) where a controller class can have
methods that respond to the same action but for different HTTP verbs:

class foo_controller(Controller):
@GET
def new(self):
# Display the form to create a new foo

@POST
def new(self):
# Receive a form post with new foo data in it

The Controller class will do all of the work behind the scenes to
makes sure that the correct method is called at run-time, but for the
sake of the programmer, I'd like to supply a clear, friendly syntax
like this. Without a little metaprogramming magic, last-in-wins, and
only the second version of foo will end up in the class, so I'd like
to mangle the names to something that will result in a unique
attribute name and that the Controller class can work with behind the
scenes to do the right thing at run time.

So, Python experts, am I completely barking up the wrong tree here?

Aaron Brady

unread,
Mar 17, 2009, 1:49:27 PM3/17/09
to

Unfortunately, your target is out of range for decorators. Decorators
can only do:

a= foo( a )

You want something like:

a_jam= foo( a )

However, metaclasses, possibly -combined- with decorators, may fit the
bill. When the class is being constructed, and is just a string, a
tuple of bases and a dictionary, you can intercept the call to 'type',
and modify the dictionary.

You would need a unique attribute to look for on values in the
dictionary, which means you'd need to detect what functions you are
renaming; possibly by using a decorator to mark them. (Untested:)

class X( metaclass= M ):
@mark( 'A' )
def foo( ... ).

class M( type ):
def __new__( cls, name, bases, namespace ):
for k, v in namespace.items():
if v.tag== 'mark-A':
namespace[ k ]= modification( v )
or in your case:
del namespace[ k ]
namespace[ k_mod ]= v.original

possibly also setting func_name as well.
return type( name, bases, namespace )

andrew cooke

unread,
Mar 17, 2009, 1:54:24 PM3/17/09
to Adam, pytho...@python.org

ah, ok. then yes, you can do that with decorators. you'd need hash
tables or something similar in a metaclass. then the decorator would take
the given function, stick it in the appropriate hash table, and return a
function that does the dispatch (ie at run time does the lookup from the
hash table) (you'd only want to set the function once once, so it would
need to check the function wasn't already defined). also, the decorator
would have one name and get/post etc would be an argument.

this is all documented in the docs and peps, although it's very spread
around. you might look at the code for the property decorator - it's not
doing what you want, but it's an interesting non-trivial example that's
public.

http://docs.python.org/library/functions.html#property

andrew

> --
> http://mail.python.org/mailman/listinfo/python-list
>
>


Aaron Brady

unread,
Mar 17, 2009, 2:45:37 PM3/17/09
to
at bottom

On Mar 17, 12:54 pm, "andrew cooke" <and...@acooke.org> wrote:
> ah, ok.  then yes, you can do that with decorators.  you'd need hash
> tables or something similar in a metaclass.  then the decorator would take
> the given function, stick it in the appropriate hash table, and return a
> function that does the dispatch (ie at run time does the lookup from the
> hash table) (you'd only want to set the function once once, so it would
> need to check the function wasn't already defined).  also, the decorator
> would have one name and get/post etc would be an argument.
>
> this is all documented in the docs and peps, although it's very spread
> around.  you might look at the code for the property decorator - it's not
> doing what you want, but it's an interesting non-trivial example that's
> public.
>
> http://docs.python.org/library/functions.html#property
>
> andrew
>
> Adam wrote:
> > Thanks, Andrew.  I'm trying to accomplish something with a
> > metaprogramming flavor, where, for the convenience of the programmer
> > and the clarity of code, I'd like to have a decorator or some other
> > mechanism do twiddling behind the scenes to make a class do something
> > it wouldn't normally do.
>
> > Here's a less-obfuscated exmaple:  I want to build a framework for
> > creating MVC web applications in Python (I know, I know, there's
> > already 2^1bazillion of them) where a controller class can have
> > methods that respond to the same action but for different HTTP verbs:
snip

I didn't study the OP post very well.

It almost sounds like you want two separate classes, one with methods
for one 'state' the other with methods for another state. You can
assign to 'self.__class__' to transition between them.

Otherwise, if you're using a hash table, the keys could be
( method_name, flag_value ) pairs, so that looking up a method with a
flag is 'meth= self._dispatch[ ( method_name, flag_value ) ]'.
However, without metaclasses or a global variable, there's no way to
remember a prior definition when you redefine a name.

class X:
@stateA
def M.
@stateB
def M.

When 'stateB( M )' is called, the result is assigned to 'M'. There's
no way to access previous definitions of M, since there is no way to
reference the namespace that is under construction.

However, if you're willing to tolerate a little redundancy, you can
chain prior definitions of a variable onto later ones.

>>> def dec( var ):
... def inner( fun ):
... fun.prior= var
... return fun
... return inner
...
>>> class X:
... def M( self ): pass
... @dec( M )
... def M( self ): pass
...
>>> X.M.prior
<function M at 0x00BA3270>
>>> X.M
<function M at 0x00BA3300>
>>>

So, you still have the earlier definition of M. You just had to
mention it when you redefined the variable.

(Perhaps someday, we will be able to write:
def dec( namespace ):
def outer( fun ):
if fun.__name__ in namespace:
namespace[ dup_var ]= namespace[ fun.__name__ ]
return fun
return outer
It allows us to see if there's a prior entry in the current namespace,
and save it to a different name.)

Michele Simionato

unread,
Mar 18, 2009, 12:58:00 AM3/18/09
to
On Mar 17, 7:45 pm, Aaron Brady <castiro...@gmail.com> wrote:

> (Perhaps someday, we will be able to write:
> def dec( namespace ):
>   def outer( fun ):
>     if fun.__name__ in namespace:
>       namespace[ dup_var ]= namespace[ fun.__name__ ]
>     return fun
>   return outer
> It allows us to see if there's a prior entry in the current namespace,
> and save it to a different name.)

Not in the future, but right now, with Python 3.0:

class noclashdict(dict):
"""
A dictionary where overriding a name actually generates a new
entry
with suffix '_new':

>>> d = noclashdict()
>>> d['a'] = 1
>>> d['a'] = 2
>>> sorted(d)
['a', 'a_new']
"""
def __setitem__(self, name, value):
setitem = super().__setitem__
if name in self:
setitem(name + "_new", value)
else:
setitem(name, value)

class Meta(type):
"A metaclass replacing the class dictionary with a noclashdict in
its instances"
@classmethod
def __prepare__(cls, name, bases):
return noclashdict()

class C(metaclass=Meta):
def foo(self):
return 1
def foo(self):
return 2

print(sorted(n for n in vars(C) if not n.startswith('__')))
# prints ['foo', 'foo_new']

if __name__ == '__main__':
import doctest; doctest.testmod()

It seems Guido's time machine is ticking again ;)

Michele Simionato

Michele Simionato

unread,
Mar 18, 2009, 1:00:12 AM3/18/09
to
I forgot; people interested in metaclasses in Python 3.0
will want to read this paper:
http://www.artima.com/weblogs/viewpost.jsp?thread=236234

Adam

unread,
Mar 18, 2009, 9:47:56 AM3/18/09
to
On Mar 17, 1:49 pm, Aaron Brady <castiro...@gmail.com> wrote:

> You would need a unique attribute to look for on values in the
> dictionary, which means you'd need to detect what functions you are
> renaming; possibly by using a decorator to mark them.  (Untested:)
>
> class X( metaclass= M ):
>   @mark( 'A' )
>   def foo( ... ).
>
> class M( type ):
>   def __new__( cls, name, bases, namespace ):
>     for k, v in namespace.items():
>       if v.tag== 'mark-A':
>         namespace[ k ]= modification( v )
> or in your case:
>         del namespace[ k ]
>         namespace[ k_mod ]= v.original
>
> possibly also setting func_name as well.
>     return type( name, bases, namespace )

I tried this, but unfortunately, it still doesn't allow me to have two
methods that initially have the same name, because the namespace
dictionary that the metaclass gets only has one one entry, the last
one in. So, if I try code like this:

def get_only(action):
setattr(action, "get_only", True)

return action

class ControllerMetaclass(type):
def __new__(cls, name, bases, namespace):
print str(namespace)


for k, v in namespace.items():

if hasattr(v, "get_only"):
new_name = "_get_" + k
print "new_name is " + new_name
del namespace[k]
namespace[new_name] = v
v.__name__ = new_name
return type(name, bases, namespace)

class Controller(object):
def __call__(self):
if (self.method != None):
get_mangled_name = "_" + self.method + "_" + self.action
if hasattr(self, get_mangled_name):
method = getattr(self, get_mangled_name)
return method()
else:
if hasattr(self, self.action):
return getattr(self, self.action)()
else:
raise NotImplementedError
else:
if hasattr(self, self.action):
return getattr(self, self.action)()
else:
raise NotImplementedError

class foo_controller(Controller):
__metaclass__= ControllerMetaclass
def __init__(self, action, method = None):
self.action = action
self.method = method


def foo(self):
print "in foo()"

@get_only
def foo(self):
print "in get_only foo()"

def bar(self):
print "in bar()"


a = foo_controller("foo", "get")
a()

b = foo_controller("foo")
print dir(b)
b()

c = foo_controller("bar","get")
c()

The first definition of foo (the one that is not decorated) is over-
written by the second one, and the metaclass never sees it. So, I
think that I understand what you said about storing the functions in a
hashtable. That makes sense, as I can keep a reference to the
function even if ti gets over-written in the class main namespace
dictionary. However, I'm not entirely sure about how to do that with
decorators. Wouldn't the decorator function have to be bound to a
context to keep a hastable between calls? I can't us a bound method
as a decorator, can I?

J. Cliff Dyer

unread,
Mar 18, 2009, 10:33:31 AM3/18/09
to andrew cooke, pytho...@python.org, Adam
You might be interested in redefining __getattribute__(self, attr) on
your class. This could operate in conjunction with the hash tables
(dictionaries) mentioned by andrew cooke. i.e. (untested code):

class C(object):
def __init__(self):
self._get_table = {}
self._post_table = {}

def __getattribute__(self, x):
if self.method=='GET':
return object.__getattribute__(self, _get_table)[x]
elif self.method=='POST':
return object.__getattribute__(self, _post_table)[x]
else:
raise AttributeError
@GET
def foo(x):
return "Got", x
@POST
def foo(x)
return "Posted to", x

This is definitely not functional code, but might get you in the right
direction on __getattribute__. __getattr__ might also work for you. I
haven't worked too much with these corners of python.

Cheers,
Cliff

On Tue, 2009-03-17 at 13:54 -0400, andrew cooke wrote:
> ah, ok. then yes, you can do that with decorators. you'd need hash
> tables or something similar in a metaclass. then the decorator would take
> the given function, stick it in the appropriate hash table, and return a
> function that does the dispatch (ie at run time does the lookup from the
> hash table) (you'd only want to set the function once once, so it would
> need to check the function wasn't already defined). also, the decorator
> would have one name and get/post etc would be an argument.
>
> this is all documented in the docs and peps, although it's very spread
> around. you might look at the code for the property decorator - it's not
> doing what you want, but it's an interesting non-trivial example that's
> public.
>
> http://docs.python.org/library/functions.html#property
>
> andrew
>
>
> Adam wrote:

> > --
> > http://mail.python.org/mailman/listinfo/python-list
> >
> >
>
>
> --
> http://mail.python.org/mailman/listinfo/python-list
>

R. David Murray

unread,
Mar 18, 2009, 11:11:55 AM3/18/09
to pytho...@python.org
> class foo_controller(Controller):
> __metaclass__= ControllerMetaclass
> def __init__(self, action, method = None):
> self.action = action
> self.method = method
>
>
> def foo(self):
> print "in foo()"
>
> @get_only
> def foo(self):
> print "in get_only foo()"
>
> def bar(self):
> print "in bar()"

I don't have any wisdom on the metaclass/decorator stuff, but what
about slightly reformulating the interface? Instead of having the
programmer type, eg:

@GET
def foo(self): pass

@POST
def foo(self): pass

have them type:

def GET_foo(self): pass
def POST_foo(self): pass

It's even one less character of typing (the <cr> :)

--
R. David Murray http://www.bitdance.com

Adam

unread,
Mar 18, 2009, 11:18:56 AM3/18/09
to

Hey, Cliff. Thanks for sharing this idea. Unfortunately, providing a
way to actually call the method with the mangled name is relatively
easy, and there are options there. The real issue, to me, seems to be
finding a way to prevent Python from eating all but the last version
of a function definition in a class. While decorators are a elegant
and unintrusive approach, I don't believe that there is any way for a
decorator to collection information in a data structure and then
provide that data back to the class instance or the class's metaclass.

I'm beginning to think that I am trying to get the square peg of
Python to fit into the round hole of a .NET idiom. I am trying to
borrow what I think is a really elegant and useful idiom from ASP.NET
MVC. Specifically, in an ASP.NET MVC Controller class, I can have two
methods with the same name that are called for different HTTP Verbs by
applying an Attribute:

public ActionResult Payment() {
ViewData["Title"] = "Payment Information";
ViewData["submit_text"] = "Next >";

return View();
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Payment(FormCollection form) {

return RedirectToAction("Legal");
}

Right? The first Payment method is called when the Payment page is
rendered. The second is called when the form that it contains is
submitted. I find it to be readable, elegant and it does not intrude
into the actual logic of the method itself. The alternatives that I
can readily identify are less-than-optimal. For instance, if could
just have an if statement inside the body of the method that branches
on the HTTP verb:

def Payment(self):
if self.request.verb == 'GET':
# Do stuff for GET
elif self.request.verb == 'POST':
# So stuff for POST

Yes, it would work, but it is ugly and requires me to mix in the same
function the behaviors for two very separate things.

Or, I could do something like this:

def GET_Payment(self):
# Do stuff for GET

def POST_Payment(self):
# Do stuff for POST

This is trivially-easy to implement (in this case, a metaclass can
very easily manipulate the namespace), but it makes the source code
less appealing and just feels crufty and hacky. It also makes it
difficult to deal elegantly with having one method respond to more
than verb like I could if I could write:

@GET
@POST
def foo(self):
# Do stuff for page foo, if it is GET or POST; PUT and DELETE not
allowed!


Adam

unread,
Mar 18, 2009, 11:31:36 AM3/18/09
to
On Mar 18, 11:11 am, "R. David Murray" <rdmur...@bitdance.com> wrote:
> I don't have any wisdom on the metaclass/decorator stuff, but what
> about slightly reformulating the interface?  Instead of having the
> programmer type, eg:
>
>     @GET
>     def foo(self): pass
>
>     @POST
>     def foo(self): pass
>
> have them type:
>
>     def GET_foo(self): pass
>     def POST_foo(self): pass
>
> It's even one less character of typing (the <cr> :)
>
> --
> R. David Murray          http://www.bitdance.com

David, would you believe that I just posted about this very idea, It
doesn't seem to have shown up yet, though. This idea works from the
perspective of being trivially easy to implement. I can easily write
a metaclass that looks in the namespace for methods with names that
start with GET_or POST_, or I can override __getattribute__ to do the
look up that way. However, there are a couple of weaknesses that I
see with this approach.

First, from a purely aesthetic point of view, prepending the desired
verb to the method name just looks a bit ugly. Also, it makes it
difficult to deal elegantly with avoiding duplicating code when one
piece of logic should dealing with more than one verb. So, if I want
to have one method that works for GET and POST, I can do this:

def GET_foo(self):


# Do stuff for GET

def POST_foo(self):
return self.GET_foo()

but then I feel like I am cluttering my controller code with unneeded
functions when writing
@GET
@POST
def foo(self):
# Blah blah blah

would be so much neater.

Or, I could allow method signatures like:
def GET_POST_foo(self):
# Blah, blah, blah

But now my code to parse and manipulate or do lookups on methods names
is much more complicated. Also, it introduces difficult ambiguities
in the case that an action of the controller has the same name as an
HTTP Verb. These ambiguities can be coded around, but doing so makes
the code more-and-more crufty and prone to breakage. I don't want to
build too much of a Rube Goldberg machine here, right? What I really
want to do is use Python's metaprogamming facilities to provide an
elegant solution to a problem. Unfortunately, I really don't think
that it is going to work out in any way that is really satisfying.

Michele Simionato

unread,
Mar 18, 2009, 11:32:43 AM3/18/09
to
On Mar 18, 4:18 pm, Adam <adam.crossl...@gmail.com> wrote:
> Hey, Cliff.  Thanks for sharing this idea.  Unfortunately, providing a
> way to actually call the method with the mangled name is relatively
> easy, and there are options there.  The real issue, to me, seems to be
> finding a way to prevent Python from eating all but the last version
> of a function definition in a class.

As I said in my other post in this thread, this can only be done in
Python 3.X.

andrew cooke

unread,
Mar 18, 2009, 11:43:12 AM3/18/09
to Adam, pytho...@python.org
Adam wrote:
> Hey, Cliff. Thanks for sharing this idea. Unfortunately, providing a
> way to actually call the method with the mangled name is relatively
> easy, and there are options there. The real issue, to me, seems to be
> finding a way to prevent Python from eating all but the last version
> of a function definition in a class. While decorators are a elegant
> and unintrusive approach, I don't believe that there is any way for a
> decorator to collection information in a data structure and then
> provide that data back to the class instance or the class's metaclass.

way back i suggested you look at the property decorator. that does a very
similar job, in that it combines three different methods into one. it
does that by using a class as decorator and accumulating the methods in
the class. as a side effect/bonus it has a curious syntax (you could make
this extensible by overriding getattr on the decorator). so you would end
up with something like:

class Foo:

@GET or @multi_dispatch('GET') or @multi.GET or something...
def foo(...):
...

@foo.POST
def foo_post(...):
...

@foo.DELETE
def foo_delete(...):
...

another idea, which i have never tried, is to look at the metaclass and
intercept duplicate names there (perhaps by substituting the class
dictionary.

you are trying to do very "deep" things that most people do not do with
python. that does not mean that there are no solutions, just that you
have to find them yourself (especially with the decline of this
newsgroup).

andrew


R. David Murray

unread,
Mar 18, 2009, 1:22:12 PM3/18/09
to pytho...@python.org
Adam <adam.cr...@gmail.com> wrote:
> David, would you believe that I just posted about this very idea, It
> doesn't seem to have shown up yet, though. This idea works from the
> perspective of being trivially easy to implement. I can easily write
> a metaclass that looks in the namespace for methods with names that
> start with GET_or POST_, or I can override __getattribute__ to do the
> look up that way. However, there are a couple of weaknesses that I
> see with this approach.
>
> First, from a purely aesthetic point of view, prepending the desired
> verb to the method name just looks a bit ugly. Also, it makes it
> difficult to deal elegantly with avoiding duplicating code when one
> piece of logic should dealing with more than one verb. So, if I want
> to have one method that works for GET and POST, I can do this:
>
> def GET_foo(self):
> # Do stuff for GET
>
> def POST_foo(self):
> return self.GET_foo()
>
> but then I feel like I am cluttering my controller code with unneeded
> functions when writing
> @GET
> @POST
> def foo(self):
> # Blah blah blah
>
> would be so much neater.

def GET_foo(self):
#do stuff for GET/POST

POST_foo = GET_foo

> Or, I could allow method signatures like:
> def GET_POST_foo(self):
> # Blah, blah, blah
>
> But now my code to parse and manipulate or do lookups on methods names
> is much more complicated. Also, it introduces difficult ambiguities
> in the case that an action of the controller has the same name as an
> HTTP Verb. These ambiguities can be coded around, but doing so makes

Hmm. I don't follow that. GET_GET would seem to be unambiguous.

> the code more-and-more crufty and prone to breakage. I don't want to
> build too much of a Rube Goldberg machine here, right? What I really
> want to do is use Python's metaprogamming facilities to provide an
> elegant solution to a problem. Unfortunately, I really don't think
> that it is going to work out in any way that is really satisfying.

Someone else suggested the property model, though that is probably not
as elegant as you want either.

So....how about the below. Extending it to handle multiple classes is
left as an exercise for the reader :) As is extending it to handle
stacking the decorators.

--
R. David Murray http://www.bitdance.com

------------------------------------------------------------------------

registry = {}

def HTTP_decorator_factory(name):
def _(f):
registry['%s_%s' % (name, f.__name__)] = f
def _(self, *args, **kw):
return _dispatch(f.__name__, self, *args, **kw)
return _
return _

def _dispatch(name, self, *args, **kw):
return registry['%s_%s' % (self.mode, name)](self, *args, **kw)

GET = HTTP_decorator_factory('GET')
POST = HTTP_decorator_factory('POST')


class Controller(object):

def __init__(self, mode='GET'):
self.mode = mode

@POST
def foo(self):
print "in POST foo"

@GET
def foo(self):
print "in GET foo"


c1 = Controller(mode='GET')
c2 = Controller(mode='POST')

c1.foo()
c2.foo()

Aaron Brady

unread,
Mar 18, 2009, 9:08:39 PM3/18/09
to
On Mar 18, 8:47 am, Adam <adam.crossl...@gmail.com> wrote:
> On Mar 17, 1:49 pm, Aaron Brady <castiro...@gmail.com> wrote:
>
>
>
> > You would need a unique attribute to look for on values in the
> > dictionary, which means you'd need to detect what functions you are
> > renaming; possibly by using a decorator to mark them.  (Untested:)
>
> > class X( metaclass= M ):
> >   @mark( 'A' )
> >   def foo( ... ).
>
> > class M( type ):
> >   def __new__( cls, name, bases, namespace ):
> >     for k, v in namespace.items():
> >       if v.tag== 'mark-A':
> >         namespace[ k ]= modification( v )
> > or in your case:
> >         del namespace[ k ]
> >         namespace[ k_mod ]= v.original
>
> > possibly also setting func_name as well.
> >     return type( name, bases, namespace )
>
> I tried this, but unfortunately, it still doesn't allow me to have two
> methods that initially have the same name, because the namespace
> dictionary that the metaclass gets only has one one entry, the last
> one in.  So, if I try code like this:
snip

> The first definition of foo (the one that is not decorated) is over-
> written by the second one, and the metaclass never sees it.

Michele presented a solution to this if you are able to use Python 3.

>  So, I
> think that I understand what you said about storing the functions in a
> hashtable.  That makes sense, as I can keep a reference to the
> function even if ti gets over-written in the class main namespace
> dictionary.  However, I'm not entirely sure about how to do that with
> decorators.

Here is a possiblity. It's redundant, but it works.

>>> class X:
... funcs= {}
... def wrap( funcs ):


... def inner( fun ):

... if fun.__name__ not in funcs:
... funcs[ fun.__name__ ]= []
... funcs[ fun.__name__ ].append( fun )
... return inner
... @wrap( funcs )
... def foo( self ): pass
... @wrap( funcs )
... def foo( self ): pass
...
>>> X.funcs
{'foo': [<function foo at 0x00BA32B8>, <function foo at 0x00BA3300>]}

> Wouldn't the decorator function have to be bound to a
> context to keep a hastable between calls?  I can't us a bound method
> as a decorator, can I?

'wrap' needs a reference to the hash table. I passed it explicitly,
but more subtle methods might be possible.

For creating the final version of 'foo' that is externally visible,
you can (I presume) just access the hash table as an attribute of the
class/object it's called on. Or you could set it to a generic
dispatcher. The two versions are defined and called by the same name,
but stored as different names.

Abstractly, function overloading is a weakness of dynamic typing and
variable argument lists. In order for them to be compatible, there
needs to be an order of precedence, and a way to specify argument
types. Decorators and annotations are two solutions.

@typed( FooA )
def jam( arg1 ).
@typed( FooB )
def jam( arg2 ).
@typed( )
def jam( *args ).

If 'jam' is called with a FooA, the first 'jam' is called. If called
with a FooB, the second is. If called with any other single
parameter, /or/ multiple parameters, the third is.

It's unlikely you need the full range of "motion" of generic
overloading, especially including variable-length and keyword argument
lists, so you can probably settle for simpler. There are a couple of
existing solutions out there, such as multi-methods.
http://www.artima.com/weblogs/viewpost.jsp?thread=155514

IMO, defining methods under different names isn't awful. You want to
call them by the same name. (Untested.)

class X:
def foo( self, arg ):
if isinstance( arg, JamA ): self.foo_jamA( arg )
if isinstance( arg, JamB ): self.foo.jamB( arg )
#exception
def foo_jamA.
def foo_jamB.

So here's a possibility, and you can probably make 'foo' slightly more
generic. Some solutions mix the /name/ of the type into the name of
the method automatically.

def foo( self, arg ):
getattr( self, 'foo_'+ type( arg ).__name__ )( arg )

So far, I have liked the metaclass __setattr__ and the definition
chaining ideas the best. However, if you're passing the prior
definition to the wrapper to chain with, it might be simpler to pass a
hash table. If you subclass the class that contains the hash table,
you can continue to access it:

class X:
funcs= {}
@wrap( funcs )
def foo( self ): pass
class Y( X ):
@X.wrap( X.funcs )
def foo( self ): pass

J. Cliff Dyer

unread,
Mar 25, 2009, 4:28:09 PM3/25/09
to Adam, pytho...@python.org

If your __getattribute__ dispatches method calls from a dictionary, it
shouldn't matter if the original name of the method has been blown away.
The actual method object lives on, and is accessed normally from the
user's standpoint.

I'm just thinking out loud now on ideas I haven't tested myself, but
what if your decorator were itself a method of the same class, so you
had something like this:

class BarBar(object):
def decorate_get(self, func):
pass
def decorate_post(self, func):
pass

@self.decorate_get
def foo(self):
pass
@self.decorate_post
def foo(self):
pass

Then the decorator has access to self, and can pass around whatever
information it needs. Maybe the decoration methods should live on a
base class somewhere.

class Decoratable(object):
def get(self, func):
pass
def post(self, func):
pass

class BarBar(Decoratable):
@self.get
def foo(self):
pass
@self.post
def foo(self)
pass

> I'm beginning to think that I am trying to get the square peg of
> Python to fit into the round hole of a .NET idiom.

Well, square is just one abstraction layer away from round anyway,
right?

> --
> http://mail.python.org/mailman/listinfo/python-list
>

Aahz

unread,
Mar 27, 2009, 12:26:21 PM3/27/09
to
In article <mailman.2130.1237391...@python.org>,

andrew cooke <and...@acooke.org> wrote:
>
>you are trying to do very "deep" things that most people do not do with
>python. that does not mean that there are no solutions, just that you
>have to find them yourself (especially with the decline of this
>newsgroup).

Excuse me? What decline of this newsgroup?
--
Aahz (aa...@pythoncraft.com) <*> http://www.pythoncraft.com/

"At Resolver we've found it useful to short-circuit any doubt and just
refer to comments in code as 'lies'. :-)"
--Michael Foord paraphrases Christian Muirhead on python-dev, 2009-3-22

andrew cooke

unread,
Mar 27, 2009, 1:15:51 PM3/27/09
to Aahz, pytho...@python.org
Aahz wrote:
> Excuse me? What decline of this newsgroup?

Hmmm. It's hard to respond to this without implicitly criticising others
here, which wasn't my point at all. But my personal impression is that
over the years various people who used to post here now stay pretty firmly
in the dev group, while others seem to have disappeared more or less
completely <wink>.

When I made this comment (which was some time ago) I went back and checked
whether there had been some splitting of newsgroups - I wondered if
perhaps I was remembering back to a time when dev did not exist and
everyone was here. That didn't seem to be the case, though.

Anyway, as I said, my intention wasn't to criticise people here (who have
provided me with useful help), but simply based on my recollection of
c.l.python many years ago (I just googled and it seems I was here at least
10 years ago).

I hope that clarifies things. I *really* don't want this to develop into
a criticism of current posters (which is completely unfair), so I am
unlikely to respond further to this thread.

Andrew


Aahz

unread,
Mar 27, 2009, 1:47:27 PM3/27/09
to
In article <mailman.2787.1238174...@python.org>,

andrew cooke <and...@acooke.org> wrote:
>Aahz wrote:
>>
>> Excuse me? What decline of this newsgroup?
>
>Hmmm. It's hard to respond to this without implicitly criticising others
>here, which wasn't my point at all. But my personal impression is that
>over the years various people who used to post here now stay pretty firmly
>in the dev group, while others seem to have disappeared more or less
>completely <wink>.

Well, yes, but that's simply the nature of online fora (I originally
wrote "nature of Usenet", but I think it's more general than that). From
my POV, if you're going to call it a "decline", you need to provide more
evidence than some people leaving and others arriving. I think that the
sheer volume and quality of posts to c.l.py is evidence that c.l.py is
not declining.

Tim Chase

unread,
Mar 27, 2009, 2:10:47 PM3/27/09
to Aahz, pytho...@python.org
Aahz wrote:
> In article <mailman.2130.1237391...@python.org>,
> andrew cooke <and...@acooke.org> wrote:
>> you are trying to do very "deep" things that most people do not do with
>> python. that does not mean that there are no solutions, just that you
>> have to find them yourself (especially with the decline of this
>> newsgroup).
>
> Excuse me? What decline of this newsgroup?

Must be a by-product of Schluehr's Law[1]...every thread degrades
into an argument about the GIL. :)

-tkc


[1]
http://mail.python.org/pipermail/python-list/2009-January/697412.html

sk...@pobox.com

unread,
Mar 27, 2009, 2:10:54 PM3/27/09
to andrew cooke, Aahz, pytho...@python.org

Aahz> Excuse me? What decline of this newsgroup?

Andrew> .... But my personal impression is that over the years various
Andrew> people who used to post here now stay pretty firmly in the dev
Andrew> group, while others seem to have disappeared more or less
Andrew> completely <wink>.

People come and go, that's true. That's to be expected though. I certainly
find many of the "newer" folks more than capable replacements for people you
don't see around here (much) anymore. Maybe you just aren't as familiar
with some of the new names. I think if you intersect the set of frequent
posters here and with the frequent posters in python-dev (say, those who
post more than a few times a month) you'll find a fairly large intersection,
and that intersection will include some of the most active Python core
developers.

Skip

Albert Hopkins

unread,
Mar 27, 2009, 3:27:04 PM3/27/09
to pytho...@python.org
On Fri, 2009-03-27 at 10:47 -0700, Aahz wrote:
> In article <mailman.2787.1238174...@python.org>,
> andrew cooke <and...@acooke.org> wrote:
> >Aahz wrote:
> >>
> >> Excuse me? What decline of this newsgroup?
> >
> >Hmmm. It's hard to respond to this without implicitly criticising others
> >here, which wasn't my point at all. But my personal impression is that
> >over the years various people who used to post here now stay pretty firmly
> >in the dev group, while others seem to have disappeared more or less
> >completely <wink>.
>
> Well, yes, but that's simply the nature of online fora (I originally
> wrote "nature of Usenet", but I think it's more general than that). From
> my POV, if you're going to call it a "decline", you need to provide more
> evidence than some people leaving and others arriving. I think that the
> sheer volume and quality of posts to c.l.py is evidence that c.l.py is
> not declining.

I agree. If the argument is simply that some devs no longer hang here
but do on -dev than that's not declining to me, especially as the amount
of traffic on -dev increases. That's ordinary. Same for people coming
and going.

For me declining means the rate of (non-spam) posts is steadily dropping
over time.

If you look at http://mail.python.org/pipermail/python-list/ it doesn't
make it clear that there is any sort of decline.

1999-04: 1708
1999-05: 2204
1999-06: 2390
1999-07: 2387
1999-08: 2149
1999-09: 2014
1999-10: 2060
1999-11: 1911
1999-12: 2304
2000-01: 2678
2000-02: 4000
2000-03: 3782
2000-04: 3236
2000-05: 4283
2000-06: 4628
2000-07: 4189
2000-08: 4275
2000-09: 3961
2000-10: 3834
2000-11: 2360
2000-12: 3116
2001-01: 4212
2001-02: 3892
2001-03: 4494
2001-04: 4731
2001-05: 5498
2001-06: 4936
2001-07: 6518
2001-08: 5247
2001-09: 3728
2001-10: 3687
2001-11: 4575
2001-12: 4472
2002-01: 5602
2002-02: 5272
2002-03: 5309
2002-04: 5984
2002-05: 5331
2002-06: 4229
2002-07: 4840
2002-08: 4948
2002-09: 4205
2002-10: 3327
2002-11: 4355
2002-12: 4108
2003-01: 6225
2003-02: 7758
2003-03: 5041
2003-04: 5025
2003-05: 5012
2003-06: 4976
2003-07: 4937
2003-08: 5703
2003-09: 4320
2003-10: 6396
2003-11: 5059
2003-12: 3930
2004-01: 4059
2004-02: 4316
2004-03: 5178
2004-04: 4358
2004-05: 3926
2004-06: 4255
2004-07: 4291
2004-08: 6275
2004-09: 5619
2004-10: 5251
2004-11: 4064
2004-12: 5295
2005-01: 5394
2005-02: 5278
2005-03: 5117
2005-04: 5098
2005-05: 4383
2005-06: 4635
2005-07: 4533
2005-08: 4546
2005-09: 4591
2005-10: 5580
2005-11: 5789
2005-12: 5119
2006-01: 15174
2006-02: 9838
2006-03: 11660
2006-04: 9776
2006-05: 10740
2006-06: 10156
2006-07: 9564
2006-08: 9806
2006-09: 10752
2006-10: 11348
2006-11: 9887
2006-12: 9186
2007-01: 7850
2007-02: 8184
2007-03: 8986
2007-04: 9965
2007-05: 10138
2007-06: 8444
2007-07: 7776
2007-08: 8544
2007-09: 8852
2007-10: 8548
2007-11: 6940
2007-12: 7454
2008-01: 8490
2008-02: 8572
2008-03: 8393
2008-04: 9508
2008-05: 10030
2008-06: 7500
2008-07: 8496
2008-08: 8198
2008-09: 7632
2008-10: 8332
2008-11: 7656
2008-12: 8694
2009-01: 9792
2009-02: 8033
2009-03: 3801


Nick Craig-Wood

unread,
Mar 27, 2009, 3:30:04 PM3/27/09
to
Aahz <aa...@pythoncraft.com> wrote:
> Well, yes, but that's simply the nature of online fora (I originally
> wrote "nature of Usenet", but I think it's more general than that). From
> my POV, if you're going to call it a "decline", you need to provide more
> evidence than some people leaving and others arriving. I think that the
> sheer volume and quality of posts to c.l.py is evidence that c.l.py is
> not declining.

c.l.py is my favourite usenet group and has been for some time. I've
been doing usenet for 16 years now!

I enjoy reading about problems and problems solved. I enjoy helping
people where I can and especially learning new things when helping
people - I think it has contributed enormously to my development as a
python programmer.

When I ask a question of c.l.py I find the answers to be informative
and enlightening. Even after quite a few years of python programing
I'm still learning new things from c.l.py

As a long time usenet user I find it easy to ignore the occasional
flame wars. Posters with the wrong sort of attitude are brought
gently into line by the majority.

If usenet groups had ratings I'd give c.l.py 5 stars.

--
Nick Craig-Wood <ni...@craig-wood.com> -- http://www.craig-wood.com/nick

sk...@pobox.com

unread,
Mar 27, 2009, 3:33:22 PM3/27/09
to Albert Hopkins, pytho...@python.org

Albert> For me declining means the rate of (non-spam) posts is steadily
Albert> dropping over time.

I know this wasn't the main point of your post, but if you subscribe to
pytho...@python.org or read it via a mail-to-news gateway like Gmane I
think you will find the ratio of spam to ham much smaller than if you read
comp.lang.python via a vanilla Usenet newsfeed.

--
Skip Montanaro - sk...@pobox.com - http://www.smontanaro.net/

Aahz

unread,
Mar 27, 2009, 4:07:45 PM3/27/09
to
In article <slrngsq9r...@irishsea.home.craig-wood.com>,

Nick Craig-Wood <ni...@craig-wood.com> wrote:
>
>c.l.py is my favourite usenet group and has been for some time. I've
>been doing usenet for 16 years now!

Newbie. ;-)

Erik Max Francis

unread,
Mar 27, 2009, 8:51:54 PM3/27/09
to
Albert Hopkins wrote:
> I agree. If the argument is simply that some devs no longer hang here
> but do on -dev than that's not declining to me, especially as the amount
> of traffic on -dev increases. That's ordinary. Same for people coming
> and going.
>
> For me declining means the rate of (non-spam) posts is steadily dropping
> over time.
>
> If you look at http://mail.python.org/pipermail/python-list/ it doesn't
> make it clear that there is any sort of decline.
...

And made all purdy-like:

http://www.alcyone.com/tmp/python-list%20traffic.pdf

--
Erik Max Francis && m...@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 18 N 121 57 W && AIM, Y!M erikmaxfrancis
Always forgive your enemies -- nothing annoys them so much.
-- Oscar Wilde

andrew cooke

unread,
Mar 27, 2009, 9:15:17 PM3/27/09
to pytho...@python.org
Erik Max Francis wrote:
[...]

That's very pretty, but neither the volume of posts, nor the quality of
the people posting here is really what I was talking about. I don't think
I explained very well, but seeing the posts here helped clarify things a
little.

c.l.python used to be the core of a community built around a language. It
no longer is. It is a very useful place, where some very helpful and
knowledgeable people hang out and give advice, but instead of representing
the full interests of the Python community it is now very much a resource
for helping new users.

At least, that's how it seems to me. And I don't think this is
necessarily "natural" or "normal" - I think it may be a failure on the
part of someone (who? I don't quite know, perhaps all of us) in managing
a community. Now there is an obvious argument against that - that the
language was becoming so popular that a single meeting place was no longer
practical - but without a crystal ball it is hard to know how true that
is, or what alternatives might have been.

I feel quite strongly about this. I thought that c.l.python was almost
exceptional in the range (the perl group was another, similar community
back then). I do worry that someone might have screwed up in a quite
major way, and that Python will suffer seriously, in the longer term, as a
result.

Another reason might be that the action has moved on to Haskell. I get
the impression that it is undergoing the same kind of surge in popularity
from the "smart early adopters" that Python might have benefited from back
in the day (for some perverse reason I am actually moving back to Python
from more strongly typed functional languages).

Andrew


Aaron Brady

unread,
Mar 27, 2009, 10:57:41 PM3/27/09
to

Hi, andrew.

> (for some perverse reason I am actually moving back to Python
> from more strongly typed functional languages).

I don't want to criticize you for this comment. In fact, it
illustrates a good point and a potential source of confusion: the
language and the newsgroup are two different things. Someone could
like the language and dislike the newsgroup; dislike the language and
like the newsgroup; or like or dislike both. Likes and dislikes can
each be passive or active by the way.

It is a shame that you are so prohibited from getting a foot in the
door of the dev newsgroup. From what you say, much of the Python-
focused, seasoned-dev discussion that you like takes place there; and
no one asks about references to parameters. I can't attest to the
intensity, formality, or tolerance there, however. It could be they
have goals, and you need more familiarity with Usenet protocol to be
understood, and not merely excluded. I am not saying that c-l-py vets
don't have goals; just that they're not the same as the dev vets'.

I see how c-l-py doesn't represent the full interests of Python,
although I can't attest to whether it used to. Naturally, among any
person or people, conflicts arise, dilemmas arise, and c-l-py vets
don't solve them in the same manner, or with the same results, that
dev vets do. The long term direction of this is dissent, struggle,
and mutiny. Logically, one of the c-l-py posters, not necessarily the
vets, will fork the source, it will become popular, and Pythoneers
will no longer be able to cut-and-paste source to share. It is a sad
destiny, but with all the authorities, veterans, and movers and
shakers cloistered away in an entrance-restricted, exclusive-
membership corner, the newbies won't see the long-term consequences.
We get our direction from the adults, and they aren't here. And, with
the community split in two, newbies will not get the answers they
need, and we'll wither away.

The motive for the fork could be anything. It could be a coup
d'elite, a lunge for power, or an honest but shallow improvement
attempt, from someone who doesn't know it will divide the community,
or doesn't know to care.

You have proposed that the precaution is greater control: it won't
happen if it can't happen; and if it can happen, it will. I don't
think either of those premises need proof, so the conclusion is
imminent. If two parties want two different things, they'll both get
them.

There are many people to control. They include the newbies, who have
taken your word for many characteristics of the language and the
group. They include the vets who already know them. Do you appoint
yourself sheriff?

Albert Hopkins

unread,
Mar 27, 2009, 10:59:18 PM3/27/09
to pytho...@python.org
On Fri, 2009-03-27 at 21:15 -0400, andrew cooke wrote:
[...]

> c.l.python used to be the core of a community built around a language. It
> no longer is. It is a very useful place, where some very helpful and
> knowledgeable people hang out and give advice, but instead of representing
> the full interests of the Python community it is now very much a resource
> for helping new users.

> At least, that's how it seems to me. And I don't think this is
> necessarily "natural" or "normal" - I think it may be a failure on the
> part of someone (who? I don't quite know, perhaps all of us) in managing
> a community. Now there is an obvious argument against that - that the
> language was becoming so popular that a single meeting place was no longer
> practical - but without a crystal ball it is hard to know how true that
> is, or what alternatives might have been.
>
> I feel quite strongly about this. I thought that c.l.python was almost
> exceptional in the range (the perl group was another, similar community
> back then). I do worry that someone might have screwed up in a quite
> major way, and that Python will suffer seriously, in the longer term, as a
> result.
>
> Another reason might be that the action has moved on to Haskell. I get
> the impression that it is undergoing the same kind of surge in popularity
> from the "smart early adopters" that Python might have benefited from back

> in the day (for some perverse reason I am actually moving back to Python


> from more strongly typed functional languages).

Sentimental... yet comical. It's still, to me, a natural event. The
same things happens to nearly every new, upcoming, grassroots
technology. Linux was the same way. So was KDE (and probably GNOME as
well). This is just a natural evolution of the connection between
community and technology.

Simply put, Python isn't a baby anymore. I remember being on c.l.python
back in like '97 or '98. Back then it was pretty much the only place to
come to share info/interest Python. There was the newsgroup,
python.org, and Starship. That's it. Nowadays Python is everywhere.
There are forums, blogs, magazines, books, local user groups, PyCon,
PyPi. etc. And Python is so big that there are sub-communities such as
CherryPy and Django, SQLAlchemy, Jython and IronPython, etc. There are
so many sub-groups with their own visions and plans and momentum, and
that's a good thing! c.l.python is no longer the big fish in a small
pond.

So I'm sorry but c.l.python can no longer be the sole place to represent
the "full interests of the Python community" because the community is
much too big for it. It can't be "managed" by a central source. It's
bigger than that. And, let's face it, a smaller fraction of people get
their information from Usenet and mailing lists today compared to 1996.

Looking back at some postings from '95 [1] I don't see that much
different from then and now, except there was a lot more off-topic
stuff, there was a periodic FAQ, GvR, and I didn't see any GIL
flamewars. Some similarities include newbie-type questions, style
questions, questions regarding the C API, architecture- and
module-specific questions, posts from some of the same people I still
see today and, of course, regular expressions. But maybe your nostalgia
predates 1995 (I didn't start using Python until 1997).

Anyway, I'm bored with this discussion. It seems to be a natural part of
technology communities as well. I'm on another mailing list where,
almost every month, a different person independently comes to the
conclusion that the technology is dying. And it's been that way ever
since I joined the mailing list 6 years ago. If these things are dying
why can't they do so quickly (and quietly)?

-a


1.
http://groups.google.com/group/comp.lang.python/topics?hl=en&start=109792&sa=N


sk...@pobox.com

unread,
Mar 28, 2009, 12:20:44 AM3/28/09
to andrew cooke, pytho...@python.org

Andrew> c.l.python used to be the core of a community built around a
Andrew> language. It no longer is. It is a very useful place, where
Andrew> some very helpful and knowledgeable people hang out and give
Andrew> advice, but instead of representing the full interests of the
Andrew> Python community it is now very much a resource for helping new
Andrew> users.

Two observations:

* The Python community has grown significantly, especially in the past
couple years. It's quite understandable that the bulk of
comp.lang.python participants now are new users. Also, as the most
readily visible "hangout", it's the natural place where most new users
will come to get help. The help and tutor mailing lists, IRC, various
other forums and subject-specific mailing lists are all much less
visible.

* As the community grows it's difficult for there to be one place where
everybody congregates. The needs of different elements of the Python
"family" differ. You will find lots of scientific users more involved
with scipy, matplotlib and ipython mailing lists, for example. I'm
sure Blender has some sort of online community for its users. The
people doing GUI programming with PyGtk probably tend to gravitate
there. The core developers spend much of their time at python-dev.
In the end, it winds up being more efficient for those subsections of
the overall Python user base to participate where they can either get
the most help, offer the most assistance, or contribute the most to
Python development or advocacy. It's too big for one size fits all.

An anecdote. I started using Sun workstations back about the time the sales
reps were delivering them out of the back of their cars. Heck, I remember
the first one at Lawrence Livermore Lab sat idle for quite awhile because
there was no software at all. No OS. Nothing. Probably just a boot
loader. Back then if you had a problem with, say, dbx, vi or cc, you called
Sun and after a couple transfers you were talking to the software engineer
who directly developed or maintained the recalcitrant program or library.
Fast forward about 25 years. I haven't spoken directly to a Sun employee in
years. I don't even think the company I work for buys its Sun computers
directly from Sun (we buy a lot of them). It's disappointing in some ways,
but I doubt it would be very efficient if all people who had problems with
Sun's C compiler were patched directly through to the head of the compiler
group at Sun. They've grown. (Well, up until relatively recently.) Their
user base has grown. There's no way they could manage their customer
interactions today the same way they managed them 25 years ago.

Aahz

unread,
Mar 28, 2009, 1:34:23 AM3/28/09
to
In article <mailman.2814.1238202...@python.org>,

andrew cooke <and...@acooke.org> wrote:
>
>c.l.python used to be the core of a community built around a language. It
>no longer is. It is a very useful place, where some very helpful and
>knowledgeable people hang out and give advice, but instead of representing
>the full interests of the Python community it is now very much a resource
>for helping new users.

It seems to me that you're making two separate assertions here. I don't
think that c.l.py ever represented the full interests of the Python
community once python-dev took off (which was essentially before I
started using Python in 1999). I do think that c.l.py is still in many
ways the core of the community, because it's the only hangout where the
disparate parts of the community come together, but the core has
diminished to a small fraction of the whole community.

>I feel quite strongly about this. I thought that c.l.python was almost
>exceptional in the range (the perl group was another, similar community
>back then). I do worry that someone might have screwed up in a quite
>major way, and that Python will suffer seriously, in the longer term, as a
>result.

From my POV as someone who has been observing Usenet for eighteen years,
c.l.py is *still* an exceptional community. And while Usenet is now an
Internet backwater, there's far too much useful traffic to claim that
Usenet is in any danger of dying.

Steven D'Aprano

unread,
Mar 29, 2009, 1:23:55 AM3/29/09
to
On Fri, 27 Mar 2009 19:57:41 -0700, Aaron Brady wrote:

> I see how c-l-py doesn't represent the full interests of Python,

Python is a *programming language*. It doesn't have interests. It just
sits there, a bunch of bits on a disk, waiting to be used. *People* have
interests, and Python is a means to an end.


> although I can't attest to whether it used to. Naturally, among any
> person or people, conflicts arise, dilemmas arise, and c-l-py vets
> don't solve them in the same manner, or with the same results, that
> dev vets do.

What makes you think that only "vets" are capable of solving issues that
arises? I have news for you: they're just people too. They put their
trousers on one leg at a time just like the rest of us.

Somebody can be a vet with 15 years experience, and still be an immature,
foolish jerk, or a grumpy old-curmudgeon. Somebody else might have just
started using the language a week ago, and yet have excellent conflict-
resolution skills. Anyone who has been on Usenet long enough to recognise
other posters will almost certainly be able to think of examples of each.


> The long term direction of this is dissent, struggle, and mutiny.

Don't forget social unrest, rioting in the streets, and the eventual
break-down of civilization as we know it. Don't worry, I'm prepared for
the invariable fallout when Python 3.1 comes out: I have a year's supply
of tinned food in the basement, and enough guns and ammo to fight off the
Chinese Army for a month.


> Logically, one of the c-l-py posters, not necessarily the
> vets, will fork the source, it will become popular, and Pythoneers
> will no longer be able to cut-and-paste source to share.

Oh noes!!! Python will be just like nearly every other language!!!

Including Python. There are already at least thirteen implementations
(forks) of Python (although some of these are defunct or unmaintained):

CPython
Jython
IronPython
Python for .NET
CLPython
PyPy
Unladen Swallow
Python for S60
PyVM
Vyper
RPython
Stackless Python
CapPython


Diversity in software is *good*, not a bad thing. If Guido gets hit by a
bus, we'll be sad, but the long term availability of Python will be in no
way endangered.


As for being "able to cut-and-paste source to share", syntax and built-in
functions are a small part of what makes Python great. The libraries are
just as important, and much Python source code can't be just cut-and-
pasted. You also need to install the appropriate modules, and sometimes
be running on the appropriate operating system.

Don't worry kiddies, rumours of Python's death are greatly exaggerated.

--
Steven

Aaron Brady

unread,
Mar 29, 2009, 2:50:46 AM3/29/09
to
On Mar 29, 12:23 am, Steven D'Aprano <st...@REMOVE-THIS-

cybersource.com.au> wrote:
> On Fri, 27 Mar 2009 19:57:41 -0700, Aaron Brady wrote:
> > I see how c-l-py doesn't represent the full interests of Python,
>
> Python is a *programming language*. It doesn't have interests. It just
> sits there, a bunch of bits on a disk, waiting to be used. *People* have
> interests, and Python is a means to an end.

I misquoted this one. andrew said:
> ...representing the full interests of the Python community...

However, he also said:
> ...and that Python will suffer seriously

I think he probably meant, its popularity, and possibly its unity.

> > although I can't attest to whether it used to.  Naturally, among any
> > person or people, conflicts arise, dilemmas arise, and c-l-py vets
> > don't solve them in the same manner, or with the same results, that
> > dev vets do.
>
> What makes you think that only "vets" are capable of solving issues that
> arises? I have news for you: they're just people too. They put their
> trousers on one leg at a time just like the rest of us.

I don't think it, but I say it because it's the vets that get their
way most of the time. Whether it's because they're more comfortable
with the environment, i.e. know what to expect from more people on the
list than newbies, or they're both due to a lurking variable, such as
obsession with computers <cough>, hostility, uncooperativeness and
dominance; I can't say. Maybe comfortableness leads to a "my ships
don't sink" kind of mentality over time. (Side effects include...)

> Somebody can be a vet with 15 years experience, and still be an immature,
> foolish jerk, or a grumpy old-curmudgeon. Somebody else might have just
> started using the language a week ago, and yet have excellent conflict-
> resolution skills.

Ok that's true. We don't know who sticks around on Usenet, or on c-l-
py in particular, or what traits they have in common. I think human-
resources-lang-python is a different list.

> Anyone who has been on Usenet long enough to recognise
> other posters will almost certainly be able to think of examples of each.
>
> > The long term direction of this is dissent, struggle, and mutiny.
>
> Don't forget social unrest, rioting in the streets, and the eventual
> break-down of civilization as we know it. Don't worry, I'm prepared for
> the invariable fallout when Python 3.1 comes out: I have a year's supply
> of tinned food in the basement, and enough guns and ammo to fight off the
> Chinese Army for a month.

Google says: "China - Population: 1,330,044,544 (July 2008 est.)". At
a rate of one cubic inch per round, that's a space of
1000"x1000"x1000", or 83'x83'x83', of solid ammo.

> > Logically, one of the c-l-py posters, not necessarily the
> > vets, will fork the source, it will become popular, and Pythoneers
> > will no longer be able to cut-and-paste source to share.
>
> Oh noes!!! Python will be just like nearly every other language!!!

Alright fine, so I got all mushy and sentimental and over-prioritized.

> Including Python. There are already at least thirteen implementations
> (forks) of Python (although some of these are defunct or unmaintained):

snip

Is that just off the top of your head, Steven? Come on, be honest...!

> Diversity in software is *good*, not a bad thing. If Guido gets hit by a
> bus, we'll be sad, but the long term availability of Python will be in no
> way endangered.

I'm not convinced. If there is no final say on what is and what isn't
Python, the costs could exceed the benefits. Otherwise, all I have is
my implementation of it, which you might have not.

> As for being "able to cut-and-paste source to share", syntax and built-in
> functions are a small part of what makes Python great. The libraries are
> just as important, and much Python source code can't be just cut-and-
> pasted. You also need to install the appropriate modules, and sometimes
> be running on the appropriate operating system.
>
> Don't worry kiddies, rumours of Python's death are greatly exaggerated.

But, but, but, what about the subject line? </wibble>

>
> --
> Steven

Hendrik van Rooyen

unread,
Mar 30, 2009, 3:46:40 AM3/30/09
to pytho...@python.org
"Steven D'Aprano" <steve@R....ource.com.au> wrote:


>Oh noes!!! Python will be just like nearly every other language!!!
>
>Including Python. There are already at least thirteen implementations
>(forks) of Python (although some of these are defunct or unmaintained):
>
>CPython
>Jython
>IronPython
>Python for .NET
>CLPython
>PyPy
>Unladen Swallow
>Python for S60
>PyVM
>Vyper
>RPython
>Stackless Python
>CapPython
>

Its kind of sad to see unladen swallow, which is just
a promise, on the list, while Shedskin, which isn't,
is ignored.

Does this say something about big corporations
vs the small man?

- Hendrik


Paul Rubin

unread,
Mar 30, 2009, 4:03:50 AM3/30/09
to
"Hendrik van Rooyen" <ma...@microcorp.co.za> writes:
> Its kind of sad to see unladen swallow, which is just
> a promise, on the list, while Shedskin, which isn't,
> is ignored.
>
> Does this say something about big corporations
> vs the small man?

I think the programs on the list were supposed to actually implement
Python and extensions of Python, but not incompatible dialects.
Otherwise Pyrex (for example) would also be on the list.

srepmub

unread,
Mar 30, 2009, 9:31:06 AM3/30/09
to

> > Its kind of sad to see unladen swallow, which is just
> > a promise, on the list, whileShedskin, which isn't,

> > is ignored.
>
> > Does this say something about big corporations
> > vs the small man?
>
> I think the programs on the list were supposed to actually implement
> Python and extensions of Python, but not incompatible dialects.
> Otherwise Pyrex (for example) would also be on the list.

for the record, the input for Shedskin is pure Python, so there is no
added syntax or optional type declaration system. that said, I can
understand it not being on some list for not being production-ready.


thanks,
mark dufour.

Michele Simionato

unread,
Mar 30, 2009, 10:36:51 AM3/30/09
to
On Mar 30, 3:31 pm, srepmub <mark.duf...@gmail.com> wrote:
> for the record, the input for Shedskin is pure Python, so there is no
> added syntax or optional type declaration system. that said, I can
> understand it not being on some list for not being production-ready.
>
> thanks,
> mark dufour.

But does ShedSkin accepts all valid Python constructs?
I thought there were restrictions.

Steven D'Aprano

unread,
Mar 30, 2009, 10:50:24 AM3/30/09
to
On Mon, 30 Mar 2009 09:46:40 +0200, Hendrik van Rooyen wrote:

> Its kind of sad to see unladen swallow, which is just a promise, on the
> list, while Shedskin, which isn't, is ignored.
>
> Does this say something about big corporations vs the small man?

No, what it says is that I had just read a post about Unladen Swallow two
minutes before, and I forgot completely about Shedskin.

Although I took a few minutes to google, I knew I'd probably missed
something, which is why I said there are *at least* thirteen
implementations of Python.


--
Steven

Tim Golden

unread,
Mar 30, 2009, 11:02:54 AM3/30/09
to pytho...@python.org

I was going to post in your defence (before realising that
you were more than capable of doing that for yourself).
It was obviously just a casual list, not the official
definitive everything-not-here-is-not-valid Python-lookalikes
competition entrants list. :)

But I was impressed you managed to get so many: I was
aware of everything on that list, but I'm quite sure I
couldn't have named them all together.

TJG

srepmub

unread,
Apr 3, 2009, 9:11:29 AM4/3/09
to
On Mar 30, 4:36 pm, Michele Simionato <michele.simion...@gmail.com>
wrote:

> On Mar 30, 3:31 pm, srepmub <mark.duf...@gmail.com> wrote:
>
> > for the record, the input forShedskinis pure Python, so there is no

> > added syntax or optional type declaration system. that said, I can
> > understand it not being on some list for not being production-ready.
>
> > thanks,
> > mark dufour.
>
> But doesShedSkinaccepts all valid Python constructs?

> I thought there were restrictions.

there are certainly several important restrictions, but what I meant
was that if it works with Shedskin it is also valid Python code, and
there are no hidden type declarations or hints hidden in docstrings
and such.


thanks,
mark dufour.

0 new messages