[pypy-svn] r18379 - in pypy/dist/pypy/rpython/ootype: . test
boria at codespeak.net
boria at codespeak.net
Tue Oct 11 11:52:59 CEST 2005
Author: boria
Date: Tue Oct 11 11:52:59 2005
New Revision: 18379
Modified:
pypy/dist/pypy/rpython/ootype/ootype.py
pypy/dist/pypy/rpython/ootype/test/test_ootype.py
Log:
(Samuele, Bert, Arre, Aurelien, Boris)
* Superclasses
Modified: pypy/dist/pypy/rpython/ootype/ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootype/ootype.py (original)
+++ pypy/dist/pypy/rpython/ootype/ootype.py Tue Oct 11 11:52:59 2005
@@ -132,9 +132,23 @@
class Class(OOType):
def __init__(self, name, superclass, fields):
- self._fields = fields
+ self._superclass = superclass
+
+ self._fields = {}
+ self._add_fields(fields)
+
+ self._null = _null_instance(self)
+
+ def _defl(self):
+ return self._null
+
+ def _add_fields(self, fields):
for name, defn in fields.iteritems():
+ if self._superclass is not None:
+ if self._superclass._has_field(name):
+ raise TypeError("Field %r exists in superclass" % name)
+
if type(defn) is not tuple:
fields[name] = (defn, defn._defl())
else:
@@ -143,6 +157,29 @@
if ootype != typeOf(default):
raise TypeError("Expected type %r for default" % ootype)
+ self._fields.update(fields)
+
+ def _init_instance(self, instance):
+ if self._superclass is not None:
+ self._superclass._init_instance(instance)
+
+ for name, (ootype, default) in self._fields.iteritems():
+ instance.__dict__[name] = default
+
+ def _has_field(self, name):
+ try:
+ self._fields[name]
+ return True
+ except KeyError:
+ if self._superclass is None:
+ return False
+
+ return self._superclass._has_field(name)
+
+ def _check_field(self, name):
+ if not self._has_field(name):
+ raise TypeError("No field named %r" % name)
+
# ____________________________________________________________
class _instance(object):
@@ -150,14 +187,10 @@
def __init__(self, CLASS):
self.__dict__["_TYPE"] = CLASS
- for name, (ootype, default) in self._TYPE._fields.iteritems():
- self.__dict__[name] = default
+ CLASS._init_instance(self)
def __getattr__(self, name):
- try:
- self._TYPE._fields[name]
- except KeyError:
- raise TypeError("No field named %r" % name)
+ self._TYPE._check_field(name)
return self.__dict__[name]
@@ -172,13 +205,13 @@
class _null_instance(_instance):
def __init__(self, CLASS):
- _instance.__init__(self, CLASS)
+ self.__dict__["_TYPE"] = CLASS
def __getattribute__(self, name):
if name.startswith("_"):
return object.__getattribute__(self, name)
- _instance.__getattr__(self, name)
+ self._TYPE._check_field(name)
raise RuntimeError("Access to field in null object")
@@ -191,7 +224,10 @@
return _instance(CLASS)
def null(CLASS):
- return _null_instance(CLASS)
+ return CLASS._null
+
+def addFields(CLASS, fields):
+ CLASS._add_fields(fields)
def typeOf(val):
try:
Modified: pypy/dist/pypy/rpython/ootype/test/test_ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootype/test/test_ootype.py (original)
+++ pypy/dist/pypy/rpython/ootype/test/test_ootype.py Tue Oct 11 11:52:59 2005
@@ -31,3 +31,33 @@
assert typeOf(c) == C
py.test.raises(RuntimeError, "c.a")
+
+def test_simple_class_field():
+ C = Class("test", None, {})
+
+ D = Class("test2", None, {"a": C})
+ d = new(D)
+
+ assert typeOf(d.a) == C
+
+ assert d.a == null(C)
+
+def test_simple_recursive_class():
+ C = Class("test", None, {})
+
+ addFields(C, {"inst": C})
+
+ c = new(C)
+ assert c.inst == null(C)
+
+def test_simple_super():
+ C = Class("test", None, {"a": (Signed, 3)})
+ D = Class("test2", C, {})
+
+ d = new(D)
+ assert d.a == 3
+
+def test_simple_field_shadowing():
+ C = Class("test", None, {"a": (Signed, 3)})
+
+ py.test.raises(TypeError, """D = Class("test2", C, {"a": (Signed, 3)})""")
More information about the Pypy-commit
mailing list