PageRenderTime 66ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/pypy/objspace/std/typeobject.py

https://bitbucket.org/pypy/pypy/
Python | 1293 lines | 1074 code | 125 blank | 94 comment | 198 complexity | 6f03bb987698a97ff9451e4546719a33 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import weakref
  2. from pypy.interpreter import gateway
  3. from pypy.interpreter.baseobjspace import W_Root, SpaceCache
  4. from pypy.interpreter.error import OperationError, oefmt
  5. from pypy.interpreter.function import Function, StaticMethod
  6. from pypy.interpreter.typedef import (
  7. weakref_descr, GetSetProperty, dict_descr, Member, TypeDef)
  8. from pypy.interpreter.astcompiler.misc import mangle
  9. from pypy.module.__builtin__ import abstractinst
  10. from rpython.rlib.jit import (promote, elidable_promote, we_are_jitted,
  11. elidable, dont_look_inside, unroll_safe)
  12. from rpython.rlib.objectmodel import current_object_addr_as_int, compute_hash
  13. from rpython.rlib.objectmodel import we_are_translated
  14. from rpython.rlib.rarithmetic import intmask, r_uint
  15. class MutableCell(W_Root):
  16. def unwrap_cell(self, space):
  17. raise NotImplementedError("abstract base")
  18. class ObjectMutableCell(MutableCell):
  19. def __init__(self, w_value=None):
  20. self.w_value = w_value
  21. def unwrap_cell(self, space):
  22. return self.w_value
  23. def __repr__(self):
  24. return "<ObjectMutableCell: %s>" % (self.w_value, )
  25. class IntMutableCell(MutableCell):
  26. def __init__(self, intvalue):
  27. self.intvalue = intvalue
  28. def unwrap_cell(self, space):
  29. return space.wrap(self.intvalue)
  30. def __repr__(self):
  31. return "<IntMutableCell: %s>" % (self.intvalue, )
  32. def unwrap_cell(space, w_value):
  33. if isinstance(w_value, MutableCell):
  34. return w_value.unwrap_cell(space)
  35. return w_value
  36. def write_cell(space, w_cell, w_value):
  37. from pypy.objspace.std.intobject import W_IntObject
  38. if w_cell is None:
  39. # attribute does not exist at all, write it without a cell first
  40. return w_value
  41. if isinstance(w_cell, ObjectMutableCell):
  42. w_cell.w_value = w_value
  43. return None
  44. elif isinstance(w_cell, IntMutableCell) and type(w_value) is W_IntObject:
  45. w_cell.intvalue = w_value.intval
  46. return None
  47. elif space.is_w(w_cell, w_value):
  48. # If the new value and the current value are the same, don't
  49. # create a level of indirection, or mutate the version.
  50. return None
  51. if type(w_value) is W_IntObject:
  52. return IntMutableCell(w_value.intval)
  53. else:
  54. return ObjectMutableCell(w_value)
  55. class VersionTag(object):
  56. pass
  57. class MethodCache(object):
  58. def __init__(self, space):
  59. SIZE = 1 << space.config.objspace.std.methodcachesizeexp
  60. self.versions = [None] * SIZE
  61. self.names = [None] * SIZE
  62. self.lookup_where = [(None, None)] * SIZE
  63. if space.config.objspace.std.withmethodcachecounter:
  64. self.hits = {}
  65. self.misses = {}
  66. def clear(self):
  67. None_None = (None, None)
  68. for i in range(len(self.versions)):
  69. self.versions[i] = None
  70. for i in range(len(self.names)):
  71. self.names[i] = None
  72. for i in range(len(self.lookup_where)):
  73. self.lookup_where[i] = None_None
  74. class _Global(object):
  75. weakref_warning_printed = False
  76. _global = _Global()
  77. class Layout(object):
  78. """A Layout is attached to every W_TypeObject to represent the
  79. layout of instances. Some W_TypeObjects share the same layout.
  80. If a W_TypeObject is a base of another, then the layout of
  81. the first is either the same or a parent layout of the second.
  82. The Layouts have single inheritance, unlike W_TypeObjects.
  83. """
  84. _immutable_ = True
  85. def __init__(self, typedef, nslots, base_layout=None):
  86. self.typedef = typedef
  87. self.nslots = nslots
  88. self.base_layout = base_layout
  89. def issublayout(self, parent):
  90. while self is not parent:
  91. self = self.base_layout
  92. if self is None:
  93. return False
  94. return True
  95. # possible values of compares_by_identity_status
  96. UNKNOWN = 0
  97. COMPARES_BY_IDENTITY = 1
  98. OVERRIDES_EQ_CMP_OR_HASH = 2
  99. class W_TypeObject(W_Root):
  100. lazyloaders = {} # can be overridden by specific instances
  101. # the version_tag changes if the dict or the inheritance hierarchy changes
  102. # other changes to the type (e.g. the name) leave it unchanged
  103. _version_tag = None
  104. _immutable_fields_ = ["flag_heaptype",
  105. "flag_cpytype",
  106. "flag_abstract?",
  107. "flag_sequence_bug_compat",
  108. "flag_map_or_seq", # '?' or 'M' or 'S'
  109. "compares_by_identity_status?",
  110. 'hasuserdel',
  111. 'weakrefable',
  112. 'hasdict',
  113. 'layout',
  114. 'terminator',
  115. '_version_tag?',
  116. 'name?',
  117. 'mro_w?[*]',
  118. ]
  119. # wether the class has an overridden __getattribute__
  120. # (False is a conservative default, fixed during real usage)
  121. uses_object_getattribute = False
  122. # for the IdentityDictStrategy
  123. compares_by_identity_status = UNKNOWN
  124. # used to cache the type's __new__ function
  125. w_new_function = None
  126. @dont_look_inside
  127. def __init__(self, space, name, bases_w, dict_w,
  128. overridetypedef=None, force_new_layout=False):
  129. self.space = space
  130. self.name = name
  131. self.bases_w = bases_w
  132. self.dict_w = dict_w
  133. self.hasdict = False
  134. self.hasuserdel = False
  135. self.weakrefable = False
  136. self.w_doc = space.w_None
  137. self.weak_subclasses = []
  138. self.flag_heaptype = False
  139. self.flag_cpytype = False
  140. self.flag_abstract = False
  141. self.flag_sequence_bug_compat = False
  142. self.flag_map_or_seq = '?' # '?' means "don't know, check otherwise"
  143. if overridetypedef is not None:
  144. assert not force_new_layout
  145. layout = setup_builtin_type(self, overridetypedef)
  146. else:
  147. layout = setup_user_defined_type(self, force_new_layout)
  148. self.layout = layout
  149. if not is_mro_purely_of_types(self.mro_w):
  150. pass
  151. else:
  152. # the _version_tag should change, whenever the content of
  153. # dict_w of any of the types in the mro changes, or if the mro
  154. # itself changes
  155. self._version_tag = VersionTag()
  156. from pypy.objspace.std.mapdict import DictTerminator, NoDictTerminator
  157. # if the typedef has a dict, then the rpython-class does all the dict
  158. # management, which means from the point of view of mapdict there is no
  159. # dict. However, W_InstanceObjects are an exception to this
  160. from pypy.module.__builtin__.interp_classobj import W_InstanceObject
  161. typedef = self.layout.typedef
  162. if (self.hasdict and not typedef.hasdict or
  163. typedef is W_InstanceObject.typedef):
  164. self.terminator = DictTerminator(space, self)
  165. else:
  166. self.terminator = NoDictTerminator(space, self)
  167. def __repr__(self):
  168. "NOT_RPYTHON"
  169. return '<W_TypeObject %r at 0x%x>' % (self.name, id(self))
  170. def mutated(self, key):
  171. """
  172. The type is being mutated. key is either the string containing the
  173. specific attribute which is being deleted/set or None to indicate a
  174. generic mutation.
  175. """
  176. space = self.space
  177. assert self.is_heaptype() or self.is_cpytype()
  178. self.uses_object_getattribute = False
  179. # ^^^ conservative default, fixed during real usage
  180. if (key is None or key == '__eq__' or
  181. key == '__cmp__' or key == '__hash__'):
  182. self.compares_by_identity_status = UNKNOWN
  183. if space.config.objspace.std.newshortcut:
  184. self.w_new_function = None
  185. if self._version_tag is not None:
  186. self._version_tag = VersionTag()
  187. subclasses_w = self.get_subclasses()
  188. for w_subclass in subclasses_w:
  189. assert isinstance(w_subclass, W_TypeObject)
  190. w_subclass.mutated(key)
  191. def version_tag(self):
  192. if not we_are_jitted() or self.is_heaptype():
  193. return self._version_tag
  194. # prebuilt objects cannot get their version_tag changed
  195. return self._pure_version_tag()
  196. @elidable_promote()
  197. def _pure_version_tag(self):
  198. return self._version_tag
  199. def getattribute_if_not_from_object(self):
  200. """ this method returns the applevel __getattribute__ if that is not
  201. the one from object, in which case it returns None """
  202. from pypy.objspace.descroperation import object_getattribute
  203. if not we_are_jitted():
  204. if not self.uses_object_getattribute:
  205. # slow path: look for a custom __getattribute__ on the class
  206. w_descr = self.lookup('__getattribute__')
  207. # if it was not actually overriden in the class, we remember this
  208. # fact for the next time.
  209. if w_descr is object_getattribute(self.space):
  210. self.uses_object_getattribute = True
  211. else:
  212. return w_descr
  213. return None
  214. # in the JIT case, just use a lookup, because it is folded away
  215. # correctly using the version_tag
  216. w_descr = self.lookup('__getattribute__')
  217. if w_descr is not object_getattribute(self.space):
  218. return w_descr
  219. def has_object_getattribute(self):
  220. return self.getattribute_if_not_from_object() is None
  221. def compares_by_identity(self):
  222. from pypy.objspace.descroperation import object_hash, type_eq
  223. #
  224. if self.compares_by_identity_status != UNKNOWN:
  225. # fast path
  226. return self.compares_by_identity_status == COMPARES_BY_IDENTITY
  227. #
  228. default_hash = object_hash(self.space)
  229. my_eq = self.lookup('__eq__')
  230. overrides_eq = (my_eq and my_eq is not type_eq(self.space))
  231. overrides_eq_cmp_or_hash = (overrides_eq or
  232. self.lookup('__cmp__') or
  233. self.lookup('__hash__') is not default_hash)
  234. if overrides_eq_cmp_or_hash:
  235. self.compares_by_identity_status = OVERRIDES_EQ_CMP_OR_HASH
  236. else:
  237. self.compares_by_identity_status = COMPARES_BY_IDENTITY
  238. return self.compares_by_identity_status == COMPARES_BY_IDENTITY
  239. def ready(self):
  240. for w_base in self.bases_w:
  241. if not isinstance(w_base, W_TypeObject):
  242. continue
  243. w_base.add_subclass(self)
  244. # compute a tuple that fully describes the instance layout
  245. def get_full_instance_layout(self):
  246. layout = self.layout
  247. return (layout, self.hasdict, self.weakrefable)
  248. def compute_default_mro(self):
  249. return compute_C3_mro(self.space, self)
  250. def getdictvalue(self, space, attr):
  251. version_tag = self.version_tag()
  252. if version_tag is not None:
  253. return unwrap_cell(
  254. space,
  255. self._pure_getdictvalue_no_unwrapping(
  256. space, version_tag, attr))
  257. w_value = self._getdictvalue_no_unwrapping(space, attr)
  258. return unwrap_cell(space, w_value)
  259. def _getdictvalue_no_unwrapping(self, space, attr):
  260. w_value = self.dict_w.get(attr, None)
  261. if self.lazyloaders and w_value is None:
  262. if attr in self.lazyloaders:
  263. # very clever next line: it forces the attr string
  264. # to be interned.
  265. space.new_interned_str(attr)
  266. loader = self.lazyloaders[attr]
  267. del self.lazyloaders[attr]
  268. w_value = loader()
  269. if w_value is not None: # None means no such attribute
  270. self.dict_w[attr] = w_value
  271. return w_value
  272. return w_value
  273. @elidable
  274. def _pure_getdictvalue_no_unwrapping(self, space, version_tag, attr):
  275. return self._getdictvalue_no_unwrapping(space, attr)
  276. def setdictvalue(self, space, name, w_value):
  277. if not self.is_heaptype():
  278. raise oefmt(space.w_TypeError,
  279. "can't set attributes on type object '%N'", self)
  280. if name == "__del__" and name not in self.dict_w:
  281. msg = ("a __del__ method added to an existing type will not be "
  282. "called")
  283. space.warn(space.wrap(msg), space.w_RuntimeWarning)
  284. version_tag = self.version_tag()
  285. if version_tag is not None:
  286. w_curr = self._pure_getdictvalue_no_unwrapping(
  287. space, version_tag, name)
  288. w_value = write_cell(space, w_curr, w_value)
  289. if w_value is None:
  290. return True
  291. self.mutated(name)
  292. self.dict_w[name] = w_value
  293. return True
  294. def deldictvalue(self, space, key):
  295. if self.lazyloaders:
  296. self._cleanup_() # force un-lazification
  297. if not (self.is_heaptype() or self.is_cpytype()):
  298. raise oefmt(space.w_TypeError,
  299. "can't delete attributes on type object '%N'", self)
  300. try:
  301. del self.dict_w[key]
  302. except KeyError:
  303. return False
  304. else:
  305. self.mutated(key)
  306. return True
  307. def lookup(self, name):
  308. # note that this doesn't call __get__ on the result at all
  309. space = self.space
  310. return self.lookup_where_with_method_cache(name)[1]
  311. def lookup_where(self, name):
  312. space = self.space
  313. return self.lookup_where_with_method_cache(name)
  314. @unroll_safe
  315. def lookup_starting_at(self, w_starttype, name):
  316. space = self.space
  317. look = False
  318. for w_class in self.mro_w:
  319. if w_class is w_starttype:
  320. look = True
  321. elif look:
  322. w_value = w_class.getdictvalue(space, name)
  323. if w_value is not None:
  324. return w_value
  325. return None
  326. @unroll_safe
  327. def _lookup(self, key):
  328. # nowadays, only called from ../../tool/ann_override.py
  329. space = self.space
  330. for w_class in self.mro_w:
  331. w_value = w_class.getdictvalue(space, key)
  332. if w_value is not None:
  333. return w_value
  334. return None
  335. @unroll_safe
  336. def _lookup_where(self, key):
  337. # like _lookup() but also returns the parent class in which the
  338. # attribute was found
  339. space = self.space
  340. for w_class in self.mro_w:
  341. w_value = w_class.getdictvalue(space, key)
  342. if w_value is not None:
  343. return w_class, w_value
  344. return None, None
  345. def _lookup_where_all_typeobjects(self, key):
  346. # like _lookup_where(), but when we know that self.mro_w only
  347. # contains W_TypeObjects. (It differs from _lookup_where() mostly
  348. # from a JIT point of view: it cannot invoke arbitrary Python code.)
  349. space = self.space
  350. for w_class in self.mro_w:
  351. assert isinstance(w_class, W_TypeObject)
  352. w_value = w_class._getdictvalue_no_unwrapping(space, key)
  353. if w_value is not None:
  354. return w_class, w_value
  355. return None, None
  356. def lookup_where_with_method_cache(self, name):
  357. space = self.space
  358. promote(self)
  359. version_tag = promote(self.version_tag())
  360. if version_tag is None:
  361. tup = self._lookup_where(name)
  362. return tup
  363. tup_w = self._pure_lookup_where_with_method_cache(name, version_tag)
  364. w_class, w_value = tup_w
  365. if isinstance(w_value, MutableCell):
  366. return w_class, w_value.unwrap_cell(space)
  367. return tup_w # don't make a new tuple, reuse the old one
  368. @elidable
  369. def _pure_lookup_where_with_method_cache(self, name, version_tag):
  370. space = self.space
  371. cache = space.fromcache(MethodCache)
  372. SHIFT2 = r_uint.BITS - space.config.objspace.std.methodcachesizeexp
  373. SHIFT1 = SHIFT2 - 5
  374. version_tag_as_int = current_object_addr_as_int(version_tag)
  375. # ^^^Note: if the version_tag object is moved by a moving GC, the
  376. # existing method cache entries won't be found any more; new
  377. # entries will be created based on the new address. The
  378. # assumption is that the version_tag object won't keep moving all
  379. # the time - so using the fast current_object_addr_as_int() instead
  380. # of a slower solution like hash() is still a good trade-off.
  381. hash_name = compute_hash(name)
  382. product = intmask(version_tag_as_int * hash_name)
  383. method_hash = (r_uint(product) ^ (r_uint(product) << SHIFT1)) >> SHIFT2
  384. # ^^^Note2: we used to just take product>>SHIFT2, but on 64-bit
  385. # platforms SHIFT2 is really large, and we loose too much information
  386. # that way (as shown by failures of the tests that typically have
  387. # method names like 'f' who hash to a number that has only ~33 bits).
  388. cached_version_tag = cache.versions[method_hash]
  389. if cached_version_tag is version_tag:
  390. cached_name = cache.names[method_hash]
  391. if cached_name is name:
  392. tup = cache.lookup_where[method_hash]
  393. if space.config.objspace.std.withmethodcachecounter:
  394. cache.hits[name] = cache.hits.get(name, 0) + 1
  395. # print "hit", self, name
  396. return tup
  397. tup = self._lookup_where_all_typeobjects(name)
  398. cache.versions[method_hash] = version_tag
  399. cache.names[method_hash] = name
  400. cache.lookup_where[method_hash] = tup
  401. if space.config.objspace.std.withmethodcachecounter:
  402. cache.misses[name] = cache.misses.get(name, 0) + 1
  403. # print "miss", self, name
  404. return tup
  405. def check_user_subclass(self, w_subtype):
  406. space = self.space
  407. if not isinstance(w_subtype, W_TypeObject):
  408. raise oefmt(space.w_TypeError,
  409. "X is not a type object ('%T')", w_subtype)
  410. if not w_subtype.issubtype(self):
  411. raise oefmt(space.w_TypeError,
  412. "%N.__new__(%N): %N is not a subtype of %N",
  413. self, w_subtype, w_subtype, self)
  414. if self.layout.typedef is not w_subtype.layout.typedef:
  415. raise oefmt(space.w_TypeError,
  416. "%N.__new__(%N) is not safe, use %N.__new__()",
  417. self, w_subtype, w_subtype)
  418. return w_subtype
  419. def _cleanup_(self):
  420. "NOT_RPYTHON. Forces the lazy attributes to be computed."
  421. if 'lazyloaders' in self.__dict__:
  422. for attr in self.lazyloaders.keys():
  423. self.getdictvalue(self.space, attr)
  424. del self.lazyloaders
  425. def getdict(self, space):
  426. from pypy.objspace.std.classdict import ClassDictStrategy
  427. from pypy.objspace.std.dictmultiobject import W_DictObject
  428. if self.lazyloaders:
  429. self._cleanup_() # force un-lazification
  430. strategy = space.fromcache(ClassDictStrategy)
  431. storage = strategy.erase(self)
  432. return W_DictObject(space, strategy, storage)
  433. def is_heaptype(self):
  434. return self.flag_heaptype
  435. def is_cpytype(self):
  436. return self.flag_cpytype
  437. def is_abstract(self):
  438. return self.flag_abstract
  439. def set_abstract(self, abstract):
  440. self.flag_abstract = bool(abstract)
  441. def issubtype(self, w_type):
  442. promote(self)
  443. promote(w_type)
  444. if we_are_jitted():
  445. version_tag1 = self.version_tag()
  446. version_tag2 = w_type.version_tag()
  447. if version_tag1 is not None and version_tag2 is not None:
  448. res = _pure_issubtype(self, w_type, version_tag1, version_tag2)
  449. return res
  450. return _issubtype(self, w_type)
  451. def get_module(self):
  452. space = self.space
  453. if self.is_heaptype():
  454. return self.getdictvalue(space, '__module__')
  455. else:
  456. dot = self.name.find('.')
  457. if dot >= 0:
  458. mod = self.name[:dot]
  459. else:
  460. mod = "__builtin__"
  461. return space.wrap(mod)
  462. def getname(self, space):
  463. if self.is_heaptype():
  464. return self.name
  465. else:
  466. dot = self.name.find('.')
  467. if dot >= 0:
  468. return self.name[dot+1:]
  469. else:
  470. return self.name
  471. def add_subclass(self, w_subclass):
  472. space = self.space
  473. if not space.config.translation.rweakref:
  474. # We don't have weakrefs! In this case, every class stores
  475. # subclasses in a non-weak list. ALL CLASSES LEAK! To make
  476. # the user aware of this annoying fact, print a warning.
  477. if we_are_translated() and not _global.weakref_warning_printed:
  478. from rpython.rlib import debug
  479. debug.debug_print("Warning: no weakref support in this PyPy. "
  480. "All user-defined classes will leak!")
  481. _global.weakref_warning_printed = True
  482. assert isinstance(w_subclass, W_TypeObject)
  483. newref = weakref.ref(w_subclass)
  484. for i in range(len(self.weak_subclasses)):
  485. ref = self.weak_subclasses[i]
  486. if ref() is None:
  487. self.weak_subclasses[i] = newref
  488. return
  489. else:
  490. self.weak_subclasses.append(newref)
  491. def remove_subclass(self, w_subclass):
  492. space = self.space
  493. for i in range(len(self.weak_subclasses)):
  494. ref = self.weak_subclasses[i]
  495. if ref() is w_subclass:
  496. del self.weak_subclasses[i]
  497. return
  498. def get_subclasses(self):
  499. space = self.space
  500. subclasses_w = []
  501. for ref in self.weak_subclasses:
  502. w_ob = ref()
  503. if w_ob is not None:
  504. subclasses_w.append(w_ob)
  505. return subclasses_w
  506. # for now, weakref support for W_TypeObject is hard to get automatically
  507. _lifeline_ = None
  508. def getweakref(self):
  509. return self._lifeline_
  510. def setweakref(self, space, weakreflifeline):
  511. self._lifeline_ = weakreflifeline
  512. def delweakref(self):
  513. self._lifeline_ = None
  514. def descr_call(self, space, __args__):
  515. promote(self)
  516. # invoke the __new__ of the type
  517. if not we_are_jitted():
  518. # note that the annotator will figure out that self.w_new_function
  519. # can only be None if the newshortcut config option is not set
  520. w_newfunc = self.w_new_function
  521. else:
  522. # for the JIT it is better to take the slow path because normal lookup
  523. # is nicely optimized, but the self.w_new_function attribute is not
  524. # known to the JIT
  525. w_newfunc = None
  526. if w_newfunc is None:
  527. w_newtype, w_newdescr = self.lookup_where('__new__')
  528. if w_newdescr is None: # see test_crash_mro_without_object_1
  529. raise oefmt(space.w_TypeError, "cannot create '%N' instances",
  530. self)
  531. w_newfunc = space.get(w_newdescr, self)
  532. if (space.config.objspace.std.newshortcut and
  533. not we_are_jitted() and
  534. isinstance(w_newtype, W_TypeObject)):
  535. self.w_new_function = w_newfunc
  536. w_newobject = space.call_obj_args(w_newfunc, self, __args__)
  537. call_init = space.isinstance_w(w_newobject, self)
  538. # maybe invoke the __init__ of the type
  539. if (call_init and not (space.is_w(self, space.w_type) and
  540. not __args__.keywords and len(__args__.arguments_w) == 1)):
  541. w_descr = space.lookup(w_newobject, '__init__')
  542. if w_descr is not None: # see test_crash_mro_without_object_2
  543. w_result = space.get_and_call_args(w_descr, w_newobject,
  544. __args__)
  545. if not space.is_w(w_result, space.w_None):
  546. raise oefmt(space.w_TypeError,
  547. "__init__() should return None")
  548. return w_newobject
  549. def descr_repr(self, space):
  550. w_mod = self.get_module()
  551. if w_mod is None or not space.isinstance_w(w_mod, space.w_str):
  552. mod = None
  553. else:
  554. mod = space.str_w(w_mod)
  555. if not self.is_heaptype():
  556. kind = 'type'
  557. else:
  558. kind = 'class'
  559. if mod is not None and mod != '__builtin__':
  560. return space.wrap("<%s '%s.%s'>" % (kind, mod, self.getname(space)))
  561. else:
  562. return space.wrap("<%s '%s'>" % (kind, self.name))
  563. def descr_getattribute(self, space, w_name):
  564. name = space.str_w(w_name)
  565. w_descr = space.lookup(self, name)
  566. if w_descr is not None:
  567. if space.is_data_descr(w_descr):
  568. w_get = space.lookup(w_descr, "__get__")
  569. if w_get is not None:
  570. return space.get_and_call_function(w_get, w_descr, self,
  571. space.type(self))
  572. w_value = self.lookup(name)
  573. if w_value is not None:
  574. # __get__(None, type): turns e.g. functions into unbound methods
  575. return space.get(w_value, space.w_None, self)
  576. if w_descr is not None:
  577. return space.get(w_descr, self)
  578. raise oefmt(space.w_AttributeError,
  579. "type object '%N' has no attribute %R", self, w_name)
  580. def descr_eq(self, space, w_other):
  581. if not isinstance(w_other, W_TypeObject):
  582. return space.w_NotImplemented
  583. return space.is_(self, w_other)
  584. def descr_ne(self, space, w_other):
  585. if not isinstance(w_other, W_TypeObject):
  586. return space.w_NotImplemented
  587. return space.newbool(not space.is_w(self, w_other))
  588. def descr__new__(space, w_typetype, w_name, w_bases=None, w_dict=None):
  589. "This is used to create user-defined classes only."
  590. # XXX check types
  591. w_typetype = _precheck_for_new(space, w_typetype)
  592. # special case for type(x)
  593. if (space.is_w(space.type(w_typetype), space.w_type) and w_bases is None and
  594. w_dict is None):
  595. return space.type(w_name)
  596. else:
  597. return _create_new_type(space, w_typetype, w_name, w_bases, w_dict)
  598. def _create_new_type(space, w_typetype, w_name, w_bases, w_dict):
  599. # this is in its own function because we want the special case 'type(x)'
  600. # above to be seen by the jit.
  601. if w_bases is None or w_dict is None:
  602. raise oefmt(space.w_TypeError, "type() takes 1 or 3 arguments")
  603. bases_w = space.fixedview(w_bases)
  604. w_winner = w_typetype
  605. for base in bases_w:
  606. w_typ = space.type(base)
  607. if space.is_w(w_typ, space.w_classobj):
  608. continue # special-case old-style classes
  609. if space.issubtype_w(w_winner, w_typ):
  610. continue
  611. if space.issubtype_w(w_typ, w_winner):
  612. w_winner = w_typ
  613. continue
  614. raise oefmt(space.w_TypeError,
  615. "metaclass conflict: the metaclass of a derived class must"
  616. " be a (non-strict) subclass of the metaclasses of all its"
  617. " bases")
  618. if not space.is_w(w_winner, w_typetype):
  619. newfunc = space.getattr(w_winner, space.wrap('__new__'))
  620. if not space.is_w(newfunc, space.getattr(space.w_type, space.wrap('__new__'))):
  621. return space.call_function(newfunc, w_winner, w_name, w_bases, w_dict)
  622. w_typetype = w_winner
  623. name = space.str_w(w_name)
  624. assert isinstance(name, str)
  625. dict_w = {}
  626. dictkeys_w = space.listview(w_dict)
  627. for w_key in dictkeys_w:
  628. key = space.str_w(w_key)
  629. dict_w[key] = space.getitem(w_dict, w_key)
  630. w_type = space.allocate_instance(W_TypeObject, w_typetype)
  631. W_TypeObject.__init__(w_type, space, name, bases_w or [space.w_object],
  632. dict_w)
  633. w_type.ready()
  634. return w_type
  635. def _precheck_for_new(space, w_type):
  636. if not isinstance(w_type, W_TypeObject):
  637. raise oefmt(space.w_TypeError, "X is not a type object (%T)", w_type)
  638. return w_type
  639. # ____________________________________________________________
  640. def _check(space, w_type, msg="descriptor is for 'type'"):
  641. if not isinstance(w_type, W_TypeObject):
  642. raise OperationError(space.w_TypeError, space.wrap(msg))
  643. return w_type
  644. def descr_get__name__(space, w_type):
  645. w_type = _check(space, w_type)
  646. return space.wrap(w_type.getname(space))
  647. def descr_set__name__(space, w_type, w_value):
  648. w_type = _check(space, w_type)
  649. if not w_type.is_heaptype():
  650. raise oefmt(space.w_TypeError, "can't set %N.__name__", w_type)
  651. name = space.str_w(w_value)
  652. if '\x00' in name:
  653. raise oefmt(space.w_ValueError, "__name__ must not contain null bytes")
  654. w_type.name = name
  655. def descr_get__mro__(space, w_type):
  656. w_type = _check(space, w_type)
  657. return space.newtuple(w_type.mro_w)
  658. def descr_mro(space, w_type):
  659. """Return a type's method resolution order."""
  660. w_type = _check(space, w_type, "expected type")
  661. return space.newlist(w_type.compute_default_mro())
  662. def descr_get__bases__(space, w_type):
  663. w_type = _check(space, w_type)
  664. return space.newtuple(w_type.bases_w)
  665. def mro_subclasses(space, w_type, temp):
  666. temp.append((w_type, w_type.mro_w))
  667. compute_mro(w_type)
  668. for w_sc in w_type.get_subclasses():
  669. assert isinstance(w_sc, W_TypeObject)
  670. mro_subclasses(space, w_sc, temp)
  671. def descr_set__bases__(space, w_type, w_value):
  672. # this assumes all app-level type objects are W_TypeObject
  673. w_type = _check(space, w_type)
  674. if not w_type.is_heaptype():
  675. raise oefmt(space.w_TypeError, "can't set %N.__bases__", w_type)
  676. if not space.isinstance_w(w_value, space.w_tuple):
  677. raise oefmt(space.w_TypeError,
  678. "can only assign tuple to %N.__bases__, not %T",
  679. w_type, w_value)
  680. newbases_w = space.fixedview(w_value)
  681. if len(newbases_w) == 0:
  682. raise oefmt(space.w_TypeError,
  683. "can only assign non-empty tuple to %N.__bases__, not ()",
  684. w_type)
  685. for w_newbase in newbases_w:
  686. if isinstance(w_newbase, W_TypeObject):
  687. if w_type in w_newbase.compute_default_mro():
  688. raise oefmt(space.w_TypeError,
  689. "a __bases__ item causes an inheritance cycle")
  690. w_oldbestbase = check_and_find_best_base(space, w_type.bases_w)
  691. w_newbestbase = check_and_find_best_base(space, newbases_w)
  692. oldlayout = w_oldbestbase.get_full_instance_layout()
  693. newlayout = w_newbestbase.get_full_instance_layout()
  694. if oldlayout != newlayout:
  695. raise oefmt(space.w_TypeError,
  696. "__bases__ assignment: '%N' object layout differs from "
  697. "'%N'", w_newbestbase, w_oldbestbase)
  698. # invalidate the version_tag of all the current subclasses
  699. w_type.mutated(None)
  700. # now we can go ahead and change 'w_type.bases_w'
  701. saved_bases_w = w_type.bases_w
  702. temp = []
  703. try:
  704. for w_oldbase in saved_bases_w:
  705. if isinstance(w_oldbase, W_TypeObject):
  706. w_oldbase.remove_subclass(w_type)
  707. w_type.bases_w = newbases_w
  708. for w_newbase in newbases_w:
  709. if isinstance(w_newbase, W_TypeObject):
  710. w_newbase.add_subclass(w_type)
  711. # try to recompute all MROs
  712. mro_subclasses(space, w_type, temp)
  713. except:
  714. for cls, old_mro in temp:
  715. cls.mro_w = old_mro
  716. w_type.bases_w = saved_bases_w
  717. raise
  718. if (w_type.version_tag() is not None and
  719. not is_mro_purely_of_types(w_type.mro_w)):
  720. # Disable method cache if the hierarchy isn't pure.
  721. w_type._version_tag = None
  722. for w_subclass in w_type.get_subclasses():
  723. if isinstance(w_subclass, W_TypeObject):
  724. w_subclass._version_tag = None
  725. def descr__base(space, w_type):
  726. w_type = _check(space, w_type)
  727. return find_best_base(w_type.bases_w)
  728. def descr__doc(space, w_type):
  729. if space.is_w(w_type, space.w_type):
  730. return space.wrap("""type(object) -> the object's type
  731. type(name, bases, dict) -> a new type""")
  732. w_type = _check(space, w_type)
  733. if not w_type.is_heaptype():
  734. return w_type.w_doc
  735. w_result = w_type.getdictvalue(space, '__doc__')
  736. if w_result is None:
  737. return space.w_None
  738. else:
  739. return space.get(w_result, space.w_None, w_type)
  740. def descr__flags(space, w_type):
  741. from copy_reg import _HEAPTYPE
  742. _CPYTYPE = 1 # used for non-heap types defined in C
  743. _ABSTRACT = 1 << 20
  744. #
  745. w_type = _check(space, w_type)
  746. flags = 0
  747. if w_type.flag_heaptype:
  748. flags |= _HEAPTYPE
  749. if w_type.flag_cpytype:
  750. flags |= _CPYTYPE
  751. if w_type.flag_abstract:
  752. flags |= _ABSTRACT
  753. return space.wrap(flags)
  754. def descr_get__module(space, w_type):
  755. w_type = _check(space, w_type)
  756. return w_type.get_module()
  757. def descr_set__module(space, w_type, w_value):
  758. w_type = _check(space, w_type)
  759. w_type.setdictvalue(space, '__module__', w_value)
  760. def descr_get___abstractmethods__(space, w_type):
  761. w_type = _check(space, w_type)
  762. # type itself has an __abstractmethods__ descriptor (this). Don't return it
  763. if not space.is_w(w_type, space.w_type):
  764. w_result = w_type.getdictvalue(space, "__abstractmethods__")
  765. if w_result is not None:
  766. return w_result
  767. raise oefmt(space.w_AttributeError, "__abstractmethods__")
  768. def descr_set___abstractmethods__(space, w_type, w_new):
  769. w_type = _check(space, w_type)
  770. w_type.setdictvalue(space, "__abstractmethods__", w_new)
  771. w_type.set_abstract(space.is_true(w_new))
  772. def descr_del___abstractmethods__(space, w_type):
  773. w_type = _check(space, w_type)
  774. if not w_type.deldictvalue(space, "__abstractmethods__"):
  775. raise oefmt(space.w_AttributeError, "__abstractmethods__")
  776. w_type.set_abstract(False)
  777. def descr___subclasses__(space, w_type):
  778. """Return the list of immediate subclasses."""
  779. w_type = _check(space, w_type)
  780. return space.newlist(w_type.get_subclasses())
  781. # ____________________________________________________________
  782. @gateway.unwrap_spec(w_obj=W_TypeObject)
  783. def type_issubtype(w_obj, space, w_sub):
  784. return space.newbool(
  785. abstractinst.p_recursive_issubclass_w(space, w_sub, w_obj))
  786. @gateway.unwrap_spec(w_obj=W_TypeObject)
  787. def type_isinstance(w_obj, space, w_inst):
  788. return space.newbool(
  789. abstractinst.p_recursive_isinstance_type_w(space, w_inst, w_obj))
  790. def type_get_dict(space, w_cls):
  791. w_cls = _check(space, w_cls)
  792. from pypy.objspace.std.dictproxyobject import W_DictProxyObject
  793. w_dict = w_cls.getdict(space)
  794. if w_dict is None:
  795. return space.w_None
  796. return W_DictProxyObject(w_dict)
  797. W_TypeObject.typedef = TypeDef("type",
  798. __new__ = gateway.interp2app(descr__new__),
  799. __name__ = GetSetProperty(descr_get__name__, descr_set__name__),
  800. __bases__ = GetSetProperty(descr_get__bases__, descr_set__bases__),
  801. __base__ = GetSetProperty(descr__base),
  802. __mro__ = GetSetProperty(descr_get__mro__),
  803. __dict__=GetSetProperty(type_get_dict),
  804. __doc__ = GetSetProperty(descr__doc),
  805. mro = gateway.interp2app(descr_mro),
  806. __flags__ = GetSetProperty(descr__flags),
  807. __module__ = GetSetProperty(descr_get__module, descr_set__module),
  808. __abstractmethods__ = GetSetProperty(descr_get___abstractmethods__,
  809. descr_set___abstractmethods__,
  810. descr_del___abstractmethods__),
  811. __subclasses__ = gateway.interp2app(descr___subclasses__),
  812. __weakref__ = weakref_descr,
  813. __instancecheck__ = gateway.interp2app(type_isinstance),
  814. __subclasscheck__ = gateway.interp2app(type_issubtype),
  815. __call__ = gateway.interp2app(W_TypeObject.descr_call),
  816. __repr__ = gateway.interp2app(W_TypeObject.descr_repr),
  817. __getattribute__ = gateway.interp2app(W_TypeObject.descr_getattribute),
  818. __eq__ = gateway.interp2app(W_TypeObject.descr_eq),
  819. __ne__ = gateway.interp2app(W_TypeObject.descr_ne),
  820. )
  821. # ____________________________________________________________
  822. # Initialization of type objects
  823. def find_best_base(bases_w):
  824. """The best base is one of the bases in the given list: the one
  825. whose layout a new type should use as a starting point.
  826. """
  827. w_bestbase = None
  828. for w_candidate in bases_w:
  829. if not isinstance(w_candidate, W_TypeObject):
  830. continue
  831. if w_bestbase is None:
  832. w_bestbase = w_candidate # for now
  833. continue
  834. cand_layout = w_candidate.layout
  835. best_layout = w_bestbase.layout
  836. if (cand_layout is not best_layout and
  837. cand_layout.issublayout(best_layout)):
  838. w_bestbase = w_candidate
  839. return w_bestbase
  840. def check_and_find_best_base(space, bases_w):
  841. """The best base is one of the bases in the given list: the one
  842. whose layout a new type should use as a starting point.
  843. This version checks that bases_w is an acceptable tuple of bases.
  844. """
  845. w_bestbase = find_best_base(bases_w)
  846. if w_bestbase is None:
  847. raise oefmt(space.w_TypeError,
  848. "a new-style class can't have only classic bases")
  849. if not w_bestbase.layout.typedef.acceptable_as_base_class:
  850. raise oefmt(space.w_TypeError,
  851. "type '%N' is not an acceptable base class", w_bestbase)
  852. # check that all other bases' layouts are "super-layouts" of the
  853. # bestbase's layout
  854. best_layout = w_bestbase.layout
  855. for w_base in bases_w:
  856. if isinstance(w_base, W_TypeObject):
  857. layout = w_base.layout
  858. if not best_layout.issublayout(layout):
  859. raise oefmt(space.w_TypeError,
  860. "instance layout conflicts in multiple inheritance")
  861. return w_bestbase
  862. def copy_flags_from_bases(w_self, w_bestbase):
  863. hasoldstylebase = False
  864. for w_base in w_self.bases_w:
  865. if not isinstance(w_base, W_TypeObject):
  866. hasoldstylebase = True
  867. continue
  868. w_self.hasdict = w_self.hasdict or w_base.hasdict
  869. w_self.hasuserdel = w_self.hasuserdel or w_base.hasuserdel
  870. w_self.weakrefable = w_self.weakrefable or w_base.weakrefable
  871. return hasoldstylebase
  872. def create_all_slots(w_self, hasoldstylebase, w_bestbase, force_new_layout):
  873. base_layout = w_bestbase.layout
  874. index_next_extra_slot = base_layout.nslots
  875. space = w_self.space
  876. dict_w = w_self.dict_w
  877. if '__slots__' not in dict_w:
  878. wantdict = True
  879. wantweakref = True
  880. else:
  881. wantdict = False
  882. wantweakref = False
  883. w_slots = dict_w['__slots__']
  884. if (space.isinstance_w(w_slots, space.w_str) or
  885. space.isinstance_w(w_slots, space.w_unicode)):
  886. slot_names_w = [w_slots]
  887. else:
  888. slot_names_w = space.unpackiterable(w_slots)
  889. for w_slot_name in slot_names_w:
  890. slot_name = space.str_w(w_slot_name)
  891. if slot_name == '__dict__':
  892. if wantdict or w_bestbase.hasdict:
  893. raise oefmt(space.w_TypeError,
  894. "__dict__ slot disallowed: we already got one")
  895. wantdict = True
  896. elif slot_name == '__weakref__':
  897. if wantweakref or w_bestbase.weakrefable:
  898. raise oefmt(space.w_TypeError,
  899. "__weakref__ slot disallowed: we already got one")
  900. wantweakref = True
  901. else:
  902. index_next_extra_slot = create_slot(w_self, slot_name,
  903. index_next_extra_slot)
  904. wantdict = wantdict or hasoldstylebase
  905. if wantdict:
  906. create_dict_slot(w_self)
  907. if wantweakref:
  908. create_weakref_slot(w_self)
  909. if '__del__' in dict_w:
  910. w_self.hasuserdel = True
  911. #
  912. if index_next_extra_slot == base_layout.nslots and not force_new_layout:
  913. return base_layout
  914. else:
  915. return Layout(base_layout.typedef, index_next_extra_slot,
  916. base_layout=base_layout)
  917. def create_slot(w_self, slot_name, index_next_extra_slot):
  918. space = w_self.space
  919. if not valid_slot_name(slot_name):
  920. raise oefmt(space.w_TypeError, "__slots__ must be identifiers")
  921. # create member
  922. slot_name = mangle(slot_name, w_self.name)
  923. if slot_name not in w_self.dict_w:
  924. # Force interning of slot names.
  925. slot_name = space.str_w(space.new_interned_str(slot_name))
  926. # in cpython it is ignored less, but we probably don't care
  927. member = Member(index_next_extra_slot, slot_name, w_self)
  928. index_next_extra_slot += 1
  929. w_self.dict_w[slot_name] = space.wrap(member)
  930. return index_next_extra_slot
  931. def create_dict_slot(w_self):
  932. if not w_self.hasdict:
  933. w_self.dict_w.setdefault('__dict__',
  934. w_self.space.wrap(dict_descr))
  935. w_self.hasdict = True
  936. def create_weakref_slot(w_self):
  937. if not w_self.weakrefable:
  938. w_self.dict_w.setdefault('__weakref__',
  939. w_self.space.wrap(weakref_descr))
  940. w_self.weakrefable = True
  941. def valid_slot_name(slot_name):
  942. if len(slot_name) == 0 or slot_name[0].isdigit():
  943. return False
  944. for c in slot_name:
  945. if not c.isalnum() and c != '_':
  946. return False
  947. return True
  948. def setup_user_defined_type(w_self, force_new_layout):
  949. if len(w_self.bases_w) == 0:
  950. w_self.bases_w = [w_self.space.w_object]
  951. w_bestbase = check_and_find_best_base(w_self.space, w_self.bases_w)
  952. w_self.flag_heaptype = True
  953. for w_base in w_self.bases_w:
  954. if not isinstance(w_base, W_TypeObject):
  955. continue
  956. w_self.flag_cpytype |= w_base.flag_cpytype
  957. w_self.flag_abstract |= w_base.flag_abstract
  958. if w_self.flag_map_or_seq == '?':
  959. w_self.flag_map_or_seq = w_base.flag_map_or_seq
  960. hasoldstylebase = copy_flags_from_bases(w_self, w_bestbase)
  961. layout = create_all_slots(w_self, hasoldstylebase, w_bestbase,
  962. force_new_layout)
  963. ensure_common_attributes(w_self)
  964. return layout
  965. def setup_builtin_type(w_self, instancetypedef):
  966. w_self.hasdict = instancetypedef.hasdict
  967. w_self.weakrefable = instancetypedef.weakrefable
  968. w_self.w_doc = w_self.space.wrap(instancetypedef.doc)
  969. ensure_common_attributes(w_self)
  970. w_self.flag_heaptype = instancetypedef.heaptype
  971. #
  972. # usually 'instancetypedef' is new, i.e. not seen in any base,
  973. # but not always (see Exception class)
  974. w_bestbase = find_best_base(w_self.bases_w)
  975. if w_bestbase is None:
  976. parent_layout = None
  977. else:
  978. parent_layout = w_bestbase.layout
  979. if parent_layout.typedef is instancetypedef:
  980. return parent_layout
  981. return Layout(instancetypedef, 0, base_layout=parent_layout)
  982. def ensure_common_attributes(w_self):
  983. ensure_static_new(w_self)
  984. w_self.dict_w.setdefault('__doc__', w_self.w_doc)
  985. if w_self.is_heaptype():
  986. ensure_module_attr(w_self)
  987. w_self.mro_w = [] # temporarily
  988. compute_mro(w_self)
  989. def ensure_static_new(w_self):
  990. # special-case __new__, as in CPython:
  991. # if it is a Function, turn it into a static method
  992. if '__new__' in w_self.dict_w:
  993. w_new = w_self.dict_w['__new__']
  994. if isinstance(w_new, Function):
  995. w_self.dict_w['__new__'] = StaticMethod(w_new)
  996. def ensure_module_attr(w_self):
  997. # initialize __module__ in the dict (user-defined types only)
  998. if '__module__' not in w_self.dict_w:
  999. space = w_self.space
  1000. caller = space.getexecutioncontext().gettopframe_nohidden()
  1001. if caller is not None:
  1002. w_globals = caller.get_w_globals()
  1003. w_name = space.finditem(w_globals, space.wrap('__name__'))
  1004. if w_name is not None:
  1005. w_self.dict_w['__module__'] = w_name
  1006. def compute_mro(w_self):
  1007. if w_self.is_heaptype():
  1008. space = w_self.space
  1009. w_metaclass = space.type(w_self)
  1010. w_where, w_mro_func = space.lookup_in_type_where(w_metaclass, 'mro')
  1011. if w_mro_func is not None and not space.is_w(w_where, space.w_type):
  1012. w_mro_meth = space.get(w_mro_func, w_self)
  1013. w_mro = space.call_function(w_mro_meth)
  1014. mro_w = space.fixedview(w_mro)
  1015. w_self.mro_w = validate_custom_mro(space, mro_w)
  1016. return # done
  1017. w_self.mro_w = w_self.compute_default_mro()[:]
  1018. def validate_custom_mro(space, mro_w):
  1019. # do some checking here. Note that unlike CPython, strange MROs
  1020. # cannot really segfault PyPy. At a minimum, we check that all
  1021. # the elements in the mro seem to be (old- or new-style) classes.
  1022. for w_class in mro_w:
  1023. if not space.abstract_isclass_w(w_class):
  1024. raise oefmt(space.w_TypeError, "mro() returned a non-class")
  1025. return mro_w
  1026. def is_mro_purely_of_types(mro_w):
  1027. for w_class in mro_w:
  1028. if not isinstance(w_class, W_TypeObject):
  1029. return False
  1030. return True
  1031. # ____________________________________________________________
  1032. def _issubtype(w_sub, w_type):
  1033. return w_type in w_sub.mro_w
  1034. @elidable_promote()
  1035. def _pure_issubtype(w_sub, w_type, version_tag1, version_tag2):
  1036. return _issubtype(w_sub, w_type)
  1037. # ____________________________________________________________
  1038. abstract_mro = gateway.applevel("""
  1039. def abstract_mro(klass):
  1040. # abstract/classic mro
  1041. mro = []
  1042. stack = [klass]
  1043. while stack:
  1044. klass = stack.pop()
  1045. if klass not in mro:
  1046. mro.append(klass)
  1047. if not isinstance(klass.__bases__, tuple):
  1048. raise TypeError, '__bases__ must be a tuple'
  1049. stack += klass.__bases__[::-1]
  1050. return mro
  1051. """, filename=__file__).interphook("abstract_mro")
  1052. def get_mro(space, klass):
  1053. if isinstance(klass, W_TypeObject):
  1054. return list(klass.mro_w)
  1055. else:
  1056. return space.unpackiterable(abstract_mro(space, klass))
  1057. def compute_C3_mro(space, cls):
  1058. order = []
  1059. orderlists = [get_mro(space, base) for base in cls.bases_w]
  1060. orderlists.append([cls] + cls.bases_w)
  1061. while orderlists:
  1062. for candidatelist in orderlists:
  1063. candidate = candidatelist[0]
  1064. if mro_blockinglist(candidate, orderlists) is None:
  1065. break # good candidate
  1066. else:
  1067. return mro_error(space, orderlists) # no candidate found
  1068. assert candidate not in order
  1069. order.append(candidate)
  1070. for i in range(len(orderlists) - 1, -1, -1):
  1071. if orderlists[i][0] is candidate:
  1072. del orderlists[i][0]
  1073. if len(orderlists[i]) == 0:
  1074. del orderlists[i]
  1075. return order
  1076. def mro_blockinglist(candidate, orderlists):
  1077. for lst in orderlists:
  1078. if candidate in lst[1:]:
  1079. return lst
  1080. return None # good candidate
  1081. def mro_error(space, orderlists):
  1082. cycle = []
  1083. candidate = orderlists[-1][0]
  1084. if candidate in orderlists[-1][1:]:
  1085. # explicit error message for this specific case
  1086. raise oefmt(space.w_TypeError, "duplicate base class '%N'", candidate)
  1087. while candidate not in cycle:
  1088. cycle.append(candidate)
  1089. nextblockinglist = mro_blockinglist(candidate, orderlists)
  1090. candidate = nextblockinglist[0]
  1091. del cycle[:cycle.index(candidate)]
  1092. cycle.append(candidate)
  1093. cycle.reverse()
  1094. names = [cls.getname(space) for cls in cycle]
  1095. raise oefmt(space.w_TypeError,
  1096. "cycle among base classes: %s", ' < '.join(names))
  1097. class TypeCache(SpaceCache):
  1098. def build(self, typedef):
  1099. "NOT_RPYTHON: initialization-time only."
  1100. from pypy.objspace.std.objectobject import W_ObjectObject
  1101. space = self.space
  1102. rawdict = typedef.rawdict
  1103. lazyloaders = {}
  1104. # compute the bases
  1105. if typedef is W_ObjectObject.typedef:
  1106. bases_w = []
  1107. else:
  1108. bases = typedef.bases or [W_ObjectObject.typedef]
  1109. bases_w = [space.gettypeobject(base) for base in bases]
  1110. # wrap everything
  1111. dict_w = {}
  1112. for descrname, descrvalue in rawdict.items():
  1113. dict_w[descrname] = space.wrap(descrvalue)
  1114. if typedef.applevel_subclasses_base is not None:
  1115. overridetypedef = typedef.applevel_subclasses_base.typedef
  1116. else:
  1117. overridetypedef = typedef
  1118. w_type = W_TypeObject(space, typedef.name, bases_w, dict_w,
  1119. overridetypedef=overridetypedef)
  1120. if typedef is not overridetypedef:
  1121. w_type.w_doc = space.wrap(typedef.doc)
  1122. if hasattr(typedef, 'flag_sequence_bug_compat'):
  1123. w_type.flag_sequence_bug_compat = typedef.flag_sequence_bug_compat
  1124. w_type.lazyloaders = lazyloaders
  1125. return w_type
  1126. def ready(self, w_type):
  1127. w_type.ready()