def __getitem__(cls, mclass): if not ismodeledclass(mclass): raise TypeError class Type(type(cls), type(mclass)): pass Type.__name__ = "%s[%s].type" % (cls.__name__, mclass.__name__) class Adapter(with_metaclass(Type, cls, mclass)): __module__ = cls.__module__ # Reset __new__ from base Adapter.__new__ # (adapting modeled instances) # to <adapted modeled class>.__new__ (instantiating class) __new__ = mclass.__new__ def __init__(self, *args, **membervalues): # first delegate to __init__ of adapted modeled class mclass.__init__(self, *args, **membervalues) self.minstance = self # and then to adapter's additional __init__ cls.__init__(self) Adapter.mclass = mclass Adapter.__name__ = "%s[%s]" % (cls.__name__, mclass.__name__) Adapter.__qualname__ = "%s[%s]" % (qualname(cls), qualname(mclass)) return Adapter
def __getitem__(cls, bases): """Get a modeled class derived from the given `bases`, which can be (mixed) modeled and non-modeled classes. - Results are cached. - Needed in Python 3 for deriving from more than one modeled class: .. code:: python class Derived(ModeledBaseOne, ModeledBaseTwo): # results in metaclass conflict! class Derived(modeled.object[ModeledBaseOne, ModeledBaseTwo]): # works! ... """ mcs = type(cls) if not isinstance(bases, tuple): bases = bases, basenames = ', '.join(qualname(b) for b in bases) clsname = '%s[%s]' % (cls.__name__, basenames) metabases = tuple(type(b) for b in bases if issubclass(b, object)) ## if type(b) is not mcs) if not any(issubclass(mb, mcs) for mb in metabases): metabases = (mcs, ) + metabases if not any(issubclass(b, cls) for b in bases): bases = (cls, ) + bases clsattrs = {'__module__': cls.__module__} meta = type(clsname + '.meta', metabases, clsattrs) cls = meta(clsname, bases, clsattrs) cls.__qualname__ = '%s[%s]' % (qualname(cls), basenames) meta.__qualname__ = cls.__qualname__ + '.meta' return cls
def __getitem__(cls, mclass): if not ismodeledclass(mclass): raise TypeError class Type(type(cls), type(mclass)): pass Type.__name__ = '%s[%s].type' % (cls.__name__, mclass.__name__) class Adapter(with_metaclass(Type, cls, mclass)): __module__ = cls.__module__ # Reset __new__ from base Adapter.__new__ # (adapting modeled instances) # to <adapted modeled class>.__new__ (instantiating class) __new__ = mclass.__new__ def __init__(self, *args, **membervalues): # first delegate to __init__ of adapted modeled class mclass.__init__(self, *args, **membervalues) self.minstance = self # and then to adapter's additional __init__ cls.__init__(self) Adapter.mclass = mclass Adapter.__name__ = '%s[%s]' % (cls.__name__, mclass.__name__) Adapter.__qualname__ = '%s[%s]' % (qualname(cls), qualname(mclass)) return Adapter
def new(self, value, func): value = func(value) if isinstance(value, self.mtype): return value raise TypeError( "%s.new.func() must return an instance of '%s', not '%s'" % (qualname(type(self)), qualname(self.mtype), qualname( type(value))))
def new(self, value, func): value = func(value) if isinstance(value, self.mtype): return value raise TypeError( "%s.new.func() must return an instance of '%s', not '%s'" % (qualname(type(self)), qualname(self.mtype), qualname(type(value))))
def __init__(cls, clsname, bases, clsattrs): modeled.object.meta.__init__(cls, clsattrs, bases, clsattrs) # to be stored as .normalize metamethod of created class def normalizer(value): """Normalize `value` based on normalizing options from metaclass. """ if isinstance(value, UserString): value = value.data return normalize(value, ignore=cls.ignore, caseless=cls.caseless, spaceless=cls.spaceless) normalizer.__qualname__ = "%s.meta.normalize" % qualname(cls) cls.meta.normalize = staticmethod(normalizer) if cls.__init__ is modeled.object.__init__: # ==> no custom cls.__init__ # ==> create default __init__ without normalizing options # from basic robot.utils.NormalizedDict.__init__ def __init__(self, mapping, **items): modeled.object.__init__(self) base.__init__(self, mapping) if items: self.update(items) cls.__init__ = __init__
def __init__(cls, clsname, bases, clsattrs): modeled.object.meta.__init__(cls, clsattrs, bases, clsattrs) # to be stored as .normalize metamethod of created class def normalizer(value): """Normalize `value` based on normalizing options from metaclass. """ if isinstance(value, UserString): value = value.data return normalize(value, ignore=cls.ignore, caseless=cls.caseless, spaceless=cls.spaceless) normalizer.__qualname__ = '%s.meta.normalize' % qualname(cls) cls.meta.normalize = staticmethod(normalizer) if cls.__init__ is modeled.object.__init__: #==> no custom cls.__init__ #==> create default __init__ without normalizing options # from basic robot.utils.NormalizedDict.__init__ def __init__(self, mapping, **items): modeled.object.__init__(self) base.__init__(self, mapping) if items: self.update(items) cls.__init__ = __init__
def switch_session(self, name): previous = cls.session active = cls.switch_session(name) if previous is not None and close_func: # explicitly close previously active session if unnamed for name, session in dictitems(cls.sessions): if session is previous: break else: try: close_func(self, previous) except Exception as exc: raise cls.SessionError( "Couldn't close unnamed session " "on switching to %s (%s: %s)" % (repr(name), qualname(type(exc)), exc)) if switch_func: try: switch_func(self, active) except Exception as exc: raise cls.SessionError( "Couldn't switch session to %s (%s: %s)" % (repr(name), qualname(type(exc)), exc)) cls.session = active
def switch_context(self, name): for current in self.contexts: if current.handler is cls: break for context in cls.contexts: if context.name == name: if switch_func: # Custom switch hook try: switch_func(self, name) except Exception as exc: raise cls.ContextError( "Couldn't switch context to %s (%s: %s)" % (repr(name), qualname(type(exc)), exc)) self.contexts.remove(current) self.contexts.append(context) return raise cls.ContextError("Context not found: %s" % repr(name))
def __repr__(self): # only relevant if a derived class overrides __new__ # to create real StrictBool instances instead of builtin bools return "<%s: %s>" % (moretools.qualname(type(self)), bool(self))