Commit Graph

51 Commits

Author SHA1 Message Date
Guido van Rossum e2b70bcf74 Get rid of dict.has_key(). Boy this has a lot of repercussions!
Not all code has been fixed yet; this is just a checkpoint...
The C API still has PyDict_HasKey() and _HasKeyString(); not sure
if I want to change those just yet.
2006-08-18 22:13:04 +00:00
Raymond Hettinger 038ca2a551 Teach the sets module to correctly compute s-=s and s^=s as the empty set. 2005-08-13 02:29:58 +00:00
Raymond Hettinger 70b9f499a3 Remove deprecation of sets.Set.update(). 2003-11-19 15:52:14 +00:00
Raymond Hettinger 859db26729 Improve backwards compatibility code to handle True/False. 2003-11-12 15:21:20 +00:00
Raymond Hettinger 9d50d91e77 Set the warnings stacklevel to two. 2003-09-08 19:16:36 +00:00
Raymond Hettinger 6a1801271a Improvements to set.py:
* Relaxed the argument restrictions for non-operator methods.  They now
  allow any iterable instead of requiring a set.  This makes the module
  a little easier to use and paves the way for an efficient C
  implementation which can take better advantage of iterable arguments
  while screening out immutables.

* Deprecated Set.update() because it now duplicates Set.union_update()

* Adapted the tests and docs to include the above changes.

* Added more test coverage including testing identities and checking
  to make sure non-restartable generators work as arguments.

Will backport to Py2.3.1 so that the interface remains consistent
across versions.  The deprecation of update() will be changed to
a FutureWarning.
2003-08-17 08:34:09 +00:00
Raymond Hettinger ee562fc084 Make sets.py compatible with Py2.2 2003-08-15 21:17:04 +00:00
Raymond Hettinger f6fe4eda6e Portion of SF patch #761104. Fixes a minor docstring error.
_TemporarilyImmutableSet is in fact a subclass of BaseSet
2003-06-26 18:49:28 +00:00
Tim Peters 44f14b0399 SF bug 693121: Set == non-Set is a TypeError.
Allow mixed-type __eq__ and __ne__ for Set objects.  This is messier than
I'd like because Set *also* implements __cmp__.  I know of one glitch now:
cmp(s, t) returns 0 now when s and t are both Sets and s == t, despite
that Set.__cmp__ unconditionally raises TypeError (and by intent).  The
rub is that __eq__ gets tried first, and the x.__eq__(y) True result
convinces Python that cmp(x, y) is 0 without even calling Set.__cmp__.
2003-03-02 00:19:49 +00:00
Raymond Hettinger 2835e37be5 SF bug #663701: sets module review
Renamed hook methods to use the double underscore convention.
2003-02-14 03:42:11 +00:00
Raymond Hettinger 60eca9331a C Code:
* Removed the ifilter flag wart by splitting it into two simpler functions.
* Fixed comment tabbing in C code.
* Factored module start-up code into a loop.

Documentation:
* Re-wrote introduction.
* Addede examples for quantifiers.
* Simplified python equivalent for islice().
* Documented split of ifilter().

