[pypy-dev] The correct way to incrementally build list in RPython

Armin Rigo arigo at tunes.org
Fri Jun 27 09:07:43 CEST 2014


Hi Yichao,

On 27 June 2014 04:09, Yichao Yu <yyc1992 at gmail.com> wrote:
> On an attempt to fix the hash function of numpy.dtype, I came up with
> the patch in the attachment translated from hashdescr.c in the
> original numpy source. The patch passed the test when running in
> pyinteractive.py. However, when started to translate pypy, I get an
> ListChangeUnallowed error.

That errors comes from space.newtuple(lst): it must be passed a list
"lst" that is "not resized", that is, a list on which we never do an
append() or pop() or similar.

The standard fix is to do "lst = [None] * length" and then fill
"lst[index] = ...".  This only works if you know the final length in
advance.  A more heavy way to fix it is simply to call
space.newtuple(lst[:]), making a fresh copy of the list.  But in this
case, a better fix would be to avoid the list and the space.newtuple()
and space.hash() completely, and instead compute the hash value
incrementally, by copying the logic in
pypy/objspace/std/tupleobject.py:descr_hash().

Similarly, I'm not sure you need to wrap self.kind, 0, self.elsize and
self.alignment and put them inside a tuple of length 4, when all you
could do is some random computation with these three numbers.


A bientôt,

Armin.


More information about the pypy-dev mailing list