PageRenderTime 53ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/pypy/objspace/std/setobject.py

https://bitbucket.org/pypy/pypy/
Python | 1726 lines | 1720 code | 6 blank | 0 comment | 0 complexity | 581bc97b9bd61f0f98ec4a9bc35b7806 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0

Large files files are truncated, but you can click here to view the full file

  1. from pypy.interpreter import gateway
  2. from pypy.interpreter.baseobjspace import W_Root
  3. from pypy.interpreter.error import OperationError, oefmt
  4. from pypy.interpreter.signature import Signature
  5. from pypy.interpreter.typedef import TypeDef
  6. from pypy.objspace.std.bytesobject import W_BytesObject
  7. from pypy.objspace.std.intobject import W_IntObject
  8. from pypy.objspace.std.unicodeobject import W_UnicodeObject
  9. from pypy.objspace.std.util import IDTAG_SPECIAL, IDTAG_SHIFT
  10. from rpython.rlib.objectmodel import r_dict
  11. from rpython.rlib.objectmodel import iterkeys_with_hash, contains_with_hash
  12. from rpython.rlib.objectmodel import setitem_with_hash, delitem_with_hash
  13. from rpython.rlib.rarithmetic import intmask, r_uint
  14. from rpython.rlib import rerased, jit
  15. UNROLL_CUTOFF = 5
  16. class W_BaseSetObject(W_Root):
  17. typedef = None
  18. def __init__(self, space, w_iterable=None):
  19. """Initialize the set by taking ownership of 'setdata'."""
  20. self.space = space
  21. set_strategy_and_setdata(space, self, w_iterable)
  22. def __repr__(self):
  23. """representation for debugging purposes"""
  24. reprlist = [repr(w_item) for w_item in self.getkeys()]
  25. return "<%s(%s)(%s)>" % (self.__class__.__name__, self.strategy, ', '.join(reprlist))
  26. def from_storage_and_strategy(self, storage, strategy):
  27. obj = self._newobj(self.space, None)
  28. assert isinstance(obj, W_BaseSetObject)
  29. obj.strategy = strategy
  30. obj.sstorage = storage
  31. return obj
  32. _lifeline_ = None
  33. def getweakref(self):
  34. return self._lifeline_
  35. def setweakref(self, space, weakreflifeline):
  36. self._lifeline_ = weakreflifeline
  37. def delweakref(self):
  38. self._lifeline_ = None
  39. def switch_to_object_strategy(self, space):
  40. d = self.strategy.getdict_w(self)
  41. self.strategy = strategy = space.fromcache(ObjectSetStrategy)
  42. self.sstorage = strategy.erase(d)
  43. def switch_to_empty_strategy(self):
  44. self.strategy = strategy = self.space.fromcache(EmptySetStrategy)
  45. self.sstorage = strategy.get_empty_storage()
  46. # _____________ strategy methods ________________
  47. def clear(self):
  48. """ Removes all elements from the set. """
  49. self.strategy.clear(self)
  50. def copy_real(self):
  51. """ Returns a clone of the set. Frozensets storages are also copied."""
  52. return self.strategy.copy_real(self)
  53. def length(self):
  54. """ Returns the number of items inside the set. """
  55. return self.strategy.length(self)
  56. def add(self, w_key):
  57. """ Adds an element to the set. The element must be wrapped. """
  58. self.strategy.add(self, w_key)
  59. def remove(self, w_item):
  60. """ Removes the given element from the set. Element must be wrapped. """
  61. return self.strategy.remove(self, w_item)
  62. def getdict_w(self):
  63. """ Returns a dict with all elements of the set. Needed only for switching to ObjectSetStrategy. """
  64. return self.strategy.getdict_w(self)
  65. def listview_bytes(self):
  66. """ If this is a string set return its contents as a list of uwnrapped strings. Otherwise return None. """
  67. return self.strategy.listview_bytes(self)
  68. def listview_unicode(self):
  69. """ If this is a unicode set return its contents as a list of uwnrapped unicodes. Otherwise return None. """
  70. return self.strategy.listview_unicode(self)
  71. def listview_int(self):
  72. """ If this is an int set return its contents as a list of uwnrapped ints. Otherwise return None. """
  73. return self.strategy.listview_int(self)
  74. def get_storage_copy(self):
  75. """ Returns a copy of the storage. Needed when we want to clone all elements from one set and
  76. put them into another. """
  77. return self.strategy.get_storage_copy(self)
  78. def getkeys(self):
  79. """ Returns a list of all elements inside the set. Only used in __repr__. Use as less as possible."""
  80. return self.strategy.getkeys(self)
  81. def difference(self, w_other):
  82. """ Returns a set with all items that are in this set, but not in w_other. W_other must be a set."""
  83. return self.strategy.difference(self, w_other)
  84. def difference_update(self, w_other):
  85. """ As difference but overwrites the sets content with the result. W_other must be a set."""
  86. self.strategy.difference_update(self, w_other)
  87. def symmetric_difference(self, w_other):
  88. """ Returns a set with all items that are either in this set or in w_other, but not in both. W_other must be a set. """
  89. return self.strategy.symmetric_difference(self, w_other)
  90. def symmetric_difference_update(self, w_other):
  91. """ As symmetric_difference but overwrites the content of the set with the result. W_other must be a set."""
  92. self.strategy.symmetric_difference_update(self, w_other)
  93. def intersect(self, w_other):
  94. """ Returns a set with all items that exists in both sets, this set and in w_other. W_other must be a set. """
  95. return self.strategy.intersect(self, w_other)
  96. def intersect_update(self, w_other):
  97. """ Keeps only those elements found in both sets, removing all other elements. W_other must be a set."""
  98. self.strategy.intersect_update(self, w_other)
  99. def issubset(self, w_other):
  100. """ Checks wether this set is a subset of w_other. W_other must be a set. """
  101. return self.strategy.issubset(self, w_other)
  102. def isdisjoint(self, w_other):
  103. """ Checks wether this set and the w_other are completly different, i.e. have no equal elements. W_other must be a set."""
  104. return self.strategy.isdisjoint(self, w_other)
  105. def update(self, w_other):
  106. """ Appends all elements from the given set to this set. W_other must be a set."""
  107. self.strategy.update(self, w_other)
  108. def has_key(self, w_key):
  109. """ Checks wether this set contains the given wrapped key."""
  110. return self.strategy.has_key(self, w_key)
  111. def equals(self, w_other):
  112. """ Checks wether this set and the given set are equal, i.e. contain the same elements. W_other must be a set."""
  113. return self.strategy.equals(self, w_other)
  114. def iter(self):
  115. """ Returns an iterator of the elements from this set. """
  116. return self.strategy.iter(self)
  117. def popitem(self):
  118. """ Removes an arbitrary element from the set. May raise KeyError if set is empty."""
  119. return self.strategy.popitem(self)
  120. # app-level operations
  121. def descr_init(self, space, __args__):
  122. w_iterable, = __args__.parse_obj(
  123. None, 'set',
  124. init_signature,
  125. init_defaults)
  126. _initialize_set(space, self, w_iterable)
  127. def descr_repr(self, space):
  128. ec = space.getexecutioncontext()
  129. w_currently_in_repr = ec._py_repr
  130. if w_currently_in_repr is None:
  131. w_currently_in_repr = ec._py_repr = space.newdict()
  132. return setrepr(space, w_currently_in_repr, self)
  133. def descr_cmp(self, space, w_other):
  134. if space.is_w(space.type(self), space.type(w_other)):
  135. # hack hack until we get the expected result
  136. raise oefmt(space.w_TypeError, "cannot compare sets using cmp()")
  137. else:
  138. return space.w_NotImplemented
  139. def descr_eq(self, space, w_other):
  140. if isinstance(w_other, W_BaseSetObject):
  141. return space.wrap(self.equals(w_other))
  142. if not space.isinstance_w(w_other, space.w_set):
  143. return space.w_NotImplemented
  144. # XXX do not make new setobject here
  145. w_other_as_set = self._newobj(space, w_other)
  146. return space.wrap(self.equals(w_other_as_set))
  147. def descr_ne(self, space, w_other):
  148. if isinstance(w_other, W_BaseSetObject):
  149. return space.wrap(not self.equals(w_other))
  150. if not space.isinstance_w(w_other, space.w_set):
  151. return space.w_NotImplemented
  152. # XXX this is not tested
  153. w_other_as_set = self._newobj(space, w_other)
  154. return space.wrap(not self.equals(w_other_as_set))
  155. # automatic registration of "lt(x, y)" as "not ge(y, x)" would not give the
  156. # correct answer here!
  157. def descr_lt(self, space, w_other):
  158. if not isinstance(w_other, W_BaseSetObject):
  159. return space.w_NotImplemented
  160. if self.length() >= w_other.length():
  161. return space.w_False
  162. else:
  163. return self.descr_issubset(space, w_other)
  164. def descr_le(self, space, w_other):
  165. if not isinstance(w_other, W_BaseSetObject):
  166. return space.w_NotImplemented
  167. if self.length() > w_other.length():
  168. return space.w_False
  169. return space.wrap(self.issubset(w_other))
  170. def descr_gt(self, space, w_other):
  171. if not isinstance(w_other, W_BaseSetObject):
  172. return space.w_NotImplemented
  173. if self.length() <= w_other.length():
  174. return space.w_False
  175. else:
  176. return self.descr_issuperset(space, w_other)
  177. def descr_ge(self, space, w_other):
  178. if not isinstance(w_other, W_BaseSetObject):
  179. return space.w_NotImplemented
  180. if self.length() < w_other.length():
  181. return space.w_False
  182. return space.wrap(w_other.issubset(self))
  183. def descr_len(self, space):
  184. return space.newint(self.length())
  185. def descr_iter(self, space):
  186. return W_SetIterObject(space, self.iter())
  187. def descr_contains(self, space, w_other):
  188. try:
  189. return space.newbool(self.has_key(w_other))
  190. except OperationError as e:
  191. if e.match(space, space.w_TypeError):
  192. w_f = _convert_set_to_frozenset(space, w_other)
  193. if w_f is not None:
  194. return space.newbool(self.has_key(w_f))
  195. raise
  196. def descr_sub(self, space, w_other):
  197. if not isinstance(w_other, W_BaseSetObject):
  198. return space.w_NotImplemented
  199. return self.difference(w_other)
  200. def descr_and(self, space, w_other):
  201. if not isinstance(w_other, W_BaseSetObject):
  202. return space.w_NotImplemented
  203. return self.intersect(w_other)
  204. def descr_or(self, space, w_other):
  205. if not isinstance(w_other, W_BaseSetObject):
  206. return space.w_NotImplemented
  207. w_copy = self.copy_real()
  208. w_copy.update(w_other)
  209. return w_copy
  210. def descr_xor(self, space, w_other):
  211. if not isinstance(w_other, W_BaseSetObject):
  212. return space.w_NotImplemented
  213. return self.symmetric_difference(w_other)
  214. def descr_inplace_sub(self, space, w_other):
  215. if not isinstance(w_other, W_BaseSetObject):
  216. return space.w_NotImplemented
  217. self.difference_update(w_other)
  218. return self
  219. def descr_inplace_and(self, space, w_other):
  220. if not isinstance(w_other, W_BaseSetObject):
  221. return space.w_NotImplemented
  222. self.intersect_update(w_other)
  223. return self
  224. def descr_inplace_or(self, space, w_other):
  225. if not isinstance(w_other, W_BaseSetObject):
  226. return space.w_NotImplemented
  227. self.update(w_other)
  228. return self
  229. def descr_inplace_xor(self, space, w_other):
  230. if not isinstance(w_other, W_BaseSetObject):
  231. return space.w_NotImplemented
  232. self.descr_symmetric_difference_update(space, w_other)
  233. return self
  234. def descr_copy(self, space):
  235. """Return a shallow copy of a set."""
  236. if type(self) is W_FrozensetObject:
  237. return self
  238. return self.copy_real()
  239. @gateway.unwrap_spec(others_w='args_w')
  240. def descr_difference(self, space, others_w):
  241. """Return a new set with elements in the set that are not in the
  242. others."""
  243. result = self.copy_real()
  244. result.descr_difference_update(space, others_w)
  245. return result
  246. @gateway.unwrap_spec(others_w='args_w')
  247. def descr_intersection(self, space, others_w):
  248. """Return a new set with elements common to the set and all others."""
  249. #XXX find smarter implementations
  250. others_w = [self] + others_w
  251. # find smallest set in others_w to reduce comparisons
  252. startindex, startlength = 0, -1
  253. for i in range(len(others_w)):
  254. w_other = others_w[i]
  255. try:
  256. length = space.int_w(space.len(w_other))
  257. except OperationError as e:
  258. if (e.match(space, space.w_TypeError) or
  259. e.match(space, space.w_AttributeError)):
  260. continue
  261. raise
  262. if startlength == -1 or length < startlength:
  263. startindex = i
  264. startlength = length
  265. others_w[startindex], others_w[0] = others_w[0], others_w[startindex]
  266. result = self._newobj(space, others_w[0])
  267. for i in range(1,len(others_w)):
  268. w_other = others_w[i]
  269. if isinstance(w_other, W_BaseSetObject):
  270. result.intersect_update(w_other)
  271. else:
  272. w_other_as_set = self._newobj(space, w_other)
  273. result.intersect_update(w_other_as_set)
  274. return result
  275. def descr_issubset(self, space, w_other):
  276. """Report whether another set contains this set."""
  277. if space.is_w(self, w_other):
  278. return space.w_True
  279. if isinstance(w_other, W_BaseSetObject):
  280. if self.length() > w_other.length():
  281. return space.w_False
  282. return space.wrap(self.issubset(w_other))
  283. w_other_as_set = self._newobj(space, w_other)
  284. if self.length() > w_other_as_set.length():
  285. return space.w_False
  286. return space.wrap(self.issubset(w_other_as_set))
  287. def descr_issuperset(self, space, w_other):
  288. """Report whether this set contains another set."""
  289. if space.is_w(self, w_other):
  290. return space.w_True
  291. if isinstance(w_other, W_BaseSetObject):
  292. if self.length() < w_other.length():
  293. return space.w_False
  294. return space.wrap(w_other.issubset(self))
  295. w_other_as_set = self._newobj(space, w_other)
  296. if self.length() < w_other_as_set.length():
  297. return space.w_False
  298. return space.wrap(w_other_as_set.issubset(self))
  299. def descr_symmetric_difference(self, space, w_other):
  300. """Return the symmetric difference of two sets as a new set.
  301. (i.e. all elements that are in exactly one of the sets.)"""
  302. if isinstance(w_other, W_BaseSetObject):
  303. return self.symmetric_difference(w_other)
  304. w_other_as_set = self._newobj(space, w_other)
  305. return self.symmetric_difference(w_other_as_set)
  306. @gateway.unwrap_spec(others_w='args_w')
  307. def descr_union(self, space, others_w):
  308. """Return a new set with elements from the set and all others."""
  309. result = self.copy_real()
  310. for w_other in others_w:
  311. if isinstance(w_other, W_BaseSetObject):
  312. result.update(w_other)
  313. else:
  314. for w_key in space.listview(w_other):
  315. result.add(w_key)
  316. return result
  317. def descr_reduce(self, space):
  318. """Return state information for pickling."""
  319. return setreduce(space, self)
  320. def descr_isdisjoint(self, space, w_other):
  321. """Return True if two sets have a null intersection."""
  322. if isinstance(w_other, W_BaseSetObject):
  323. return space.newbool(self.isdisjoint(w_other))
  324. #XXX may be optimized when other strategies are added
  325. for w_key in space.listview(w_other):
  326. if self.has_key(w_key):
  327. return space.w_False
  328. return space.w_True
  329. def descr_add(self, space, w_other):
  330. """Add an element to a set.
  331. This has no effect if the element is already present."""
  332. self.add(w_other)
  333. def descr_clear(self, space):
  334. """Remove all elements from this set."""
  335. self.clear()
  336. @gateway.unwrap_spec(others_w='args_w')
  337. def descr_difference_update(self, space, others_w):
  338. """Update the set, removing elements found in others."""
  339. for w_other in others_w:
  340. if isinstance(w_other, W_BaseSetObject):
  341. self.difference_update(w_other)
  342. else:
  343. w_other_as_set = self._newobj(space, w_other)
  344. self.difference_update(w_other_as_set)
  345. def _discard_from_set(self, space, w_item):
  346. """
  347. Discard an element from a set, with automatic conversion to
  348. frozenset if the argument is a set.
  349. Returns True if successfully removed.
  350. """
  351. try:
  352. deleted = self.remove(w_item)
  353. except OperationError as e:
  354. if not e.match(space, space.w_TypeError):
  355. raise
  356. else:
  357. w_f = _convert_set_to_frozenset(space, w_item)
  358. if w_f is None:
  359. raise
  360. deleted = self.remove(w_f)
  361. if self.length() == 0:
  362. self.switch_to_empty_strategy()
  363. return deleted
  364. def descr_discard(self, space, w_item):
  365. """Remove an element from a set if it is a member.
  366. If the element is not a member, do nothing."""
  367. self._discard_from_set(space, w_item)
  368. @gateway.unwrap_spec(others_w='args_w')
  369. def descr_intersection_update(self, space, others_w):
  370. """Update the set, keeping only elements found in it and all others."""
  371. result = self.descr_intersection(space, others_w)
  372. self.strategy = result.strategy
  373. self.sstorage = result.sstorage
  374. def descr_pop(self, space):
  375. """Remove and return an arbitrary set element."""
  376. return self.popitem()
  377. def descr_remove(self, space, w_item):
  378. """Remove an element from a set; it must be a member.
  379. If the element is not a member, raise a KeyError."""
  380. if not self._discard_from_set(space, w_item):
  381. space.raise_key_error(w_item)
  382. def descr_symmetric_difference_update(self, space, w_other):
  383. """Update a set with the symmetric difference of itself and another."""
  384. if isinstance(w_other, W_BaseSetObject):
  385. self.symmetric_difference_update(w_other)
  386. return
  387. w_other_as_set = self._newobj(space, w_other)
  388. self.symmetric_difference_update(w_other_as_set)
  389. @gateway.unwrap_spec(others_w='args_w')
  390. def descr_update(self, space, others_w):
  391. """Update a set with the union of itself and another."""
  392. for w_other in others_w:
  393. if isinstance(w_other, W_BaseSetObject):
  394. self.update(w_other)
  395. else:
  396. for w_key in space.listview(w_other):
  397. self.add(w_key)
  398. class W_SetObject(W_BaseSetObject):
  399. def _newobj(self, space, w_iterable):
  400. """Make a new set by taking ownership of 'w_iterable'."""
  401. if type(self) is W_SetObject:
  402. return W_SetObject(space, w_iterable)
  403. w_type = space.type(self)
  404. w_obj = space.allocate_instance(W_SetObject, w_type)
  405. W_SetObject.__init__(w_obj, space, w_iterable)
  406. return w_obj
  407. @staticmethod
  408. def descr_new(space, w_settype, __args__):
  409. w_obj = space.allocate_instance(W_SetObject, w_settype)
  410. W_SetObject.__init__(w_obj, space)
  411. return w_obj
  412. W_SetObject.typedef = TypeDef("set",
  413. __doc__ = """set(iterable) --> set object
  414. Build an unordered collection.""",
  415. __new__ = gateway.interp2app(W_SetObject.descr_new),
  416. __init__ = gateway.interp2app(W_BaseSetObject.descr_init),
  417. __repr__ = gateway.interp2app(W_BaseSetObject.descr_repr),
  418. __hash__ = None,
  419. __cmp__ = gateway.interp2app(W_BaseSetObject.descr_cmp),
  420. # comparison operators
  421. __eq__ = gateway.interp2app(W_BaseSetObject.descr_eq),
  422. __ne__ = gateway.interp2app(W_BaseSetObject.descr_ne),
  423. __lt__ = gateway.interp2app(W_BaseSetObject.descr_lt),
  424. __le__ = gateway.interp2app(W_BaseSetObject.descr_le),
  425. __gt__ = gateway.interp2app(W_BaseSetObject.descr_gt),
  426. __ge__ = gateway.interp2app(W_BaseSetObject.descr_ge),
  427. # non-mutating operators
  428. __len__ = gateway.interp2app(W_BaseSetObject.descr_len),
  429. __iter__ = gateway.interp2app(W_BaseSetObject.descr_iter),
  430. __contains__ = gateway.interp2app(W_BaseSetObject.descr_contains),
  431. __sub__ = gateway.interp2app(W_BaseSetObject.descr_sub),
  432. __and__ = gateway.interp2app(W_BaseSetObject.descr_and),
  433. __or__ = gateway.interp2app(W_BaseSetObject.descr_or),
  434. __xor__ = gateway.interp2app(W_BaseSetObject.descr_xor),
  435. # mutating operators
  436. __isub__ = gateway.interp2app(W_BaseSetObject.descr_inplace_sub),
  437. __iand__ = gateway.interp2app(W_BaseSetObject.descr_inplace_and),
  438. __ior__ = gateway.interp2app(W_BaseSetObject.descr_inplace_or),
  439. __ixor__ = gateway.interp2app(W_BaseSetObject.descr_inplace_xor),
  440. # non-mutating methods
  441. __reduce__ = gateway.interp2app(W_BaseSetObject.descr_reduce),
  442. copy = gateway.interp2app(W_BaseSetObject.descr_copy),
  443. difference = gateway.interp2app(W_BaseSetObject.descr_difference),
  444. intersection = gateway.interp2app(W_BaseSetObject.descr_intersection),
  445. issubset = gateway.interp2app(W_BaseSetObject.descr_issubset),
  446. issuperset = gateway.interp2app(W_BaseSetObject.descr_issuperset),
  447. symmetric_difference = gateway.interp2app(W_BaseSetObject.descr_symmetric_difference),
  448. union = gateway.interp2app(W_BaseSetObject.descr_union),
  449. isdisjoint = gateway.interp2app(W_BaseSetObject.descr_isdisjoint),
  450. # mutating methods
  451. add = gateway.interp2app(W_BaseSetObject.descr_add),
  452. clear = gateway.interp2app(W_BaseSetObject.descr_clear),
  453. difference_update = gateway.interp2app(W_BaseSetObject.descr_difference_update),
  454. discard = gateway.interp2app(W_BaseSetObject.descr_discard),
  455. intersection_update = gateway.interp2app(W_BaseSetObject.descr_intersection_update),
  456. pop = gateway.interp2app(W_BaseSetObject.descr_pop),
  457. remove = gateway.interp2app(W_BaseSetObject.descr_remove),
  458. symmetric_difference_update = gateway.interp2app(W_BaseSetObject.descr_symmetric_difference_update),
  459. update = gateway.interp2app(W_BaseSetObject.descr_update)
  460. )
  461. set_typedef = W_SetObject.typedef
  462. class W_FrozensetObject(W_BaseSetObject):
  463. hash = 0
  464. def is_w(self, space, w_other):
  465. if not isinstance(w_other, W_FrozensetObject):
  466. return False
  467. if self is w_other:
  468. return True
  469. if self.user_overridden_class or w_other.user_overridden_class:
  470. return False
  471. # empty frozensets are unique-ified
  472. return 0 == w_other.length() == self.length()
  473. def immutable_unique_id(self, space):
  474. if self.user_overridden_class or self.length() > 0:
  475. return None
  476. # empty frozenset: base value 259
  477. uid = (259 << IDTAG_SHIFT) | IDTAG_SPECIAL
  478. return space.wrap(uid)
  479. def _newobj(self, space, w_iterable):
  480. """Make a new frozenset by taking ownership of 'w_iterable'."""
  481. if type(self) is W_FrozensetObject:
  482. return W_FrozensetObject(space, w_iterable)
  483. w_type = space.type(self)
  484. w_obj = space.allocate_instance(W_FrozensetObject, w_type)
  485. W_FrozensetObject.__init__(w_obj, space, w_iterable)
  486. return w_obj
  487. @staticmethod
  488. def descr_new2(space, w_frozensettype, w_iterable=None):
  489. if (space.is_w(w_frozensettype, space.w_frozenset) and
  490. w_iterable is not None and type(w_iterable) is W_FrozensetObject):
  491. return w_iterable
  492. w_obj = space.allocate_instance(W_FrozensetObject, w_frozensettype)
  493. W_FrozensetObject.__init__(w_obj, space, w_iterable)
  494. return w_obj
  495. def descr_hash(self, space):
  496. multi = r_uint(1822399083) + r_uint(1822399083) + 1
  497. if self.hash != 0:
  498. return space.wrap(self.hash)
  499. hash = r_uint(1927868237)
  500. hash *= r_uint(self.length() + 1)
  501. w_iterator = self.iter()
  502. while True:
  503. w_item = w_iterator.next_entry()
  504. if w_item is None:
  505. break
  506. h = space.hash_w(w_item)
  507. value = (r_uint(h ^ (h << 16) ^ 89869747) * multi)
  508. hash = hash ^ value
  509. hash = hash * 69069 + 907133923
  510. if hash == 0:
  511. hash = 590923713
  512. hash = intmask(hash)
  513. self.hash = hash
  514. return space.wrap(hash)
  515. W_FrozensetObject.typedef = TypeDef("frozenset",
  516. __doc__ = """frozenset(iterable) --> frozenset object
  517. Build an immutable unordered collection.""",
  518. __new__ = gateway.interp2app(W_FrozensetObject.descr_new2),
  519. __repr__ = gateway.interp2app(W_BaseSetObject.descr_repr),
  520. __hash__ = gateway.interp2app(W_FrozensetObject.descr_hash),
  521. __cmp__ = gateway.interp2app(W_BaseSetObject.descr_cmp),
  522. # comparison operators
  523. __eq__ = gateway.interp2app(W_BaseSetObject.descr_eq),
  524. __ne__ = gateway.interp2app(W_BaseSetObject.descr_ne),
  525. __lt__ = gateway.interp2app(W_BaseSetObject.descr_lt),
  526. __le__ = gateway.interp2app(W_BaseSetObject.descr_le),
  527. __gt__ = gateway.interp2app(W_BaseSetObject.descr_gt),
  528. __ge__ = gateway.interp2app(W_BaseSetObject.descr_ge),
  529. # non-mutating operators
  530. __len__ = gateway.interp2app(W_BaseSetObject.descr_len),
  531. __iter__ = gateway.interp2app(W_BaseSetObject.descr_iter),
  532. __contains__ = gateway.interp2app(W_BaseSetObject.descr_contains),
  533. __sub__ = gateway.interp2app(W_BaseSetObject.descr_sub),
  534. __and__ = gateway.interp2app(W_BaseSetObject.descr_and),
  535. __or__ = gateway.interp2app(W_BaseSetObject.descr_or),
  536. __xor__ = gateway.interp2app(W_BaseSetObject.descr_xor),
  537. # non-mutating methods
  538. __reduce__ = gateway.interp2app(W_BaseSetObject.descr_reduce),
  539. copy = gateway.interp2app(W_BaseSetObject.descr_copy),
  540. difference = gateway.interp2app(W_BaseSetObject.descr_difference),
  541. intersection = gateway.interp2app(W_BaseSetObject.descr_intersection),
  542. issubset = gateway.interp2app(W_BaseSetObject.descr_issubset),
  543. issuperset = gateway.interp2app(W_BaseSetObject.descr_issuperset),
  544. symmetric_difference = gateway.interp2app(W_BaseSetObject.descr_symmetric_difference),
  545. union = gateway.interp2app(W_BaseSetObject.descr_union),
  546. isdisjoint = gateway.interp2app(W_BaseSetObject.descr_isdisjoint)
  547. )
  548. frozenset_typedef = W_FrozensetObject.typedef
  549. class SetStrategy(object):
  550. def __init__(self, space):
  551. self.space = space
  552. def get_empty_dict(self):
  553. """ Returns an empty dictionary depending on the strategy. Used to initalize a new storage. """
  554. raise NotImplementedError
  555. def get_empty_storage(self):
  556. """ Returns an empty storage (erased) object. Used to initialize an empty set."""
  557. raise NotImplementedError
  558. def listview_bytes(self, w_set):
  559. return None
  560. def listview_unicode(self, w_set):
  561. return None
  562. def listview_int(self, w_set):
  563. return None
  564. #def erase(self, storage):
  565. # raise NotImplementedError
  566. #def unerase(self, storage):
  567. # raise NotImplementedError
  568. # __________________ methods called on W_SetObject _________________
  569. def clear(self, w_set):
  570. raise NotImplementedError
  571. def copy_real(self, w_set):
  572. raise NotImplementedError
  573. def length(self, w_set):
  574. raise NotImplementedError
  575. def add(self, w_set, w_key):
  576. raise NotImplementedError
  577. def remove(self, w_set, w_item):
  578. raise NotImplementedError
  579. def getdict_w(self, w_set):
  580. raise NotImplementedError
  581. def get_storage_copy(self, w_set):
  582. raise NotImplementedError
  583. def getkeys(self, w_set):
  584. raise NotImplementedError
  585. def difference(self, w_set, w_other):
  586. raise NotImplementedError
  587. def difference_update(self, w_set, w_other):
  588. raise NotImplementedError
  589. def symmetric_difference(self, w_set, w_other):
  590. raise NotImplementedError
  591. def symmetric_difference_update(self, w_set, w_other):
  592. raise NotImplementedError
  593. def intersect(self, w_set, w_other):
  594. raise NotImplementedError
  595. def intersect_update(self, w_set, w_other):
  596. raise NotImplementedError
  597. def issubset(self, w_set, w_other):
  598. raise NotImplementedError
  599. def isdisjoint(self, w_set, w_other):
  600. raise NotImplementedError
  601. def update(self, w_set, w_other):
  602. raise NotImplementedError
  603. def has_key(self, w_set, w_key):
  604. raise NotImplementedError
  605. def equals(self, w_set, w_other):
  606. raise NotImplementedError
  607. def iter(self, w_set):
  608. raise NotImplementedError
  609. def popitem(self, w_set):
  610. raise NotImplementedError
  611. class EmptySetStrategy(SetStrategy):
  612. erase, unerase = rerased.new_erasing_pair("empty")
  613. erase = staticmethod(erase)
  614. unerase = staticmethod(unerase)
  615. def get_empty_storage(self):
  616. return self.erase(None)
  617. def is_correct_type(self, w_key):
  618. return False
  619. def length(self, w_set):
  620. return 0
  621. def clear(self, w_set):
  622. pass
  623. def copy_real(self, w_set):
  624. storage = self.erase(None)
  625. clone = w_set.from_storage_and_strategy(storage, self)
  626. return clone
  627. def add(self, w_set, w_key):
  628. if type(w_key) is W_IntObject:
  629. strategy = self.space.fromcache(IntegerSetStrategy)
  630. elif type(w_key) is W_BytesObject:
  631. strategy = self.space.fromcache(BytesSetStrategy)
  632. elif type(w_key) is W_UnicodeObject:
  633. strategy = self.space.fromcache(UnicodeSetStrategy)
  634. elif self.space.type(w_key).compares_by_identity():
  635. strategy = self.space.fromcache(IdentitySetStrategy)
  636. else:
  637. strategy = self.space.fromcache(ObjectSetStrategy)
  638. w_set.strategy = strategy
  639. w_set.sstorage = strategy.get_empty_storage()
  640. w_set.add(w_key)
  641. def remove(self, w_set, w_item):
  642. return False
  643. def getdict_w(self, w_set):
  644. return newset(self.space)
  645. def get_storage_copy(self, w_set):
  646. return w_set.sstorage
  647. def getkeys(self, w_set):
  648. return []
  649. def has_key(self, w_set, w_key):
  650. return False
  651. def equals(self, w_set, w_other):
  652. if w_other.strategy is self or w_other.length() == 0:
  653. return True
  654. return False
  655. def difference(self, w_set, w_other):
  656. return w_set.copy_real()
  657. def difference_update(self, w_set, w_other):
  658. pass
  659. def intersect(self, w_set, w_other):
  660. return w_set.copy_real()
  661. def intersect_update(self, w_set, w_other):
  662. pass
  663. def isdisjoint(self, w_set, w_other):
  664. return True
  665. def issubset(self, w_set, w_other):
  666. return True
  667. def symmetric_difference(self, w_set, w_other):
  668. return w_other.copy_real()
  669. def symmetric_difference_update(self, w_set, w_other):
  670. w_set.strategy = w_other.strategy
  671. w_set.sstorage = w_other.get_storage_copy()
  672. def update(self, w_set, w_other):
  673. w_set.strategy = w_other.strategy
  674. w_set.sstorage = w_other.get_storage_copy()
  675. def iter(self, w_set):
  676. return EmptyIteratorImplementation(self.space, self, w_set)
  677. def popitem(self, w_set):
  678. raise oefmt(self.space.w_KeyError, "pop from an empty set")
  679. class AbstractUnwrappedSetStrategy(object):
  680. _mixin_ = True
  681. def is_correct_type(self, w_key):
  682. """ Checks wether the given wrapped key fits this strategy."""
  683. raise NotImplementedError
  684. def unwrap(self, w_item):
  685. """ Returns the unwrapped value of the given wrapped item."""
  686. raise NotImplementedError
  687. def wrap(self, item):
  688. """ Returns a wrapped version of the given unwrapped item. """
  689. raise NotImplementedError
  690. @jit.look_inside_iff(lambda self, list_w:
  691. jit.loop_unrolling_heuristic(list_w, len(list_w), UNROLL_CUTOFF))
  692. def get_storage_from_list(self, list_w):
  693. setdata = self.get_empty_dict()
  694. for w_item in list_w:
  695. setdata[self.unwrap(w_item)] = None
  696. return self.erase(setdata)
  697. @jit.look_inside_iff(lambda self, items:
  698. jit.loop_unrolling_heuristic(items, len(items), UNROLL_CUTOFF))
  699. def get_storage_from_unwrapped_list(self, items):
  700. setdata = self.get_empty_dict()
  701. for item in items:
  702. setdata[item] = None
  703. return self.erase(setdata)
  704. def length(self, w_set):
  705. return len(self.unerase(w_set.sstorage))
  706. def clear(self, w_set):
  707. w_set.switch_to_empty_strategy()
  708. def copy_real(self, w_set):
  709. # may be used internally on frozen sets, although frozenset().copy()
  710. # returns self in frozenset_copy__Frozenset.
  711. strategy = w_set.strategy
  712. d = self.unerase(w_set.sstorage)
  713. storage = self.erase(d.copy())
  714. clone = w_set.from_storage_and_strategy(storage, strategy)
  715. return clone
  716. def add(self, w_set, w_key):
  717. if self.is_correct_type(w_key):
  718. d = self.unerase(w_set.sstorage)
  719. d[self.unwrap(w_key)] = None
  720. else:
  721. w_set.switch_to_object_strategy(self.space)
  722. w_set.add(w_key)
  723. def remove(self, w_set, w_item):
  724. d = self.unerase(w_set.sstorage)
  725. if not self.is_correct_type(w_item):
  726. #XXX check type of w_item and immediately return False in some cases
  727. w_set.switch_to_object_strategy(self.space)
  728. return w_set.remove(w_item)
  729. key = self.unwrap(w_item)
  730. try:
  731. del d[key]
  732. return True
  733. except KeyError:
  734. return False
  735. def getdict_w(self, w_set):
  736. result = newset(self.space)
  737. keys = self.unerase(w_set.sstorage).keys()
  738. for key in keys:
  739. result[self.wrap(key)] = None
  740. return result
  741. def get_storage_copy(self, w_set):
  742. d = self.unerase(w_set.sstorage)
  743. copy = self.erase(d.copy())
  744. return copy
  745. def getkeys(self, w_set):
  746. keys = self.unerase(w_set.sstorage).keys()
  747. keys_w = [self.wrap(key) for key in keys]
  748. return keys_w
  749. def has_key(self, w_set, w_key):
  750. if not self.is_correct_type(w_key):
  751. #XXX check type of w_item and immediately return False in some cases
  752. w_set.switch_to_object_strategy(self.space)
  753. return w_set.has_key(w_key)
  754. d = self.unerase(w_set.sstorage)
  755. return self.unwrap(w_key) in d
  756. def equals(self, w_set, w_other):
  757. if w_set.length() != w_other.length():
  758. return False
  759. if w_set.length() == 0:
  760. return True
  761. # it's possible to have 0-length strategy that's not empty
  762. if w_set.strategy is w_other.strategy:
  763. return self._issubset_unwrapped(w_set, w_other)
  764. if not self.may_contain_equal_elements(w_other.strategy):
  765. return False
  766. items = self.unerase(w_set.sstorage).keys()
  767. for key in items:
  768. if not w_other.has_key(self.wrap(key)):
  769. return False
  770. return True
  771. def _difference_wrapped(self, w_set, w_other):
  772. iterator = self.unerase(w_set.sstorage).iterkeys()
  773. result_dict = self.get_empty_dict()
  774. for key in iterator:
  775. w_item = self.wrap(key)
  776. if not w_other.has_key(w_item):
  777. result_dict[key] = None
  778. return self.erase(result_dict)
  779. def _difference_unwrapped(self, w_set, w_other):
  780. self_dict = self.unerase(w_set.sstorage)
  781. other_dict = self.unerase(w_other.sstorage)
  782. result_dict = self.get_empty_dict()
  783. for key, keyhash in iterkeys_with_hash(self_dict):
  784. if not contains_with_hash(other_dict, key, keyhash):
  785. setitem_with_hash(result_dict, key, keyhash, None)
  786. return self.erase(result_dict)
  787. def _difference_base(self, w_set, w_other):
  788. if self is w_other.strategy:
  789. storage = self._difference_unwrapped(w_set, w_other)
  790. elif not w_set.strategy.may_contain_equal_elements(w_other.strategy):
  791. d = self.unerase(w_set.sstorage)
  792. storage = self.erase(d.copy())
  793. else:
  794. storage = self._difference_wrapped(w_set, w_other)
  795. return storage
  796. def difference(self, w_set, w_other):
  797. storage = self._difference_base(w_set, w_other)
  798. w_newset = w_set.from_storage_and_strategy(storage, w_set.strategy)
  799. return w_newset
  800. def _difference_update_unwrapped(self, w_set, w_other):
  801. my_dict = self.unerase(w_set.sstorage)
  802. if w_set.sstorage is w_other.sstorage:
  803. my_dict.clear()
  804. return
  805. other_dict = self.unerase(w_other.sstorage)
  806. for key, keyhash in iterkeys_with_hash(other_dict):
  807. try:
  808. delitem_with_hash(my_dict, key, keyhash)
  809. except KeyError:
  810. pass
  811. def _difference_update_wrapped(self, w_set, w_other):
  812. w_iterator = w_other.iter()
  813. while True:
  814. w_item = w_iterator.next_entry()
  815. if w_item is None:
  816. break
  817. w_set.remove(w_item)
  818. def difference_update(self, w_set, w_other):
  819. if self.length(w_set) < w_other.strategy.length(w_other):
  820. # small_set -= big_set: compute the difference as a new set
  821. storage = self._difference_base(w_set, w_other)
  822. w_set.sstorage = storage
  823. else:
  824. # big_set -= small_set: be more subtle
  825. if self is w_other.strategy:
  826. self._difference_update_unwrapped(w_set, w_other)
  827. elif w_set.strategy.may_contain_equal_elements(w_other.strategy):
  828. self._difference_update_wrapped(w_set, w_other)
  829. def _symmetric_difference_unwrapped(self, w_set, w_other):
  830. d_new = self.get_empty_dict()
  831. d_this = self.unerase(w_set.sstorage)
  832. d_other = self.unerase(w_other.sstorage)
  833. for key, keyhash in iterkeys_with_hash(d_other):
  834. if not contains_with_hash(d_this, key, keyhash):
  835. setitem_with_hash(d_new, key, keyhash, None)
  836. for key, keyhash in iterkeys_with_hash(d_this):
  837. if not contains_with_hash(d_other, key, keyhash):
  838. setitem_with_hash(d_new, key, keyhash, None)
  839. storage = self.erase(d_new)
  840. return storage
  841. def _symmetric_difference_wrapped(self, w_set, w_other):
  842. newsetdata = newset(self.space)
  843. for obj in self.unerase(w_set.sstorage):
  844. w_item = self.wrap(obj)
  845. if not w_other.has_key(w_item):
  846. newsetdata[w_item] = None
  847. w_iterator = w_other.iter()
  848. while True:
  849. w_item = w_iterator.next_entry()
  850. if w_item is None:
  851. break
  852. if not w_set.has_key(w_item):
  853. newsetdata[w_item] = None
  854. strategy = self.space.fromcache(ObjectSetStrategy)
  855. return strategy.erase(newsetdata)
  856. def _symmetric_difference_base(self, w_set, w_other):
  857. if self is w_other.strategy:
  858. strategy = w_set.strategy
  859. storage = self._symmetric_difference_unwrapped(w_set, w_other)
  860. else:
  861. strategy = self.space.fromcache(ObjectSetStrategy)
  862. storage = self._symmetric_difference_wrapped(w_set, w_other)
  863. return storage, strategy
  864. def symmetric_difference(self, w_set, w_other):
  865. if w_other.length() == 0:
  866. return w_set.copy_real()
  867. storage, strategy = self._symmetric_difference_base(w_set, w_other)
  868. return w_set.from_storage_and_strategy(storage, strategy)
  869. def symmetric_difference_update(self, w_set, w_other):
  870. if w_other.length() == 0:
  871. return
  872. storage, strategy = self._symmetric_difference_base(w_set, w_other)
  873. w_set.strategy = strategy
  874. w_set.sstorage = storage
  875. def _intersect_base(self, w_set, w_other):
  876. if self is w_other.strategy:
  877. strategy = self
  878. if w_set.length() > w_other.length():
  879. # swap operands
  880. storage = self._intersect_unwrapped(w_other, w_set)
  881. else:
  882. storage = self._intersect_unwrapped(w_set, w_other)
  883. elif not w_set.strategy.may_contain_equal_elements(w_other.strategy):
  884. strategy = self.space.fromcache(EmptySetStrategy)
  885. storage = strategy.get_empty_storage()
  886. else:
  887. strategy = self.space.fromcache(ObjectSetStrategy)
  888. if w_set.length() > w_other.length():
  889. # swap operands
  890. storage = w_other.strategy._intersect_wrapped(w_other, w_set)
  891. else:
  892. storage = self._intersect_wrapped(w_set, w_other)
  893. return storage, strategy
  894. def _intersect_wrapped(self, w_set, w_other):
  895. result = newset(self.space)
  896. for key in self.unerase(w_set.sstorage):
  897. self.intersect_jmp.jit_merge_point()
  898. w_key = self.wrap(key)
  899. if w_other.has_key(w_key):
  900. result[w_key] = None
  901. strategy = self.space.fromcache(ObjectSetStrategy)
  902. return strategy.erase(result)
  903. def _intersect_unwrapped(self, w_set, w_other):
  904. result = self.get_empty_dict()
  905. d_this = self.unerase(w_set.sstorage)
  906. d_other = self.unerase(w_other.sstorage)
  907. for key, keyhash in iterkeys_with_hash(d_this):
  908. if contains_with_hash(d_other, key, keyhash):
  909. setitem_with_hash(result, key, keyhash, None)
  910. return self.erase(result)
  911. def intersect(self, w_set, w_other):
  912. storage, strategy = self._intersect_base(w_set, w_other)
  913. return w_set.from_storage_and_strategy(storage, strategy)
  914. def intersect_update(self, w_set, w_other):
  915. if w_set.length() > w_other.length():
  916. w_intersection = w_other.intersect(w_set)
  917. strategy = w_intersection.strategy
  918. storage = w_intersection.sstorage
  919. else:
  920. storage, strategy = self._intersect_base(w_set, w_other)
  921. w_set.strategy = strategy
  922. w_set.sstorage = storage
  923. def _issubset_unwrapped(self, w_set, w_other):
  924. d_set = self.unerase(w_set.sstorage)
  925. d_other = self.unerase(w_other.sstorage)
  926. for key, keyhash in iterkeys_with_hash(d_set):
  927. if not contains_with_hash(d_other, key, keyhash):
  928. return False
  929. return True
  930. def _issubset_wrapped(self, w_set, w_other):
  931. for obj in self.unerase(w_set.sstorage):
  932. w_item = self.wrap(obj)
  933. if not w_other.has_key(w_item):
  934. return False
  935. return True
  936. def issubset(self, w_set, w_other):
  937. if w_set.length() == 0:
  938. return True
  939. if w_set.strategy is w_other.strategy:
  940. return self._issubset_unwrapped(w_set, w_other)
  941. elif not w_set.strategy.may_contain_equal_elements(w_other.strategy):
  942. return False
  943. else:
  944. return self._issubset_wrapped(w_set, w_other)
  945. def _isdisjoint_unwrapped(self, w_set, w_other):
  946. d_set = self.unerase(w_set.sstorage)
  947. d_other = self.unerase(w_other.sstorage)
  948. for key, keyhash in iterkeys_with_hash(d_set):
  949. if contains_with_hash(d_other, key, keyhash):
  950. return False
  951. return True
  952. def _isdisjoint_wrapped(self, w_set, w_other):
  953. d = self.unerase(w_set.sstorage)
  954. for key in d:
  955. if w_other.has_key(self.wrap(key)):
  956. return False
  957. return True
  958. def isdisjoint(self, w_set, w_other):
  959. if w_other.length() == 0:
  960. return True
  961. if w_set.length() > w_other.length():
  962. return w_other.isdisjoint(w_set)
  963. if w_set.strategy is w_other.strategy:
  964. return self._isdisjoint_unwrapped(w_set, w_other)
  965. elif not w_set.strategy.may_contain_equal_elements(w_other.strategy):
  966. return True
  967. else:
  968. return self._isdisjoint_wrapped(w_set, w_other)
  969. def update(self, w_set, w_other):
  970. if self is w_other.strategy:
  971. d_set = self.unerase(w_set.sstorage)
  972. d_other = self.unerase(w_other.sstorage)
  973. d_set.update(d_other)
  974. return
  975. if w_other.length() == 0:
  976. return
  977. w_set.switch_to_object_strategy(self.space)
  978. w_set.update(w_other)
  979. def popitem(self, w_set):
  980. storage = self.unerase(w_set.sstorage)
  981. try:
  982. # this returns a tuple because internally sets are dicts
  983. result = storage.popitem()
  984. except KeyError:
  985. # strategy may still be the same even if dict is empty
  986. raise oefmt(self.space.w_KeyError, "pop from an empty set")
  987. return self.wrap(result[0])
  988. class BytesSetStrategy(AbstractUnwrappedSetStrategy, SetStrategy):
  989. erase, unerase = rerased.new_erasing_pair("bytes")
  990. erase = staticmethod(erase)
  991. unerase = staticmethod(unerase)
  992. intersect_jmp = jit.JitDriver(greens = [], reds = 'auto',
  993. name='set(bytes).intersect')
  994. def get_empty_storage(self):
  995. return self.erase({})
  996. def get_empty_dict(self):
  997. return {}
  998. def listview_bytes(self, w_set):
  999. return self.unerase(w_set.sstorage).keys()
  1000. def is_correct_type(self, w_key):
  1001. return type(w_key) is W_BytesObject
  1002. def may_contain_equal_elements(self, strategy):
  1003. if strategy is self.space.fromcache(IntegerSetStrategy):
  1004. return False
  1005. elif strategy is self.space.fromcache(EmptySetStrategy):
  1006. return False
  1007. elif strategy is self.space.fromcache(IdentitySetStrategy):
  1008. return False
  1009. return True
  1010. def unwrap(self, w_item):
  1011. return self.space.str_w(w_item)
  1012. def wrap(self, item):
  1013. return self.space.wrap(item)
  1014. def iter(self, w_set):
  1015. return BytesIteratorImplementation(self.space, self, w_set)
  1016. class UnicodeSetStrategy(AbstractUnwrappedSetStrategy, SetStrategy):
  1017. erase, unerase = rerased.new_erasing_pair("unicode")
  1018. erase = staticmethod(erase)
  1019. unerase = staticmethod(unerase)
  1020. intersect_jmp = jit.JitDriver(greens = [], reds = 'auto',
  1021. name='set(unicode).intersect')
  1022. def get_empty_storage(self):
  1023. return self.erase({})
  1024. def get_empty_dict(self):
  1025. return {}
  1026. def listview_unicode(self, w_set):
  1027. return self.unerase(w_set.sstorage).keys()
  1028. def is_correct_type(self, w_key):
  1029. return type(w_key) is W_UnicodeObject
  1030. def may_contain_equal_elements(self, strategy):
  1031. if strategy is self.space.fromcache(IntegerSetStrategy):
  1032. return False
  1033. elif strategy is self.space.fromcache(EmptySetStrategy):
  1034. return False
  1035. elif strategy is self.space.fromcache(IdentitySetStrategy):
  1036. return False
  1037. return True
  1038. def unwrap(self, w_item):
  1039. return self.space.unicode_w(w_item)
  1040. def wrap(self, item):
  1041. return self.space.wrap(item)
  1042. def iter(self, w_set):
  1043. return UnicodeIteratorImplementation(self.space, self, w_set)
  1044. class IntegerSetStrategy(AbstractUnwrappedSetStrategy, SetStrategy):
  1045. erase, unerase = rerased.new_erasing_pair("integer")
  1046. erase = staticmethod(erase)
  1047. unerase = staticmethod(unerase)
  1048. intersect_jmp = jit.JitDriver(greens = [], reds = 'auto',
  1049. name='set(int).intersect')
  1050. def get_empty_storage(self):
  1051. return self.erase({})
  1052. def get_empty_dict(self):
  1053. return {}
  1054. def listview_int(self, w_set):
  1055. return self.unerase(w_set.sstorage).keys()
  1056. def is_correct_type(self, w_key):
  1057. return type(w_key) is W_IntObject
  1058. def may_contain_equal_elements(self, strategy):
  1059. if strategy is self.space.fromcache(BytesSetStrategy):
  1060. return False
  1061. elif strategy is self.space.fromcache(UnicodeSetStrategy):
  1062. return False
  1063. elif strategy is self.space.fromcache(EmptySetStrategy):
  1064. return False
  1065. elif strategy is self.space.fromcache(IdentitySetStrategy):
  1066. return False
  1067. return True
  1068. def unwrap(self, w_item):
  1069. return self.space.int_w(w_item)
  1070. def wrap(self, item):
  1071. return self.space.wrap(item)
  1072. def iter(self, w_set):
  1073. return IntegerIteratorImplementation(self.space, self, w_set)
  1074. class ObjectSetStrategy(AbstractUnwrappedSetStrategy, SetStrategy):
  1075. erase, unerase = rerased.new_erasing_pair("object")
  1076. erase = staticmethod(erase)
  1077. unerase = staticmethod(unerase)
  1078. intersect_jmp = jit.JitDriver(greens = [], reds = 'auto',
  1079. name='set(object).intersect')
  1080. def get_empty_storage(self):
  1081. return self.erase(self.get_empty_dict())
  1082. def get_empty_dict(self):
  1083. return newset(self.space)
  1084. def is_correct_type(self, w_key):
  1085. return True
  1086. def may_contain_equal_elements(self, strategy):
  1087. if strategy is self.space.fromcache(EmptySetStrategy):
  1088. return False
  1089. return True
  1090. def unwrap(self, w_item):
  1091. return w_item
  1092. def wrap(self, item):
  1093. return item
  1094. def iter(self, w_set):
  1095. return RDictIteratorImplementation(self.space, self, w_set)
  1096. def update(self, w_set, w_other):
  1097. d_obj = self.unerase(w_set.sstorage)
  1098. # optimization only
  1099. if w_other.strategy is self:
  1100. d_other = self.unerase(w_other.sstorage)
  1101. d_obj.update(d_other)
  1102. return
  1103. w_iterator = w_other.iter()
  1104. while True:
  1105. w_item = w_iterator.next_entry()
  1106. if w_item is None:
  1107. break
  1108. d_obj[w_item] = None
  1109. class IdentitySetStrategy(A

Large files files are truncated, but you can click here to view the full file