summaryrefslogtreecommitdiffstats
path: root/Demo/newmetaclasses
diff options
context:
space:
mode:
Diffstat (limited to 'Demo/newmetaclasses')
-rw-r--r--Demo/newmetaclasses/Eiffel.py141
-rw-r--r--Demo/newmetaclasses/Enum.py177
2 files changed, 0 insertions, 318 deletions
diff --git a/Demo/newmetaclasses/Eiffel.py b/Demo/newmetaclasses/Eiffel.py
deleted file mode 100644
index 15fa58a..0000000
--- a/Demo/newmetaclasses/Eiffel.py
+++ /dev/null
@@ -1,141 +0,0 @@
-"""Support Eiffel-style preconditions and postconditions."""
-
-from types import FunctionType as function
-
-class EiffelBaseMetaClass(type):
-
- def __new__(meta, name, bases, dict):
- meta.convert_methods(dict)
- return super(EiffelBaseMetaClass, meta).__new__(meta, name, bases,
- dict)
-
- @classmethod
- def convert_methods(cls, dict):
- """Replace functions in dict with EiffelMethod wrappers.
-
- The dict is modified in place.
-
- If a method ends in _pre or _post, it is removed from the dict
- regardless of whether there is a corresponding method.
- """
- # find methods with pre or post conditions
- methods = []
- for k, v in dict.items():
- if k.endswith('_pre') or k.endswith('_post'):
- assert isinstance(v, function)
- elif isinstance(v, function):
- methods.append(k)
- for m in methods:
- pre = dict.get("%s_pre" % m)
- post = dict.get("%s_post" % m)
- if pre or post:
- dict[k] = cls.make_eiffel_method(dict[m], pre, post)
-
-class EiffelMetaClass1(EiffelBaseMetaClass):
- # an implementation of the "eiffel" meta class that uses nested functions
-
- @staticmethod
- def make_eiffel_method(func, pre, post):
- def method(self, *args, **kwargs):
- if pre:
- pre(self, *args, **kwargs)
- x = func(self, *args, **kwargs)
- if post:
- post(self, x, *args, **kwargs)
- return x
-
- if func.__doc__:
- method.__doc__ = func.__doc__
-
- return method
-
-class EiffelMethodWrapper:
-
- def __init__(self, inst, descr):
- self._inst = inst
- self._descr = descr
-
- def __call__(self, *args, **kwargs):
- return self._descr.callmethod(self._inst, args, kwargs)
-
-class EiffelDescriptor(object):
-
- def __init__(self, func, pre, post):
- self._func = func
- self._pre = pre
- self._post = post
-
- self.__name__ = func.__name__
- self.__doc__ = func.__doc__
-
- def __get__(self, obj, cls):
- return EiffelMethodWrapper(obj, self)
-
- def callmethod(self, inst, args, kwargs):
- if self._pre:
- self._pre(inst, *args, **kwargs)
- x = self._func(inst, *args, **kwargs)
- if self._post:
- self._post(inst, x, *args, **kwargs)
- return x
-
-class EiffelMetaClass2(EiffelBaseMetaClass):
- # an implementation of the "eiffel" meta class that uses descriptors
-
- make_eiffel_method = EiffelDescriptor
-
-def _test(metaclass):
- class Eiffel(metaclass=metaclass):
- pass
-
- class Test(Eiffel):
-
- def m(self, arg):
- """Make it a little larger"""
- return arg + 1
-
- def m2(self, arg):
- """Make it a little larger"""
- return arg + 1
-
- def m2_pre(self, arg):
- assert arg > 0
-
- def m2_post(self, result, arg):
- assert result > arg
-
- class Sub(Test):
- def m2(self, arg):
- return arg**2
- def m2_post(self, Result, arg):
- super(Sub, self).m2_post(Result, arg)
- assert Result < 100
-
- t = Test()
- t.m(1)
- t.m2(1)
- try:
- t.m2(0)
- except AssertionError:
- pass
- else:
- assert False
-
- s = Sub()
- try:
- s.m2(1)
- except AssertionError:
- pass # result == arg
- else:
- assert False
- try:
- s.m2(10)
- except AssertionError:
- pass # result == 100
- else:
- assert False
- s.m2(5)
-
-if __name__ == "__main__":
- _test(EiffelMetaClass1)
- _test(EiffelMetaClass2)
diff --git a/Demo/newmetaclasses/Enum.py b/Demo/newmetaclasses/Enum.py
deleted file mode 100644
index 3ff8ddd..0000000
--- a/Demo/newmetaclasses/Enum.py
+++ /dev/null
@@ -1,177 +0,0 @@
-"""Enumeration metaclass."""
-
-class EnumMetaclass(type):
- """Metaclass for enumeration.
-
- To define your own enumeration, do something like
-
- class Color(Enum):
- red = 1
- green = 2
- blue = 3
-
- Now, Color.red, Color.green and Color.blue behave totally
- different: they are enumerated values, not integers.
-
- Enumerations cannot be instantiated; however they can be
- subclassed.
- """
-
- def __init__(cls, name, bases, dict):
- super(EnumMetaclass, cls).__init__(name, bases, dict)
- cls._members = []
- for attr in dict.keys():
- if not (attr.startswith('__') and attr.endswith('__')):
- enumval = EnumInstance(name, attr, dict[attr])
- setattr(cls, attr, enumval)
- cls._members.append(attr)
-
- def __getattr__(cls, name):
- if name == "__members__":
- return cls._members
- raise AttributeError(name)
-
- def __repr__(cls):
- s1 = s2 = ""
- enumbases = [base.__name__ for base in cls.__bases__
- if isinstance(base, EnumMetaclass) and not base is Enum]
- if enumbases:
- s1 = "(%s)" % ", ".join(enumbases)
- enumvalues = ["%s: %d" % (val, getattr(cls, val))
- for val in cls._members]
- if enumvalues:
- s2 = ": {%s}" % ", ".join(enumvalues)
- return "%s%s%s" % (cls.__name__, s1, s2)
-
-class FullEnumMetaclass(EnumMetaclass):
- """Metaclass for full enumerations.
-
- A full enumeration displays all the values defined in base classes.
- """
-
- def __init__(cls, name, bases, dict):
- super(FullEnumMetaclass, cls).__init__(name, bases, dict)
- for obj in cls.__mro__:
- if isinstance(obj, EnumMetaclass):
- for attr in obj._members:
- # XXX inefficient
- if not attr in cls._members:
- cls._members.append(attr)
-
-class EnumInstance(int):
- """Class to represent an enumeration value.
-
- EnumInstance('Color', 'red', 12) prints as 'Color.red' and behaves
- like the integer 12 when compared, but doesn't support arithmetic.
-
- XXX Should it record the actual enumeration rather than just its
- name?
- """
-
- def __new__(cls, classname, enumname, value):
- return int.__new__(cls, value)
-
- def __init__(self, classname, enumname, value):
- self.__classname = classname
- self.__enumname = enumname
-
- def __repr__(self):
- return "EnumInstance(%s, %s, %d)" % (self.__classname, self.__enumname,
- self)
-
- def __str__(self):
- return "%s.%s" % (self.__classname, self.__enumname)
-
-class Enum(metaclass=EnumMetaclass):
- pass
-
-class FullEnum(metaclass=FullEnumMetaclass):
- pass
-
-def _test():
-
- class Color(Enum):
- red = 1
- green = 2
- blue = 3
-
- print(Color.red)
-
- print(repr(Color.red))
- print(Color.red == Color.red)
- print(Color.red == Color.blue)
- print(Color.red == 1)
- print(Color.red == 2)
-
- class ExtendedColor(Color):
- white = 0
- orange = 4
- yellow = 5
- purple = 6
- black = 7
-
- print(ExtendedColor.orange)
- print(ExtendedColor.red)
-
- print(Color.red == ExtendedColor.red)
-
- class OtherColor(Enum):
- white = 4
- blue = 5
-
- class MergedColor(Color, OtherColor):
- pass
-
- print(MergedColor.red)
- print(MergedColor.white)
-
- print(Color)
- print(ExtendedColor)
- print(OtherColor)
- print(MergedColor)
-
-def _test2():
-
- class Color(FullEnum):
- red = 1
- green = 2
- blue = 3
-
- print(Color.red)
-
- print(repr(Color.red))
- print(Color.red == Color.red)
- print(Color.red == Color.blue)
- print(Color.red == 1)
- print(Color.red == 2)
-
- class ExtendedColor(Color):
- white = 0
- orange = 4
- yellow = 5
- purple = 6
- black = 7
-
- print(ExtendedColor.orange)
- print(ExtendedColor.red)
-
- print(Color.red == ExtendedColor.red)
-
- class OtherColor(FullEnum):
- white = 4
- blue = 5
-
- class MergedColor(Color, OtherColor):
- pass
-
- print(MergedColor.red)
- print(MergedColor.white)
-
- print(Color)
- print(ExtendedColor)
- print(OtherColor)
- print(MergedColor)
-
-if __name__ == '__main__':
- _test()
- _test2()