332 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			332 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			Python
		
	
	
	
 | 
						|
""" model - type system model for apigen
 | 
						|
"""
 | 
						|
 | 
						|
# we implement all the types which are in the types.*, naming
 | 
						|
# scheme after pypy's
 | 
						|
 | 
						|
import py
 | 
						|
import types
 | 
						|
 | 
						|
set = py.builtin.set
 | 
						|
 | 
						|
 | 
						|
# __extend__ and pairtype?
 | 
						|
class SomeObject(object):
 | 
						|
    typedef = types.ObjectType
 | 
						|
    
 | 
						|
    def __repr__(self):
 | 
						|
        return "<%s>" % self.__class__.__name__[4:]
 | 
						|
        return str(self.typedef)[7:-2]
 | 
						|
    
 | 
						|
    def unionof(self, other):
 | 
						|
        if isinstance(other, SomeImpossibleValue):
 | 
						|
            return self
 | 
						|
        if isinstance(other, SomeUnion):
 | 
						|
            return other.unionof(self)
 | 
						|
        if self == other:
 | 
						|
            return self
 | 
						|
        return SomeUnion([self, other])
 | 
						|
    
 | 
						|
    def gettypedef(self):
 | 
						|
        return self.typedef
 | 
						|
    
 | 
						|
    def __hash__(self):
 | 
						|
        return hash(self.__class__)
 | 
						|
    
 | 
						|
    def __eq__(self, other):
 | 
						|
        return self.__class__ == other.__class__
 | 
						|
    
 | 
						|
    def __ne__(self, other):
 | 
						|
        return not self == other
 | 
						|
        
 | 
						|
    # this is to provide possibility of eventually linking some stuff
 | 
						|
    def striter(self):
 | 
						|
        yield str(self)
 | 
						|
 | 
						|
class SomeUnion(object):
 | 
						|
    # empty typedef
 | 
						|
    def __init__(self, possibilities):
 | 
						|
        self.possibilities = set(possibilities)
 | 
						|
    
 | 
						|
    def unionof(self, other):
 | 
						|
        if isinstance(other, SomeUnion):
 | 
						|
            return SomeUnion(self.possibilities.union(other.possibilities))
 | 
						|
        return SomeUnion(list(self.possibilities) + [other])
 | 
						|
    
 | 
						|
    def __eq__(self, other):
 | 
						|
        if type(other) is not SomeUnion:
 | 
						|
            return False
 | 
						|
        return self.possibilities == other.possibilities
 | 
						|
    
 | 
						|
    def __ne__(self, other):
 | 
						|
        return not self == other
 | 
						|
    
 | 
						|
    def __repr__(self):
 | 
						|
        return "AnyOf(%s)" % ", ".join([str(i) for i in list(self.possibilities)])
 | 
						|
    
 | 
						|
    def gettypedef(self):
 | 
						|
        return (None, None)
 | 
						|
    
 | 
						|
    def striter(self):
 | 
						|
        yield "AnyOf("
 | 
						|
        for num, i in enumerate(self.possibilities):
 | 
						|
            yield i
 | 
						|
            if num != len(self.possibilities) - 1:
 | 
						|
                yield ", "
 | 
						|
        yield ")"
 | 
						|
 | 
						|
class SomeBoolean(SomeObject):
 | 
						|
    typedef = types.BooleanType
 | 
						|
 | 
						|
class SomeBuffer(SomeObject):
 | 
						|
    typedef = types.BufferType
 | 
						|
 | 
						|
class SomeBuiltinFunction(SomeObject):
 | 
						|
    typedef = types.BuiltinFunctionType
 | 
						|
 | 
						|
#class SomeBuiltinMethod(SomeObject):
 | 
						|
#    typedef = types.BuiltinMethodType
 | 
						|
 | 
						|
class SomeClass(SomeObject):
 | 
						|
    typedef = types.ClassType
 | 
						|
    
 | 
						|
    def __init__(self, cls):
 | 
						|
        self.cls = cls
 | 
						|
        self.name = cls.__name__
 | 
						|
        self.id = id(cls)
 | 
						|
 | 
						|
    def __getstate__(self):
 | 
						|
        return (self.name, self.id)
 | 
						|
 | 
						|
    def __setstate__(self, state):
 | 
						|
        self.name, self.id = state
 | 
						|
        self.cls = None
 | 
						|
    
 | 
						|
    def __hash__(self):
 | 
						|
        return hash("Class") ^ hash(self.id)
 | 
						|
    
 | 
						|
    def __eq__(self, other):
 | 
						|
        if type(other) is not SomeClass:
 | 
						|
            return False
 | 
						|
        return self.id == other.id
 | 
						|
    
 | 
						|
    def unionof(self, other):
 | 
						|
        if type(other) is not SomeClass or self.id is not other.id:
 | 
						|
            return super(SomeClass, self).unionof(other)
 | 
						|
        return self
 | 
						|
    
 | 
						|
    def __repr__(self):
 | 
						|
        return "Class %s" % self.name
 | 
						|
    
 | 
						|
class SomeCode(SomeObject):
 | 
						|
    typedef = types.CodeType
 | 
						|
 | 
						|
class SomeComplex(SomeObject):
 | 
						|
    typedef = types.ComplexType
 | 
						|
 | 
						|
class SomeDictProxy(SomeObject):
 | 
						|
    typedef = types.DictProxyType
 | 
						|
 | 
						|
class SomeDict(SomeObject):
 | 
						|
    typedef = types.DictType
 | 
						|
 | 
						|
class SomeEllipsis(SomeObject):
 | 
						|
    typedef = types.EllipsisType
 | 
						|
 | 
						|
class SomeFile(SomeObject):
 | 
						|
    typedef = types.FileType
 | 
						|
 | 
						|
class SomeFloat(SomeObject):
 | 
						|
    typedef = types.FloatType
 | 
						|
 | 
						|
class SomeFrame(SomeObject):
 | 
						|
    typedef = types.FrameType
 | 
						|
 | 
						|
class SomeFunction(SomeObject):
 | 
						|
    typedef = types.FunctionType
 | 
						|
 | 
						|
class SomeGenerator(SomeObject):
 | 
						|
    typedef = types.GeneratorType
 | 
						|
 | 
						|
class SomeInstance(SomeObject):
 | 
						|
    def __init__(self, classdef):
 | 
						|
        self.classdef = classdef
 | 
						|
        
 | 
						|
    def __hash__(self):
 | 
						|
        return hash("SomeInstance") ^ hash(self.classdef)
 | 
						|
    
 | 
						|
    def __eq__(self, other):
 | 
						|
        if type(other) is not SomeInstance:
 | 
						|
            return False
 | 
						|
        return other.classdef == self.classdef
 | 
						|
    
 | 
						|
    def unionof(self, other):
 | 
						|
        if type(other) is not SomeInstance:
 | 
						|
            return super(SomeInstance, self).unionof(other)
 | 
						|
        if self.classdef == other.classdef:
 | 
						|
            return self
 | 
						|
        return SomeInstance(unionof(self.classdef, other.classdef))
 | 
						|
    
 | 
						|
    def __repr__(self):
 | 
						|
        return "<Instance of %s>" % str(self.classdef)
 | 
						|
    
 | 
						|
    def striter(self):
 | 
						|
        yield "<Instance of "
 | 
						|
        yield self.classdef
 | 
						|
        yield ">"
 | 
						|
    
 | 
						|
    typedef = types.InstanceType
 | 
						|
 | 
						|
class SomeInt(SomeObject):
 | 
						|
    typedef = types.IntType
 | 
						|
 | 
						|
class SomeLambda(SomeObject):
 | 
						|
    typedef = types.LambdaType
 | 
						|
 | 
						|
class SomeList(SomeObject):
 | 
						|
    typedef = types.ListType
 | 
						|
 | 
						|
class SomeLong(SomeObject):
 | 
						|
    typedef = types.LongType
 | 
						|
 | 
						|
class SomeMethod(SomeObject):
 | 
						|
    typedef = types.MethodType
 | 
						|
 | 
						|
class SomeModule(SomeObject):
 | 
						|
    typedef = types.ModuleType
 | 
						|
 | 
						|
class SomeNone(SomeObject):
 | 
						|
    typedef = types.NoneType
 | 
						|
 | 
						|
class SomeNotImplemented(SomeObject):
 | 
						|
    typedef = types.NotImplementedType
 | 
						|
 | 
						|
class SomeObject(SomeObject):
 | 
						|
    typedef = types.ObjectType
 | 
						|
 | 
						|
class SomeSlice(SomeObject):
 | 
						|
    typedef = types.SliceType
 | 
						|
 | 
						|
class SomeString(SomeObject):
 | 
						|
    typedef = types.StringType
 | 
						|
 | 
						|
class SomeTraceback(SomeObject):
 | 
						|
    typedef = types.TracebackType
 | 
						|
 | 
						|
class SomeTuple(SomeObject):
 | 
						|
    typedef = types.TupleType
 | 
						|
 | 
						|
class SomeType(SomeObject):
 | 
						|
    typedef = types.TypeType
 | 
						|
 | 
						|
class SomeUnboundMethod(SomeObject):
 | 
						|
    typedef = types.UnboundMethodType
 | 
						|
 | 
						|
class SomeUnicode(SomeObject):
 | 
						|
    typedef = types.UnicodeType
 | 
						|
 | 
						|
class SomeXRange(SomeObject):
 | 
						|
    typedef = types.XRangeType
 | 
						|
 | 
						|
class SomeImpossibleValue(SomeObject):
 | 
						|
    def unionof(self, other):
 | 
						|
        return other
 | 
						|
    
 | 
						|
    def __repr__(self):
 | 
						|
        return "<UNKNOWN>"
 | 
						|
 | 
						|
s_ImpossibleValue = SomeImpossibleValue()
 | 
						|
s_None = SomeNone()
 | 
						|
s_Ellipsis = SomeEllipsis()
 | 
						|
 | 
						|
