Commit Graph

943 Commits

Author SHA1 Message Date
Tim Peters 3918fb2549 Repair typo in comment. 2001-05-10 18:58:31 +00:00
Tim Peters 95bf9390a4 SF bug #422121 Insecurities in dict comparison.
Fixed a half dozen ways in which general dict comparison could crash
Python (even cause Win98SE to reboot) in the presence of kay and/or
value comparison routines that mutate the dict during dict comparison.
Bugfix candidate.
2001-05-10 08:32:44 +00:00
Tim Peters 9c012af3c3 Heh. I need a break. After this: stropmodule & stringobject were more
out of synch than I realized, and I managed to break replace's "count"
argument when it was 0.  All is well again.  Maybe.
Bugfix candidate.
2001-05-10 00:32:57 +00:00
Tim Peters 4cd44ef4bf Fudge. stropmodule and stringobject both had copies of the buggy
mymemXXX stuff, and they were already out of synch.  Fix the remaining
bugs in both and get them back in synch.
Bugfix release candidate.
2001-05-10 00:05:33 +00:00
Tim Peters 1a97d5f098 SF patch #416247 2.1c1 stringobject: unused vrbl cleanup.
Thanks to Mark Favas.
2001-05-09 20:06:00 +00:00
Tim Peters 4862ab7bf4 Sheesh -- repair the dodge around "cast isn't an lvalue" complaints to
restore correct semantics.
2001-05-09 08:43:21 +00:00
Tim Peters 9e897f41db Mark Favas reported that gcc caught me using casts as lvalues. Dodge it. 2001-05-09 07:37:07 +00:00
Tim Peters b4bbcd76ea Ack! Restore the COUNT_ALLOCS one_strings code. 2001-05-09 00:31:40 +00:00
Tim Peters cf5ad5d6f6 My change to string_item() left an extra reference to each 1-character
interned string created by "string"[i].  Since they're immortal anyway,
this was hard to notice, but it was still wrong <wink>.
2001-05-09 00:24:55 +00:00
Tim Peters 5b4d477568 Intern 1-character strings as soon as they're created. As-is, they aren't
interned when created, so the cached versions generally aren't ever
interned.  With the patch, the
		Py_INCREF(t);
		*p = t;
		Py_DECREF(s);
		return;
indirection block in PyString_InternInPlace() is never executed during a
full run of the test suite, but was executed very many times before.  So
I'm trading more work when creating one-character strings for doing less
work later.  Note that the "more work" here can happen at most 256 times
per program run, so it's trivial.  The same reasoning accounts for the
patch's simplification of string_item (the new version can call
PyString_FromStringAndSize() no more than 256 times per run, so there's
no point to inlining that stuff -- if we were serious about saving time
here, we'd pre-initialize the characters vector so that no runtime testing
at all was needed!).
2001-05-08 22:33:50 +00:00
Tim Peters 72f98e9b83 SF bug #422177: Results from .pyc differs from .py
Store floats and doubles to full precision in marshal.
Test that floats read from .pyc/.pyo closely match those read from .py.
Declare PyFloat_AsString() in floatobject header file.
Add new PyFloat_AsReprString() API function.
Document the functions declared in floatobject.h.
2001-05-08 15:19:57 +00:00
Tim Peters e63415ead8 SF patch #421922: Implement rich comparison for dicts.
d1 == d2 and d1 != d2 now work even if the keys and values in d1 and d2
don't support comparisons other than ==, and testing dicts for equality
is faster now (especially when inequality obtains).
2001-05-08 04:38:29 +00:00
Jeremy Hylton 4c889011db SF patch 419176 from MvL; fixed bug 418977
Two errors in dict_to_map() helper used by PyFrame_LocalsToFast().
2001-05-08 04:08:59 +00:00
Jeremy Hylton d37292bb8d Remove unused variable 2001-05-08 04:00:45 +00:00
Tim Peters 6d60b2e762 SF bug #422108 - Error in rich comparisons.
2.1.1 bugfix candidate too.
Fix a bad (albeit unlikely) return value in try_rich_to_3way_compare().
Also document do_cmp()'s return values.
2001-05-07 20:53:51 +00:00
Tim Peters cb8d368b82 Reimplement PySequence_Contains() and instance_contains(), so they work
safely together and don't duplicate logic (the common logic was factored
out into new private API function _PySequence_IterContains()).
Visible change:
    some_complex_number  in  some_instance
no longer blows up if some_instance has __getitem__ but neither
__contains__ nor __iter__.  test_iter changed to ensure that remains true.
2001-05-05 21:05:01 +00:00
Tim Peters 75f8e35ef4 Generalize PySequence_Count() (operator.countOf) to work with iterators. 2001-05-05 11:33:43 +00:00
Tim Peters de9725f135 Make 'x in y' and 'x not in y' (PySequence_Contains) play nice w/ iterators.
NEEDS DOC CHANGES
A few more AttributeErrors turned into TypeErrors, but in test_contains
this time.
The full story for instance objects is pretty much unexplainable, because
instance_contains() tries its own flavor of iteration-based containment
testing first, and PySequence_Contains doesn't get a chance at it unless
instance_contains() blows up.  A consequence is that
    some_complex_number in some_instance
