PageRenderTime 57ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/pypy/module/__builtin__/interp_classobj.py

https://bitbucket.org/pypy/pypy/
Python | 735 lines | 618 code | 83 blank | 34 comment | 173 complexity | 8a7438dcf0f24594524a22c3cf0fbc22 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import new
  2. from pypy.interpreter.error import OperationError, oefmt
  3. from pypy.interpreter.gateway import interp2app, unwrap_spec
  4. from pypy.interpreter.typedef import TypeDef, make_weakref_descr
  5. from pypy.interpreter.baseobjspace import W_Root
  6. from pypy.interpreter.typedef import GetSetProperty, descr_get_dict, descr_set_dict
  7. from rpython.rlib.objectmodel import compute_identity_hash
  8. from rpython.rlib.debug import make_sure_not_resized
  9. from rpython.rlib import jit
  10. def raise_type_err(space, argument, expected, w_obj):
  11. raise oefmt(space.w_TypeError,
  12. "argument %s must be %s, not %T", argument, expected, w_obj)
  13. def descr_classobj_new(space, w_subtype, w_name, w_bases, w_dict):
  14. if not space.isinstance_w(w_bases, space.w_tuple):
  15. raise_type_err(space, 'bases', 'tuple', w_bases)
  16. if not space.isinstance_w(w_dict, space.w_dict):
  17. raise_type_err(space, 'bases', 'tuple', w_bases)
  18. if not space.contains_w(w_dict, space.wrap("__doc__")):
  19. space.setitem(w_dict, space.wrap("__doc__"), space.w_None)
  20. # XXX missing: lengthy and obscure logic about "__module__"
  21. bases_w = space.fixedview(w_bases)
  22. for w_base in bases_w:
  23. if not isinstance(w_base, W_ClassObject):
  24. w_metaclass = space.type(w_base)
  25. if space.is_true(space.callable(w_metaclass)):
  26. return space.call_function(w_metaclass, w_name,
  27. w_bases, w_dict)
  28. raise oefmt(space.w_TypeError, "base must be class")
  29. return W_ClassObject(space, w_name, bases_w, w_dict)
  30. class W_ClassObject(W_Root):
  31. def __init__(self, space, w_name, bases, w_dict):
  32. self.name = space.str_w(w_name)
  33. make_sure_not_resized(bases)
  34. self.bases_w = bases
  35. self.w_dict = w_dict
  36. def has_user_del(self, space):
  37. return self.lookup(space, '__del__') is not None
  38. def instantiate(self, space):
  39. cache = space.fromcache(Cache)
  40. return cache.InstanceObjectCls(space, self)
  41. def getdict(self, space):
  42. return self.w_dict
  43. def setdict(self, space, w_dict):
  44. if not space.isinstance_w(w_dict, space.w_dict):
  45. raise oefmt(space.w_TypeError,
  46. "__dict__ must be a dictionary object")
  47. self.w_dict = w_dict
  48. def setname(self, space, w_newname):
  49. if not space.isinstance_w(w_newname, space.w_str):
  50. raise oefmt(space.w_TypeError, "__name__ must be a string object")
  51. self.name = space.str_w(w_newname)
  52. def setbases(self, space, w_bases):
  53. if not space.isinstance_w(w_bases, space.w_tuple):
  54. raise oefmt(space.w_TypeError, "__bases__ must be a tuple object")
  55. bases_w = space.fixedview(w_bases)
  56. for w_base in bases_w:
  57. if not isinstance(w_base, W_ClassObject):
  58. raise oefmt(space.w_TypeError,
  59. "__bases__ items must be classes")
  60. self.bases_w = bases_w
  61. def is_subclass_of(self, other):
  62. assert isinstance(other, W_ClassObject)
  63. if self is other:
  64. return True
  65. for base in self.bases_w:
  66. assert isinstance(base, W_ClassObject)
  67. if base.is_subclass_of(other):
  68. return True
  69. return False
  70. @jit.unroll_safe
  71. def lookup(self, space, attr):
  72. # returns w_value or interplevel None
  73. w_result = space.finditem_str(self.w_dict, attr)
  74. if w_result is not None:
  75. return w_result
  76. for base in self.bases_w:
  77. # XXX fix annotation of bases_w to be a list of W_ClassObjects
  78. assert isinstance(base, W_ClassObject)
  79. w_result = base.lookup(space, attr)
  80. if w_result is not None:
  81. return w_result
  82. return None
  83. @unwrap_spec(name=str)
  84. def descr_getattribute(self, space, name):
  85. if name and name[0] == "_":
  86. if name == "__dict__":
  87. return self.w_dict
  88. elif name == "__name__":
  89. return space.wrap(self.name)
  90. elif name == "__bases__":
  91. return space.newtuple(self.bases_w)
  92. w_value = self.lookup(space, name)
  93. if w_value is None:
  94. raise oefmt(space.w_AttributeError,
  95. "class %s has no attribute '%s'", self.name, name)
  96. w_descr_get = space.lookup(w_value, '__get__')
  97. if w_descr_get is None:
  98. return w_value
  99. return space.call_function(w_descr_get, w_value, space.w_None, self)
  100. def descr_setattr(self, space, w_attr, w_value):
  101. name = space.str_w(w_attr)
  102. if name and name[0] == "_":
  103. if name == "__dict__":
  104. self.setdict(space, w_value)
  105. return
  106. elif name == "__name__":
  107. self.setname(space, w_value)
  108. return
  109. elif name == "__bases__":
  110. self.setbases(space, w_value)
  111. return
  112. elif name == "__del__":
  113. if not self.has_user_del(space):
  114. msg = ("a __del__ method added to an existing class will "
  115. "only be called on instances made from now on")
  116. space.warn(space.wrap(msg), space.w_RuntimeWarning)
  117. space.setitem(self.w_dict, w_attr, w_value)
  118. def descr_delattr(self, space, w_attr):
  119. name = space.str_w(w_attr)
  120. if name in ("__dict__", "__name__", "__bases__"):
  121. raise oefmt(space.w_TypeError,
  122. "cannot delete attribute '%s'", name)
  123. try:
  124. space.delitem(self.w_dict, w_attr)
  125. except OperationError as e:
  126. if not e.match(space, space.w_KeyError):
  127. raise
  128. raise oefmt(space.w_AttributeError,
  129. "class %s has no attribute '%s'", self.name, name)
  130. def descr_repr(self, space):
  131. mod = self.get_module_string(space)
  132. return self.getrepr(space, "class %s.%s" % (mod, self.name))
  133. def descr_str(self, space):
  134. mod = self.get_module_string(space)
  135. if mod == "?":
  136. return space.wrap(self.name)
  137. else:
  138. return space.wrap("%s.%s" % (mod, self.name))
  139. def get_module_string(self, space):
  140. try:
  141. w_mod = self.descr_getattribute(space, "__module__")
  142. except OperationError as e:
  143. if not e.match(space, space.w_AttributeError):
  144. raise
  145. return "?"
  146. if space.isinstance_w(w_mod, space.w_str):
  147. return space.str_w(w_mod)
  148. return "?"
  149. def __repr__(self):
  150. # NOT_RPYTHON
  151. return '<W_ClassObject(%s)>' % self.name
  152. class Cache:
  153. def __init__(self, space):
  154. from pypy.interpreter.typedef import _getusercls
  155. if hasattr(space, 'is_fake_objspace'):
  156. # hack: with the fake objspace, we don't want to see typedef's
  157. # _getusercls() at all
  158. self.InstanceObjectCls = W_InstanceObject
  159. return
  160. self.InstanceObjectCls = _getusercls(
  161. W_InstanceObject, reallywantdict=True)
  162. def class_descr_call(space, w_self, __args__):
  163. self = space.interp_w(W_ClassObject, w_self)
  164. w_inst = self.instantiate(space)
  165. w_init = w_inst.getattr_from_class(space, '__init__')
  166. if w_init is not None:
  167. w_result = space.call_args(w_init, __args__)
  168. if not space.is_w(w_result, space.w_None):
  169. raise oefmt(space.w_TypeError, "__init__() should return None")
  170. elif __args__.arguments_w or __args__.keywords:
  171. raise oefmt(space.w_TypeError, "this constructor takes no arguments")
  172. return w_inst
  173. W_ClassObject.typedef = TypeDef("classobj",
  174. __new__ = interp2app(descr_classobj_new),
  175. __repr__ = interp2app(W_ClassObject.descr_repr),
  176. __str__ = interp2app(W_ClassObject.descr_str),
  177. __call__ = interp2app(class_descr_call),
  178. __getattribute__ = interp2app(W_ClassObject.descr_getattribute),
  179. __setattr__ = interp2app(W_ClassObject.descr_setattr),
  180. __delattr__ = interp2app(W_ClassObject.descr_delattr),
  181. __weakref__ = make_weakref_descr(W_ClassObject),
  182. )
  183. W_ClassObject.typedef.acceptable_as_base_class = False
  184. def make_unary_instance_method(name):
  185. def unaryop(self, space):
  186. w_meth = self.getattr(space, name, True)
  187. return space.call_function(w_meth)
  188. unaryop.func_name = name
  189. return unaryop
  190. def make_binary_returning_notimplemented_instance_method(name):
  191. def binaryop(self, space, w_other):
  192. try:
  193. w_meth = self.getattr(space, name, False)
  194. except OperationError as e:
  195. if e.match(space, space.w_AttributeError):
  196. return space.w_NotImplemented
  197. raise
  198. else:
  199. if w_meth is None:
  200. return space.w_NotImplemented
  201. return space.call_function(w_meth, w_other)
  202. binaryop.func_name = name
  203. return binaryop
  204. def make_binary_instance_method(name):
  205. specialname = "__%s__" % (name, )
  206. rspecialname = "__r%s__" % (name, )
  207. objspacename = name
  208. if name in ['and', 'or']:
  209. objspacename = name + '_'
  210. def binaryop(self, space, w_other):
  211. w_a, w_b = _coerce_helper(space, self, w_other)
  212. if isinstance(w_a, W_InstanceObject):
  213. w_meth = w_a.getattr(space, specialname, False)
  214. if w_meth is None:
  215. return space.w_NotImplemented
  216. return space.call_function(w_meth, w_b)
  217. else:
  218. # fall back to space.xxx() if coerce returns a non-W_Instance
  219. # object as first argument
  220. return getattr(space, objspacename)(w_a, w_b)
  221. binaryop.func_name = name
  222. def rbinaryop(self, space, w_other):
  223. w_a, w_b = _coerce_helper(space, self, w_other)
  224. if isinstance(w_a, W_InstanceObject):
  225. w_meth = w_a.getattr(space, rspecialname, False)
  226. if w_meth is None:
  227. return space.w_NotImplemented
  228. return space.call_function(w_meth, w_b)
  229. else:
  230. # fall back to space.xxx() if coerce returns a non-W_Instance
  231. # object as first argument
  232. return getattr(space, objspacename)(w_b, w_a)
  233. rbinaryop.func_name = "r" + name
  234. return binaryop, rbinaryop
  235. def _coerce_helper(space, w_self, w_other):
  236. try:
  237. w_tup = space.coerce(w_self, w_other)
  238. except OperationError as e:
  239. if not e.match(space, space.w_TypeError):
  240. raise
  241. return [w_self, w_other]
  242. return space.fixedview(w_tup, 2)
  243. def descr_instance_new(space, w_type, w_class, w_dict=None):
  244. # w_type is not used at all
  245. if not isinstance(w_class, W_ClassObject):
  246. raise oefmt(space.w_TypeError, "instance() first arg must be class")
  247. w_result = w_class.instantiate(space)
  248. if not space.is_none(w_dict):
  249. w_result.setdict(space, w_dict)
  250. return w_result
  251. class W_InstanceObject(W_Root):
  252. def __init__(self, space, w_class):
  253. # note that user_setup is overridden by the typedef.py machinery
  254. self.space = space
  255. self.user_setup(space, space.gettypeobject(self.typedef))
  256. assert isinstance(w_class, W_ClassObject)
  257. self.w_class = w_class
  258. if w_class.has_user_del(space):
  259. space.finalizer_queue.register_finalizer(self)
  260. def user_setup(self, space, w_subtype):
  261. pass
  262. def set_oldstyle_class(self, space, w_class):
  263. if w_class is None or not isinstance(w_class, W_ClassObject):
  264. raise oefmt(space.w_TypeError, "__class__ must be set to a class")
  265. self.w_class = w_class
  266. def getattr_from_class(self, space, name):
  267. # Look up w_name in the class dict, and call its __get__.
  268. # This method ignores the instance dict and the __getattr__.
  269. # Returns None if not found.
  270. assert isinstance(name, str)
  271. w_value = self.w_class.lookup(space, name)
  272. if w_value is None:
  273. return None
  274. w_descr_get = space.lookup(w_value, '__get__')
  275. if w_descr_get is None:
  276. return w_value
  277. return space.call_function(w_descr_get, w_value, self, self.w_class)
  278. def getattr(self, space, name, exc=True):
  279. # Normal getattr rules: look up w_name in the instance dict,
  280. # in the class dict, and then via a call to __getatttr__.
  281. assert isinstance(name, str)
  282. w_result = self.getdictvalue(space, name)
  283. if w_result is not None:
  284. return w_result
  285. w_result = self.getattr_from_class(space, name)
  286. if w_result is not None:
  287. return w_result
  288. w_meth = self.getattr_from_class(space, '__getattr__')
  289. if w_meth is not None:
  290. try:
  291. return space.call_function(w_meth, space.wrap(name))
  292. except OperationError as e:
  293. if not exc and e.match(space, space.w_AttributeError):
  294. return None # eat the AttributeError
  295. raise
  296. # not found at all
  297. if exc:
  298. raise oefmt(space.w_AttributeError,
  299. "%s instance has no attribute '%s'",
  300. self.w_class.name, name)
  301. else:
  302. return None
  303. @unwrap_spec(name=str)
  304. def descr_getattribute(self, space, name):
  305. if len(name) >= 8 and name[0] == '_':
  306. if name == "__dict__":
  307. return self.getdict(space)
  308. elif name == "__class__":
  309. return self.w_class
  310. return self.getattr(space, name)
  311. def descr_setattr(self, space, w_name, w_value):
  312. name = space.str_w(w_name)
  313. w_meth = self.getattr_from_class(space, '__setattr__')
  314. if name and name[0] == "_":
  315. if name == '__dict__':
  316. self.setdict(space, w_value)
  317. return
  318. if name == '__class__':
  319. self.set_oldstyle_class(space, w_value)
  320. return
  321. if name == '__del__' and w_meth is None:
  322. if (not self.w_class.has_user_del(space)
  323. and self.getdictvalue(space, '__del__') is None):
  324. msg = ("a __del__ method added to an instance with no "
  325. "__del__ in the class will not be called")
  326. space.warn(space.wrap(msg), space.w_RuntimeWarning)
  327. if w_meth is not None:
  328. space.call_function(w_meth, w_name, w_value)
  329. else:
  330. self.setdictvalue(space, name, w_value)
  331. def descr_delattr(self, space, w_name):
  332. name = space.str_w(w_name)
  333. if name and name[0] == "_":
  334. if name == '__dict__':
  335. # use setdict to raise the error
  336. self.setdict(space, space.w_None)
  337. return
  338. elif name == '__class__':
  339. # use set_oldstyle_class to raise the error
  340. self.set_oldstyle_class(space, None)
  341. return
  342. w_meth = self.getattr_from_class(space, '__delattr__')
  343. if w_meth is not None:
  344. space.call_function(w_meth, w_name)
  345. else:
  346. if not self.deldictvalue(space, name):
  347. raise oefmt(space.w_AttributeError,
  348. "%s instance has no attribute '%s'",
  349. self.w_class.name, name)
  350. def descr_repr(self, space):
  351. w_meth = self.getattr(space, '__repr__', False)
  352. if w_meth is None:
  353. w_class = self.w_class
  354. mod = w_class.get_module_string(space)
  355. return self.getrepr(space, "%s.%s instance" % (mod, w_class.name))
  356. return space.call_function(w_meth)
  357. def descr_str(self, space):
  358. w_meth = self.getattr(space, '__str__', False)
  359. if w_meth is None:
  360. return self.descr_repr(space)
  361. return space.call_function(w_meth)
  362. def descr_unicode(self, space):
  363. w_meth = self.getattr(space, '__unicode__', False)
  364. if w_meth is None:
  365. return self.descr_str(space)
  366. return space.call_function(w_meth)
  367. def descr_format(self, space, w_format_spec):
  368. w_meth = self.getattr(space, "__format__", False)
  369. if w_meth is not None:
  370. return space.call_function(w_meth, w_format_spec)
  371. else:
  372. if space.isinstance_w(w_format_spec, space.w_unicode):
  373. w_as_str = self.descr_unicode(space)
  374. else:
  375. w_as_str = self.descr_str(space)
  376. if space.len_w(w_format_spec) > 0:
  377. msg = ("object.__format__ with a non-empty format string is "
  378. "deprecated")
  379. space.warn(space.wrap(msg), space.w_PendingDeprecationWarning)
  380. return space.format(w_as_str, w_format_spec)
  381. def descr_len(self, space):
  382. w_meth = self.getattr(space, '__len__')
  383. w_result = space.call_function(w_meth)
  384. if space.isinstance_w(w_result, space.w_int):
  385. if space.is_true(space.lt(w_result, space.wrap(0))):
  386. raise oefmt(space.w_ValueError, "__len__() should return >= 0")
  387. return w_result
  388. raise oefmt(space.w_TypeError, "__len__() should return an int")
  389. def descr_getitem(self, space, w_key):
  390. w_meth = self.getattr(space, '__getitem__')
  391. return space.call_function(w_meth, w_key)
  392. def descr_setitem(self, space, w_key, w_value):
  393. w_meth = self.getattr(space, '__setitem__')
  394. space.call_function(w_meth, w_key, w_value)
  395. def descr_delitem(self, space, w_key):
  396. w_meth = self.getattr(space, '__delitem__')
  397. space.call_function(w_meth, w_key)
  398. def descr_iter(self, space):
  399. w_meth = self.getattr(space, '__iter__', False)
  400. if w_meth is not None:
  401. return space.call_function(w_meth)
  402. w_meth = self.getattr(space, '__getitem__', False)
  403. if w_meth is None:
  404. raise oefmt(space.w_TypeError, "iteration over non-sequence")
  405. return space.newseqiter(self)
  406. #XXX do I really need a next method? the old implementation had one, but I
  407. # don't see the point
  408. def descr_getslice(self, space, w_i, w_j):
  409. w_meth = self.getattr(space, '__getslice__', False)
  410. if w_meth is not None:
  411. return space.call_function(w_meth, w_i, w_j)
  412. else:
  413. return space.getitem(self, space.newslice(w_i, w_j, space.w_None))
  414. def descr_setslice(self, space, w_i, w_j, w_sequence):
  415. w_meth = self.getattr(space, '__setslice__', False)
  416. if w_meth is not None:
  417. space.call_function(w_meth, w_i, w_j, w_sequence)
  418. else:
  419. space.setitem(self, space.newslice(w_i, w_j, space.w_None),
  420. w_sequence)
  421. def descr_delslice(self, space, w_i, w_j):
  422. w_meth = self.getattr(space, '__delslice__', False)
  423. if w_meth is not None:
  424. space.call_function(w_meth, w_i, w_j)
  425. else:
  426. return space.delitem(self, space.newslice(w_i, w_j, space.w_None))
  427. def descr_call(self, space, __args__):
  428. w_meth = self.getattr(space, '__call__')
  429. return space.call_args(w_meth, __args__)
  430. def descr_nonzero(self, space):
  431. w_func = self.getattr(space, '__nonzero__', False)
  432. if w_func is None:
  433. w_func = self.getattr(space, '__len__', False)
  434. if w_func is None:
  435. return space.w_True
  436. w_result = space.call_function(w_func)
  437. if space.isinstance_w(w_result, space.w_int):
  438. if space.is_true(space.lt(w_result, space.wrap(0))):
  439. raise oefmt(space.w_ValueError,
  440. "__nonzero__() should return >= 0")
  441. return w_result
  442. raise oefmt(space.w_TypeError, "__nonzero__() should return an int")
  443. def descr_cmp(self, space, w_other): # do all the work here like CPython
  444. w_a, w_b = _coerce_helper(space, self, w_other)
  445. if (not isinstance(w_a, W_InstanceObject) and
  446. not isinstance(w_b, W_InstanceObject)):
  447. return space.cmp(w_a, w_b)
  448. if isinstance(w_a, W_InstanceObject):
  449. w_func = w_a.getattr(space, '__cmp__', False)
  450. if w_func is not None:
  451. w_res = space.call_function(w_func, w_b)
  452. if space.is_w(w_res, space.w_NotImplemented):
  453. return w_res
  454. try:
  455. res = space.int_w(w_res)
  456. except OperationError as e:
  457. if e.match(space, space.w_TypeError):
  458. raise oefmt(space.w_TypeError,
  459. "__cmp__ must return int")
  460. raise
  461. if res > 0:
  462. return space.wrap(1)
  463. if res < 0:
  464. return space.wrap(-1)
  465. return space.wrap(0)
  466. if isinstance(w_b, W_InstanceObject):
  467. w_func = w_b.getattr(space, '__cmp__', False)
  468. if w_func is not None:
  469. w_res = space.call_function(w_func, w_a)
  470. if space.is_w(w_res, space.w_NotImplemented):
  471. return w_res
  472. try:
  473. res = space.int_w(w_res)
  474. except OperationError as e:
  475. if e.match(space, space.w_TypeError):
  476. raise oefmt(space.w_TypeError,
  477. "__cmp__ must return int")
  478. raise
  479. if res < 0:
  480. return space.wrap(1)
  481. if res > 0:
  482. return space.wrap(-1)
  483. return space.wrap(0)
  484. return space.w_NotImplemented
  485. def descr_hash(self, space):
  486. w_func = self.getattr(space, '__hash__', False)
  487. if w_func is None:
  488. w_eq = self.getattr(space, '__eq__', False)
  489. w_cmp = self.getattr(space, '__cmp__', False)
  490. if w_eq is not None or w_cmp is not None:
  491. raise oefmt(space.w_TypeError, "unhashable instance")
  492. else:
  493. return space.wrap(compute_identity_hash(self))
  494. w_ret = space.call_function(w_func)
  495. if (not space.isinstance_w(w_ret, space.w_int) and
  496. not space.isinstance_w(w_ret, space.w_long)):
  497. raise oefmt(space.w_TypeError, "__hash__ must return int or long")
  498. return w_ret
  499. def descr_int(self, space):
  500. w_func = self.getattr(space, '__int__', False)
  501. if w_func is not None:
  502. return space.call_function(w_func)
  503. w_truncated = space.trunc(self)
  504. # int() needs to return an int
  505. try:
  506. return space.int(w_truncated)
  507. except OperationError:
  508. # Raise a different error
  509. raise oefmt(space.w_TypeError, "__trunc__ returned non-Integral")
  510. def descr_long(self, space):
  511. w_func = self.getattr(space, '__long__', False)
  512. if w_func is not None:
  513. return space.call_function(w_func)
  514. return self.descr_int(space)
  515. def descr_index(self, space):
  516. w_func = self.getattr(space, '__index__', False)
  517. if w_func is not None:
  518. return space.call_function(w_func)
  519. raise oefmt(space.w_TypeError,
  520. "object cannot be interpreted as an index")
  521. def descr_contains(self, space, w_obj):
  522. w_func = self.getattr(space, '__contains__', False)
  523. if w_func is not None:
  524. return space.wrap(space.is_true(space.call_function(w_func, w_obj)))
  525. # now do it ourselves
  526. w_iter = space.iter(self)
  527. while 1:
  528. try:
  529. w_x = space.next(w_iter)
  530. except OperationError as e:
  531. if e.match(space, space.w_StopIteration):
  532. return space.w_False
  533. raise
  534. if space.eq_w(w_x, w_obj):
  535. return space.w_True
  536. def descr_pow(self, space, w_other, w_modulo=None):
  537. if space.is_none(w_modulo):
  538. w_a, w_b = _coerce_helper(space, self, w_other)
  539. if isinstance(w_a, W_InstanceObject):
  540. w_func = w_a.getattr(space, '__pow__', False)
  541. if w_func is None:
  542. return space.w_NotImplemented
  543. return space.call_function(w_func, w_other)
  544. else:
  545. return space.pow(w_a, w_b, space.w_None)
  546. else:
  547. # CPython also doesn't try coercion in this case
  548. w_func = self.getattr(space, '__pow__', False)
  549. if w_func is None:
  550. return space.w_NotImplemented
  551. return space.call_function(w_func, w_other, w_modulo)
  552. def descr_rpow(self, space, w_other, w_modulo=None):
  553. if space.is_none(w_modulo):
  554. w_a, w_b = _coerce_helper(space, self, w_other)
  555. if isinstance(w_a, W_InstanceObject):
  556. w_func = w_a.getattr(space, '__rpow__', False)
  557. if w_func is None:
  558. return space.w_NotImplemented
  559. return space.call_function(w_func, w_other)
  560. else:
  561. return space.pow(w_b, w_a, space.w_None)
  562. else:
  563. # CPython also doesn't try coercion in this case
  564. w_func = self.getattr(space, '__rpow__', False)
  565. if w_func is None:
  566. return space.w_NotImplemented
  567. return space.call_function(w_func, w_other, w_modulo)
  568. def descr_next(self, space):
  569. w_func = self.getattr(space, 'next', False)
  570. if w_func is None:
  571. raise oefmt(space.w_TypeError, "instance has no next() method")
  572. return space.call_function(w_func)
  573. def _finalize_(self):
  574. space = self.space
  575. w_func = self.getdictvalue(space, '__del__')
  576. if w_func is None:
  577. w_func = self.getattr_from_class(space, '__del__')
  578. if w_func is not None:
  579. if self.space.user_del_action.gc_disabled(self):
  580. return
  581. space.call_function(w_func)
  582. def descr_exit(self, space, w_type, w_value, w_tb):
  583. w_func = self.getattr(space, '__exit__', False)
  584. if w_func is not None:
  585. return space.call_function(w_func, w_type, w_value, w_tb)
  586. rawdict = {}
  587. # unary operations
  588. for op in "neg pos abs invert trunc float oct hex enter reversed".split():
  589. specialname = "__%s__" % (op, )
  590. # fool the gateway logic by giving it a real unbound method
  591. meth = new.instancemethod(
  592. make_unary_instance_method(specialname),
  593. None,
  594. W_InstanceObject)
  595. rawdict[specialname] = interp2app(meth)
  596. # binary operations that return NotImplemented if they fail
  597. # e.g. rich comparisons, coerce and inplace ops
  598. for op in 'eq ne gt lt ge le coerce imod iand ipow itruediv ilshift ixor irshift ifloordiv idiv isub imul iadd ior'.split():
  599. specialname = "__%s__" % (op, )
  600. # fool the gateway logic by giving it a real unbound method
  601. meth = new.instancemethod(
  602. make_binary_returning_notimplemented_instance_method(specialname),
  603. None,
  604. W_InstanceObject)
  605. rawdict[specialname] = interp2app(meth)
  606. for op in "or and xor lshift rshift add sub mul div mod divmod floordiv truediv".split():
  607. specialname = "__%s__" % (op, )
  608. rspecialname = "__r%s__" % (op, )
  609. func, rfunc = make_binary_instance_method(op)
  610. # fool the gateway logic by giving it a real unbound method
  611. meth = new.instancemethod(func, None, W_InstanceObject)
  612. rawdict[specialname] = interp2app(meth)
  613. rmeth = new.instancemethod(rfunc, None, W_InstanceObject)
  614. rawdict[rspecialname] = interp2app(rmeth)
  615. def descr_del_dict(space, w_inst):
  616. # use setdict to raise the error
  617. w_inst.setdict(space, space.w_None)
  618. dict_descr = GetSetProperty(descr_get_dict, descr_set_dict, descr_del_dict)
  619. dict_descr.name = '__dict__'
  620. W_InstanceObject.typedef = TypeDef("instance",
  621. __new__ = interp2app(descr_instance_new),
  622. __getattribute__ = interp2app(W_InstanceObject.descr_getattribute),
  623. __setattr__ = interp2app(W_InstanceObject.descr_setattr),
  624. __delattr__ = interp2app(W_InstanceObject.descr_delattr),
  625. __repr__ = interp2app(W_InstanceObject.descr_repr),
  626. __str__ = interp2app(W_InstanceObject.descr_str),
  627. __unicode__ = interp2app(W_InstanceObject.descr_unicode),
  628. __format__ = interp2app(W_InstanceObject.descr_format),
  629. __len__ = interp2app(W_InstanceObject.descr_len),
  630. __getitem__ = interp2app(W_InstanceObject.descr_getitem),
  631. __setitem__ = interp2app(W_InstanceObject.descr_setitem),
  632. __delitem__ = interp2app(W_InstanceObject.descr_delitem),
  633. __iter__ = interp2app(W_InstanceObject.descr_iter),
  634. __getslice__ = interp2app(W_InstanceObject.descr_getslice),
  635. __setslice__ = interp2app(W_InstanceObject.descr_setslice),
  636. __delslice__ = interp2app(W_InstanceObject.descr_delslice),
  637. __call__ = interp2app(W_InstanceObject.descr_call),
  638. __nonzero__ = interp2app(W_InstanceObject.descr_nonzero),
  639. __cmp__ = interp2app(W_InstanceObject.descr_cmp),
  640. __hash__ = interp2app(W_InstanceObject.descr_hash),
  641. __int__ = interp2app(W_InstanceObject.descr_int),
  642. __long__ = interp2app(W_InstanceObject.descr_long),
  643. __index__ = interp2app(W_InstanceObject.descr_index),
  644. __contains__ = interp2app(W_InstanceObject.descr_contains),
  645. __pow__ = interp2app(W_InstanceObject.descr_pow),
  646. __rpow__ = interp2app(W_InstanceObject.descr_rpow),
  647. next = interp2app(W_InstanceObject.descr_next),
  648. __exit__ = interp2app(W_InstanceObject.descr_exit),
  649. __dict__ = dict_descr,
  650. **rawdict
  651. )
  652. W_InstanceObject.typedef.acceptable_as_base_class = False