PageRenderTime 49ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/pypy/objspace/std/objspace.py

https://bitbucket.org/pypy/pypy/
Python | 647 lines | 483 code | 84 blank | 80 comment | 130 complexity | 501e8d4358de0f3f9b2039067bc917a4 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import __builtin__
  2. from pypy.interpreter import special
  3. from pypy.interpreter.baseobjspace import ObjSpace, W_Root
  4. from pypy.interpreter.error import OperationError, oefmt
  5. from pypy.interpreter.typedef import get_unique_interplevel_subclass
  6. from pypy.objspace.std import frame, transparent, callmethod
  7. from pypy.objspace.descroperation import DescrOperation, raiseattrerror
  8. from rpython.rlib.objectmodel import instantiate, specialize, is_annotation_constant
  9. from rpython.rlib.debug import make_sure_not_resized
  10. from rpython.rlib.rarithmetic import base_int, widen, is_valid_int
  11. from rpython.rlib.objectmodel import import_from_mixin
  12. from rpython.rlib import jit
  13. # Object imports
  14. from pypy.objspace.std.basestringtype import basestring_typedef
  15. from pypy.objspace.std.boolobject import W_BoolObject
  16. from pypy.objspace.std.bufferobject import W_Buffer
  17. from pypy.objspace.std.bytearrayobject import W_BytearrayObject
  18. from pypy.objspace.std.bytesobject import W_AbstractBytesObject, W_BytesObject
  19. from pypy.objspace.std.complexobject import W_ComplexObject
  20. from pypy.objspace.std.dictmultiobject import W_DictMultiObject, W_DictObject
  21. from pypy.objspace.std.floatobject import W_FloatObject
  22. from pypy.objspace.std.intobject import W_IntObject, setup_prebuilt, wrapint
  23. from pypy.objspace.std.iterobject import W_AbstractSeqIterObject, W_SeqIterObject
  24. from pypy.objspace.std.listobject import W_ListObject
  25. from pypy.objspace.std.longobject import W_LongObject, newlong
  26. from pypy.objspace.std.memoryobject import W_MemoryView
  27. from pypy.objspace.std.noneobject import W_NoneObject
  28. from pypy.objspace.std.objectobject import W_ObjectObject
  29. from pypy.objspace.std.setobject import W_SetObject, W_FrozensetObject
  30. from pypy.objspace.std.sliceobject import W_SliceObject
  31. from pypy.objspace.std.tupleobject import W_AbstractTupleObject, W_TupleObject
  32. from pypy.objspace.std.typeobject import W_TypeObject, TypeCache
  33. from pypy.objspace.std.unicodeobject import W_UnicodeObject
  34. class StdObjSpace(ObjSpace):
  35. """The standard object space, implementing a general-purpose object
  36. library in Restricted Python."""
  37. import_from_mixin(DescrOperation)
  38. def initialize(self):
  39. """NOT_RPYTHON: only for initializing the space
  40. Setup all the object types and implementations.
  41. """
  42. setup_prebuilt(self)
  43. self.FrameClass = frame.build_frame(self)
  44. self.StringObjectCls = W_BytesObject
  45. self.UnicodeObjectCls = W_UnicodeObject
  46. # singletons
  47. self.w_None = W_NoneObject.w_None
  48. self.w_False = W_BoolObject.w_False
  49. self.w_True = W_BoolObject.w_True
  50. self.w_NotImplemented = self.wrap(special.NotImplemented())
  51. self.w_Ellipsis = self.wrap(special.Ellipsis())
  52. # types
  53. builtin_type_classes = {
  54. W_BoolObject.typedef: W_BoolObject,
  55. W_Buffer.typedef: W_Buffer,
  56. W_BytearrayObject.typedef: W_BytearrayObject,
  57. W_BytesObject.typedef: W_BytesObject,
  58. W_ComplexObject.typedef: W_ComplexObject,
  59. W_DictMultiObject.typedef: W_DictMultiObject,
  60. W_FloatObject.typedef: W_FloatObject,
  61. W_IntObject.typedef: W_IntObject,
  62. W_AbstractSeqIterObject.typedef: W_AbstractSeqIterObject,
  63. W_ListObject.typedef: W_ListObject,
  64. W_LongObject.typedef: W_LongObject,
  65. W_MemoryView.typedef: W_MemoryView,
  66. W_NoneObject.typedef: W_NoneObject,
  67. W_ObjectObject.typedef: W_ObjectObject,
  68. W_SetObject.typedef: W_SetObject,
  69. W_FrozensetObject.typedef: W_FrozensetObject,
  70. W_SliceObject.typedef: W_SliceObject,
  71. W_TupleObject.typedef: W_TupleObject,
  72. W_TypeObject.typedef: W_TypeObject,
  73. W_UnicodeObject.typedef: W_UnicodeObject,
  74. }
  75. if self.config.objspace.std.withstrbuf:
  76. builtin_type_classes[W_BytesObject.typedef] = W_AbstractBytesObject
  77. self.builtin_types = {}
  78. self._interplevel_classes = {}
  79. for typedef, cls in builtin_type_classes.items():
  80. w_type = self.gettypeobject(typedef)
  81. self.builtin_types[typedef.name] = w_type
  82. setattr(self, 'w_' + typedef.name, w_type)
  83. self._interplevel_classes[w_type] = cls
  84. self.w_dict.flag_map_or_seq = 'M'
  85. self.builtin_types["NotImplemented"] = self.w_NotImplemented
  86. self.builtin_types["Ellipsis"] = self.w_Ellipsis
  87. self.w_basestring = self.builtin_types['basestring'] = \
  88. self.gettypeobject(basestring_typedef)
  89. # exceptions & builtins
  90. self.make_builtins()
  91. # the type of old-style classes
  92. self.w_classobj = self.builtin.get('__metaclass__')
  93. # final setup
  94. self.setup_builtin_modules()
  95. # Adding transparent proxy call
  96. if self.config.objspace.std.withtproxy:
  97. transparent.setup(self)
  98. def get_builtin_types(self):
  99. return self.builtin_types
  100. def createexecutioncontext(self):
  101. # add space specific fields to execution context
  102. # note that this method must not call space methods that might need an
  103. # execution context themselves (e.g. nearly all space methods)
  104. ec = ObjSpace.createexecutioncontext(self)
  105. ec._py_repr = None
  106. return ec
  107. def gettypefor(self, cls):
  108. return self.gettypeobject(cls.typedef)
  109. def gettypeobject(self, typedef):
  110. # typeobject.TypeCache maps a TypeDef instance to its
  111. # unique-for-this-space W_TypeObject instance
  112. assert typedef is not None
  113. return self.fromcache(TypeCache).getorbuild(typedef)
  114. @specialize.argtype(1)
  115. def wrap(self, x):
  116. "Wraps the Python value 'x' into one of the wrapper classes."
  117. # You might notice that this function is rather conspicuously
  118. # not RPython. We can get away with this because the function
  119. # is specialized (see after the function body). Also worth
  120. # noting is that the isinstance's involving integer types
  121. # behave rather differently to how you might expect during
  122. # annotation (see pypy/annotation/builtin.py)
  123. if x is None:
  124. return self.w_None
  125. if isinstance(x, OperationError):
  126. raise TypeError("attempt to wrap already wrapped exception: %s"%
  127. (x,))
  128. if isinstance(x, int):
  129. if isinstance(x, bool):
  130. return self.newbool(x)
  131. else:
  132. return self.newint(x)
  133. if isinstance(x, str):
  134. return self.newbytes(x)
  135. if isinstance(x, unicode):
  136. return self.newunicode(x)
  137. if isinstance(x, float):
  138. return W_FloatObject(x)
  139. if isinstance(x, W_Root):
  140. w_result = x.__spacebind__(self)
  141. #print 'wrapping', x, '->', w_result
  142. return w_result
  143. if isinstance(x, base_int):
  144. if self.config.objspace.std.withsmalllong:
  145. from pypy.objspace.std.smalllongobject import W_SmallLongObject
  146. from rpython.rlib.rarithmetic import r_longlong, r_ulonglong
  147. from rpython.rlib.rarithmetic import longlongmax
  148. if (not isinstance(x, r_ulonglong)
  149. or x <= r_ulonglong(longlongmax)):
  150. return W_SmallLongObject(r_longlong(x))
  151. x = widen(x)
  152. if isinstance(x, int):
  153. return self.newint(x)
  154. else:
  155. return W_LongObject.fromrarith_int(x)
  156. return self._wrap_not_rpython(x)
  157. def _wrap_not_rpython(self, x):
  158. "NOT_RPYTHON"
  159. # _____ this code is here to support testing only _____
  160. # we might get there in non-translated versions if 'x' is
  161. # a long that fits the correct range.
  162. if is_valid_int(x):
  163. return self.newint(x)
  164. # wrap() of a container works on CPython, but the code is
  165. # not RPython. Don't use -- it is kept around mostly for tests.
  166. # Use instead newdict(), newlist(), newtuple().
  167. if isinstance(x, dict):
  168. items_w = [(self.wrap(k), self.wrap(v)) for (k, v) in x.iteritems()]
  169. r = self.newdict()
  170. r.initialize_content(items_w)
  171. return r
  172. if isinstance(x, tuple):
  173. wrappeditems = [self.wrap(item) for item in list(x)]
  174. return self.newtuple(wrappeditems)
  175. if isinstance(x, list):
  176. wrappeditems = [self.wrap(item) for item in x]
  177. return self.newlist(wrappeditems)
  178. # The following cases are even stranger.
  179. # Really really only for tests.
  180. if type(x) is long:
  181. return self.wraplong(x)
  182. if isinstance(x, slice):
  183. return W_SliceObject(self.wrap(x.start),
  184. self.wrap(x.stop),
  185. self.wrap(x.step))
  186. if isinstance(x, complex):
  187. return W_ComplexObject(x.real, x.imag)
  188. if isinstance(x, set):
  189. res = W_SetObject(self, self.newlist([self.wrap(item) for item in x]))
  190. return res
  191. if isinstance(x, frozenset):
  192. wrappeditems = [self.wrap(item) for item in x]
  193. return W_FrozensetObject(self, wrappeditems)
  194. if x is __builtin__.Ellipsis:
  195. # '__builtin__.Ellipsis' avoids confusion with special.Ellipsis
  196. return self.w_Ellipsis
  197. raise OperationError(self.w_RuntimeError,
  198. self.wrap("refusing to wrap cpython value %r" % (x,))
  199. )
  200. def wrap_exception_cls(self, x):
  201. """NOT_RPYTHON"""
  202. if hasattr(self, 'w_' + x.__name__):
  203. w_result = getattr(self, 'w_' + x.__name__)
  204. return w_result
  205. return None
  206. def wraplong(self, x):
  207. "NOT_RPYTHON"
  208. if self.config.objspace.std.withsmalllong:
  209. from rpython.rlib.rarithmetic import r_longlong
  210. try:
  211. rx = r_longlong(x)
  212. except OverflowError:
  213. pass
  214. else:
  215. from pypy.objspace.std.smalllongobject import \
  216. W_SmallLongObject
  217. return W_SmallLongObject(rx)
  218. return W_LongObject.fromlong(x)
  219. def unwrap(self, w_obj):
  220. """NOT_RPYTHON"""
  221. # _____ this code is here to support testing only _____
  222. if isinstance(w_obj, W_Root):
  223. return w_obj.unwrap(self)
  224. raise TypeError("cannot unwrap: %r" % w_obj)
  225. def newint(self, intval):
  226. return wrapint(self, intval)
  227. def newfloat(self, floatval):
  228. return W_FloatObject(floatval)
  229. def newcomplex(self, realval, imagval):
  230. return W_ComplexObject(realval, imagval)
  231. def unpackcomplex(self, w_complex):
  232. from pypy.objspace.std.complexobject import unpackcomplex
  233. return unpackcomplex(self, w_complex)
  234. def newlong(self, val): # val is an int
  235. if self.config.objspace.std.withsmalllong:
  236. from pypy.objspace.std.smalllongobject import W_SmallLongObject
  237. return W_SmallLongObject.fromint(val)
  238. return W_LongObject.fromint(self, val)
  239. def newlong_from_rbigint(self, val):
  240. return newlong(self, val)
  241. def newtuple(self, list_w):
  242. from pypy.objspace.std.tupleobject import wraptuple
  243. assert isinstance(list_w, list)
  244. make_sure_not_resized(list_w)
  245. return wraptuple(self, list_w)
  246. def newlist(self, list_w, sizehint=-1):
  247. assert not list_w or sizehint == -1
  248. return W_ListObject(self, list_w, sizehint)
  249. def newlist_bytes(self, list_s):
  250. return W_ListObject.newlist_bytes(self, list_s)
  251. def newlist_unicode(self, list_u):
  252. return W_ListObject.newlist_unicode(self, list_u)
  253. def newlist_int(self, list_i):
  254. return W_ListObject.newlist_int(self, list_i)
  255. def newlist_float(self, list_f):
  256. return W_ListObject.newlist_float(self, list_f)
  257. def newdict(self, module=False, instance=False, kwargs=False,
  258. strdict=False):
  259. return W_DictMultiObject.allocate_and_init_instance(
  260. self, module=module, instance=instance,
  261. strdict=strdict, kwargs=kwargs)
  262. def newset(self, iterable_w=None):
  263. if iterable_w is None:
  264. return W_SetObject(self, None)
  265. return W_SetObject(self, self.newtuple(iterable_w))
  266. def newfrozenset(self, iterable_w=None):
  267. if iterable_w is None:
  268. return W_FrozensetObject(self, None)
  269. return W_FrozensetObject(self, self.newtuple(iterable_w))
  270. def newslice(self, w_start, w_end, w_step):
  271. return W_SliceObject(w_start, w_end, w_step)
  272. def newseqiter(self, w_obj):
  273. return W_SeqIterObject(w_obj)
  274. def newbuffer(self, w_obj):
  275. return W_Buffer(w_obj)
  276. def newbytes(self, s):
  277. return W_BytesObject(s)
  278. def newunicode(self, uni):
  279. return W_UnicodeObject(uni)
  280. def type(self, w_obj):
  281. jit.promote(w_obj.__class__)
  282. return w_obj.getclass(self)
  283. def lookup(self, w_obj, name):
  284. w_type = self.type(w_obj)
  285. return w_type.lookup(name)
  286. lookup._annspecialcase_ = 'specialize:lookup'
  287. def lookup_in_type_where(self, w_type, name):
  288. return w_type.lookup_where(name)
  289. lookup_in_type_where._annspecialcase_ = 'specialize:lookup_in_type_where'
  290. def lookup_in_type_starting_at(self, w_type, w_starttype, name):
  291. """ Only supposed to be used to implement super, w_starttype
  292. and w_type are the same as for super(starttype, type)
  293. """
  294. assert isinstance(w_type, W_TypeObject)
  295. assert isinstance(w_starttype, W_TypeObject)
  296. return w_type.lookup_starting_at(w_starttype, name)
  297. def allocate_instance(self, cls, w_subtype):
  298. """Allocate the memory needed for an instance of an internal or
  299. user-defined type, without actually __init__ializing the instance."""
  300. w_type = self.gettypeobject(cls.typedef)
  301. if self.is_w(w_type, w_subtype):
  302. instance = instantiate(cls)
  303. elif cls.typedef.acceptable_as_base_class:
  304. # the purpose of the above check is to avoid the code below
  305. # to be annotated at all for 'cls' if it is not necessary
  306. w_subtype = w_type.check_user_subclass(w_subtype)
  307. if cls.typedef.applevel_subclasses_base is not None:
  308. cls = cls.typedef.applevel_subclasses_base
  309. #
  310. subcls = get_unique_interplevel_subclass(self, cls)
  311. instance = instantiate(subcls)
  312. assert isinstance(instance, cls)
  313. instance.user_setup(self, w_subtype)
  314. if w_subtype.hasuserdel:
  315. self.finalizer_queue.register_finalizer(instance)
  316. else:
  317. raise oefmt(self.w_TypeError,
  318. "%N.__new__(%N): only for the type %N",
  319. w_type, w_subtype, w_type)
  320. return instance
  321. allocate_instance._annspecialcase_ = "specialize:arg(1)"
  322. # two following functions are almost identical, but in fact they
  323. # have different return type. First one is a resizable list, second
  324. # one is not
  325. def _wrap_expected_length(self, expected, got):
  326. return oefmt(self.w_ValueError,
  327. "expected length %d, got %d", expected, got)
  328. def unpackiterable(self, w_obj, expected_length=-1):
  329. if isinstance(w_obj, W_AbstractTupleObject) and self._uses_tuple_iter(w_obj):
  330. t = w_obj.getitems_copy()
  331. elif type(w_obj) is W_ListObject:
  332. t = w_obj.getitems_copy()
  333. else:
  334. return ObjSpace.unpackiterable(self, w_obj, expected_length)
  335. if expected_length != -1 and len(t) != expected_length:
  336. raise self._wrap_expected_length(expected_length, len(t))
  337. return t
  338. @specialize.arg(3)
  339. def fixedview(self, w_obj, expected_length=-1, unroll=False):
  340. """ Fast paths
  341. """
  342. if isinstance(w_obj, W_AbstractTupleObject) and self._uses_tuple_iter(w_obj):
  343. t = w_obj.tolist()
  344. elif type(w_obj) is W_ListObject:
  345. if unroll:
  346. t = w_obj.getitems_unroll()
  347. else:
  348. t = w_obj.getitems_fixedsize()
  349. else:
  350. if unroll:
  351. return make_sure_not_resized(ObjSpace.unpackiterable_unroll(
  352. self, w_obj, expected_length))
  353. else:
  354. return make_sure_not_resized(ObjSpace.unpackiterable(
  355. self, w_obj, expected_length)[:])
  356. if expected_length != -1 and len(t) != expected_length:
  357. raise self._wrap_expected_length(expected_length, len(t))
  358. return make_sure_not_resized(t)
  359. def fixedview_unroll(self, w_obj, expected_length):
  360. assert expected_length >= 0
  361. return self.fixedview(w_obj, expected_length, unroll=True)
  362. def listview_no_unpack(self, w_obj):
  363. if type(w_obj) is W_ListObject:
  364. return w_obj.getitems()
  365. elif isinstance(w_obj, W_AbstractTupleObject) and self._uses_tuple_iter(w_obj):
  366. return w_obj.getitems_copy()
  367. elif isinstance(w_obj, W_ListObject) and self._uses_list_iter(w_obj):
  368. return w_obj.getitems()
  369. else:
  370. return None
  371. def listview(self, w_obj, expected_length=-1):
  372. t = self.listview_no_unpack(w_obj)
  373. if t is None:
  374. return ObjSpace.unpackiterable(self, w_obj, expected_length)
  375. if expected_length != -1 and len(t) != expected_length:
  376. raise self._wrap_expected_length(expected_length, len(t))
  377. return t
  378. def listview_bytes(self, w_obj):
  379. # note: uses exact type checking for objects with strategies,
  380. # and isinstance() for others. See test_listobject.test_uses_custom...
  381. if type(w_obj) is W_ListObject:
  382. return w_obj.getitems_bytes()
  383. if type(w_obj) is W_DictObject:
  384. return w_obj.listview_bytes()
  385. if type(w_obj) is W_SetObject or type(w_obj) is W_FrozensetObject:
  386. return w_obj.listview_bytes()
  387. if isinstance(w_obj, W_BytesObject) and self._uses_no_iter(w_obj):
  388. return w_obj.listview_bytes()
  389. if isinstance(w_obj, W_ListObject) and self._uses_list_iter(w_obj):
  390. return w_obj.getitems_bytes()
  391. return None
  392. def listview_unicode(self, w_obj):
  393. # note: uses exact type checking for objects with strategies,
  394. # and isinstance() for others. See test_listobject.test_uses_custom...
  395. if type(w_obj) is W_ListObject:
  396. return w_obj.getitems_unicode()
  397. if type(w_obj) is W_DictObject:
  398. return w_obj.listview_unicode()
  399. if type(w_obj) is W_SetObject or type(w_obj) is W_FrozensetObject:
  400. return w_obj.listview_unicode()
  401. if isinstance(w_obj, W_UnicodeObject) and self._uses_no_iter(w_obj):
  402. return w_obj.listview_unicode()
  403. if isinstance(w_obj, W_ListObject) and self._uses_list_iter(w_obj):
  404. return w_obj.getitems_unicode()
  405. return None
  406. def listview_int(self, w_obj):
  407. if type(w_obj) is W_ListObject:
  408. return w_obj.getitems_int()
  409. if type(w_obj) is W_DictObject:
  410. return w_obj.listview_int()
  411. if type(w_obj) is W_SetObject or type(w_obj) is W_FrozensetObject:
  412. return w_obj.listview_int()
  413. if isinstance(w_obj, W_ListObject) and self._uses_list_iter(w_obj):
  414. return w_obj.getitems_int()
  415. return None
  416. def listview_float(self, w_obj):
  417. if type(w_obj) is W_ListObject:
  418. return w_obj.getitems_float()
  419. # dict and set don't have FloatStrategy, so we can just ignore them
  420. # for now
  421. if isinstance(w_obj, W_ListObject) and self._uses_list_iter(w_obj):
  422. return w_obj.getitems_float()
  423. return None
  424. def view_as_kwargs(self, w_dict):
  425. # Tries to return (keys_list, values_list), or (None, None) if
  426. # it fails. It can fail on some dict implementations, so don't
  427. # rely on it. For dict subclasses, though, it never fails;
  428. # this emulates CPython's behavior which often won't call
  429. # custom __iter__() or keys() methods in dict subclasses.
  430. if isinstance(w_dict, W_DictObject):
  431. return w_dict.view_as_kwargs()
  432. return (None, None)
  433. def _uses_list_iter(self, w_obj):
  434. from pypy.objspace.descroperation import list_iter
  435. return self.lookup(w_obj, '__iter__') is list_iter(self)
  436. def _uses_tuple_iter(self, w_obj):
  437. from pypy.objspace.descroperation import tuple_iter
  438. return self.lookup(w_obj, '__iter__') is tuple_iter(self)
  439. def _uses_no_iter(self, w_obj):
  440. return self.lookup(w_obj, '__iter__') is None
  441. def sliceindices(self, w_slice, w_length):
  442. if isinstance(w_slice, W_SliceObject):
  443. a, b, c = w_slice.indices3(self, self.int_w(w_length))
  444. return (a, b, c)
  445. w_indices = self.getattr(w_slice, self.wrap('indices'))
  446. w_tup = self.call_function(w_indices, w_length)
  447. l_w = self.unpackiterable(w_tup)
  448. if not len(l_w) == 3:
  449. raise oefmt(self.w_ValueError, "Expected tuple of length 3")
  450. return self.int_w(l_w[0]), self.int_w(l_w[1]), self.int_w(l_w[2])
  451. _DescrOperation_is_true = is_true
  452. def is_true(self, w_obj):
  453. # a shortcut for performance
  454. if type(w_obj) is W_BoolObject:
  455. return bool(w_obj.intval)
  456. return self._DescrOperation_is_true(w_obj)
  457. def getattr(self, w_obj, w_name):
  458. # an optional shortcut for performance
  459. w_type = self.type(w_obj)
  460. w_descr = w_type.getattribute_if_not_from_object()
  461. if w_descr is not None:
  462. return self._handle_getattribute(w_descr, w_obj, w_name)
  463. # fast path: XXX this is duplicating most of the logic
  464. # from the default __getattribute__ and the getattr() method...
  465. name = self.str_w(w_name)
  466. w_descr = w_type.lookup(name)
  467. e = None
  468. if w_descr is not None:
  469. w_get = None
  470. is_data = self.is_data_descr(w_descr)
  471. if is_data:
  472. w_get = self.lookup(w_descr, "__get__")
  473. if w_get is None:
  474. w_value = w_obj.getdictvalue(self, name)
  475. if w_value is not None:
  476. return w_value
  477. if not is_data:
  478. w_get = self.lookup(w_descr, "__get__")
  479. if w_get is not None:
  480. # __get__ is allowed to raise an AttributeError to trigger
  481. # use of __getattr__.
  482. try:
  483. return self.get_and_call_function(w_get, w_descr, w_obj,
  484. w_type)
  485. except OperationError as e:
  486. if not e.match(self, self.w_AttributeError):
  487. raise
  488. else:
  489. return w_descr
  490. else:
  491. w_value = w_obj.getdictvalue(self, name)
  492. if w_value is not None:
  493. return w_value
  494. w_descr = self.lookup(w_obj, '__getattr__')
  495. if w_descr is not None:
  496. return self.get_and_call_function(w_descr, w_obj, w_name)
  497. elif e is not None:
  498. raise e
  499. else:
  500. raiseattrerror(self, w_obj, name)
  501. def finditem_str(self, w_obj, key):
  502. """ Perform a getitem on w_obj with key (string). Returns found
  503. element or None on element not found.
  504. performance shortcut to avoid creating the OperationError(KeyError)
  505. and allocating W_BytesObject
  506. """
  507. if (isinstance(w_obj, W_DictMultiObject) and
  508. not w_obj.user_overridden_class):
  509. return w_obj.getitem_str(key)
  510. return ObjSpace.finditem_str(self, w_obj, key)
  511. def finditem(self, w_obj, w_key):
  512. """ Perform a getitem on w_obj with w_key (any object). Returns found
  513. element or None on element not found.
  514. performance shortcut to avoid creating the OperationError(KeyError).
  515. """
  516. if (isinstance(w_obj, W_DictMultiObject) and
  517. not w_obj.user_overridden_class):
  518. return w_obj.getitem(w_key)
  519. return ObjSpace.finditem(self, w_obj, w_key)
  520. def setitem_str(self, w_obj, key, w_value):
  521. """ Same as setitem, but takes string instead of any wrapped object
  522. """
  523. if (isinstance(w_obj, W_DictMultiObject) and
  524. not w_obj.user_overridden_class):
  525. w_obj.setitem_str(key, w_value)
  526. else:
  527. self.setitem(w_obj, self.wrap(key), w_value)
  528. def getindex_w(self, w_obj, w_exception, objdescr=None):
  529. if type(w_obj) is W_IntObject:
  530. return w_obj.intval
  531. return ObjSpace.getindex_w(self, w_obj, w_exception, objdescr)
  532. def unicode_from_object(self, w_obj):
  533. from pypy.objspace.std.unicodeobject import unicode_from_object
  534. return unicode_from_object(self, w_obj)
  535. def call_method(self, w_obj, methname, *arg_w):
  536. return callmethod.call_method_opt(self, w_obj, methname, *arg_w)
  537. def _type_issubtype(self, w_sub, w_type):
  538. if isinstance(w_sub, W_TypeObject) and isinstance(w_type, W_TypeObject):
  539. return w_sub.issubtype(w_type)
  540. raise oefmt(self.w_TypeError, "need type objects")
  541. @specialize.arg_or_var(2)
  542. def _type_isinstance(self, w_inst, w_type):
  543. if not isinstance(w_type, W_TypeObject):
  544. raise oefmt(self.w_TypeError, "need type object")
  545. if is_annotation_constant(w_type):
  546. cls = self._get_interplevel_cls(w_type)
  547. if cls is not None:
  548. assert w_inst is not None
  549. if isinstance(w_inst, cls):
  550. return True
  551. return self.type(w_inst).issubtype(w_type)
  552. @specialize.memo()
  553. def _get_interplevel_cls(self, w_type):
  554. if not hasattr(self, "_interplevel_classes"):
  555. return None # before running initialize
  556. return self._interplevel_classes.get(w_type, None)
  557. @specialize.arg(2, 3)
  558. def is_overloaded(self, w_obj, tp, method):
  559. return (self.lookup(w_obj, method) is not
  560. self.lookup_in_type_where(tp, method)[1])