dies with a TypeError unless some_instance.__class__ defines __iter__ but
does not define __getitem__.
2001-05-05 10:06:17 +00:00
Tim Peters 2cfe368283 Make unicode.join() work nice with iterators. This also required a change
to string.join(), so that when the latter figures out in midstream that
it really needs unicode.join() instead, unicode.join() can actually get
all the sequence elements (i.e., there's no guarantee that the sequence
passed to string.join() can be iterated over *again* by unicode.join(),
so string.join() must not pass on the original sequence object anymore).
2001-05-05 05:36:48 +00:00
Tim Peters 12d0a6c78a Fix a tiny and unlikely memory leak. Was there before too, and actually
several of these turned up and got fixed during the iteration crusade.
2001-05-05 04:10:25 +00:00
Tim Peters 6912d4ddf0 Generalize tuple() to work nicely with iterators.
NEEDS DOC CHANGES.
This one surprised me!  While I expected tuple() to be a no-brainer, turns
out it's actually dripping with consequences:
1. It will *allow* the popular PySequence_Fast() to work with any iterable
   object (code for that not yet checked in, but should be trivial).
2. It caused two std tests to fail.  This because some places used
   PyTuple_Sequence() (the C spelling of tuple()) as an indirect way to test
   whether something *is* a sequence.  But tuple() code only looked for the
   existence of sq->item to determine that, and e.g. an instance passed
   that test whether or not it supported the other operations tuple()
   needed (e.g., __len__).  So some things the tests *expected* to fail
   with an AttributeError now fail with a TypeError instead.  This looks
   like an improvement to me; e.g., test_coercion used to produce 559
   TypeErrors and 2 AttributeErrors, and now they're all TypeErrors.  The
   error details are more informative too, because the places calling this
   were *looking* for TypeErrors in order to replace the generic tuple()
   "not a sequence" msg with their own more specific text, and
   AttributeErrors snuck by that.
2001-05-05 03:56:37 +00:00
Tim Peters f4848dac41 Make PyIter_Next() a little smarter (wrt its knowledge of iterator
internals) so clients can be a lot dumber (wrt their knowledge).
2001-05-05 00:14:56 +00:00
Fred Drake 6aebded915 The weakref support in PyObject_InitVar() as well; this should have come out
at the same time as it did from PyObject_Init() .
2001-05-03 20:04:33 +00:00
Fred Drake ba40ec42c8 Remove unnecessary intialization for the case of weakly-referencable objects;
the code necessary to accomplish this is simpler and faster if confined to
the object implementations, so we only do this there.

This causes no behaviorial changes beyond a (very slight) speedup.
2001-05-03 19:44:50 +00:00
Fred Drake 4dcb85b817 Since Py_TPFLAGS_HAVE_WEAKREFS is set in Py_TPFLAGS_DEFAULT, it does not
need to be specified in the type structures independently.  The flag
exists only for binary compatibility.

This is a "source cleanliness" issue and introduces no behavioral changes.
2001-05-03 16:04:13 +00:00
Guido van Rossum b1f35bffe5 Mchael Hudson pointed out that the code for detecting changes in
dictionary size was comparing ma_size, the hash table size, which is
always a power of two, rather than ma_used, wich changes on each
insertion or deletion.  Fixed this.
2001-05-02 15:13:44 +00:00
Marc-André Lemburg 542fe56cb9 Fix for bug #417030: "print '%*s' fails for unicode string" 2001-05-02 14:21:53 +00:00
Tim Peters 6ad22c41c2 Plug a memory leak in list(), when appending to the result list. 2001-05-02 07:12:39 +00:00
Tim Peters f553f89d45 Generalize list(seq) to work with iterators. This also generalizes list()
to no longer insist that len(seq) be defined.
NEEDS DOC CHANGES.
This is meant to be a model for how other functions of this ilk (max,
filter, etc) can be generalized similarly.  Feel encouraged to grab your
favorite and convert it!
Note some cute consequences:
    list(file) == file.readlines() == list(file.xreadlines())
    list(dict) == dict.keys()
    list(dict.iteritems()) = dict.items()
    list(xrange(i, j, k)) == range(i, j, k)
2001-05-01 20:45:31 +00:00
Guido van Rossum 47668928e6 Discard a misleading comment about iter_iternext(). 2001-05-01 17:01:25 +00:00
Guido van Rossum 4f288ab7d6 Printing objects to a real file still wasn't done right: if the
object's type didn't define tp_print, there were still cases where the
full "print uses str() which falls back to repr()" semantics weren't
honored.  This resulted in

    >>> print None
    <None object at 0x80bd674>
    >>> print type(u'')
    <type object at 0x80c0a80>

