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)
|