def __call__( me, typ): '''опит за (йерархично) съответствие тип-поле -> тип-колона. първо се търси на ниво StaticType, пряко и обхождане по йерархията на класовете. (филтър в typemap по isinstance не може да направи правилен ред на обхождане) после, се търси на ниво тип-на-стойността, пряко и филтър в typemap по isinstance съответно, StaticType-огъвки с разни тип-на-стойността (като Number) не трябва да се слагат като StaticType в typemap_upper, а в typemap_lower ! ''' assert isinstance( typ, StaticType) t = typ.__class__ while t is not StaticType: try: r = me.typemap_upper[ t] except KeyError: pass else: if callable(r): r = r( typ) return r for t in t.__bases__: if issubclass( t, StaticType): break ttyp = typ.typ try: return me.typemap_lower[ ttyp] except KeyError, e: for k,v in me.typemap_lower.iteritems(): if issubclass( ttyp, k): return v raise
def subklasi4any( me, klas): 'return all mappable classes that are subclasses of klas, be it mappable or not' if me.mappable( klas): return klas, me.subklasi[ klas] if not issubclass( klas, me.base_klas): return klas, () klas_mappable = me.base( klas) subklasi_mappable = me.subklasi[ klas_mappable] subs = [ k for k in subklasi_mappable if issubclass( k, klas) ] return klas_mappable, subs
def subklasi4any(me, klas): 'return all mappable classes that are subclasses of klas, be it mappable or not' if me.mappable(klas): return klas, me.subklasi[klas] if not issubclass(klas, me.base_klas): return klas, () klas_mappable = me.base(klas) subklasi_mappable = me.subklasi[klas_mappable] subs = [k for k in subklasi_mappable if issubclass(k, klas)] return klas_mappable, subs
def base( me, klas): '''дава (първия) базов валиден клас, None ако няма такъв. т.е. на или отвъд валидния корен $ get (first) base that is mappable, None if no such, i.e. at or under root-mappable''' #TODO optimize via __mro__ assert klas base_klas = me.base_klas while klas is not base_klas: assert issubclass( klas, base_klas), 'klas %(klas)s does not inherit base_klas %(base_klas)s' % locals() for base in klas.__bases__: if issubclass( base, base_klas): break else: assert 0, 'klas %(klas)s does not inherit base_klas %(base_klas)s' % locals() if me.mappable( base): return base # allow non-mapped classes to declare props -> added to _all_ their children klas = base return None
def mappable(me, klas): if klas and issubclass(klas, me.base_klas) and klas is not me.base_klas: DBCOOK_no_mapping = getattr_local_instance_only( klas, 'DBCOOK_no_mapping', None) if not DBCOOK_no_mapping: return True return False
def walker( namespace, reflector, baseklas): 'aliases are ignored; same-name items are overwritten' klasi = {} dbgsorted = _debug and sorted or _pipe for k,klas in dbgsorted( namespace.iteritems() ): if not issubclass( klas, baseklas): continue name = klas.__name__ key = (name, klas.__module__) if klas is klasi.get( key, (None,))[0]: if _debug: print 'walk: ignoring dup', k,'=',name continue if _debug: print 'walk: got', name, klas.__module__ klasi[ key ] = klas, 'namespace' if _debug: print '\n '.join( ['walk 0'] + [str(kv) for kv in dbgsorted( klasi.iteritems() )]) pas = 0 new = 1 while new: pas +=1 if _debug: print 'walk: ------ pass', pas new = 0 for (kname,kmod),(klas,isnamespace) in dbgsorted( klasi.items() ): #copy if isinstance( klas, str): continue new += walk1( klas,isnamespace, kname,kmod, klasi, reflector, namespace) if _debug: print '\n '.join( ['eopass'] + [ str(kv) for kv in dbgsorted( klasi.iteritems() )]) for (kname,kmod),(klas,isnamespace) in dbgsorted( klasi.items() ): #copy add_bases( klas, klasi, baseklas) r = dict( (kname,klas) for (kname,kmod),(klas,isnamespace) in klasi.iteritems() ) if _debug: print dbgsorted(r) if _debug: print 'walk: end' return r
def __init__( me, type, auto_set =None, default_value =_NONE, factory =None, **kargs): assert issubclass( type, StaticStruct) if auto_set is None: auto_set = getattr( type, 'auto_set', me.auto_set) if auto_set: default_value = type me.auto_set = auto_set #store, needed in ForwardSubStruct StaticType.__init__( me, type=type, default_value=default_value, factory=factory or type, typ_matcher= static_type.typ_matcher_isinstance, **kargs)
def add_bases(klas, klasi, baseklas): b = klas.__bases__ while b and issubclass(b[0], baseklas): b = b[0] key = (b.__name__, b.__module__) if key not in klasi: klasi[key] = b, None if _debug: print 'walk: add base', b b = b.__bases__
def add_bases( klas, klasi, baseklas): b = klas.__bases__ while b and issubclass( b[0], baseklas): b = b[0] key = (b.__name__, b.__module__) if key not in klasi: klasi[ key ] = b,None if _debug: print 'walk: add base', b b = b.__bases__
def base(me, klas): '''дава (първия) базов валиден клас, None ако няма такъв. т.е. на или отвъд валидния корен $ get (first) base that is mappable, None if no such, i.e. at or under root-mappable''' #TODO optimize via __mro__ assert klas base_klas = me.base_klas while klas is not base_klas: assert issubclass( klas, base_klas ), 'klas %(klas)s does not inherit base_klas %(base_klas)s' % locals( ) for base in klas.__bases__: if issubclass(base, base_klas): break else: assert 0, 'klas %(klas)s does not inherit base_klas %(base_klas)s' % locals( ) if me.mappable(base): return base # allow non-mapped classes to declare props -> added to _all_ their children klas = base return None
def convert( klas, name, bases, adict): slots_outside_StaticType = [] alts = [] for p,t in adict.iteritems(): need_slot = getattr( t, 'need_slot_outside_StaticType', None) if callable( need_slot ): need_slot = need_slot() if need_slot: slots_outside_StaticType.append( p) autos = getattr( t, 'auto_StaticTypes', None) if autos: alts += autos for a in autos: f = getattr( a, 'slot_outside_StaticType', None) if f: if callable(f): f = f(p) slots_outside_StaticType.append( f ) static_type.StaticTyper_factory.convert( klas, name, bases, adict, slots_outside_StaticType= slots_outside_StaticType) or name # make x accessible via class.x (not via class.StaticType['x'] - hence after convert()) for t in alts: adict[ t.name ] = t # have __slots__ = () automatic in each class - do not introduce __dict__ etc. adict.setdefault( '__slots__', ()) for tname,t in adict.iteritems(): if issubclass( t, static_type.StaticTyper): if config.STRUCT_AUTO_INSTANTIATE: adict[ tname ] = class_attr.Descriptor4AutoCreatedReadonlyAttr( t, tname) #or just make it StaticType(t) ? else: if config.DISABLE_NON_STATICTYPE_ATTRIBS: adict[ tname ] = class_attr.Descriptor4ClassOnlyAttr( t, tname) for p,t in adict[ 'StaticType' ].iteritems(): #flattened if t.meta: try: v = adict[ p] except KeyError: for b in bases: try: bv = getattr( b,p) bt = b.StaticType except AttributeError: continue if p in bt and bt[p] is not bv: #has a value break else: msg_MissingValue( struct=name, member=p ) continue if v is t: continue #self - definition try: t._validate( v) except (TypeError,ValueError), e: msg_WrongValue( struct=name, member=p, value=v, e=e )
def pklasi( me, Base, namespace, **kargs): me.Base = Base try: namespace = namespace.itervalues() except AttributeError: pass all = [klas for klas in namespace if issubclass( klas, Base)] all.sort( key=lambda kl:kl.__name__) for klas in all: me.pklas( klas, **kargs) me.nl() me.done.append( 'pklasi')
def _importFromFile( me, name): assert name module = __import__( name) for k, v in vars( module).items(): if issubclass( v, TestBase): try: n= v.__name__.split('_', 1)[1] me.translator[ n.lower()] = v except IndexError: pass return module
def pklasi(me, Base, namespace, **kargs): me.Base = Base try: namespace = namespace.itervalues() except AttributeError: pass all = [klas for klas in namespace if issubclass(klas, Base)] all.sort(key=lambda kl: kl.__name__) for klas in all: me.pklas(klas, **kargs) me.nl() me.done.append('pklasi')
def group( me, threshold =None, aggregators =None, name =None, filter_func =None): if not me.use_dynamic_grouping and (me.finished or not me.empty): return from row import AggrRow from group import Group, UnorderedGroup from svd_util.attr import issubclass if issubclass( aggregators, AggrRow): aggregators = [ aggregators ] group_factory = me.preserve_input_order and Group or UnorderedGroup g = group_factory( me._rows_and_packets, len(me._groups), name, aggregators, threshold, filter_func) me._groups.append( g) if not me.empty: me._update_group( g)
def test_namespace_partial( me, namespace =namespace, expect =None): expect = expect or me.expect from svd_util.attr import issubclass print 'in:', ' '.join( k+':'+v.__name__ for k,v in namespace.items() if issubclass( v,Base) ) r = walkklas.walker( namespace, Builder.reflector, Base ) if walkklas._debug: print print '\n '.join( ['result:'] + [str(a) for a in r.iteritems() ] ) if r != expect: q = dict( res=r,exp=expect) for k in q: q[k] = '\n'.join( sorted( '\t%s:%s' % kv for kv in q[k].items())) #print for a,b in q.items(): print a,b me.assertEquals( *q.values())
def __init__( klas, name, bases, dict_): for mdcl in klas.methods_walk(): mdcl.decl.name = mdcl.name if dict_.get('DONT_CHECK_METHODS_AND_TYPES'): return if len(bases)==1: return fbases = [ b for b in bases if issubclass( b, FaceDeclaration) ] if len(fbases)<=1: return #check type name clashes between bases types = getattr( klas, 'Types', None) # kl dtypes = types and types.__dict__ or {} rtypes = dict( dtypes) for b in fbases: btypes = getattr( b, 'Types', None) if not btypes: continue for k in dir( btypes): if k.startswith('__'): continue bt = getattr( btypes, k) if k in dtypes: t = dtypes[k] if t is not bt: bname = b.__name__ warnings.warn( 'duplicate typename %(k)r: %(bname)s:%(bt)s, %(name)s:%(t)s' % locals(), stacklevel=2) else: rtypes[ k] = bt #flatten if not types or types is not klas.__dict__.get( 'Types'): klas.Types = Types() klas.Types.__dict__.update( rtypes) else: for k,m in rtypes.items(): if k not in dtypes: setattr( klas.Types, k, m) klas.MTypes = MTypes( klas.Types) #check method name clashes between bases mets = klas.methods_dict() for b in fbases: bname = b.__name__ for k,bm in b.methods_dict().iteritems(): m = mets.get(k) mdecl = m.decl bmdecl = bm.decl if mdecl is not bmdecl: warnings.warn( 'duplicate method %(k)r: %(bname)s:%(bmdecl)s, %(name)s:%(mdecl)s' % locals(), stacklevel=2)
def set_container_data( container, data_obj, description, context, **kargs): for name, fld in description.iteritems(): if issubclass( fld.typ, Spravka): subrep = isinstance( fld.setup, dict) and fld.typ( **fld.setup) or fld.typ() if callable( fld.setup): fld.setup( container, subrep) o = data_obj if fld.model: o = get_attrib( data_obj, fld.model) subrep.refresh( context, container, o, **kargs) setattr( container, name, subrep) elif fld.model: try: value = get_attrib( data_obj, fld.model) except AttributeError: value = None print container.__class__.__name__, ''' warning: query obj has no attr "%s"''' % fld.model setattr( container, name, value)
def test_namespace_partial(me, namespace=namespace, expect=None): expect = expect or me.expect from svd_util.attr import issubclass print 'in:', ' '.join(k + ':' + v.__name__ for k, v in namespace.items() if issubclass(v, Base)) r = walkklas.walker(namespace, Builder.reflector, Base) if walkklas._debug: print print '\n '.join(['result:'] + [str(a) for a in r.iteritems()]) if r != expect: q = dict(res=r, exp=expect) for k in q: q[k] = '\n'.join(sorted('\t%s:%s' % kv for kv in q[k].items())) #print for a, b in q.items(): print a, b me.assertEquals(*q.values())
def walker(namespace, reflector, baseklas): 'aliases are ignored; same-name items are overwritten' klasi = {} dbgsorted = _debug and sorted or _pipe for k, klas in dbgsorted(namespace.iteritems()): if not issubclass(klas, baseklas): continue name = klas.__name__ key = (name, klas.__module__) if klas is klasi.get(key, (None, ))[0]: if _debug: print 'walk: ignoring dup', k, '=', name continue if _debug: print 'walk: got', name, klas.__module__ klasi[key] = klas, 'namespace' if _debug: print '\n '.join(['walk 0'] + [str(kv) for kv in dbgsorted(klasi.iteritems())]) pas = 0 new = 1 while new: pas += 1 if _debug: print 'walk: ------ pass', pas new = 0 for (kname, kmod), (klas, isnamespace) in dbgsorted(klasi.items()): #copy if isinstance(klas, str): continue new += walk1(klas, isnamespace, kname, kmod, klasi, reflector, namespace) if _debug: print '\n '.join( ['eopass'] + [str(kv) for kv in dbgsorted(klasi.iteritems())]) for (kname, kmod), (klas, isnamespace) in dbgsorted(klasi.items()): #copy add_bases(klas, klasi, baseklas) r = dict((kname, klas) for (kname, kmod), (klas, isnamespace) in klasi.iteritems()) if _debug: print dbgsorted(r) if _debug: print 'walk: end' return r
def do( me, current, walker =None): c = current typ = c.typ obj = c.obj notSetYet = config.notSetYet meta = getattr( typ, 'meta', None) if meta and not me.meta: return optional_switch = getattr( typ, 'optional', None) if optional_switch: parent = me.stack[-2].obj if parent is notSetYet: on = notSetYet else: on = optional_switch.__get__( parent ) if me.optional_switch: tmp = me.Frame( name=optional_switch.name, typ=optional_switch, obj=on, level=len(me.stack)-1 ) me.stack[-1] = tmp me._do( tmp) me.stack[-1] = c if on is not notSetYet and not on: if not me.optional_off: return if me.non_atomary or not getattr( typ, 'non_atomary', None): me._do( c) if not walker: return if me.only_if_struct and not issubclass( typ, StaticStruct): return if me.only_if_obj and obj is notSetYet: return try: if walker.im_self is None: return #unbound method, i.e. no info without instance except AttributeError: pass try: walker( me) except: if not me._ERROR: me._ERROR = True for f in me.stack: print f print walker raise
def _panel4any( **kargs): typ = kargs['typ'] # global _level # print _level*' ', '_panel4any', typ if issubclass( typ, _static_type.StaticStruct): # _level+=1 make_panel = kargs['make_panel'] p = make_panel( is_root= False, **kargs) # _level-=1 elif isinstance( typ, _static_type.SubStruct): if kargs.pop( 'choosable', True): field_attrs = kargs.pop( 'field_attrs', {}) field_attrs.update( choosable='button', readonly=True) p = panel4StaticType( field_attrs=field_attrs, **kargs) else: #expanded p = make_panel4Struct( **kargs) elif isinstance( typ, _static_type.Sequence): p = panel4StaticSeq( **kargs) else: #plain atomary assert not getattr( typ, 'non_atomary', None) p = panel4StaticType( **kargs) return p
def __init__(me, *args, **kargs): from spravka import Spravka DictAttr.__init__(me, **kargs) # links need this when dereferencing, # also needed for inheritance by flattening style = Style(None) for v in args: # if iscollection(v): # style.update( get_views_from_args(v)) if isinstance(v, FldViewBase): style.inherit(Style(None, v)) # style[ v.view_context_name] = v elif isinstance(v, Style): style.inherit(v) # style.update( v.views) elif isinstance(v, me.__class__): me.inherit(v, ignore_style=style) elif issubclass(v, Spravka): me.inherit(v.description, ignore_style=style) ViewDef.__init__(me, *style.views.itervalues()) views = me.views # to be deleted from me for k in me.keys(): # flatten all field containers v = me[k] if isinstance(v, me.__class__): me.update(v.get_fields()) if not isinstance(v, FieldDef): del me[k] s = Style(None, *views.itervalues()) for field in me.itervalues(): assert isinstance(field, FieldDef), "neshto za zachistvane e ostanalo" field.inherit(s, lock=True, not_inheritable=True) me.dereference(me) # FIXME only the outermost container should do this
def convert( klas, arg): if isinstance( arg, klas): return arg if issubclass( arg, klas): return arg if isinstance( arg, tuple): return klas( *arg) return klas( arg)
def mappable( me, klas): if klas and issubclass( klas, me.base_klas) and klas is not me.base_klas: DBCOOK_no_mapping = getattr_local_instance_only( klas, 'DBCOOK_no_mapping', None) if not DBCOOK_no_mapping: return True return False