Sets.py:
* Replace old ifilter() usage with new.
2003-02-09 06:40:58 +00:00
Tim Peters 322d553143 Whitespace normalization. 2003-02-04 00:38:20 +00:00
Raymond Hettinger 1ecfb73c26 One more use of ifilter() 2003-02-02 16:07:53 +00:00
Raymond Hettinger a3a53180c0 SF patch #678899: Save time and memory by using itertools in sets module. 2003-02-02 14:27:19 +00:00
Guido van Rossum 50e92235e7 Explicitly raise an exception in __cmp__ -- this clarifies that cmp()
is not supported on sets.  (Unfortunately, sorting a list of sets may
still return random results because it uses < exclusively, but for
sets that inly implements a partial ordering.  Oh well.)
2003-01-14 16:45:04 +00:00
Raymond Hettinger 35e48d2426 SF 643115: Set._update() had a special case for dictionaries which allowed
non-true values to leak in.  This threw-off equality testing which depends
on the underlying dictionaries having both the same keys and values.
2002-11-25 20:43:55 +00:00
Jeremy Hylton cd58b8f532 Add getstate and setstate implementation to concrete set classes. 2002-11-13 19:34:26 +00:00
Guido van Rossum 7cd83ca9ad Another attempt at making the set constructor both safe and fast. [SF
bug 628246]
2002-11-08 17:03:36 +00:00
Tim Peters 0ec1ddcdcf _update(): Commented the new obscurity. Materialized into a tuple
instead of into a list for a bit of speed/space savings.  Reopened the
bug report too (628246), as I'm unclear on why we don't sort out the
cause of the TypeError instead.
2002-11-08 05:26:52 +00:00
Raymond Hettinger 1eb1fb814b Closes SF bug #628246.
The _update method detected mutable elements by trapping TypeErrors.
Unfortunately, this masked useful TypeErrors raised by the iterable
itself.  For cases where it is possible for an iterable to raise
a TypeError, the iterable is pre-converted to a list outside the
try/except so that any TypeErrors propagate through.
2002-11-08 05:03:21 +00:00
Raymond Hettinger bfcdb8734e .iterkeys() is not needed. 2002-10-04 20:01:48 +00:00
Raymond Hettinger 1a8d193121 Sped _update().
Uses the fast update() method when a dictionary is available.
2002-08-29 15:13:50 +00:00
Tim Peters 454602f0f7 Gave intersection_update a speed boost. 2002-08-26 00:44:07 +00:00
Tim Peters cd06eeb20c Gave issubet() and issuperset() major speed boosts. That's it for now!
Someone else may want to tackle the mutating operations similarly.
2002-08-25 20:12:19 +00:00
Tim Peters b8940393e9 Gave __sub__/difference a factor of 2-5 speed boost. 2002-08-25 19:50:43 +00:00
Tim Peters 334b4a5c39 Gave __xor__/symmetric_difference a factor of 2-5 speed boost. 2002-08-25 19:47:54 +00:00
Tim Peters 37faed2532 Sped union by a factor of 3-4. 2002-08-25 19:21:27 +00:00
Tim Peters d33e6be59d Sped intersection by large factors (3-5x faster than before on sets of
cardinality 500; and the smaller the intersection, the bigger the speedup).
2002-08-25 19:12:45 +00:00
Tim Peters 4a2f91e302 Added a clue about why xyz_update isn't the same as __xyz__. 2002-08-25 18:59:04 +00:00
Tim Peters ea76c98014 Implemented <, <=, >, >= for sets, giving subset and proper-subset
meanings.  I did not add new, e.g., ispropersubset() methods; we're
going nuts on those, and, e.g., there was no "friendly name" for
== either.
2002-08-25 18:43:10 +00:00
Tim Peters 4924db176b Record a clue about why __or__ is not union, etc. 2002-08-25 17:10:17 +00:00
Raymond Hettinger e87ab3fefe Removed < <= > >= from the API. Implemented as comparisons of the
underlying dictionaries, there were no reasonable use cases (lexicographic
sorting of a list of sets is somewhat esoteric).  Frees the operators
for other uses (such as strict subset and superset comparisons).

Updated documentation and test suite accordingly.
2002-08-24 07:33:06 +00:00
Raymond Hettinger 1b9f5d4c1a At Tim Peter's suggestion, propagated GvR's binary operator changes to
the inplace operators.  The strategy is to have the operator overloading
code do the work and then to define equivalent method calls which rely on
the operators.  The changes facilitate proper application of TypeError
and NonImplementedErrors.

Added corresponding tests to the test suite to make sure both the operator
and method call versions get exercised.

Add missing tests for difference_update().
2002-08-24 06:19:02 +00:00
Raymond Hettinger d50185127f Since instances of _TemporarilyImmutableSet are always thrown away
immediately after the comparison, there in no use in caching the hashcode.
The test, 'if self._hashcode is None', never fails.  Removing the caching
saves a few lines and a little time.
2002-08-24 04:47:42 +00:00
Raymond Hettinger fa1480f686 1. Removed module self test in favor of unittests -- Timbot's suggestion.
2. Replaced calls to Set([]) with Set() -- Timbot's suggestion
3. Fixed subtle bug in sets of sets:

The following code did not work (will add to test suite):
    d = Set('d')
    s = Set([d])  # Stores inner set as an ImmutableSet
    s.remove(d)   # For comparison, wraps d in _TemporarilyImmutableSet

The comparison proceeds by computing the hash of the
_TemporarilyImmutableSet and finding it in the dictionary.
It then verifies equality by calling ImmutableSet.__eq__()
and crashes from the binary sanity check.

The problem is that the code assumed equality would be checked
with _TemporarilyImmutableSet.__eq__().

The solution is to let _TemporarilyImmutableSet derive from BaseSet
so it will pass the sanity check and then to provide it with the
._data element from the wrapped set so that ImmutableSet.__eq__()
will find ._data where it expects.

Since ._data is now provided and because BaseSet is the base class,
_TemporarilyImmutableSet no longer needs .__eq__() or .__ne__().