def guess_type(x):
 | 
						|
    # this is mostly copy of immutablevalue
 | 
						|
    if hasattr(x, 'im_self') and x.im_self is None:
 | 
						|
        x = x.im_func
 | 
						|
        assert not hasattr(x, 'im_self')
 | 
						|
    tp = type(x)
 | 
						|
    if tp is bool:
 | 
						|
        result = SomeBoolean()
 | 
						|
    elif tp is int:
 | 
						|
        result = SomeInt()
 | 
						|
    elif issubclass(tp, str):
 | 
						|
        result = SomeString()
 | 
						|
    elif tp is unicode:
 | 
						|
        result = SomeUnicode()
 | 
						|
    elif tp is tuple:
 | 
						|
        result = SomeTuple()
 | 
						|
        #result = SomeTuple(items = [self.immutablevalue(e, need_const) for e in x])
 | 
						|
    elif tp is float:
 | 
						|
        result = SomeFloat()
 | 
						|
    elif tp is list:
 | 
						|
        #else:
 | 
						|
        #    listdef = ListDef(self, s_ImpossibleValue)
 | 
						|
        #    for e in x:
 | 
						|
        #        listdef.generalize(self.annotation_from_example(e))
 | 
						|
        result = SomeList()
 | 
						|
    elif tp is dict:
 | 
						|
##        dictdef = DictDef(self, 
 | 
						|
##        s_ImpossibleValue,
 | 
						|
##        s_ImpossibleValue,
 | 
						|
##        is_r_dict = tp is r_dict)
 | 
						|
##        if tp is r_dict:
 | 
						|
##            s_eqfn = self.immutablevalue(x.key_eq)
 | 
						|
##            s_hashfn = self.immutablevalue(x.key_hash)
 | 
						|
##            dictdef.dictkey.update_rdict_annotations(s_eqfn,
 | 
						|
##                s_hashfn)
 | 
						|
##        for ek, ev in x.iteritems():
 | 
						|
##            dictdef.generalize_key(self.annotation_from_example(ek))
 | 
						|
##            dictdef.generalize_value(self.annotation_from_example(ev))
 | 
						|
        result = SomeDict()
 | 
						|
    elif tp is types.ModuleType:
 | 
						|
        result = SomeModule()
 | 
						|
    elif callable(x):
 | 
						|
        #if hasattr(x, '__self__') and x.__self__ is not None:
 | 
						|
        #    # for cases like 'l.append' where 'l' is a global constant list
 | 
						|
        #    s_self = self.immutablevalue(x.__self__, need_const)
 | 
						|
        #    result = s_self.find_method(x.__name__)
 | 
						|
        #    if result is None:
 | 
						|
        #        result = SomeObject()
 | 
						|
        #elif hasattr(x, 'im_self') and hasattr(x, 'im_func'):
 | 
						|
        #    # on top of PyPy, for cases like 'l.append' where 'l' is a
 | 
						|
        #    # global constant list, the find_method() returns non-None
 | 
						|
        #    s_self = self.immutablevalue(x.im_self, need_const)
 | 
						|
        #    result = s_self.find_method(x.im_func.__name__)
 | 
						|
        #else:
 | 
						|
        #    result = None
 | 
						|
        #if result is None:
 | 
						|
        #    if (self.annotator.policy.allow_someobjects
 | 
						|
        #        and getattr(x, '__module__', None) == '__builtin__'
 | 
						|
        #        # XXX note that the print support functions are __builtin__
 | 
						|
        #        and tp not in (types.FunctionType, types.MethodType)):
 | 
						|
        ##        result = SomeObject()
 | 
						|
        #        result.knowntype = tp # at least for types this needs to be correct
 | 
						|
        #    else:
 | 
						|
        #        result = SomePBC([self.getdesc(x)])
 | 
						|
        if tp is types.BuiltinFunctionType or tp is types.BuiltinMethodType:
 | 
						|
            result = SomeBuiltinFunction()
 | 
						|
        elif hasattr(x, 'im_func'):
 | 
						|
            result = SomeMethod()
 | 
						|
        elif hasattr(x, 'func_code'):
 | 
						|
            result = SomeFunction()
 | 
						|
        elif hasattr(x, '__class__'):
 | 
						|
            if x.__class__ is type:
 | 
						|
                result = SomeClass(x)
 | 
						|
            else:
 | 
						|
                result = SomeInstance(SomeClass(x.__class__))
 | 
						|
        elif tp is types.ClassType:
 | 
						|
            result = SomeClass(x)
 | 
						|
    elif x is None:
 | 
						|
        return s_None
 | 
						|
    elif hasattr(x, '__class__'):
 | 
						|
        result = SomeInstance(SomeClass(x.__class__))
 | 
						|
    else:
 | 
						|
        result = SomeObject()
 | 
						|
    # XXX here we might want to consider stuff like
 | 
						|
    # buffer, slice, etc. etc. Let's leave it for now
 | 
						|
    return result
 | 
						|
 | 
						|
def unionof(first, other):
 | 
						|
    return first.unionof(other)
 |