I've moved my blog to jmcneil.net. This is no longer being updated!

Monday, April 21, 2008

Dipping into 3.0

A couple of days ago I downloaded the latest alpha release of Python 3.0. It's still pretty early, but I decided it made a lot of sense to start going through the new features in order to get a feel for what type of porting work we'll have to do.


Using the What's New page as a guide, I compared some of the behavior in the new 3.0 branch with the current 2.5 release. A lot of the changes appear to be "decruftification" updates. For instance, moving to a print() built in removes some of the awkward looking "print >>sys.stderr," code that never feels quite right.


The first feature that really caught my eye is the function annotation addition. I like the fact that the Python developers chose to go with a generic system as opposed to static typing alternative. I especially like the fact that annotations can be any valid Python expression.


We store all of our Linux user attributes in LDAP. This includes POSIX data as well as some domain specific stuff that makes sense. The first thought I had after reading up on function annotations was streamlining access to an LDAP system. It seems that one may be able to do something like:



#!/home/jeff/py3k/bin/python

LDAP_CONNECTION = "localhost"

class LDAPProxy:
def __init__(self, connection):
self._connection = connection

def do_ldap_lookup(self, dn, attr):
"""LDAP Query Mock"""
print("query ldap server on on {0}:{1} for {2}".format(
self._connection, dn, attr))
# For example, something that can go string or int...
return 0

def __call__(self, attribute, kind):
"""Return a tuple of functions for use as a property"""
def get_value(inner_self, attr=attribute) -> kind:
result = self.do_ldap_lookup(inner_self.dn, attr)
return get_value.__annotations__['return'](result)

def set_value(inner_self, value):
pass

return (get_value, set_value)

class User:
m = LDAPProxy(LDAP_CONNECTION)

def __init__(self, dn):
self.dn = dn

uid = property(*m("uidNumber", int))
home = property(*m("homeDirectory", str))

u = User("cn=user,ou=accounts,dc=domain,dc=com")
uid = u.uid
home = u.home
print ("{0} is ({1})".format(uid, type(uid)))
print ("{0} is ({1})".format(home, type(home))


Ok, so perhaps that's not the best example as it looks very possible
without the annotation. Still a pretty cool new feature, especially
when dealing with XMLRPC & SOAP. Ought to do make introspection and
WSDL generation much easier.


 

No comments: