Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

odd.py 2.9KB

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. ##############################################################################
  2. #
  3. # Copyright (c) 2003 Zope Foundation and Contributors.
  4. # All Rights Reserved.
  5. #
  6. # This software is subject to the provisions of the Zope Public License,
  7. # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
  8. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
  9. # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  10. # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
  11. # FOR A PARTICULAR PURPOSE.
  12. #
  13. ##############################################################################
  14. """Odd meta class that doesn't subclass type.
  15. This is used for testing support for ExtensionClass in new interfaces.
  16. >>> class A(object):
  17. ... __metaclass__ = MetaClass
  18. ... a = 1
  19. ...
  20. >>> A.__name__
  21. 'A'
  22. >>> A.__bases__ == (object,)
  23. True
  24. >>> class B(object):
  25. ... __metaclass__ = MetaClass
  26. ... b = 1
  27. ...
  28. >>> class C(A, B): pass
  29. ...
  30. >>> C.__name__
  31. 'C'
  32. >>> int(C.__bases__ == (A, B))
  33. 1
  34. >>> a = A()
  35. >>> aa = A()
  36. >>> a.a
  37. 1
  38. >>> aa.a
  39. 1
  40. >>> aa.a = 2
  41. >>> a.a
  42. 1
  43. >>> aa.a
  44. 2
  45. >>> c = C()
  46. >>> c.a
  47. 1
  48. >>> c.b
  49. 1
  50. >>> c.b = 2
  51. >>> c.b
  52. 2
  53. >>> C.c = 1
  54. >>> c.c
  55. 1
  56. >>> int(C.__class__.__class__ is C.__class__)
  57. 1
  58. """
  59. # class OddClass is an odd meta class
  60. class MetaMetaClass(type):
  61. def __getattribute__(cls, name):
  62. if name == '__class__':
  63. return cls
  64. # Under Python 3.6, __prepare__ gets requested
  65. return type.__getattribute__(cls, name)
  66. class MetaClass:
  67. """Odd classes
  68. """
  69. def __init__(self, name, bases, dict):
  70. self.__name__ = name
  71. self.__bases__ = bases
  72. self.__dict__.update(dict)
  73. def __call__(self):
  74. return OddInstance(self)
  75. def __getattr__(self, name):
  76. for b in self.__bases__:
  77. v = getattr(b, name, self)
  78. if v is not self:
  79. return v
  80. raise AttributeError(name)
  81. def __repr__(self): # pragma: no cover
  82. return "<odd class {} at {}>".format(self.__name__, hex(id(self)))
  83. MetaClass = MetaMetaClass('MetaClass',
  84. MetaClass.__bases__,
  85. {k: v for k, v in MetaClass.__dict__.items()
  86. if k not in ('__dict__',)})
  87. class OddInstance:
  88. def __init__(self, cls):
  89. self.__dict__['__class__'] = cls
  90. def __getattribute__(self, name):
  91. dict = object.__getattribute__(self, '__dict__')
  92. if name == '__dict__':
  93. return dict
  94. v = dict.get(name, self)
  95. if v is not self:
  96. return v
  97. return getattr(dict['__class__'], name)
  98. def __setattr__(self, name, v):
  99. self.__dict__[name] = v
  100. def __delattr__(self, name):
  101. raise NotImplementedError()
  102. def __repr__(self): # pragma: no cover
  103. return "<odd {} instance at {}>".format(
  104. self.__class__.__name__, hex(id(self)))