Note that inheriting all of BaseSet's methods is harmless because
none of those methods (except ones starting with an underscore)
can mutate the .data element.  Also _TemporarilyImmutableSet is only
used internally as is not otherwise visible.
2002-08-24 02:35:48 +00:00
Tim Peters 53506be258 pop() docstring: this isn't a randomly-chosen element, it's merely
arbitrary.  I already changed the docs for this.
2002-08-23 20:36:58 +00:00
Tim Peters d06d03041b Comment repair. 2002-08-23 20:06:42 +00:00
Guido van Rossum e399d08a4a RH pointed out that discard(element) doesn't do the transformation on
the element if necessary.  Fixed by calling self.remove(element).
2002-08-23 14:45:02 +00:00
Guido van Rossum dc61cdf6c0 Change the binary operators |, &, ^, - to return NotImplemented rather
than raising TypeError when the other argument is not a BaseSet.  This
made it necessary to separate the implementation of e.g. __or__ from
the union method; the latter should not return NotImplemented but
raise TypeError.  This is accomplished by making union(self, other)
return self|other, etc.; Python's binary operator machinery will raise
TypeError.

The idea behind this change is to allow other set implementations with
an incompatible internal structure; these can provide union (etc.) with
standard sets by implementing __ror__ etc.

I wish I could do this for comparisons too, but the default comparison
implementation allows comparing anything to anything else (returning
false); we don't want that (at least the test suite makes sure
e.g. Set()==42 raises TypeError).  That's probably fine; otherwise
other set implementations would be constrained to implementing a hash
that's compatible with ours.
2002-08-22 17:23:33 +00:00
Raymond Hettinger d9c9151a53 Now that __init__ transforms set elements, we know that all of the
elements are hashable, so we can use dict.update() or dict.copy()
for a C speed Set.copy().
2002-08-21 13:20:51 +00:00
Raymond Hettinger 80d21af614 Sped ._update() method by factoring try/except out of the inner loop. 2002-08-21 04:12:03 +00:00
Guido van Rossum 9f87293bf5 Ouch. The test suite *really* needs work!!!!! There were several
superficial errors and one deep one that aren't currently caught.  I'm
headed for bed after this checkin.

- Fixed several typos introduced by Raymond Hettinger (through
  cut-n-paste from my template): it's _as_temporarily_immutable, not
  _as_temporary_immutable, and moreover when the element is added, we
  should use _as_immutable.

- Made the seq argument to ImmutableSet.__init__ optional, so we can
  write ImmutableSet() to create an immutable empty set.

- Rename the seq argument to Set and ImmutableSet to iterable.

- Add a Set.__hash__ method that raises a TypeError.  We inherit a
  default __hash__ implementation from object, and we don't want that.
  We can then catch this in update(), so that
  e.g. s.update([Set([1])]) will transform the Set([1]) to
  ImmutableSet([1]).

- Added the dance to catch TypeError and try _as_immutable in the
  constructors too (by calling _update()).  This is needed so that
  Set([Set([1])]) is correctly interpreted as
  Set([ImmutableSet([1])]).  (I was puzzled by a side effect of this
  and the inherited __hash__ when comparing two sets of sets while
  testing different powerset implementations: the Set element passed
  to a Set constructor wasn't transformed to an ImmutableSet, and then
  the dictionary didn't believe the Set found in one dict it was the
  same as ImmutableSet in the other, because the hashes were
  different.)

- Refactored Set.update() and both __init__() methods; moved the body
  of update() into BaseSet as _update(), and call this from __init__()
  and update().

- Changed the NotImplementedError in BaseSet.__init__ to TypeError,
  both for consistency with basestring() and because we have to use
  TypeError when denying Set.__hash__.  Together those provide
  sufficient evidence that an unimplemented method needs to raise
  TypeError.
2002-08-21 03:20:44 +00:00
Guido van Rossum 26588222b3 Add Raymond H to the list of authors; add some XXX comments about
possible API improvements.
2002-08-21 02:44:04 +00:00
Raymond Hettinger 43db0d6a2c Fast size check for sub/super set tests 2002-08-21 02:22:08 +00:00
Raymond Hettinger de6d697987 Optimize try/except ordering in sets.py.
Gains a 5:1 speed-up for membership testing by
handling the most common case first (the case
where the element is hashable).

Closes SF Patch 597444.
2002-08-21 01:35:29 +00:00
Raymond Hettinger ede3a0da8b Minor typo 2002-08-20 23:34:01 +00:00
Guido van Rossum c9196bc88d Rename popitem() to pop(). (An idea from SF patch 597444.) 2002-08-20 21:51:59 +00:00
Guido van Rossum 5033b36c44 Move __init__ from BaseSet into Set and ImmutableSet. This causes a
tiny amount of code duplication, but makes it possible to give BaseSet
an __init__ that raises an exception.
2002-08-20 21:38:37 +00:00
Guido van Rossum 290f1870f1 Add a note reminding the reader that sets are not sequences. I
received feedback that was based in the misunderstanding that sets
were sequences.
2002-08-20 20:05:23 +00:00
Guido van Rossum 0b650d7565 Fix typo in __slots__ of ImmutableSet. 2002-08-19 16:29:58 +00:00