Fixed this by always using the appropriate PyObject_Repr() or
PyObject_Str() call, rather than trying to emulate what they would do.

Also simplified PyObject_Str() to always fall back on PyObject_Repr()
when tp_str is not defined (rather than making an extra check for
instances with a __str__ method).  And got rid of the special case for
strings.
2001-05-01 16:53:37 +00:00
Guido van Rossum 189f1df301 Add a proper implementation for the tp_str slot (returning self, of
course), so I can get rid of the special case for strings in
PyObject_Str().
2001-05-01 16:51:53 +00:00
Guido van Rossum 09e563abb4 Add experimental iterkeys(), itervalues(), iteritems() to dict
objects.

Tests show that iteritems() is 5-10% faster than iterating over the
dict and extracting the value with dict[key].
2001-05-01 12:10:21 +00:00
Guido van Rossum 82c690f11a Well darnit! The innocuous fix I made to PyObject_Print() caused
printing of instances not to look for __str__().  Fix this.
2001-04-30 14:39:18 +00:00
Tim Peters b3d8d1f76c A different approach to the problem reported in
Patch #419651: Metrowerks on Mac adds 0x itself
C std says %#x and %#X conversion of 0 do not add the 0x/0X base marker.
Metrowerks apparently does.  Mark Favas reported the same bug under a
Compaq compiler on Tru64 Unix, but no other libc broken in this respect
is known (known to be OK under MSVC and gcc).
So just try the damn thing at runtime and see what the platform does.
Note that we've always had bugs here, but never knew it before because
a relevant test case didn't exist before 2.1.
2001-04-28 05:38:26 +00:00
Guido van Rossum 3a80c4a29c (Adding this to the trunk as well.)
Fix a very old flaw in PyObject_Print().  Amazing!  When an object
type defines tp_str but not tp_repr, 'print x' to a real file
object would not call the tp_str slot but rather print a default style
representation: <foo object at 0x....>.  This even though 'print x' to
a file-like-object would correctly call the tp_str slot.
2001-04-27 21:35:01 +00:00
Marc-André Lemburg 8155e0e541 This patch originated from an idea by Martin v. Loewis who submitted a
patch for sharing single character Unicode objects.

Martin's patch had to be reworked in a number of ways to take Unicode
resizing into consideration as well. Here's what the updated patch
implements:

* Single character Unicode strings in the Latin-1 range are shared
  (not only ASCII chars as in Martin's original patch).

* The ASCII and Latin-1 codecs make use of this optimization,
  providing a noticable speedup for single character strings. Most
  Unicode methods can use the optimization as well (by virtue
  of using PyUnicode_FromUnicode()).

* Some code cleanup was done (replacing memcpy with Py_UNICODE_COPY)

* The PyUnicode_Resize() can now also handle the case of resizing
  unicode_empty which previously resulted in an error.

* Modified the internal API _PyUnicode_Resize() and
  the public PyUnicode_Resize() API to handle references to
  shared objects correctly. The _PyUnicode_Resize() signature
  changed due to this.

* Callers of PyUnicode_FromUnicode() may now only modify the Unicode
  object contents of the returned object in case they called the API
  with NULL as content template.

Note that even though this patch passes the regression tests, there
may still be subtle bugs in the sharing code.
2001-04-23 14:44:21 +00:00
Guido van Rossum 213c7a6aa5 Mondo changes to the iterator stuff, without changing how Python code
sees it (test_iter.py is unchanged).

- Added a tp_iternext slot, which calls the iterator's next() method;
  this is much faster for built-in iterators over built-in types
  such as lists and dicts, speeding up pybench's ForLoop with about
  25% compared to Python 2.1.  (Now there's a good argument for
  iterators. ;-)

- Renamed the built-in sequence iterator SeqIter, affecting the C API
  functions for it.  (This frees up the PyIter prefix for generic
  iterator operations.)

- Added PyIter_Check(obj), which checks that obj's type has a
  tp_iternext slot and that the proper feature flag is set.

- Added PyIter_Next(obj) which calls the tp_iternext slot.  It has a
  somewhat complex return condition due to the need for speed: when it
  returns NULL, it may not have set an exception condition, meaning
  the iterator is exhausted; when the exception StopIteration is set
  (or a derived exception class), it means the same thing; any other
  exception means some other error occurred.
2001-04-23 14:08:49 +00:00
Guido van Rossum 65967259f2 Oops, forgot to merge this from the iter-branch to the trunk.
This adds "for line in file" iteration, as promised.
2001-04-21 13:20:18 +00:00
Tim Peters cf96de052f SF but #417587: compiler warnings compiling 2.1.
Repaired *some* of the SGI compiler warnings Sjoerd Mullender reported.
2001-04-21 02:46:11 +00:00
Guido van Rossum 05311481d4 Adding iterobject.[ch], which were accidentally not added. Sorry\! 2001-04-20 21:06:46 +00:00
Guido van Rossum 59d1d2b434 Iterators phase 1. This comprises:
new slot tp_iter in type object, plus new flag Py_TPFLAGS_HAVE_ITER
new C API PyObject_GetIter(), calls tp_iter
new builtin iter(), with two forms: iter(obj), and iter(function, sentinel)
new internal object types iterobject and calliterobject
new exception StopIteration
new opcodes for "for" loops, GET_ITER and FOR_ITER (also supported by dis.py)
new magic number for .pyc files
new special method for instances: __iter__() returns an iterator
iteration over dictionaries: "for x in dict" iterates over the keys
iteration over files: "for x in file" iterates over lines

TODO:

documentation
test suite
decide whether to use a different way to spell iter(function, sentinal)
decide whether "for key in dict" is a good idea
use iterators in map/filter/reduce, min/max, and elsewhere (in/not in?)
speed tuning (make next() a slot tp_next???)
2001-04-20 19:13:02 +00:00
Guido van Rossum 55ad67d74d Oops. Removed dictiter_new decl that wasn't supposed to go in yet. 2001-04-20 16:52:06 +00:00
Guido van Rossum 0dbb4fba4c Implement, test and document "key in dict" and "key not in dict".
I know some people don't like this -- if it's really controversial,
I'll take it out again.  (If it's only Alex Martelli who doesn't like
it, that doesn't count as "real controversial" though. :-)

That's why this is a separate checkin from the iterators stuff I'm
about to check in next.
2001-04-20 16:50:40 +00:00
Tim Peters 78fe5308b4 CVS patch 416248: 2.1c1 unicodeobject: unused vrbl cleanup, from Mark Favas. 2001-04-19 21:55:14 +00:00
Jeremy Hylton b8a93215c2 Revert previous checkin, which caused test_unicodedata to fail. 2001-04-19 16:43:49 +00:00
Martin v. Löwis da3dc5b892 Patch #416953: Cache ASCII characters to speed up ASCII decoding. 2001-04-18 12:49:15 +00:00
Guido van Rossum e04eaec5b6 Tim pointed out a remaining vulnerability in popitem(): the
PyTuple_New() could *conceivably* clear the dict, so move the test for
an empty dict after the tuple allocation.  It means that we waste time
allocating and deallocating a 2-tuple when the dict is empty, but who
cares.  It also means that when the dict is empty *and* there's no
memory to allocate a 2-tuple, we raise MemoryError, not KeyError --
but that may actually a good idea: if there's no room for a lousy
2-tuple, what are the chances that there's room for a KeyError
instance?
2001-04-16 00:02:32 +00:00
Guido van Rossum a4dd011259 Tentative fix for a problem that Tim discovered at the last moment,
and reported to python-dev: because we were calling dict_resize() in
PyDict_Next(), and because GC's dict_traverse() uses PyDict_Next(),
and because PyTuple_New() can cause GC, and because dict_items() calls
PyTuple_New(), it was possible for dict_items() to have the dict
resized right under its nose.

The solution is convoluted, and touches several places: keys(),
values(), items(), popitem(), PyDict_Next(), and PyDict_SetItem().

There are two parts to it. First, we no longer call dict_resize() in
PyDict_Next(), which seems to solve the immediate problem.  But then
PyDict_SetItem() must have a different policy about when *it* calls
dict_resize(), because we want to guarantee (e.g. for an algorithm
that Jeremy uses in the compiler) that you can loop over a dict using
PyDict_Next() and make changes to the dict as long as those changes
are only value replacements for existing keys using PyDict_SetItem().
This is done by resizing *after* the insertion instead of before, and
by remembering the size before we insert the item, and if the size is
still the same, we don't bother to even check if we might need to
resize.  An additional detail is that if the dict starts out empty, we
must still resize it before the insertion.

That was the first part. :-)

The second part is to make keys(), values(), items(), and popitem()
safe against side effects on the dict caused by allocations, under the
assumption that if the GC can cause arbitrary Python code to run, it
can cause other threads to run, and it's not inconceivable that our
dict could be resized -- it would be insane to write code that relies
on this, but not all code is sane.

Now, I have this nagging feeling that the loops in lookdict probably
are blissfully assuming that doing a simple key comparison does not
change the dict's size.  This is not necessarily true (the keys could
be class instances after all).  But that's a battle for another day.
2001-04-15 22:16:26 +00:00
Guido van Rossum 6b356e70b5 Make one more private symbol static. 2001-04-14 17:55:41 +00:00