[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