Author: Armin Rigo <[email protected]>
Branch: release-2.0.x
Changeset: r64218:4239096147a7
Date: 2013-05-16 11:17 +0200
http://bitbucket.org/pypy/pypy/changeset/4239096147a7/
Log: hg merge default: only a few changes
diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -27,7 +27,7 @@
new_inst = mod.get('generator_new')
w = space.wrap
if self.frame:
- w_frame = w(self.frame)
+ w_frame = self.frame._reduce_state(space)
else:
w_frame = space.w_None
@@ -36,7 +36,20 @@
w(self.running),
]
- return space.newtuple([new_inst, space.newtuple(tup)])
+ return space.newtuple([new_inst, space.newtuple([]),
+ space.newtuple(tup)])
+
+ def descr__setstate__(self, space, w_args):
+ from rpython.rlib.objectmodel import instantiate
+ args_w = space.unpackiterable(w_args)
+ w_framestate, w_running = args_w
+ if space.is_w(w_framestate, space.w_None):
+ self.frame = None
+ else:
+ frame = instantiate(space.FrameClass) # XXX fish
+ frame.descr__setstate__(space, w_framestate)
+ GeneratorIterator.__init__(self, frame)
+ self.running = self.space.is_true(w_running)
def descr__iter__(self):
"""x.__iter__() <==> iter(x)"""
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -16,10 +16,9 @@
from rpython.tool.stdlib_opcode import host_bytecode_spec
# Define some opcodes used
-g = globals()
for op in '''DUP_TOP POP_TOP SETUP_LOOP SETUP_EXCEPT SETUP_FINALLY
POP_BLOCK END_FINALLY'''.split():
- g[op] = stdlib_opcode.opmap[op]
+ globals()[op] = stdlib_opcode.opmap[op]
HAVE_ARGUMENT = stdlib_opcode.HAVE_ARGUMENT
class PyFrame(eval.Frame):
@@ -304,11 +303,17 @@
@jit.dont_look_inside
def descr__reduce__(self, space):
from pypy.interpreter.mixedmodule import MixedModule
- from pypy.module._pickle_support import maker # helper fns
w_mod = space.getbuiltinmodule('_pickle_support')
mod = space.interp_w(MixedModule, w_mod)
new_inst = mod.get('frame_new')
- w = space.wrap
+ w_tup_state = self._reduce_state(space)
+ nt = space.newtuple
+ return nt([new_inst, nt([]), w_tup_state])
+
+ @jit.dont_look_inside
+ def _reduce_state(self, space):
+ from pypy.module._pickle_support import maker # helper fns
+ w = space.wrap
nt = space.newtuple
cells = self._getcells()
@@ -359,8 +364,7 @@
w(self.instr_prev_plus_one),
w_cells,
]
-
- return nt([new_inst, nt([]), nt(tup_state)])
+ return nt(tup_state)
@jit.dont_look_inside
def descr__setstate__(self, space, w_args):
diff --git a/pypy/interpreter/test/test_zzpickle_and_slow.py
b/pypy/interpreter/test/test_zzpickle_and_slow.py
--- a/pypy/interpreter/test/test_zzpickle_and_slow.py
+++ b/pypy/interpreter/test/test_zzpickle_and_slow.py
@@ -485,3 +485,68 @@
pckl = pickle.dumps(pack.mod)
result = pickle.loads(pckl)
assert pack.mod is result
+
+
+class AppTestGeneratorCloning:
+
+ def setup_class(cls):
+ try:
+ cls.space.appexec([], """():
+ def f(): yield 42
+ f().__reduce__()
+ """)
+ except TypeError, e:
+ if 'pickle generator' not in str(e):
+ raise
+ py.test.skip("Frames can't be __reduce__()-ed")
+
+ def test_deepcopy_generator(self):
+ import copy
+
+ def f(n):
+ for i in range(n):
+ yield 42 + i
+ g = f(4)
+ g2 = copy.deepcopy(g)
+ res = g.next()
+ assert res == 42
+ res = g2.next()
+ assert res == 42
+ g3 = copy.deepcopy(g)
+ res = g.next()
+ assert res == 43
+ res = g2.next()
+ assert res == 43
+ res = g3.next()
+ assert res == 43
+
+ def test_shallowcopy_generator(self):
+ """Note: shallow copies of generators are often confusing.
+ To start with, 'for' loops have an iterator that will not
+ be copied, and so create tons of confusion.
+ """
+ import copy
+
+ def f(n):
+ while n > 0:
+ yield 42 + n
+ n -= 1
+ g = f(2)
+ g2 = copy.copy(g)
+ res = g.next()
+ assert res == 44
+ res = g2.next()
+ assert res == 44
+ g3 = copy.copy(g)
+ res = g.next()
+ assert res == 43
+ res = g2.next()
+ assert res == 43
+ res = g3.next()
+ assert res == 43
+ g4 = copy.copy(g2)
+ for i in range(2):
+ raises(StopIteration, g.next)
+ raises(StopIteration, g2.next)
+ raises(StopIteration, g3.next)
+ raises(StopIteration, g4.next)
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -913,6 +913,7 @@
GeneratorIterator.typedef = TypeDef("generator",
__repr__ = interp2app(GeneratorIterator.descr__repr__),
__reduce__ = interp2app(GeneratorIterator.descr__reduce__),
+ __setstate__ = interp2app(GeneratorIterator.descr__setstate__),
next = interp2app(GeneratorIterator.descr_next,
descrmismatch='next'),
send = interp2app(GeneratorIterator.descr_send,
diff --git a/pypy/module/_cffi_backend/misc.py
b/pypy/module/_cffi_backend/misc.py
--- a/pypy/module/_cffi_backend/misc.py
+++ b/pypy/module/_cffi_backend/misc.py
@@ -235,11 +235,17 @@
eci = ExternalCompilationInfo(post_include_bits=["""
#define pypy__is_nonnull_longdouble(x) ((x) != 0.0)
"""])
-is_nonnull_longdouble = rffi.llexternal(
+_is_nonnull_longdouble = rffi.llexternal(
"pypy__is_nonnull_longdouble", [rffi.LONGDOUBLE], lltype.Bool,
compilation_info=eci, _nowrapper=True, elidable_function=True,
sandboxsafe=True)
+# split here for JIT backends that don't support floats/longlongs/etc.
+def is_nonnull_longdouble(cdata):
+ return _is_nonnull_longdouble(read_raw_longdouble_data(cdata))
+def is_nonnull_float(cdata, size):
+ return read_raw_float_data(cdata, size) != 0.0
+
def object_as_bool(space, w_ob):
# convert and cast a Python object to a boolean. Accept an integer
# or a float object, up to a CData 'long double'.
@@ -254,10 +260,9 @@
is_cdata = isinstance(w_ob, W_CData)
if is_cdata and isinstance(w_ob.ctype, W_CTypePrimitiveFloat):
if isinstance(w_ob.ctype, W_CTypePrimitiveLongDouble):
- result = is_nonnull_longdouble(
- read_raw_longdouble_data(w_ob._cdata))
+ result = is_nonnull_longdouble(w_ob._cdata)
else:
- result = read_raw_float_data(w_ob._cdata, w_ob.ctype.size) != 0.0
+ result = is_nonnull_float(w_ob._cdata, w_ob.ctype.size)
keepalive_until_here(w_ob)
return result
#
diff --git a/pypy/module/_pickle_support/maker.py
b/pypy/module/_pickle_support/maker.py
--- a/pypy/module/_pickle_support/maker.py
+++ b/pypy/module/_pickle_support/maker.py
@@ -59,11 +59,8 @@
tb = instantiate(PyTraceback)
return space.wrap(tb)
-@unwrap_spec(running=int)
-def generator_new(space, w_frame, running):
- frame = space.interp_w(PyFrame, w_frame, can_be_None=True)
- new_generator = GeneratorIterator(frame)
- new_generator.running = running
+def generator_new(space):
+ new_generator = instantiate(GeneratorIterator)
return space.wrap(new_generator)
@unwrap_spec(current=int, remaining=int, step=int)
diff --git a/rpython/translator/goal/translate.py
b/rpython/translator/goal/translate.py
--- a/rpython/translator/goal/translate.py
+++ b/rpython/translator/goal/translate.py
@@ -147,6 +147,10 @@
else:
show_help(translateconfig, opt_parser, None, config)
+ # print the version of the host
+ # (if it's PyPy, it includes the hg checksum)
+ log.info(sys.version)
+
# apply the platform settings
set_platform(config)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit