PyPy newbie question: How to play with types
![](https://secure.gravatar.com/avatar/3ef1af3f43e91a0acd17c0739681de5d.jpg?s=120&d=mm&r=g)
Hello, I want to use PyPy as a way of trying a change I will propose to Python. It includes a bit of messing with types. For example, I want to make a new type called frozendict, and another new type, basedict. frozendict and dict will be subclasses of basedict. basedict will not be instantiable, but will implement all the dict methods that do not change the dict. frozendict will add a single operation to basedict - it will be hashable. dict will be the same as the dict today, but since many operations will be inherited from basedict, it will be shorter. I also want to add a new built-in, frozen(x), that will simply call x.__frozen__(). I have looked into the directories. I have found pypy/objspace/dict{object,type}.py. My questions are: 1. How do I make new built-in types, play with their inheritence, make them uninstantiable? Should I register it somewhere? 2. Where do I add a new built-in like frozen()? How should I make it callable from interpreter-level code? Thanks a lot, Noam
![](https://secure.gravatar.com/avatar/5b37e6b4ac97453e4ba9dba37954cf79.jpg?s=120&d=mm&r=g)
Hi Noam, On Sun, Nov 13, 2005 at 01:44:32AM +0200, Noam Raphael wrote:
I want to use PyPy as a way of trying a change I will propose to Python.
I suppose that's what we are supposed to make easier :-) Understanding all the details of PyPy's built-in types is not exactly straightforward, but I suppose that with good documentation it could be made accessible. Let me give you a quick start...
I have looked into the directories. I have found pypy/objspace/dict{object,type}.py. My questions are:
1. How do I make new built-in types, play with their inheritence, make them uninstantiable? Should I register it somewhere?
Built-in types go in files xxxtype.py. The StdTypeDef declared in xxxtype.py declares how the type behaves. For an example see e.g. stringtype.py and basestringtype.py. Inheritance is declared in the StdTypeDef. If you want the type name to appear in the built-ins automatically, register it in model.py. Then you can declare one (or zero or several) implementation of a type, traditionally in xxxobject.py as a W_XxxObject. It must be registered by being added to the dictionary 'self.typeorder' in model.py. Note that you can also register automatic conversions there, like str->unicode, but I think it's not necessary in your case. There is no inheritance of the W_XxxObject classes -- typically, you don't need a W_BaseDictObject at all because it's not instantiatable, just like there is no W_BaseStringObject (and no basestringobject.py).
2. Where do I add a new built-in like frozen()? How should I make it callable from interpreter-level code?
A new __freeze__ protocol means a new multimethod. Add it to the ObjSpace.MethodTable in interpreter/baseobjspace.py. E.g. follow the example of 'len' and how various xxxobject.py files define len__Xxx(). (There are name-based hacks going on here. You don't need to register 'freeze' anywhere else than in ObjSpace.MethodTable, it will pick up the freeze__Xxx implementations and be available as 'space.freeze()'). Then follow the example of len() again to make it available as a built-in: you need to modify module/__builtin__/operation.py and __init__.py (that's just 4 lines of code to add :-) A bientot, Armin.
![](https://secure.gravatar.com/avatar/3ef1af3f43e91a0acd17c0739681de5d.jpg?s=120&d=mm&r=g)
Ok, I just tried to add the "frozen" multimethod. I managed to make it work as a one-argument function. I had to add a line to the flow/operation.py, to make it work: ('frozen', None), I then tried to make it a function which gets two arguments, the second one is optional (so you can call frozen(x), which means x.__frozen__(), and also frozen(x, y), which means x.__frozen__(y).) I replaced the "1" with "2" in the line in baseobjspace.py, and it didn't work - it said: Traceback (most recent call last): File "pypy/bin/py.py", line 205, in ? sys.exit(main_(sys.argv)) File "pypy/bin/py.py", line 81, in main_ space = make_objspace(Options) File "pypy/bin/py.py", line 58, in make_objspace from pypy.objspace.std import Space File "/home/noam/sand/pypy/pypy/objspace/std/__init__.py", line 1, in ? from objspace import StdObjSpace File "/home/noam/sand/pypy/pypy/objspace/std/objspace.py", line 11, in ? from pypy.objspace.descroperation import DescrOperation File "/home/noam/sand/pypy/pypy/objspace/descroperation.py", line 573, in ? raise Exception, "missing def for operation%s" % _name Exception: missing def for operationfrozen Another thing that I had to find out: I had to copy the "py" directory from the bz2 distribution in order to make pypy work (I checked out from subversion). I didn't see it mentioned in the subversion instructions. I will probably have more questions in the future, but that's it for now... Thanks again, Noam
![](https://secure.gravatar.com/avatar/5b37e6b4ac97453e4ba9dba37954cf79.jpg?s=120&d=mm&r=g)
Hi Noam, On Fri, Nov 18, 2005 at 02:32:28PM +0200, Noam Raphael wrote:
File "/home/noam/sand/pypy/pypy/objspace/descroperation.py", line 573, in ? raise Exception, "missing def for operation%s" % _name Exception: missing def for operationfrozen
Indeed, to allow the user to define custom '__freeze__' method there is a step to take in descroperation.py that I forgot. See for example 'def setitem'. It would go something like: def freeze(space, w_obj): w_descr = space.lookup(w_obj, '__freeze__') if w_descr is None: # no __freeze__, complain or perform some default behavior else: return space.get_and_call_function(w_descr, w_obj) Adding another optional argument needs to be done with some care, because most of the places will internally need a non-optional argument. It's possible in theory to have default arguments on multimethods, but I suppose that you should just make the user-visible 'freeze()' in the __builtin__ module accept less arguments and add a default if necessary. About the py lib: the "Svn-check out" instructions at http://codespeak.net/pypy/dist/pypy/doc/getting-started.html should have checked out the 'py' subdirectory as well. A bientot, Armin
![](https://secure.gravatar.com/avatar/3ef1af3f43e91a0acd17c0739681de5d.jpg?s=120&d=mm&r=g)
Thanks for your instructions, it now works. About py: On 11/19/05, Armin Rigo <arigo@tunes.org> wrote:
About the py lib: the "Svn-check out" instructions at http://codespeak.net/pypy/dist/pypy/doc/getting-started.html should have checked out the 'py' subdirectory as well.
I've now checked - it does. The problem was that I used svk, which presumably doesn't support the svn:externals property. Perhaps it should be mentioned in the instructions that the py directory should be downloaded automatically, but if it doesn't you can get it from ... Have a good week, Noam
participants (2)
-
Armin Rigo
-
Noam Raphael