PageRenderTime 699ms CodeModel.GetById 9ms RepoModel.GetById 1ms app.codeStats 0ms

/pypy/annotation/model.py

https://bitbucket.org/pypy/pypy/
Python | 799 lines | 728 code | 52 blank | 19 comment | 58 complexity | a15215416db2f4e531c957be0e545eee MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. """
  2. This file defines the 'subset' SomeValue classes.
  3. An instance of a SomeValue class stands for a Python object that has some
  4. known properties, for example that is known to be a list of non-negative
  5. integers. Each instance can be considered as an object that is only
  6. 'partially defined'. Another point of view is that each instance is a
  7. generic element in some specific subset of the set of all objects.
  8. """
  9. # Old terminology still in use here and there:
  10. # SomeValue means one of the SomeXxx classes in this file.
  11. # Cell is an instance of one of these classes.
  12. #
  13. # Think about cells as potato-shaped circles in a diagram:
  14. # ______________________________________________________
  15. # / SomeObject() \
  16. # / ___________________________ ______________ \
  17. # | / SomeInteger(nonneg=False) \____ / SomeString() \ \
  18. # | / __________________________ \ | | |
  19. # | | / SomeInteger(nonneg=True) \ | | "hello" | |
  20. # | | | 0 42 _________/ | \______________/ |
  21. # | \ -3 \________________/ / |
  22. # \ \ -5 _____/ /
  23. # \ \________________________/ 3.1416 /
  24. # \_____________________________________________________/
  25. #
  26. from types import BuiltinFunctionType, MethodType, FunctionType
  27. import pypy
  28. from pypy.tool import descriptor
  29. from pypy.tool.pairtype import pair, extendabletype
  30. from pypy.rlib.rarithmetic import r_uint, r_ulonglong, base_int
  31. from pypy.rlib.rarithmetic import r_singlefloat, r_longfloat
  32. import inspect, weakref
  33. DEBUG = False # set to False to disable recording of debugging information
  34. class State(object):
  35. # A global attribute :-( Patch it with 'True' to enable checking of
  36. # the no_nul attribute...
  37. check_str_without_nul = False
  38. TLS = State()
  39. class SomeObject(object):
  40. """The set of all objects. Each instance stands
  41. for an arbitrary object about which nothing is known."""
  42. __metaclass__ = extendabletype
  43. knowntype = object
  44. immutable = False
  45. def __eq__(self, other):
  46. return (self.__class__ is other.__class__ and
  47. self.__dict__ == other.__dict__)
  48. def __ne__(self, other):
  49. return not (self == other)
  50. def __repr__(self):
  51. try:
  52. reprdict = TLS.reprdict
  53. except AttributeError:
  54. reprdict = TLS.reprdict = {}
  55. if self in reprdict:
  56. kwds = '...'
  57. else:
  58. reprdict[self] = True
  59. try:
  60. items = self.__dict__.items()
  61. items.sort()
  62. args = []
  63. for k, v in items:
  64. m = getattr(self, 'fmt_' + k, repr)
  65. r = m(v)
  66. if r is not None:
  67. args.append('%s=%s'%(k, r))
  68. kwds = ', '.join(args)
  69. finally:
  70. del reprdict[self]
  71. return '%s(%s)' % (self.__class__.__name__, kwds)
  72. def fmt_knowntype(self, t):
  73. return t.__name__
  74. def contains(self, other):
  75. if self == other:
  76. return True
  77. try:
  78. TLS.no_side_effects_in_union += 1
  79. except AttributeError:
  80. TLS.no_side_effects_in_union = 1
  81. try:
  82. try:
  83. return pair(self, other).union() == self
  84. except UnionError:
  85. return False
  86. finally:
  87. TLS.no_side_effects_in_union -= 1
  88. def is_constant(self):
  89. d = self.__dict__
  90. return 'const' in d or 'const_box' in d
  91. def is_immutable_constant(self):
  92. return self.immutable and 'const' in self.__dict__
  93. # delegate accesses to 'const' to accesses to 'const_box.value',
  94. # where const_box is a Constant. XXX the idea is to eventually
  95. # use systematically 'const_box' instead of 'const' for
  96. # non-immutable constant annotations
  97. class ConstAccessDelegator(object):
  98. def __get__(self, obj, cls=None):
  99. return obj.const_box.value
  100. const = ConstAccessDelegator()
  101. del ConstAccessDelegator
  102. # for debugging, record where each instance comes from
  103. # this is disabled if DEBUG is set to False
  104. def __new__(cls, *args, **kw):
  105. new = super(SomeObject, cls).__new__
  106. if new is object.__new__:
  107. # Since python 2.6, object.__new__ warns
  108. # when parameters are passed
  109. self = new(cls)
  110. else:
  111. self = new(cls, *args, **kw)
  112. if DEBUG:
  113. try:
  114. bookkeeper = pypy.annotation.bookkeeper.getbookkeeper()
  115. position_key = bookkeeper.position_key
  116. except AttributeError:
  117. pass
  118. else:
  119. bookkeeper._isomeobject_coming_from[self] = position_key, None
  120. return self
  121. def origin(self):
  122. bookkeeper = pypy.annotation.bookkeeper.getbookkeeper()
  123. if bookkeeper is None:
  124. return None
  125. return bookkeeper._isomeobject_coming_from.get(self, (None, None))[0]
  126. origin = property(origin)
  127. def caused_by_merge(self):
  128. bookkeeper = pypy.annotation.bookkeeper.getbookkeeper()
  129. if bookkeeper is None:
  130. return None
  131. return bookkeeper._isomeobject_coming_from.get(self, (None, None))[1]
  132. def set_caused_by_merge(self, nvalue):
  133. bookkeeper = pypy.annotation.bookkeeper.getbookkeeper()
  134. if bookkeeper is None:
  135. return
  136. bookkeeper._isomeobject_coming_from[self] = self.origin, nvalue
  137. caused_by_merge = property(caused_by_merge, set_caused_by_merge)
  138. del set_caused_by_merge
  139. def can_be_none(self):
  140. return True
  141. def nonnoneify(self):
  142. return self
  143. class SomeFloat(SomeObject):
  144. "Stands for a float or an integer."
  145. knowntype = float # if we don't know if it's a float or an int,
  146. # pretend it's a float.
  147. immutable = True
  148. def __eq__(self, other):
  149. if (type(self) is SomeFloat and type(other) is SomeFloat and
  150. self.is_constant() and other.is_constant()):
  151. from pypy.rlib.rfloat import isnan, copysign
  152. # NaN unpleasantness.
  153. if isnan(self.const) and isnan(other.const):
  154. return True
  155. # 0.0 vs -0.0 unpleasantness.
  156. if not self.const and not other.const:
  157. return copysign(1., self.const) == copysign(1., other.const)
  158. #
  159. return super(SomeFloat, self).__eq__(other)
  160. def can_be_none(self):
  161. return False
  162. class SomeSingleFloat(SomeObject):
  163. "Stands for an r_singlefloat."
  164. # No operation supported, not even union with a regular float
  165. knowntype = r_singlefloat
  166. immutable = True
  167. def can_be_none(self):
  168. return False
  169. class SomeLongFloat(SomeObject):
  170. "Stands for an r_longfloat."
  171. # No operation supported, not even union with a regular float
  172. knowntype = r_longfloat
  173. immutable = True
  174. def can_be_none(self):
  175. return False
  176. class SomeInteger(SomeFloat):
  177. "Stands for an object which is known to be an integer."
  178. knowntype = int
  179. # size is in multiples of C's sizeof(long)!
  180. def __init__(self, nonneg=False, unsigned=None, knowntype=None):
  181. assert (knowntype is None or knowntype is int or
  182. issubclass(knowntype, base_int))
  183. if knowntype is None:
  184. if unsigned:
  185. knowntype = r_uint
  186. else:
  187. knowntype = int
  188. elif unsigned is not None:
  189. raise TypeError('Conflicting specification for SomeInteger')
  190. self.knowntype = knowntype
  191. unsigned = self.knowntype(-1) > 0
  192. self.nonneg = unsigned or nonneg
  193. self.unsigned = unsigned # pypy.rlib.rarithmetic.r_uint
  194. class SomeBool(SomeInteger):
  195. "Stands for true or false."
  196. knowntype = bool
  197. nonneg = True
  198. unsigned = False
  199. def __init__(self):
  200. pass
  201. class SomeStringOrUnicode(SomeObject):
  202. immutable = True
  203. can_be_None=False
  204. no_nul = False # No NUL character in the string.
  205. def __init__(self, can_be_None=False, no_nul=False):
  206. if can_be_None:
  207. self.can_be_None = True
  208. if no_nul:
  209. self.no_nul = True
  210. def can_be_none(self):
  211. return self.can_be_None
  212. def __eq__(self, other):
  213. if self.__class__ is not other.__class__:
  214. return False
  215. d1 = self.__dict__
  216. d2 = other.__dict__
  217. if not TLS.check_str_without_nul:
  218. d1 = d1.copy(); d1['no_nul'] = 0 # ignored
  219. d2 = d2.copy(); d2['no_nul'] = 0 # ignored
  220. return d1 == d2
  221. class SomeString(SomeStringOrUnicode):
  222. "Stands for an object which is known to be a string."
  223. knowntype = str
  224. def nonnoneify(self):
  225. return SomeString(can_be_None=False, no_nul=self.no_nul)
  226. class SomeUnicodeString(SomeStringOrUnicode):
  227. "Stands for an object which is known to be an unicode string"
  228. knowntype = unicode
  229. def nonnoneify(self):
  230. return SomeUnicodeString(can_be_None=False, no_nul=self.no_nul)
  231. class SomeChar(SomeString):
  232. "Stands for an object known to be a string of length 1."
  233. can_be_None = False
  234. def __init__(self, no_nul=False): # no 'can_be_None' argument here
  235. if no_nul:
  236. self.no_nul = True
  237. class SomeUnicodeCodePoint(SomeUnicodeString):
  238. "Stands for an object known to be a unicode codepoint."
  239. can_be_None = False
  240. def __init__(self, no_nul=False): # no 'can_be_None' argument here
  241. if no_nul:
  242. self.no_nul = True
  243. SomeString.basestringclass = SomeString
  244. SomeString.basecharclass = SomeChar
  245. SomeUnicodeString.basestringclass = SomeUnicodeString
  246. SomeUnicodeString.basecharclass = SomeUnicodeCodePoint
  247. class SomeList(SomeObject):
  248. "Stands for a homogenous list of any length."
  249. knowntype = list
  250. def __init__(self, listdef):
  251. self.listdef = listdef
  252. def __eq__(self, other):
  253. if self.__class__ is not other.__class__:
  254. return False
  255. if not self.listdef.same_as(other.listdef):
  256. return False
  257. selfdic = self.__dict__.copy()
  258. otherdic = other.__dict__.copy()
  259. del selfdic['listdef']
  260. del otherdic['listdef']
  261. return selfdic == otherdic
  262. def can_be_none(self):
  263. return True
  264. class SomeTuple(SomeObject):
  265. "Stands for a tuple of known length."
  266. knowntype = tuple
  267. immutable = True
  268. def __init__(self, items):
  269. self.items = tuple(items) # tuple of s_xxx elements
  270. for i in items:
  271. if not i.is_constant():
  272. break
  273. else:
  274. self.const = tuple([i.const for i in items])
  275. def can_be_none(self):
  276. return False
  277. class SomeDict(SomeObject):
  278. "Stands for a dict."
  279. knowntype = dict
  280. def __init__(self, dictdef):
  281. self.dictdef = dictdef
  282. def __eq__(self, other):
  283. if self.__class__ is not other.__class__:
  284. return False
  285. if not self.dictdef.same_as(other.dictdef):
  286. return False
  287. selfdic = self.__dict__.copy()
  288. otherdic = other.__dict__.copy()
  289. del selfdic['dictdef']
  290. del otherdic['dictdef']
  291. return selfdic == otherdic
  292. def can_be_none(self):
  293. return True
  294. def fmt_const(self, const):
  295. if len(const) < 20:
  296. return repr(const)
  297. else:
  298. return '{...%s...}'%(len(const),)
  299. class SomeIterator(SomeObject):
  300. "Stands for an iterator returning objects from a given container."
  301. knowntype = type(iter([])) # arbitrarily chose seqiter as the type
  302. def __init__(self, s_container, *variant):
  303. self.variant = variant
  304. self.s_container = s_container
  305. def can_be_none(self):
  306. return False
  307. class SomeInstance(SomeObject):
  308. "Stands for an instance of a (user-defined) class."
  309. def __init__(self, classdef, can_be_None=False, flags={}):
  310. self.classdef = classdef
  311. self.knowntype = classdef or object
  312. self.can_be_None = can_be_None
  313. self.flags = flags
  314. def fmt_knowntype(self, kt):
  315. return None
  316. def fmt_classdef(self, cdef):
  317. if cdef is None:
  318. return 'object'
  319. else:
  320. return cdef.name
  321. def fmt_flags(self, flags):
  322. if flags:
  323. return repr(flags)
  324. else:
  325. return None
  326. def can_be_none(self):
  327. return self.can_be_None
  328. def nonnoneify(self):
  329. return SomeInstance(self.classdef, can_be_None=False)
  330. class SomePBC(SomeObject):
  331. """Stands for a global user instance, built prior to the analysis,
  332. or a set of such instances."""
  333. immutable = True
  334. def __init__(self, descriptions, can_be_None=False, subset_of=None):
  335. # descriptions is a set of Desc instances
  336. descriptions = set(descriptions)
  337. self.descriptions = descriptions
  338. self.can_be_None = can_be_None
  339. self.subset_of = subset_of
  340. self.simplify()
  341. if self.isNone():
  342. self.knowntype = type(None)
  343. self.const = None
  344. else:
  345. knowntype = reduce(commonbase,
  346. [x.knowntype for x in descriptions])
  347. if knowntype == type(Exception):
  348. knowntype = type
  349. if knowntype != object:
  350. self.knowntype = knowntype
  351. if len(descriptions) == 1 and not can_be_None:
  352. # hack for the convenience of direct callers to SomePBC():
  353. # only if there is a single object in descriptions
  354. desc, = descriptions
  355. if desc.pyobj is not None:
  356. self.const = desc.pyobj
  357. def any_description(self):
  358. return iter(self.descriptions).next()
  359. def getKind(self):
  360. "Return the common Desc class of all descriptions in this PBC."
  361. kinds = {}
  362. for x in self.descriptions:
  363. assert type(x).__name__.endswith('Desc') # avoid import nightmares
  364. kinds[x.__class__] = True
  365. assert len(kinds) <= 1, (
  366. "mixing several kinds of PBCs: %r" % (kinds.keys(),))
  367. if not kinds:
  368. raise ValueError("no 'kind' on the 'None' PBC")
  369. return kinds.keys()[0]
  370. def simplify(self):
  371. if self.descriptions:
  372. # We check that the set only contains a single kind of Desc instance
  373. kind = self.getKind()
  374. # then we remove unnecessary entries in self.descriptions:
  375. # some MethodDescs can be 'shadowed' by others
  376. if len(self.descriptions) > 1:
  377. kind.simplify_desc_set(self.descriptions)
  378. else:
  379. assert self.can_be_None, "use s_ImpossibleValue"
  380. def isNone(self):
  381. return len(self.descriptions) == 0
  382. def can_be_none(self):
  383. return self.can_be_None
  384. def nonnoneify(self):
  385. if self.isNone():
  386. return s_ImpossibleValue
  387. else:
  388. return SomePBC(self.descriptions, can_be_None=False)
  389. def fmt_descriptions(self, pbis):
  390. if hasattr(self, 'const'):
  391. return None
  392. else:
  393. return '{...%s...}'%(len(pbis),)
  394. def fmt_knowntype(self, kt):
  395. if self.is_constant():
  396. return None
  397. else:
  398. return kt.__name__
  399. class SomeGenericCallable(SomeObject):
  400. """ Stands for external callable with known signature
  401. """
  402. def __init__(self, args, result):
  403. self.args_s = args
  404. self.s_result = result
  405. def can_be_None(self):
  406. return True
  407. class SomeBuiltin(SomeObject):
  408. "Stands for a built-in function or method with special-cased analysis."
  409. knowntype = BuiltinFunctionType # == BuiltinMethodType
  410. immutable = True
  411. def __init__(self, analyser, s_self=None, methodname=None):
  412. if isinstance(analyser, MethodType):
  413. analyser = descriptor.InstanceMethod(
  414. analyser.im_func,
  415. analyser.im_self,
  416. analyser.im_class)
  417. self.analyser = analyser
  418. self.s_self = s_self
  419. self.methodname = methodname
  420. def can_be_none(self):
  421. return False
  422. class SomeBuiltinMethod(SomeBuiltin):
  423. """ Stands for a built-in method which has got special meaning
  424. """
  425. knowntype = MethodType
  426. class SomeExternalObject(SomeObject):
  427. """Stands for an object of 'external' type. External types have a Repr
  428. controlled by pypy.rpython.extregistry."""
  429. def __init__(self, knowntype):
  430. self.knowntype = knowntype
  431. def can_be_none(self):
  432. return True
  433. class SomeImpossibleValue(SomeObject):
  434. """The empty set. Instances are placeholders for objects that
  435. will never show up at run-time, e.g. elements of an empty list."""
  436. immutable = True
  437. annotationcolor = (160,160,160)
  438. def can_be_none(self):
  439. return False
  440. s_None = SomePBC([], can_be_None=True)
  441. s_Bool = SomeBool()
  442. s_ImpossibleValue = SomeImpossibleValue()
  443. s_Str0 = SomeString(no_nul=True)
  444. # ____________________________________________________________
  445. # weakrefs
  446. class SomeWeakRef(SomeObject):
  447. knowntype = weakref.ReferenceType
  448. immutable = True
  449. def __init__(self, classdef):
  450. # 'classdef' is None for known-to-be-dead weakrefs.
  451. self.classdef = classdef
  452. # ____________________________________________________________
  453. # memory addresses
  454. from pypy.rpython.lltypesystem import llmemory
  455. class SomeAddress(SomeObject):
  456. immutable = True
  457. def can_be_none(self):
  458. return False
  459. def is_null_address(self):
  460. return self.is_immutable_constant() and not self.const
  461. # The following class is used to annotate the intermediate value that
  462. # appears in expressions of the form:
  463. # addr.signed[offset] and addr.signed[offset] = value
  464. class SomeTypedAddressAccess(SomeObject):
  465. def __init__(self, type):
  466. self.type = type
  467. def can_be_none(self):
  468. return False
  469. #____________________________________________________________
  470. # annotation of low-level types
  471. from pypy.rpython.lltypesystem import lltype
  472. from pypy.rpython.ootypesystem import ootype
  473. class SomePtr(SomeObject):
  474. knowntype = lltype._ptr
  475. immutable = True
  476. def __init__(self, ll_ptrtype):
  477. assert isinstance(ll_ptrtype, lltype.Ptr)
  478. self.ll_ptrtype = ll_ptrtype
  479. def can_be_none(self):
  480. return False
  481. class SomeInteriorPtr(SomePtr):
  482. def __init__(self, ll_ptrtype):
  483. assert isinstance(ll_ptrtype, lltype.InteriorPtr)
  484. self.ll_ptrtype = ll_ptrtype
  485. class SomeLLADTMeth(SomeObject):
  486. immutable = True
  487. def __init__(self, ll_ptrtype, func):
  488. self.ll_ptrtype = ll_ptrtype
  489. self.func = func
  490. def can_be_none(self):
  491. return False
  492. class SomeOOObject(SomeObject):
  493. def __init__(self):
  494. self.ootype = ootype.Object
  495. class SomeOOClass(SomeObject):
  496. def __init__(self, ootype):
  497. self.ootype = ootype
  498. class SomeOOInstance(SomeObject):
  499. def __init__(self, ootype, can_be_None=False):
  500. self.ootype = ootype
  501. self.can_be_None = can_be_None
  502. class SomeOOBoundMeth(SomeObject):
  503. immutable = True
  504. def __init__(self, ootype, name):
  505. self.ootype = ootype
  506. self.name = name
  507. class SomeOOStaticMeth(SomeObject):
  508. immutable = True
  509. def __init__(self, method):
  510. self.method = method
  511. annotation_to_ll_map = [
  512. (SomeSingleFloat(), lltype.SingleFloat),
  513. (s_None, lltype.Void), # also matches SomeImpossibleValue()
  514. (s_Bool, lltype.Bool),
  515. (SomeFloat(), lltype.Float),
  516. (SomeLongFloat(), lltype.LongFloat),
  517. (SomeChar(), lltype.Char),
  518. (SomeUnicodeCodePoint(), lltype.UniChar),
  519. (SomeAddress(), llmemory.Address),
  520. ]
  521. def annotation_to_lltype(s_val, info=None):
  522. if isinstance(s_val, SomeOOInstance):
  523. return s_val.ootype
  524. if isinstance(s_val, SomeOOStaticMeth):
  525. return s_val.method
  526. if isinstance(s_val, SomeOOClass):
  527. return ootype.Class
  528. if isinstance(s_val, SomeOOObject):
  529. return s_val.ootype
  530. if isinstance(s_val, SomeInteriorPtr):
  531. p = s_val.ll_ptrtype
  532. if 0 in p.offsets:
  533. assert list(p.offsets).count(0) == 1
  534. return lltype.Ptr(lltype.Ptr(p.PARENTTYPE)._interior_ptr_type_with_index(p.TO))
  535. else:
  536. return lltype.Ptr(p.PARENTTYPE)
  537. if isinstance(s_val, SomePtr):
  538. return s_val.ll_ptrtype
  539. if type(s_val) is SomeInteger:
  540. return lltype.build_number(None, s_val.knowntype)
  541. for witness, T in annotation_to_ll_map:
  542. if witness.contains(s_val):
  543. return T
  544. if info is None:
  545. info = ''
  546. else:
  547. info = '%s: ' % info
  548. raise ValueError("%sshould return a low-level type,\ngot instead %r" % (
  549. info, s_val))
  550. ll_to_annotation_map = dict([(ll, ann) for ann, ll in annotation_to_ll_map])
  551. def lltype_to_annotation(T):
  552. try:
  553. s = ll_to_annotation_map.get(T)
  554. except TypeError:
  555. s = None # unhashable T, e.g. a Ptr(GcForwardReference())
  556. if s is None:
  557. if isinstance(T, lltype.Typedef):
  558. return lltype_to_annotation(T.OF)
  559. if isinstance(T, lltype.Number):
  560. return SomeInteger(knowntype=T._type)
  561. if isinstance(T, (ootype.Instance, ootype.BuiltinType)):
  562. return SomeOOInstance(T)
  563. elif isinstance(T, ootype.StaticMethod):
  564. return SomeOOStaticMeth(T)
  565. elif T == ootype.Class:
  566. return SomeOOClass(ootype.ROOT)
  567. elif T == ootype.Object:
  568. return SomeOOObject()
  569. elif isinstance(T, lltype.InteriorPtr):
  570. return SomeInteriorPtr(T)
  571. else:
  572. return SomePtr(T)
  573. else:
  574. return s
  575. def ll_to_annotation(v):
  576. if v is None:
  577. # i think we can only get here in the case of void-returning
  578. # functions
  579. return s_None
  580. if isinstance(v, lltype._interior_ptr):
  581. ob = v._parent
  582. if ob is None:
  583. raise RuntimeError
  584. T = lltype.InteriorPtr(lltype.typeOf(ob), v._T, v._offsets)
  585. return SomeInteriorPtr(T)
  586. return lltype_to_annotation(lltype.typeOf(v))
  587. # ____________________________________________________________
  588. class UnionError(Exception):
  589. """Signals an suspicious attempt at taking the union of
  590. deeply incompatible SomeXxx instances."""
  591. def unionof(*somevalues):
  592. "The most precise SomeValue instance that contains all the values."
  593. try:
  594. s1, s2 = somevalues
  595. except ValueError:
  596. s1 = s_ImpossibleValue
  597. for s2 in somevalues:
  598. if s1 != s2:
  599. s1 = pair(s1, s2).union()
  600. else:
  601. # this is just a performance shortcut
  602. if s1 != s2:
  603. s1 = pair(s1, s2).union()
  604. if DEBUG:
  605. if s1.caused_by_merge is None and len(somevalues) > 1:
  606. s1.caused_by_merge = somevalues
  607. return s1
  608. def isdegenerated(s_value):
  609. return s_value.__class__ is SomeObject and s_value.knowntype is not type
  610. # make knowntypedata dictionary
  611. def add_knowntypedata(ktd, truth, vars, s_obj):
  612. for v in vars:
  613. ktd[(truth, v)] = s_obj
  614. def merge_knowntypedata(ktd1, ktd2):
  615. r = {}
  616. for truth_v in ktd1:
  617. if truth_v in ktd2:
  618. r[truth_v] = unionof(ktd1[truth_v], ktd2[truth_v])
  619. return r
  620. def not_const(s_obj):
  621. if s_obj.is_constant():
  622. new_s_obj = SomeObject.__new__(s_obj.__class__)
  623. dic = new_s_obj.__dict__ = s_obj.__dict__.copy()
  624. if 'const' in dic:
  625. del new_s_obj.const
  626. else:
  627. del new_s_obj.const_box
  628. s_obj = new_s_obj
  629. return s_obj
  630. # ____________________________________________________________
  631. # internal
  632. def commonbase(cls1, cls2): # XXX single inheritance only XXX hum
  633. l1 = inspect.getmro(cls1)
  634. l2 = inspect.getmro(cls2)
  635. if l1[-1] != object:
  636. l1 = l1 + (object,)
  637. if l2[-1] != object:
  638. l2 = l2 + (object,)
  639. for x in l1:
  640. if x in l2:
  641. return x
  642. assert 0, "couldn't get to commonbase of %r and %r" % (cls1, cls2)
  643. def missing_operation(cls, name):
  644. def default_op(*args):
  645. if args and isinstance(args[0], tuple):
  646. flattened = tuple(args[0]) + args[1:]
  647. else:
  648. flattened = args
  649. for arg in flattened:
  650. if arg.__class__ is SomeObject and arg.knowntype is not type:
  651. return SomeObject()
  652. bookkeeper = pypy.annotation.bookkeeper.getbookkeeper()
  653. bookkeeper.warning("no precise annotation supplied for %s%r" % (name, args))
  654. return s_ImpossibleValue
  655. setattr(cls, name, default_op)
  656. class HarmlesslyBlocked(Exception):
  657. """Raised by the unaryop/binaryop to signal a harmless kind of
  658. BlockedInference: the current block is blocked, but not in a way
  659. that gives 'Blocked block' errors at the end of annotation."""
  660. def read_can_only_throw(opimpl, *args):
  661. can_only_throw = getattr(opimpl, "can_only_throw", None)
  662. if can_only_throw is None or isinstance(can_only_throw, list):
  663. return can_only_throw
  664. return can_only_throw(*args)
  665. #
  666. # safety check that no-one is trying to make annotation and translation
  667. # faster by providing the -O option to Python.
  668. try:
  669. assert False
  670. except AssertionError:
  671. pass # fine
  672. else:
  673. raise RuntimeError("The annotator relies on 'assert' statements from the\n"
  674. "\tannotated program: you cannot run it with 'python -O'.")
  675. # this has the side-effect of registering the unary and binary operations
  676. from pypy.annotation.unaryop import UNARY_OPERATIONS
  677. from pypy.annotation.binaryop import BINARY_OPERATIONS