PageRenderTime 56ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/pypy/interpreter/typedef.py

https://bitbucket.org/pypy/pypy/
Python | 779 lines | 703 code | 48 blank | 28 comment | 37 complexity | c9c0628cd3c37585e8c3d70b41837bdf MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import py
  2. from pypy.interpreter.argument import Arguments
  3. from pypy.interpreter.baseobjspace import W_Root, DescrMismatch
  4. from pypy.interpreter.error import OperationError, oefmt
  5. from pypy.interpreter.gateway import (interp2app, BuiltinCode, unwrap_spec,
  6. WrappedDefault)
  7. from rpython.rlib.jit import promote
  8. from rpython.rlib.objectmodel import compute_identity_hash, specialize
  9. from rpython.tool.sourcetools import compile2, func_with_new_name
  10. class TypeDef(object):
  11. def __init__(self, __name, __base=None, __total_ordering__=None,
  12. __buffer=None, **rawdict):
  13. "NOT_RPYTHON: initialization-time only"
  14. self.name = __name
  15. if __base is None:
  16. bases = []
  17. elif isinstance(__base, tuple):
  18. bases = list(__base)
  19. else:
  20. bases = [__base]
  21. self.bases = bases
  22. # Used in cpyext to fill tp_as_buffer slots
  23. assert __buffer in {None, 'read-write', 'read'}, "Unknown value for __buffer"
  24. self.buffer = __buffer
  25. self.heaptype = False
  26. self.hasdict = '__dict__' in rawdict
  27. # no __del__: use an RPython _finalize_() method and register_finalizer
  28. assert '__del__' not in rawdict
  29. self.weakrefable = '__weakref__' in rawdict
  30. self.doc = rawdict.pop('__doc__', None)
  31. for base in bases:
  32. self.hasdict |= base.hasdict
  33. self.weakrefable |= base.weakrefable
  34. self.rawdict = {}
  35. self.acceptable_as_base_class = '__new__' in rawdict
  36. self.applevel_subclasses_base = None
  37. self.add_entries(**rawdict)
  38. assert __total_ordering__ in (None, 'auto'), "Unknown value for __total_ordering"
  39. if __total_ordering__ == 'auto':
  40. self.auto_total_ordering()
  41. def add_entries(self, **rawdict):
  42. # xxx fix the names of the methods to match what app-level expects
  43. for key, value in rawdict.items():
  44. if isinstance(value, (interp2app, GetSetProperty)):
  45. value.name = key
  46. self.rawdict.update(rawdict)
  47. def auto_total_ordering(self):
  48. assert '__lt__' in self.rawdict, "__total_ordering='auto' requires __lt__"
  49. assert '__eq__' in self.rawdict, "__total_ordering='auto' requires __eq__"
  50. self.add_entries(__le__ = auto__le__,
  51. __gt__ = auto__gt__,
  52. __ge__ = auto__ge__,
  53. __ne__ = auto__ne__)
  54. def _freeze_(self):
  55. # hint for the annotator: track individual constant instances of TypeDef
  56. return True
  57. def __repr__(self):
  58. return "<%s name=%r>" % (self.__class__.__name__, self.name)
  59. # generic special cmp methods defined on top of __lt__ and __eq__, used by
  60. # automatic total ordering
  61. @interp2app
  62. def auto__le__(space, w_self, w_other):
  63. return space.not_(space.lt(w_other, w_self))
  64. @interp2app
  65. def auto__gt__(space, w_self, w_other):
  66. return space.lt(w_other, w_self)
  67. @interp2app
  68. def auto__ge__(space, w_self, w_other):
  69. return space.not_(space.lt(w_self, w_other))
  70. @interp2app
  71. def auto__ne__(space, w_self, w_other):
  72. return space.not_(space.eq(w_self, w_other))
  73. # ____________________________________________________________
  74. # Hash support
  75. def default_identity_hash(space, w_obj):
  76. w_unique_id = w_obj.immutable_unique_id(space)
  77. if w_unique_id is None: # common case
  78. return space.wrap(compute_identity_hash(w_obj))
  79. else:
  80. return space.hash(w_unique_id)
  81. # ____________________________________________________________
  82. #
  83. # For each built-in app-level type Xxx that can be subclassed at
  84. # app-level, the corresponding interp-level W_XxxObject class cannot
  85. # generally represent instances of app-level subclasses of Xxx. The
  86. # reason is that it is missing a place to store the __dict__, the slots,
  87. # the weakref lifeline, and it typically has no interp-level __del__.
  88. # So we create a few interp-level subclasses of W_XxxObject, which add
  89. # some combination of features. This is done using mapdict.
  90. # we need two subclasses of the app-level type, one to add mapdict, and then one
  91. # to add del to not slow down the GC.
  92. def get_unique_interplevel_subclass(space, cls):
  93. "NOT_RPYTHON: initialization-time only"
  94. assert cls.typedef.acceptable_as_base_class
  95. try:
  96. return _unique_subclass_cache[cls]
  97. except KeyError:
  98. subcls = _getusercls(cls)
  99. assert cls not in _unique_subclass_cache
  100. _unique_subclass_cache[cls] = subcls
  101. return subcls
  102. get_unique_interplevel_subclass._annspecialcase_ = "specialize:memo"
  103. _unique_subclass_cache = {}
  104. def _getusercls(cls, reallywantdict=False):
  105. from rpython.rlib import objectmodel
  106. from pypy.objspace.std.objectobject import W_ObjectObject
  107. from pypy.module.__builtin__.interp_classobj import W_InstanceObject
  108. from pypy.objspace.std.mapdict import (BaseUserClassMapdict,
  109. MapdictDictSupport, MapdictWeakrefSupport,
  110. _make_storage_mixin_size_n, MapdictStorageMixin)
  111. typedef = cls.typedef
  112. name = cls.__name__ + "User"
  113. if cls is W_ObjectObject or cls is W_InstanceObject:
  114. base_mixin = _make_storage_mixin_size_n()
  115. else:
  116. base_mixin = MapdictStorageMixin
  117. copy_methods = [BaseUserClassMapdict]
  118. if reallywantdict or not typedef.hasdict:
  119. # the type has no dict, mapdict to provide the dict
  120. copy_methods.append(MapdictDictSupport)
  121. name += "Dict"
  122. if not typedef.weakrefable:
  123. # the type does not support weakrefs yet, mapdict to provide weakref
  124. # support
  125. copy_methods.append(MapdictWeakrefSupport)
  126. name += "Weakrefable"
  127. class subcls(cls):
  128. user_overridden_class = True
  129. objectmodel.import_from_mixin(base_mixin)
  130. for copycls in copy_methods:
  131. _copy_methods(copycls, subcls)
  132. subcls.__name__ = name
  133. return subcls
  134. def _copy_methods(copycls, subcls):
  135. for key, value in copycls.__dict__.items():
  136. if (not key.startswith('__') or key == '__del__'):
  137. setattr(subcls, key, value)
  138. # ____________________________________________________________
  139. @specialize.arg(0)
  140. def make_descr_typecheck_wrapper(tag, func, extraargs=(), cls=None,
  141. use_closure=False):
  142. if func is None:
  143. return None
  144. return _make_descr_typecheck_wrapper(tag, func, extraargs, cls, use_closure)
  145. @specialize.memo()
  146. def _make_descr_typecheck_wrapper(tag, func, extraargs, cls, use_closure):
  147. # - if cls is None, the wrapped object is passed to the function
  148. # - if cls is a class, an unwrapped instance is passed
  149. # - if cls is a string, XXX unused?
  150. if cls is None and use_closure:
  151. return func
  152. if hasattr(func, 'im_func'):
  153. assert func.im_class is cls
  154. func = func.im_func
  155. miniglobals = {
  156. func.__name__: func,
  157. 'OperationError': OperationError
  158. }
  159. if cls is None:
  160. source = """
  161. def descr_typecheck_%(name)s(closure, space, obj, %(extra)s):
  162. return %(name)s(%(args)s, %(extra)s)
  163. """
  164. else:
  165. cls_name = cls.__name__
  166. assert issubclass(cls, W_Root)
  167. source = """
  168. def descr_typecheck_%(name)s(closure, space, w_obj, %(extra)s):
  169. obj = space.descr_self_interp_w(%(cls_name)s, w_obj)
  170. return %(name)s(%(args)s, %(extra)s)
  171. """
  172. miniglobals[cls_name] = cls
  173. name = func.__name__
  174. extra = ', '.join(extraargs)
  175. from pypy.interpreter import pycode
  176. argnames, _, _ = pycode.cpython_code_signature(func.func_code)
  177. if use_closure:
  178. if argnames[1] == 'space':
  179. args = "closure, space, obj"
  180. else:
  181. args = "closure, obj, space"
  182. else:
  183. if argnames[0] == 'space':
  184. args = "space, obj"
  185. else:
  186. args = "obj, space"
  187. source = py.code.Source(source % locals())
  188. exec source.compile() in miniglobals
  189. return miniglobals['descr_typecheck_%s' % func.__name__]
  190. def unknown_objclass_getter(space):
  191. # NB. this is an AttributeError to make inspect.py happy
  192. raise oefmt(space.w_AttributeError, "generic property has no __objclass__")
  193. @specialize.arg(0)
  194. def make_objclass_getter(tag, func, cls):
  195. if func and hasattr(func, 'im_func'):
  196. assert not cls or cls is func.im_class
  197. cls = func.im_class
  198. return _make_objclass_getter(cls)
  199. @specialize.memo()
  200. def _make_objclass_getter(cls):
  201. if not cls:
  202. return unknown_objclass_getter, cls
  203. miniglobals = {}
  204. if isinstance(cls, str):
  205. assert cls.startswith('<'), "pythontype typecheck should begin with <"
  206. cls_name = cls[1:]
  207. typeexpr = "space.w_%s" % cls_name
  208. else:
  209. miniglobals['cls'] = cls
  210. typeexpr = "space.gettypeobject(cls.typedef)"
  211. source = """if 1:
  212. def objclass_getter(space):
  213. return %s
  214. \n""" % (typeexpr,)
  215. exec compile2(source) in miniglobals
  216. res = miniglobals['objclass_getter'], cls
  217. return res
  218. class GetSetProperty(W_Root):
  219. _immutable_fields_ = ["fget", "fset", "fdel"]
  220. @specialize.arg(7)
  221. def __init__(self, fget, fset=None, fdel=None, doc=None,
  222. cls=None, use_closure=False, tag=None):
  223. objclass_getter, cls = make_objclass_getter(tag, fget, cls)
  224. fget = make_descr_typecheck_wrapper((tag, 0), fget,
  225. cls=cls, use_closure=use_closure)
  226. fset = make_descr_typecheck_wrapper((tag, 1), fset, ('w_value',),
  227. cls=cls, use_closure=use_closure)
  228. fdel = make_descr_typecheck_wrapper((tag, 2), fdel,
  229. cls=cls, use_closure=use_closure)
  230. self.fget = fget
  231. self.fset = fset
  232. self.fdel = fdel
  233. self.doc = doc
  234. self.reqcls = cls
  235. self.name = '<generic property>'
  236. self.objclass_getter = objclass_getter
  237. self.use_closure = use_closure
  238. @unwrap_spec(w_cls = WrappedDefault(None))
  239. def descr_property_get(self, space, w_obj, w_cls=None):
  240. """property.__get__(obj[, type]) -> value
  241. Read the value of the property of the given obj."""
  242. # XXX HAAAAAAAAAAAACK (but possibly a good one)
  243. if (space.is_w(w_obj, space.w_None)
  244. and not space.is_w(w_cls, space.type(space.w_None))):
  245. #print self, w_obj, w_cls
  246. return space.wrap(self)
  247. else:
  248. try:
  249. return self.fget(self, space, w_obj)
  250. except DescrMismatch:
  251. return w_obj.descr_call_mismatch(
  252. space, '__getattribute__',
  253. self.reqcls, Arguments(space, [w_obj,
  254. space.wrap(self.name)]))
  255. def descr_property_set(self, space, w_obj, w_value):
  256. """property.__set__(obj, value)
  257. Change the value of the property of the given obj."""
  258. fset = self.fset
  259. if fset is None:
  260. raise oefmt(space.w_TypeError, "readonly attribute")
  261. try:
  262. fset(self, space, w_obj, w_value)
  263. except DescrMismatch:
  264. w_obj.descr_call_mismatch(
  265. space, '__setattr__',
  266. self.reqcls, Arguments(space, [w_obj,
  267. space.wrap(self.name),
  268. w_value]))
  269. def descr_property_del(self, space, w_obj):
  270. """property.__delete__(obj)
  271. Delete the value of the property from the given obj."""
  272. fdel = self.fdel
  273. if fdel is None:
  274. raise oefmt(space.w_AttributeError, "cannot delete attribute")
  275. try:
  276. fdel(self, space, w_obj)
  277. except DescrMismatch:
  278. w_obj.descr_call_mismatch(
  279. space, '__delattr__',
  280. self.reqcls, Arguments(space, [w_obj,
  281. space.wrap(self.name)]))
  282. def descr_get_objclass(space, property):
  283. return property.objclass_getter(space)
  284. def interp_attrproperty(name, cls, doc=None):
  285. "NOT_RPYTHON: initialization-time only"
  286. def fget(space, obj):
  287. return space.wrap(getattr(obj, name))
  288. return GetSetProperty(fget, cls=cls, doc=doc)
  289. def interp_attrproperty_w(name, cls, doc=None):
  290. "NOT_RPYTHON: initialization-time only"
  291. def fget(space, obj):
  292. w_value = getattr(obj, name)
  293. if w_value is None:
  294. return space.w_None
  295. else:
  296. return w_value
  297. return GetSetProperty(fget, cls=cls, doc=doc)
  298. GetSetProperty.typedef = TypeDef(
  299. "getset_descriptor",
  300. __get__ = interp2app(GetSetProperty.descr_property_get),
  301. __set__ = interp2app(GetSetProperty.descr_property_set),
  302. __delete__ = interp2app(GetSetProperty.descr_property_del),
  303. __name__ = interp_attrproperty('name', cls=GetSetProperty),
  304. __objclass__ = GetSetProperty(GetSetProperty.descr_get_objclass),
  305. __doc__ = interp_attrproperty('doc', cls=GetSetProperty),
  306. )
  307. assert not GetSetProperty.typedef.acceptable_as_base_class # no __new__
  308. class Member(W_Root):
  309. """For slots."""
  310. _immutable_ = True
  311. def __init__(self, index, name, w_cls):
  312. self.index = index
  313. self.name = name
  314. self.w_cls = w_cls
  315. def typecheck(self, space, w_obj):
  316. if not space.isinstance_w(w_obj, self.w_cls):
  317. raise oefmt(space.w_TypeError,
  318. "descriptor '%N' for '%N' objects doesn't apply to "
  319. "'%T' object", self, self.w_cls, w_obj)
  320. def descr_member_get(self, space, w_obj, w_cls=None):
  321. """member.__get__(obj[, type]) -> value
  322. Read the slot 'member' of the given 'obj'."""
  323. if space.is_w(w_obj, space.w_None):
  324. return space.wrap(self)
  325. else:
  326. self.typecheck(space, w_obj)
  327. w_result = w_obj.getslotvalue(self.index)
  328. if w_result is None:
  329. raise OperationError(space.w_AttributeError,
  330. space.wrap(self.name)) # XXX better message
  331. return w_result
  332. def descr_member_set(self, space, w_obj, w_value):
  333. """member.__set__(obj, value)
  334. Write into the slot 'member' of the given 'obj'."""
  335. self.typecheck(space, w_obj)
  336. w_obj.setslotvalue(self.index, w_value)
  337. def descr_member_del(self, space, w_obj):
  338. """member.__delete__(obj)
  339. Delete the value of the slot 'member' from the given 'obj'."""
  340. self.typecheck(space, w_obj)
  341. success = w_obj.delslotvalue(self.index)
  342. if not success:
  343. raise OperationError(space.w_AttributeError,
  344. space.wrap(self.name)) # XXX better message
  345. Member.typedef = TypeDef(
  346. "member_descriptor",
  347. __get__ = interp2app(Member.descr_member_get),
  348. __set__ = interp2app(Member.descr_member_set),
  349. __delete__ = interp2app(Member.descr_member_del),
  350. __name__ = interp_attrproperty('name', cls=Member),
  351. __objclass__ = interp_attrproperty_w('w_cls', cls=Member),
  352. )
  353. assert not Member.typedef.acceptable_as_base_class # no __new__
  354. # ____________________________________________________________
  355. class ClassAttr(W_Root):
  356. """For class-level attributes that need to be initialized
  357. with some code. This code is provided as a callback function
  358. invoked with the space.
  359. """
  360. def __init__(self, function):
  361. self.function = function
  362. def __spacebind__(self, space):
  363. return self.function(space)
  364. # ____________________________________________________________
  365. def generic_new_descr(W_Type):
  366. def descr_new(space, w_subtype, __args__):
  367. self = space.allocate_instance(W_Type, w_subtype)
  368. W_Type.__init__(self, space)
  369. return space.wrap(self)
  370. descr_new = func_with_new_name(descr_new, 'descr_new_%s' % W_Type.__name__)
  371. return interp2app(descr_new)
  372. # ____________________________________________________________
  373. #
  374. # Definition of the type's descriptors for all the internal types
  375. from pypy.interpreter.eval import Code
  376. from pypy.interpreter.pycode import PyCode, CO_VARARGS, CO_VARKEYWORDS
  377. from pypy.interpreter.pyframe import PyFrame
  378. from pypy.interpreter.pyopcode import SuspendedUnroller
  379. from pypy.interpreter.module import Module
  380. from pypy.interpreter.function import (Function, Method, StaticMethod,
  381. ClassMethod, BuiltinFunction, descr_function_get)
  382. from pypy.interpreter.pytraceback import PyTraceback
  383. from pypy.interpreter.generator import GeneratorIterator
  384. from pypy.interpreter.nestedscope import Cell
  385. from pypy.interpreter.special import NotImplemented, Ellipsis
  386. def descr_get_dict(space, w_obj):
  387. w_dict = w_obj.getdict(space)
  388. if w_dict is None:
  389. raise oefmt(space.w_TypeError,
  390. "descriptor '__dict__' doesn't apply to '%T' objects",
  391. w_obj)
  392. return w_dict
  393. def descr_set_dict(space, w_obj, w_dict):
  394. w_obj.setdict(space, w_dict)
  395. def descr_del_dict(space, w_obj): # blame CPython for the existence of this one
  396. w_obj.setdict(space, space.newdict())
  397. def descr_get_weakref(space, w_obj):
  398. lifeline = w_obj.getweakref()
  399. if lifeline is None:
  400. return space.w_None
  401. return lifeline.get_any_weakref(space)
  402. dict_descr = GetSetProperty(descr_get_dict, descr_set_dict, descr_del_dict,
  403. doc="dictionary for instance variables (if defined)")
  404. dict_descr.name = '__dict__'
  405. def generic_ne(space, w_obj1, w_obj2):
  406. if space.eq_w(w_obj1, w_obj2):
  407. return space.w_False
  408. else:
  409. return space.w_True
  410. descr_generic_ne = interp2app(generic_ne)
  411. # co_xxx interface emulation for built-in code objects
  412. def fget_co_varnames(space, code): # unwrapping through unwrap_spec
  413. return space.newtuple([space.wrap(name) for name in code.getvarnames()])
  414. def fget_co_argcount(space, code): # unwrapping through unwrap_spec
  415. return space.wrap(code.signature().num_argnames())
  416. def fget_co_flags(space, code): # unwrapping through unwrap_spec
  417. sig = code.signature()
  418. flags = 0
  419. if sig.has_vararg():
  420. flags |= CO_VARARGS
  421. if sig.has_kwarg():
  422. flags |= CO_VARKEYWORDS
  423. return space.wrap(flags)
  424. def fget_co_consts(space, code): # unwrapping through unwrap_spec
  425. w_docstring = code.getdocstring(space)
  426. return space.newtuple([w_docstring])
  427. weakref_descr = GetSetProperty(descr_get_weakref,
  428. doc="list of weak references to the object (if defined)")
  429. weakref_descr.name = '__weakref__'
  430. def make_weakref_descr(cls):
  431. """Make instances of the W_Root subclass 'cls' weakrefable.
  432. This returns the '__weakref__' desctriptor to use for the TypeDef.
  433. Note that if the class also defines a custom '__del__', the
  434. __del__ should call self.clear_all_weakrefs() before it clears
  435. the resources used by the object.
  436. """
  437. # force the interface into the given cls
  438. def getweakref(self):
  439. return self._lifeline_
  440. def setweakref(self, space, weakreflifeline):
  441. self._lifeline_ = weakreflifeline
  442. def delweakref(self):
  443. self._lifeline_ = None
  444. cls._lifeline_ = None
  445. cls.getweakref = getweakref
  446. cls.setweakref = setweakref
  447. cls.delweakref = delweakref
  448. return weakref_descr
  449. Code.typedef = TypeDef('internal-code',
  450. co_name = interp_attrproperty('co_name', cls=Code),
  451. co_varnames = GetSetProperty(fget_co_varnames, cls=Code),
  452. co_argcount = GetSetProperty(fget_co_argcount, cls=Code),
  453. co_flags = GetSetProperty(fget_co_flags, cls=Code),
  454. co_consts = GetSetProperty(fget_co_consts, cls=Code),
  455. )
  456. assert not Code.typedef.acceptable_as_base_class # no __new__
  457. BuiltinCode.typedef = TypeDef('builtin-code',
  458. __reduce__ = interp2app(BuiltinCode.descr__reduce__),
  459. co_name = interp_attrproperty('co_name', cls=BuiltinCode),
  460. co_varnames = GetSetProperty(fget_co_varnames, cls=BuiltinCode),
  461. co_argcount = GetSetProperty(fget_co_argcount, cls=BuiltinCode),
  462. co_flags = GetSetProperty(fget_co_flags, cls=BuiltinCode),
  463. co_consts = GetSetProperty(fget_co_consts, cls=BuiltinCode),
  464. )
  465. assert not BuiltinCode.typedef.acceptable_as_base_class # no __new__
  466. PyCode.typedef = TypeDef('code',
  467. __new__ = interp2app(PyCode.descr_code__new__.im_func),
  468. __eq__ = interp2app(PyCode.descr_code__eq__),
  469. __ne__ = descr_generic_ne,
  470. __hash__ = interp2app(PyCode.descr_code__hash__),
  471. __reduce__ = interp2app(PyCode.descr__reduce__),
  472. __repr__ = interp2app(PyCode.repr),
  473. co_argcount = interp_attrproperty('co_argcount', cls=PyCode),
  474. co_nlocals = interp_attrproperty('co_nlocals', cls=PyCode),
  475. co_stacksize = interp_attrproperty('co_stacksize', cls=PyCode),
  476. co_flags = interp_attrproperty('co_flags', cls=PyCode),
  477. co_code = interp_attrproperty('co_code', cls=PyCode),
  478. co_consts = GetSetProperty(PyCode.fget_co_consts),
  479. co_names = GetSetProperty(PyCode.fget_co_names),
  480. co_varnames = GetSetProperty(PyCode.fget_co_varnames),
  481. co_freevars = GetSetProperty(PyCode.fget_co_freevars),
  482. co_cellvars = GetSetProperty(PyCode.fget_co_cellvars),
  483. co_filename = interp_attrproperty('co_filename', cls=PyCode),
  484. co_name = interp_attrproperty('co_name', cls=PyCode),
  485. co_firstlineno = interp_attrproperty('co_firstlineno', cls=PyCode),
  486. co_lnotab = interp_attrproperty('co_lnotab', cls=PyCode),
  487. __weakref__ = make_weakref_descr(PyCode),
  488. )
  489. PyCode.typedef.acceptable_as_base_class = False
  490. PyFrame.typedef = TypeDef('frame',
  491. __reduce__ = interp2app(PyFrame.descr__reduce__),
  492. __setstate__ = interp2app(PyFrame.descr__setstate__),
  493. f_builtins = GetSetProperty(PyFrame.fget_f_builtins),
  494. f_lineno = GetSetProperty(PyFrame.fget_f_lineno, PyFrame.fset_f_lineno),
  495. f_back = GetSetProperty(PyFrame.fget_f_back),
  496. f_lasti = GetSetProperty(PyFrame.fget_f_lasti),
  497. f_trace = GetSetProperty(PyFrame.fget_f_trace, PyFrame.fset_f_trace,
  498. PyFrame.fdel_f_trace),
  499. f_exc_type = GetSetProperty(PyFrame.fget_f_exc_type),
  500. f_exc_value = GetSetProperty(PyFrame.fget_f_exc_value),
  501. f_exc_traceback = GetSetProperty(PyFrame.fget_f_exc_traceback),
  502. f_restricted = GetSetProperty(PyFrame.fget_f_restricted),
  503. f_code = GetSetProperty(PyFrame.fget_code),
  504. f_locals = GetSetProperty(PyFrame.fget_getdictscope),
  505. f_globals = GetSetProperty(PyFrame.fget_w_globals),
  506. )
  507. assert not PyFrame.typedef.acceptable_as_base_class # no __new__
  508. Module.typedef = TypeDef("module",
  509. __new__ = interp2app(Module.descr_module__new__.im_func),
  510. __init__ = interp2app(Module.descr_module__init__),
  511. __repr__ = interp2app(Module.descr_module__repr__),
  512. __reduce__ = interp2app(Module.descr__reduce__),
  513. __dict__ = GetSetProperty(descr_get_dict, cls=Module), # module dictionaries are readonly attributes
  514. __doc__ = 'module(name[, doc])\n\nCreate a module object.\nThe name must be a string; the optional doc argument can have any type.'
  515. )
  516. getset_func_doc = GetSetProperty(Function.fget_func_doc,
  517. Function.fset_func_doc,
  518. Function.fdel_func_doc)
  519. # __module__ attribute lazily gets its value from the w_globals
  520. # at the time of first invocation. This is not 100% compatible but
  521. # avoid problems at the time we construct the first functions when
  522. # it's not really possible to do a get or getitem on dictionaries
  523. # (mostly because wrapped exceptions don't exist at that time)
  524. getset___module__ = GetSetProperty(Function.fget___module__,
  525. Function.fset___module__,
  526. Function.fdel___module__)
  527. getset_func_defaults = GetSetProperty(Function.fget_func_defaults,
  528. Function.fset_func_defaults,
  529. Function.fdel_func_defaults)
  530. getset_func_code = GetSetProperty(Function.fget_func_code,
  531. Function.fset_func_code)
  532. getset_func_name = GetSetProperty(Function.fget_func_name,
  533. Function.fset_func_name)
  534. getset_func_dict = GetSetProperty(descr_get_dict, descr_set_dict, cls=Function)
  535. Function.typedef = TypeDef("function",
  536. __new__ = interp2app(Function.descr_function__new__.im_func),
  537. __call__ = interp2app(Function.descr_function_call,
  538. descrmismatch='__call__'),
  539. __get__ = interp2app(descr_function_get),
  540. __repr__ = interp2app(Function.descr_function_repr, descrmismatch='__repr__'),
  541. __reduce__ = interp2app(Function.descr_function__reduce__),
  542. __setstate__ = interp2app(Function.descr_function__setstate__),
  543. func_code = getset_func_code,
  544. func_doc = getset_func_doc,
  545. func_name = getset_func_name,
  546. func_dict = getset_func_dict,
  547. func_defaults = getset_func_defaults,
  548. func_globals = interp_attrproperty_w('w_func_globals', cls=Function),
  549. func_closure = GetSetProperty(Function.fget_func_closure),
  550. __code__ = getset_func_code,
  551. __doc__ = getset_func_doc,
  552. __name__ = getset_func_name,
  553. __dict__ = getset_func_dict,
  554. __defaults__ = getset_func_defaults,
  555. __globals__ = interp_attrproperty_w('w_func_globals', cls=Function),
  556. __closure__ = GetSetProperty(Function.fget_func_closure),
  557. __module__ = getset___module__,
  558. __weakref__ = make_weakref_descr(Function),
  559. )
  560. Function.typedef.acceptable_as_base_class = False
  561. Method.typedef = TypeDef(
  562. "method",
  563. __doc__ = """instancemethod(function, instance, class)
  564. Create an instance method object.""",
  565. __new__ = interp2app(Method.descr_method__new__.im_func),
  566. __call__ = interp2app(Method.descr_method_call),
  567. __get__ = interp2app(Method.descr_method_get),
  568. im_func = interp_attrproperty_w('w_function', cls=Method),
  569. __func__ = interp_attrproperty_w('w_function', cls=Method),
  570. im_self = interp_attrproperty_w('w_instance', cls=Method),
  571. __self__ = interp_attrproperty_w('w_instance', cls=Method),
  572. im_class = interp_attrproperty_w('w_class', cls=Method),
  573. __getattribute__ = interp2app(Method.descr_method_getattribute),
  574. __eq__ = interp2app(Method.descr_method_eq),
  575. __ne__ = descr_generic_ne,
  576. __hash__ = interp2app(Method.descr_method_hash),
  577. __repr__ = interp2app(Method.descr_method_repr),
  578. __reduce__ = interp2app(Method.descr_method__reduce__),
  579. __weakref__ = make_weakref_descr(Method),
  580. )
  581. Method.typedef.acceptable_as_base_class = False
  582. StaticMethod.typedef = TypeDef("staticmethod",
  583. __doc__ = """staticmethod(function) -> static method
  584. Convert a function to be a static method.
  585. A static method does not receive an implicit first argument.
  586. To declare a static method, use this idiom:
  587. class C:
  588. def f(arg1, arg2, ...): ...
  589. f = staticmethod(f)
  590. It can be called either on the class (e.g. C.f()) or on an instance
  591. (e.g. C().f()). The instance is ignored except for its class.""",
  592. __get__ = interp2app(StaticMethod.descr_staticmethod_get),
  593. __new__ = interp2app(StaticMethod.descr_staticmethod__new__.im_func),
  594. __func__= interp_attrproperty_w('w_function', cls=StaticMethod),
  595. )
  596. ClassMethod.typedef = TypeDef(
  597. 'classmethod',
  598. __new__ = interp2app(ClassMethod.descr_classmethod__new__.im_func),
  599. __get__ = interp2app(ClassMethod.descr_classmethod_get),
  600. __func__= interp_attrproperty_w('w_function', cls=ClassMethod),
  601. __doc__ = """classmethod(function) -> class method
  602. Convert a function to be a class method.
  603. A class method receives the class as implicit first argument,
  604. just like an instance method receives the instance.
  605. To declare a class method, use this idiom:
  606. class C:
  607. def f(cls, arg1, arg2, ...): ...
  608. f = classmethod(f)
  609. It can be called either on the class (e.g. C.f()) or on an instance
  610. (e.g. C().f()). The instance is ignored except for its class.
  611. If a class method is called for a derived class, the derived class
  612. object is passed as the implied first argument.""",
  613. )
  614. def always_none(self, obj):
  615. return None
  616. BuiltinFunction.typedef = TypeDef("builtin_function", **Function.typedef.rawdict)
  617. BuiltinFunction.typedef.rawdict.update({
  618. '__new__': interp2app(BuiltinFunction.descr_builtinfunction__new__.im_func),
  619. '__self__': GetSetProperty(always_none, cls=BuiltinFunction),
  620. '__repr__': interp2app(BuiltinFunction.descr_function_repr),
  621. '__doc__': getset_func_doc,
  622. })
  623. del BuiltinFunction.typedef.rawdict['__get__']
  624. BuiltinFunction.typedef.acceptable_as_base_class = False
  625. PyTraceback.typedef = TypeDef("traceback",
  626. __reduce__ = interp2app(PyTraceback.descr__reduce__),
  627. __setstate__ = interp2app(PyTraceback.descr__setstate__),
  628. tb_frame = interp_attrproperty('frame', cls=PyTraceback),
  629. tb_lasti = interp_attrproperty('lasti', cls=PyTraceback),
  630. tb_lineno = GetSetProperty(PyTraceback.descr_tb_lineno),
  631. tb_next = interp_attrproperty('next', cls=PyTraceback),
  632. )
  633. assert not PyTraceback.typedef.acceptable_as_base_class # no __new__
  634. GeneratorIterator.typedef = TypeDef("generator",
  635. __repr__ = interp2app(GeneratorIterator.descr__repr__),
  636. __reduce__ = interp2app(GeneratorIterator.descr__reduce__),
  637. __setstate__ = interp2app(GeneratorIterator.descr__setstate__),
  638. next = interp2app(GeneratorIterator.descr_next,
  639. descrmismatch='next'),
  640. send = interp2app(GeneratorIterator.descr_send,
  641. descrmismatch='send'),
  642. throw = interp2app(GeneratorIterator.descr_throw,
  643. descrmismatch='throw'),
  644. close = interp2app(GeneratorIterator.descr_close,
  645. descrmismatch='close'),
  646. __iter__ = interp2app(GeneratorIterator.descr__iter__,
  647. descrmismatch='__iter__'),
  648. gi_running = interp_attrproperty('running', cls=GeneratorIterator),
  649. gi_frame = GetSetProperty(GeneratorIterator.descr_gi_frame),
  650. gi_code = GetSetProperty(GeneratorIterator.descr_gi_code),
  651. __name__ = GetSetProperty(GeneratorIterator.descr__name__),
  652. __weakref__ = make_weakref_descr(GeneratorIterator),
  653. )
  654. assert not GeneratorIterator.typedef.acceptable_as_base_class # no __new__
  655. Cell.typedef = TypeDef("cell",
  656. __cmp__ = interp2app(Cell.descr__cmp__),
  657. __hash__ = None,
  658. __reduce__ = interp2app(Cell.descr__reduce__),
  659. __repr__ = interp2app(Cell.descr__repr__),
  660. __setstate__ = interp2app(Cell.descr__setstate__),
  661. cell_contents= GetSetProperty(Cell.descr__cell_contents, cls=Cell),
  662. )
  663. assert not Cell.typedef.acceptable_as_base_class # no __new__
  664. Ellipsis.typedef = TypeDef("Ellipsis",
  665. __repr__ = interp2app(Ellipsis.descr__repr__),
  666. )
  667. assert not Ellipsis.typedef.acceptable_as_base_class # no __new__
  668. NotImplemented.typedef = TypeDef("NotImplemented",
  669. __repr__ = interp2app(NotImplemented.descr__repr__),
  670. )
  671. assert not NotImplemented.typedef.acceptable_as_base_class # no __new__
  672. SuspendedUnroller.typedef = TypeDef("SuspendedUnroller")
  673. assert not SuspendedUnroller.typedef.acceptable_as_base_class # no __new__