[Python-checkins] r55317 - sandbox/trunk/abc/struct.py
guido.van.rossum
python-checkins at python.org
Mon May 14 21:08:34 CEST 2007
Author: guido.van.rossum
Date: Mon May 14 21:08:31 2007
New Revision: 55317
Added:
sandbox/trunk/abc/struct.py (contents, props changed)
Log:
Checkpoint. Non-working code for now.
Added: sandbox/trunk/abc/struct.py
==============================================================================
--- (empty file)
+++ sandbox/trunk/abc/struct.py Mon May 14 21:08:31 2007
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3.0
+
+"""Define a structure using a class.
+
+Structures have some properties that normal classes don't:
+
+(a) instance attributes are typed
+(b) only pre-defined instance attributes are allowed
+(c) instance variables have a well-defined order (i.e., declaration order)
+
+Example:
+
+ class C(Structure):
+
+ '''A class with two fields, an int and a string.'''
+
+ a = Field(int)
+ b = Field(str)
+
+ x = C()
+ x.a = 42
+ x.b = "hello"
+ print(x.a) # 42
+ print(x.b) # hello
+
+The following assignments are now all disallowed:
+
+ x.a = "hello"
+ x.b = 42
+ x.c = 0
+
+"""
+
+class _FieldDict(dict):
+
+ __slots__ = ["_order"]
+
+ def __init__(self, initial=()):
+ if hasattr(initial, "keys"):
+ initial = [(key, initial[key]) for key in initial.keys()]
+ self._order = list(initial)
+ dict.__init__(self, initial)
+
+ def __setitem__(self, key, value):
+ self._order.append((key, value))
+ dict.__setitem__(self, key, value)
+
+class Field:
+
+ def __init__(self, type=object):
+ self._type = type
+ self._get = None
+ self._set = None
+ self._delete = None
+ self._name = "?"
+
+ def __get__(self, obj, cls=None):
+ return self._get(obj, cls)
+
+ def __set__(self, obj, value):
+ if not isinstance(value, self._type):
+ raise TypeError("can't set %s to %.100r; %s required" %
+ (self._name, value, self._type.__name__))
+ self._set(obj, value)
+
+ def __delete__(self, obj):
+ self._delete(obj)
+
+class _StructureClass(type):
+
+ @classmethod
+ def __prepare__(mcls, *args):
+ return _FieldDict()
+
+ def __new__(mcls, classname, bases, namespace):
+ if "__slots__" in namespace:
+ raise TypeError("You can't define __slots__ in a Structure")
+ slots = []
+ fields = {}
+ for name, value in namespace._order:
+ if isinstance(value, Field):
+ if namespace.get(name) is value and name not in fields:
+ value._name = name
+ slots.append(name)
+ fields[name] = value
+ del namespace[name]
+ namespace = dict(namespace)
+ namespace["__slots__"] = slots
+ cls = type.__new__(mcls, classname, bases, namespace)
+ for name in slots:
+ field = fields[name]
+ descr = getattr(cls, name)
+ field._get = descr.__get__
+ field._set = descr.__set__
+ field._delete = descr.__delete__
+ setattr(cls, name, field)
+ return cls
+
+class Structure(metaclass=_StructureClass):
+
+ pass
+
+# Example
+
+class C(Structure):
+
+ a = Field(int)
+ b = Field(str)
+
+ def f(self):
+ print(self.a, self.b)
+
+x = C()
+x.a = 42
+x.b = "hello"
+assert not hasattr(x, "__dict__")
+print(x.__slots__)
+x.f()
+x.a = "hello"
More information about the Python-checkins
mailing list