[pypy-commit] extradoc extradoc: Copy and adapt the talk from pycon-italy-2014 (thanks antocuni)
Author: Armin Rigo ar...@tunes.org Branch: extradoc Changeset: r5362:3dd14da26db0 Date: 2014-07-19 13:57 +0200 http://bitbucket.org/pypy/extradoc/changeset/3dd14da26db0/ Log:Copy and adapt the talk from pycon-italy-2014 (thanks antocuni) diff --git a/talk/pycon-italy-2014/Makefile b/talk/ep2014/status/Makefile copy from talk/pycon-italy-2014/Makefile copy to talk/ep2014/status/Makefile --- a/talk/pycon-italy-2014/Makefile +++ b/talk/ep2014/status/Makefile @@ -1,10 +1,10 @@ # you can find rst2beamer.py here: -# http://codespeak.net/svn/user/antocuni/bin/rst2beamer.py +# https://bitbucket.org/antocuni/env/raw/default/bin/rst2beamer.py # WARNING: to work, it needs this patch for docutils # https://sourceforge.net/tracker/?func=detailatid=422032aid=1459707group_id=38414 -talk.pdf: talk.rst author.latex title.latex stylesheet.latex +talk.pdf: talk.rst author.latex stylesheet.latex python `which rst2beamer.py` --stylesheet=stylesheet.latex --documentoptions=14pt talk.rst talk.latex || exit #/home/antocuni/.virtualenvs/rst2beamer/bin/python `which rst2beamer.py` --stylesheet=stylesheet.latex --documentoptions=14pt talk.rst talk.latex || exit sed 's/\\date{}/\\input{author.latex}/' -i talk.latex || exit diff --git a/talk/pycon-italy-2014/author.latex b/talk/ep2014/status/author.latex copy from talk/pycon-italy-2014/author.latex copy to talk/ep2014/status/author.latex --- a/talk/pycon-italy-2014/author.latex +++ b/talk/ep2014/status/author.latex @@ -1,8 +1,10 @@ \definecolor{rrblitbackground}{rgb}{0.0, 0.0, 0.0} -\title[PyPy Status]{PyPy Status\\\small{(no, PyPy is not dead)}} -\author[antocuni] -{Antonio Cuni} +\title[PyPy Status Talk]{PyPy Status Talk\\\small{(no no, PyPy is not dead)}} +\author[arigo, rguillebert] +{Armin Rigo, Romain Guillebert\\ +based on a PyCon Italia talk by Antonio Cuni\\ +\includegraphics[width=80px]{../../img/py-web-new.png}} -\institute{PyCon Cinque} -\date{May 24, 2014} +\institute{EuroPython} +\date{July 22, 2014} diff --git a/talk/pycon-italy-2014/beamerdefs.txt b/talk/ep2014/status/beamerdefs.txt copy from talk/pycon-italy-2014/beamerdefs.txt copy to talk/ep2014/status/beamerdefs.txt diff --git a/talk/ep2014/status/speed.png b/talk/ep2014/status/speed.png new file mode 100644 index ..33fe20ac9d81ddbd3ced48f52f9717693dc15518 GIT binary patch [cut] diff --git a/talk/pycon-italy-2014/stylesheet.latex b/talk/ep2014/status/stylesheet.latex copy from talk/pycon-italy-2014/stylesheet.latex copy to talk/ep2014/status/stylesheet.latex diff --git a/talk/ep2014/status/talk.pdf b/talk/ep2014/status/talk.pdf new file mode 100644 index ..f9532b263b7bf1aa53ba0d807a875af9991c6a39 GIT binary patch [cut] diff --git a/talk/pycon-italy-2014/talk.pdf.info b/talk/ep2014/status/talk.pdf.info copy from talk/pycon-italy-2014/talk.pdf.info copy to talk/ep2014/status/talk.pdf.info diff --git a/talk/pycon-italy-2014/talk.rst b/talk/ep2014/status/talk.rst copy from talk/pycon-italy-2014/talk.rst copy to talk/ep2014/status/talk.rst --- a/talk/pycon-italy-2014/talk.rst +++ b/talk/ep2014/status/talk.rst @@ -4,18 +4,6 @@ PyPy Status -About me -- - -- PyPy core dev - -- ``pdb++``, ``fancycompleter``, ... - -- Consultant, trainer - -- http://antocuni.eu - - PyPy is not dead @@ -114,6 +102,8 @@ * ~7x faster than standard PHP + * comparable speed as HHVM + * http://hippyvm.com/ @@ -121,18 +111,27 @@ Fundraising campaign - -- py3k: 50'852 $ of 105'000 $ (48.4%) +- py3k: 52'000 $ of 105'000 $ (50%) -- numpy: 48'121 $ of 60'000 $ (80.2%) +- numpy: 48'000 $ of 60'000 $ (80%) - STM, 1st call: 25'000 $ -- STM, 2nd call: 2'097 $ of 80'000 $ (2.6%) - - * more on STM later +- STM, 2nd call: 3'000 $ of 80'000 $ (4%) - thank to all donors! +Commercial support +-- + +- We offer commercial support for PyPy + +- Consultancy and training + +- Performance issues for open- or closed-source programs, porting, + improving support in parts of the Python or non-Python interpreters, + etc. + Current status --- @@ -155,11 +154,11 @@ - numpy: in-progress (more later) -Speed: 6.3x faster than CPython +Speed: 6.5x faster than CPython .. image:: speed.png - :scale: 47% + :scale: 44% ARM @@ -252,92 +251,19 @@ * by Armin Rigo and Remi Meier -STM semantics -- - -- N threads - -- Each thread split into atomic blocks - -- Sequential execution in some arbitrary order - -- In practice: - -- Parallel execution, conflicts solved by STM - - -Unit of execution (1) -- - -- Atomic blocks == 1 Python bytecode - -- Threads are executed in arbitrary order, but bytecodes are atomic - -- == Same semantics as GIL - -- and this will solve the GIL problem (A. Rigo, EuroPython 2011 lighting
[pypy-commit] lang-smalltalk storage-context-state: Fixed tests, added tests.
Author: Anton Gulenko anton.gule...@googlemail.com Branch: storage-context-state Changeset: r922:2d1854d40231 Date: 2014-07-18 15:29 +0200 http://bitbucket.org/pypy/lang-smalltalk/changeset/2d1854d40231/ Log:Fixed tests, added tests. diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -978,9 +978,32 @@ 2, value:value:]], test) -def test_c_stack_reset_on_sender_chain_manipulation(): -bytes = reduce(operator.add, map(chr, [0x84, 0xc0, 0x00])) +def test_frame_dirty_if_active(): +bytes = reduce(operator.add, map(chr, [0x84, 0xc0, 0x00])) + returnReceiverBytecode w_frame, s_frame = new_frame(bytes) s_frame.store_w_receiver(w_frame) s_frame.push(w_frame) -py.test.raises(interpreter.SenderChainManipulation, step_in_interp, s_frame) +s_frame.state = shadow.ActiveContext +step_in_interp(s_frame) +assert s_frame.state is shadow.DirtyContext + +def test_frame_not_dirty_if_inactive(): +bytes = reduce(operator.add, map(chr, [0x84, 0xc0, 0x00])) + returnReceiverBytecode +w_frame, s_frame = new_frame(bytes) +w_other_frame, s_other_frame = new_frame() +s_frame.store_w_receiver(w_other_frame) +s_frame.push(w_frame) +s_frame.state = shadow.ActiveContext +step_in_interp(s_frame) +assert s_frame.state is shadow.ActiveContext +assert s_other_frame.state is shadow.InactiveContext + +def test_raise_SenderManipulation_on_dirty_frame(): +w_frame, s_frame = new_frame(returnReceiverBytecode) +s_frame.state = shadow.DirtyContext +def run_frame(): +#import pdb; pdb.set_trace() +interp._loop = True +interp.stack_frame(s_frame, None) +py.test.raises(interpreter.SenderChainManipulation, run_frame) + \ No newline at end of file diff --git a/spyvm/test/test_zin_squeak_4_5_image.py b/spyvm/test/test_zin_squeak_4_5_image.py --- a/spyvm/test/test_zin_squeak_4_5_image.py +++ b/spyvm/test/test_zin_squeak_4_5_image.py @@ -43,7 +43,7 @@ # create a frame for our newly crafted method with a valid sender (to avoid raising returnFromTop to early) s_initial_frame = create_method(chr(0x7c)).create_frame(space, w(0), []) s_frame = w_method.create_frame(space, w(0)) -s_frame.store_s_sender(s_initial_frame, raise_error=False) +s_frame.store_s_sender(s_initial_frame) try: interp.loop(s_frame.w_self()) @@ -70,7 +70,7 @@ # create a frame for our newly crafted method with a valid sender (to avoid raising returnFromTop to early) s_initial_frame = create_method(chr(0x7c)).create_frame(space, w(0)) s_frame = w_method.create_frame(space, w(0)) -s_frame.store_s_sender(s_initial_frame, raise_error=False) +s_frame.store_s_sender(s_initial_frame) try: interp.loop(s_frame.w_self()) diff --git a/spyvm/test/util.py b/spyvm/test/util.py --- a/spyvm/test/util.py +++ b/spyvm/test/util.py @@ -85,7 +85,7 @@ if not self._loop: # this test is done to not loop in test, but rather step just once where wanted # Unfortunately, we have to mimick some of the original behaviour. -s_new_frame.store_s_sender(s_sender, raise_error=False) +s_new_frame.store_s_sender(s_sender) return s_new_frame return interpreter.Interpreter.stack_frame(self, s_new_frame, s_sender, may_context_switch) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] lang-smalltalk storage-context-state: Fixed ensure: mechanism. Fixed test.
Author: Anton Gulenko anton.gule...@googlemail.com Branch: storage-context-state Changeset: r924:f5b3945a1fdc Date: 2014-07-19 13:48 +0200 http://bitbucket.org/pypy/lang-smalltalk/changeset/f5b3945a1fdc/ Log:Fixed ensure: mechanism. Fixed test. diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -819,10 +819,8 @@ self.push(self.gettemp(0)) # push the first argument try: self.bytecodePrimValue(interp, 0) -except Return, nlr: -assert nlr.s_target_context or nlr.is_local -if self is not nlr.s_target_context and not nlr.is_local: -raise nlr +except LocalReturn, ret: +pass # Local return value of ensure: block is ignored finally: self.mark_returned() diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py --- a/spyvm/test/test_interpreter.py +++ b/spyvm/test/test_interpreter.py @@ -979,7 +979,7 @@ test) def test_frame_dirty_if_active(): -bytes = reduce(operator.add, map(chr, [0x84, 0xc0, 0x00])) + returnReceiverBytecode +bytes = reduce(operator.add, map(chr, [0x84, 0xc0, 0x00])) w_frame, s_frame = new_frame(bytes) s_frame.store_w_receiver(w_frame) s_frame.push(w_frame) @@ -988,7 +988,7 @@ assert s_frame.state is shadow.DirtyContext def test_frame_not_dirty_if_inactive(): -bytes = reduce(operator.add, map(chr, [0x84, 0xc0, 0x00])) + returnReceiverBytecode +bytes = reduce(operator.add, map(chr, [0x84, 0xc0, 0x00])) w_frame, s_frame = new_frame(bytes) w_other_frame, s_other_frame = new_frame() s_frame.store_w_receiver(w_other_frame) @@ -998,12 +998,14 @@ assert s_frame.state is shadow.ActiveContext assert s_other_frame.state is shadow.InactiveContext -def test_raise_SenderManipulation_on_dirty_frame(): -w_frame, s_frame = new_frame(returnReceiverBytecode) -s_frame.state = shadow.DirtyContext -def run_frame(): -#import pdb; pdb.set_trace() -interp._loop = True +def test_raise_NonVirtualReturn_on_dirty_frame(): +bytes = reduce(operator.add, map(chr, [0x84, 0xc0, 0x00])) + returnTopFromMethodBytecode +w_frame, s_frame = new_frame(bytes) +s_frame.store_w_receiver(w_frame) +s_frame.push(w_frame) + +interp._loop = True +def do_test(): interp.stack_frame(s_frame, None) -py.test.raises(interpreter.SenderChainManipulation, run_frame) +py.test.raises(interpreter.NonVirtualReturn, do_test) \ No newline at end of file ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] lang-smalltalk storage: Refactoring, reduced code duplication.
Author: Anton Gulenko anton.gule...@googlemail.com Branch: storage Changeset: r920:2dd2b3555772 Date: 2014-07-18 14:21 +0200 http://bitbucket.org/pypy/lang-smalltalk/changeset/2dd2b3555772/ Log:Refactoring, reduced code duplication. diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -66,13 +66,9 @@ try: self.loop_bytecodes(s_new_context) raise Exception(loop_bytecodes left without raising...) -except StackOverflow, e: +except ContextSwitchException, e: if self.is_tracing(): -print == StackOverflow, contexts forced to heap at: %s % e.s_new_context.short_str() -s_new_context = e.s_new_context -except SenderChainManipulation, e: -if self.is_tracing(): -print == SenderChainManipulation, contexts forced to heap at: %s % e.s_new_context.short_str() +e.print_trace(s_new_context) s_new_context = e.s_new_context except Return, nlr: assert nlr.s_target_context or nlr.is_local @@ -83,13 +79,7 @@ s_new_context._activate_unwind_context(self) s_new_context = s_sender s_new_context.push(nlr.value) -except ProcessSwitch, p: -assert not self.space.suppress_process_switch.is_set(), ProcessSwitch should be disabled... -if self.is_tracing(): -print == Switched process from: %s % s_new_context.short_str() -print == to: %s % p.s_new_context.short_str() -s_new_context = p.s_new_context - + def loop_bytecodes(self, s_context, may_context_switch=True): old_pc = 0 if not jit.we_are_jitted() and may_context_switch: @@ -267,23 +257,34 @@ class ContextSwitchException(Exception): General Exception that causes the interpreter to leave the current context. + _attrs_ = [s_new_context] +type = ContextSwitch def __init__(self, s_new_context): self.s_new_context = s_new_context - + +def print_trace(self, old_context): +print == %s, contexts forced to heap at: %s % (self.type, self.s_new_context.short_str()) + class StackOverflow(ContextSwitchException): This causes the current jit-loop to be left, dumping all virtualized objects to the heap. This breaks performance, so it should rarely happen. In case of severe performance problems, execute with -t and check if this occurrs. - +type = Stack Overflow + class ProcessSwitch(ContextSwitchException): This causes the interpreter to switch the executed context. Triggered when switching the process. - + +def print_trace(self, old_context): +print == Switched process from: %s % old_context.short_str() +print == to: %s % self.s_new_context.short_str() + class SenderChainManipulation(ContextSwitchException): Manipulation of the sender chain can invalidate the jitted C stack. We have to dump all virtual objects and rebuild the stack. We try to raise this as rarely as possible and as late as possible. +type = Sender Manipulation import rpython.rlib.unroll if hasattr(unroll, unrolling_zero): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] lang-smalltalk storage-context-state: Delaying SenderChainManipulation as much as possible.
Author: Anton Gulenko anton.gule...@googlemail.com Branch: storage-context-state Changeset: r921:76c81645836d Date: 2014-07-18 15:29 +0200 http://bitbucket.org/pypy/lang-smalltalk/changeset/76c81645836d/ Log:Delaying SenderChainManipulation as much as possible. Added a 'state' field to Context objects, can be Inactive, Active or Dirty. Setting the sender of an Active context makes it Dirty. When a Dirty context is left, SenderChainManipulation will be raised, forcing all remaining contexts from the stack to the heap. diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -1,6 +1,6 @@ import py import os -from spyvm.shadow import ContextPartShadow, MethodContextShadow, BlockContextShadow, MethodNotFound +from spyvm.shadow import ContextPartShadow, MethodContextShadow, BlockContextShadow, MethodNotFound, ActiveContext, InactiveContext, DirtyContext from spyvm import model, constants, primitives, conftest, wrapper, objspace from spyvm.tool.bitmanipulation import splitter @@ -118,8 +118,10 @@ if self.is_tracing(): self.stack_depth += 1 if s_frame._s_sender is None and s_sender is not None: -s_frame.store_s_sender(s_sender, raise_error=False) +s_frame.store_s_sender(s_sender) # Now (continue to) execute the context bytecodes +assert s_frame.state is InactiveContext +s_frame.state = ActiveContext self.loop_bytecodes(s_frame, may_context_switch) except rstackovf.StackOverflow: rstackovf.check_stack_overflow() @@ -127,7 +129,11 @@ finally: if self.is_tracing(): self.stack_depth -= 1 - +dirty_frame = s_frame.state is DirtyContext +s_frame.state = InactiveContext +if dirty_frame: +raise SenderChainManipulation(s_frame) + def step(self, context): bytecode = context.fetch_next_bytecode() for entry in UNROLLING_BYTECODE_RANGES: @@ -755,16 +761,9 @@ association = wrapper.AssociationWrapper(self.space, w_association) self.push(association.value()) elif opType == 5: -# TODO - the following two special cases should not be necessary -try: -self.w_receiver().store(self.space, third, self.top()) -except SenderChainManipulation, e: -raise SenderChainManipulation(self) +self.w_receiver().store(self.space, third, self.top()) elif opType == 6: -try: -self.w_receiver().store(self.space, third, self.pop()) -except SenderChainManipulation, e: -raise SenderChainManipulation(self) +self.w_receiver().store(self.space, third, self.pop()) elif opType == 7: w_association = self.w_method().getliteral(third) association = wrapper.AssociationWrapper(self.space, w_association) diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -636,18 +636,29 @@ def size(self): return self._w_self_size +class ContextState(object): +def __init__(self, name): +self.name = name +def __str__(self): +return self.name +def __repr__(self): +return self.name +InactiveContext = ContextState(InactiveContext) +ActiveContext = ContextState(ActiveContext) +DirtyContext = ContextState(DirtyContext) + class ContextPartShadow(AbstractRedirectingShadow): __metaclass__ = extendabletype _attrs_ = ['_s_sender', '_pc', '_temps_and_stack', -'_stack_ptr', 'instances_w'] +'_stack_ptr', 'instances_w', 'state'] repr_classname = ContextPartShadow _virtualizable_ = [ '_s_sender', _pc, _temps_and_stack[*], _stack_ptr, -_w_self, _w_self_size +_w_self, _w_self_size, 'state' ] # __ @@ -657,13 +668,7 @@ self._s_sender = None AbstractRedirectingShadow.__init__(self, space, w_self, size) self.instances_w = {} - -def copy_field_from(self, n0, other_shadow): -from spyvm.interpreter import SenderChainManipulation -try: -AbstractRedirectingShadow.copy_field_from(self, n0, other_shadow) -except SenderChainManipulation, e: -assert e.s_new_context == self +self.state = InactiveContext def copy_from(self, other_shadow): # Some fields have to be initialized before the rest, to ensure correct initialization. @@ -705,7 +710,7 @@ if n0 == constants.CTXPART_SENDER_INDEX: assert isinstance(w_value, model.W_PointersObject) if w_value.is_nil(self.space): -self.store_s_sender(None, raise_error=False) +
[pypy-commit] lang-smalltalk storage-context-state: Refactored Return-mechanism to make the context state and late sender-chain-manipulation refactoring work.
Author: Anton Gulenko anton.gule...@googlemail.com Branch: storage-context-state Changeset: r923:a27bd7d3d458 Date: 2014-07-19 13:15 +0200 http://bitbucket.org/pypy/lang-smalltalk/changeset/a27bd7d3d458/ Log:Refactored Return-mechanism to make the context state and late sender-chain-manipulation refactoring work. Added LocalReturn class. stack_frame() handles dispatching of Return types, always invoked together with loop_bytecodes now. diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -60,25 +60,58 @@ def loop(self, w_active_context): # This is the top-level loop and is not invoked recursively. -s_new_context = w_active_context.as_context_get_shadow(self.space) +s_context = w_active_context.as_context_get_shadow(self.space) while True: -s_sender = s_new_context.s_sender() +s_sender = s_context.s_sender() try: -self.loop_bytecodes(s_new_context) +self.stack_frame(s_context, None) raise Exception(loop_bytecodes left without raising...) except ContextSwitchException, e: if self.is_tracing(): -e.print_trace(s_new_context) -s_new_context = e.s_new_context -except Return, nlr: -assert nlr.s_target_context or nlr.is_local -s_new_context = s_sender -if not nlr.is_local: -while s_new_context is not nlr.s_target_context: -s_sender = s_new_context.s_sender() -s_new_context._activate_unwind_context(self) -s_new_context = s_sender -s_new_context.push(nlr.value) +e.print_trace() +s_context = e.s_new_context +except LocalReturn, ret: +s_context = self.unwind_context_chain(s_sender, s_sender, ret.value) +except Return, ret: +s_context = self.unwind_context_chain(s_sender, ret.s_target_context, ret.value) +except NonVirtualReturn, ret: +if self.is_tracing(): +ret.print_trace() +s_context = self.unwind_context_chain(ret.s_current_context, ret.s_target_context, ret.value) + +# This is a wrapper around loop_bytecodes that cleanly enters/leaves the frame, +# handles the stack overflow protection mechanism and handles/dispatches Returns. +def stack_frame(self, s_frame, s_sender, may_context_switch=True): +try: +if self.is_tracing(): +self.stack_depth += 1 +if s_frame._s_sender is None and s_sender is not None: +s_frame.store_s_sender(s_sender) +# Now (continue to) execute the context bytecodes +assert s_frame.state is InactiveContext +s_frame.state = ActiveContext +self.loop_bytecodes(s_frame, may_context_switch) +except rstackovf.StackOverflow: +rstackovf.check_stack_overflow() +raise StackOverflow(s_frame) +except Return, e: +# Do not catch NonVirtualReturn. If there are multiple dirty contexts +# on the stack, the inner-most one will count. +if s_frame.state is DirtyContext: +s_sender = s_frame.s_sender() +s_frame._activate_unwind_context(self) +target_context = s_sender if e.is_local else e.s_target_context +raise NonVirtualReturn(target_context, e.value, s_sender) +else: +s_frame._activate_unwind_context(self) +if e.s_target_context is s_sender or e.is_local: +raise LocalReturn(e.value) +else: +raise e +finally: +if self.is_tracing(): +self.stack_depth -= 1 +s_frame.state = InactiveContext def loop_bytecodes(self, s_context, may_context_switch=True): old_pc = 0 @@ -100,39 +133,22 @@ s_context=s_context) try: self.step(s_context) -except Return, nlr: -if nlr.s_target_context is s_context or nlr.is_local: -s_context.push(nlr.value) -else: -if nlr.s_target_context is None: -# This is the case where we are returning to our sender. -# Mark the return as local, so our sender will take it -nlr.is_local = True -s_context._activate_unwind_context(self) -raise nlr - -# This is a wrapper around loop_bytecodes that cleanly enters/leaves the frame -# and handles the stack overflow protection mechanism. -def stack_frame(self, s_frame, s_sender,
[pypy-commit] pypy utf8-unicode2: Fix unicodedb
Author: Tyler Wade way...@gmail.com Branch: utf8-unicode2 Changeset: r72471:6ae77b6a146a Date: 2014-07-19 07:40 -0500 http://bitbucket.org/pypy/pypy/changeset/6ae77b6a146a/ Log:Fix unicodedb diff --git a/pypy/module/unicodedata/interp_ucd.py b/pypy/module/unicodedata/interp_ucd.py --- a/pypy/module/unicodedata/interp_ucd.py +++ b/pypy/module/unicodedata/interp_ucd.py @@ -6,11 +6,11 @@ from pypy.interpreter.baseobjspace import W_Root from pypy.interpreter.error import OperationError from pypy.interpreter.typedef import TypeDef, interp_attrproperty +from pypy.interpreter.utf8 import utf8chr from rpython.rlib.rarithmetic import r_longlong from rpython.rlib.objectmodel import we_are_translated -from rpython.rlib.runicode import MAXUNICODE from rpython.rlib.unicodedata import unicodedb_5_2_0, unicodedb_3_2_0 -from rpython.rlib.runicode import code_to_unichr, ord_accepts_surrogate +from rpython.rlib.runicode import ord_accepts_surrogate import sys @@ -30,47 +30,15 @@ # unicode code point. -if MAXUNICODE 0x: -# Target is wide build -def unichr_to_code_w(space, w_unichr): -if not space.isinstance_w(w_unichr, space.w_unicode): +def unichr_to_code_w(space, w_unichr): +if not space.isinstance_w(w_unichr, space.w_unicode): +raise OperationError(space.w_TypeError, space.wrap( +'argument 1 must be unicode')) + +if not space.len_w(w_unichr) == 1: raise OperationError(space.w_TypeError, space.wrap( -'argument 1 must be unicode')) - -if not we_are_translated() and sys.maxunicode == 0x: -# Host CPython is narrow build, accept surrogates -try: -return ord_accepts_surrogate(space.unicode_w(w_unichr)) -except TypeError: -raise OperationError(space.w_TypeError, space.wrap( 'need a single Unicode character as parameter')) -else: -if not space.len_w(w_unichr) == 1: -raise OperationError(space.w_TypeError, space.wrap( -'need a single Unicode character as parameter')) -return space.int_w(space.ord(w_unichr)) - -else: -# Target is narrow build -def unichr_to_code_w(space, w_unichr): -if not space.isinstance_w(w_unichr, space.w_unicode): -raise OperationError(space.w_TypeError, space.wrap( -'argument 1 must be unicode')) - -if not we_are_translated() and sys.maxunicode 0x: -# Host CPython is wide build, forbid surrogates -if not space.len_w(w_unichr) == 1: -raise OperationError(space.w_TypeError, space.wrap( -'need a single Unicode character as parameter')) -return space.int_w(space.ord(w_unichr)) - -else: -# Accept surrogates -try: -return ord_accepts_surrogate(space.unicode_w(w_unichr)) -except TypeError: -raise OperationError(space.w_TypeError, space.wrap( -'need a single Unicode character as parameter')) +return space.int_w(space.ord(w_unichr)) class UCD(W_Root): @@ -108,7 +76,7 @@ except KeyError: msg = space.mod(space.wrap(undefined character name '%s'), space.wrap(name)) raise OperationError(space.w_KeyError, msg) -return space.wrap(code_to_unichr(code)) +return space.wrap(utf8chr(code)) def name(self, space, w_unichr, w_default=None): code = unichr_to_code_w(space, w_unichr) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy utf8-unicode2: Fix _io
Author: Tyler Wade way...@gmail.com Branch: utf8-unicode2 Changeset: r72470:ed2146bad83c Date: 2014-07-17 23:18 -0500 http://bitbucket.org/pypy/pypy/changeset/ed2146bad83c/ Log:Fix _io diff --git a/pypy/module/_io/interp_stringio.py b/pypy/module/_io/interp_stringio.py --- a/pypy/module/_io/interp_stringio.py +++ b/pypy/module/_io/interp_stringio.py @@ -1,6 +1,7 @@ from pypy.interpreter.error import OperationError, oefmt from pypy.interpreter.typedef import ( TypeDef, generic_new_descr, GetSetProperty) +from pypy.interpreter.utf8 import Utf8Str, utf8ord from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault from pypy.module._io.interp_textio import W_TextIOBase, W_IncrementalNewlineDecoder from pypy.module._io.interp_iobase import convert_size @@ -26,8 +27,8 @@ else: newline = space.unicode_w(w_newline) -if (newline is not None and newline != u and newline != u\n and -newline != u\r and newline != u\r\n): +if (newline is not None and len(newline) != 0 and +newline not in (Utf8Str('\n'), Utf8Str('\r\n'), Utf8Str('\r'))): # Not using oefmt() because I don't know how to ues it # with unicode raise OperationError(space.w_ValueError, @@ -37,9 +38,9 @@ ) if newline is not None: self.readnl = newline -self.readuniversal = newline is None or newline == u +self.readuniversal = newline is None or len(newline) == 0 self.readtranslate = newline is None -if newline and newline[0] == u\r: +if newline and utf8ord(newline) == ord(\r): self.writenl = newline if self.readuniversal: self.w_decoder = space.call_function( @@ -112,7 +113,7 @@ if len(self.buf) newlength: self.buf = self.buf[:newlength] if len(self.buf) newlength: -self.buf.extend([u'\0'] * (newlength - len(self.buf))) +self.buf.extend([Utf8Str('\0')] * (newlength - len(self.buf))) def write(self, string): length = len(string) @@ -156,21 +157,21 @@ start = self.pos available = len(self.buf) - start if available = 0: -return space.wrap(u) +return space.wrap(Utf8Str()) if size = 0 and size = available: end = start + size else: end = len(self.buf) assert 0 = start = end self.pos = end -return space.wrap(u''.join(self.buf[start:end])) +return space.wrap(Utf8Str('').join(self.buf[start:end])) def readline_w(self, space, w_limit=None): self._check_closed(space) limit = convert_size(space, w_limit) if self.pos = len(self.buf): -return space.wrap(u) +return space.wrap(Utf8Str()) start = self.pos if limit 0 or limit len(self.buf) - self.pos: @@ -181,7 +182,7 @@ endpos, consumed = self._find_line_ending( # XXX: super inefficient, makes a copy of the entire contents. -u.join(self.buf), +Utf8Str().join(self.buf), start, end ) @@ -191,7 +192,7 @@ endpos = end assert endpos = 0 self.pos = endpos -return space.wrap(u.join(self.buf[start:endpos])) +return space.wrap(Utf8Str().join(self.buf[start:endpos])) @unwrap_spec(pos=int, mode=int) def seek_w(self, space, pos, mode=0): @@ -234,7 +235,7 @@ def getvalue_w(self, space): self._check_closed(space) -return space.wrap(u''.join(self.buf)) +return space.wrap(Utf8Str('').join(self.buf)) def readable_w(self, space): self._check_closed(space) diff --git a/pypy/module/_io/interp_textio.py b/pypy/module/_io/interp_textio.py --- a/pypy/module/_io/interp_textio.py +++ b/pypy/module/_io/interp_textio.py @@ -6,11 +6,11 @@ from pypy.interpreter.typedef import ( GetSetProperty, TypeDef, generic_new_descr, interp_attrproperty, interp_attrproperty_w) +from pypy.interpreter.utf8 import Utf8Str, Utf8Builder, utf8ord from pypy.module._codecs import interp_codecs from pypy.module._io.interp_iobase import W_IOBase, convert_size, trap_eintr from rpython.rlib.rarithmetic import intmask, r_uint, r_ulonglong from rpython.rlib.rbigint import rbigint -from rpython.rlib.rstring import UnicodeBuilder STATE_ZERO, STATE_OK, STATE_DETACHED = range(3) @@ -29,17 +29,17 @@ def __init__(self, space): self.w_newlines_dict = { -SEEN_CR: space.wrap(u\r), -SEEN_LF: space.wrap(u\n), -SEEN_CRLF: space.wrap(u\r\n), +SEEN_CR: space.wrap(Utf8Str(\r)), +SEEN_LF: space.wrap(Utf8Str(\n)), +SEEN_CRLF: space.wrap(Utf8Str(\r\n)), SEEN_CR | SEEN_LF: space.newtuple( -[space.wrap(u\r), space.wrap(u\n)]), +
[pypy-commit] pypy utf8-unicode2: Fix _multibytecodec
Author: Tyler Wade way...@gmail.com Branch: utf8-unicode2 Changeset: r72468:e70f582fd5dc Date: 2014-07-17 01:43 -0500 http://bitbucket.org/pypy/pypy/changeset/e70f582fd5dc/ Log:Fix _multibytecodec diff --git a/pypy/interpreter/utf8.py b/pypy/interpreter/utf8.py --- a/pypy/interpreter/utf8.py +++ b/pypy/interpreter/utf8.py @@ -2,9 +2,8 @@ from rpython.rlib.objectmodel import specialize from rpython.rlib.runicode import utf8_code_length from rpython.rlib.unicodedata import unicodedb_5_2_0 as unicodedb -from rpython.rlib.rarithmetic import r_uint -from rpython.rtyper.lltypesystem import rffi -from rpython.rtyper.lltypesystem import lltype +from rpython.rlib.rarithmetic import r_uint, intmask +from rpython.rtyper.lltypesystem import rffi, lltype wchar_rint = rffi.r_uint WCHAR_INTP = rffi.UINTP @@ -464,7 +463,7 @@ if rffi.sizeof(rffi.WCHAR_T) == 2: if 0xD800 = c = 0xDBFF: i += 1 -c2 = int(array[i]) +c2 = intmask(array[i]) if c2 == 0: builder.append(c) break @@ -485,7 +484,7 @@ builder = Utf8Builder() i = 0; while i size: -c = int(array[i]) +c = intmask(array[i]) if c == 0: break @@ -513,7 +512,7 @@ builder = Utf8Builder() i = 0; while i size: -c = int(array[i]) +c = intmask(array[i]) if rffi.sizeof(rffi.WCHAR_T) == 2: if i != size - 1 and 0xD800 = c = 0xDBFF: diff --git a/pypy/module/_multibytecodec/c_codecs.py b/pypy/module/_multibytecodec/c_codecs.py --- a/pypy/module/_multibytecodec/c_codecs.py +++ b/pypy/module/_multibytecodec/c_codecs.py @@ -1,8 +1,9 @@ import py from rpython.rtyper.lltypesystem import lltype, rffi from rpython.translator.tool.cbuild import ExternalCompilationInfo +from pypy.interpreter.utf8 import Utf8Str -UNICODE_REPLACEMENT_CHARACTER = u'\uFFFD' +UNICODE_REPLACEMENT_CHARACTER = Utf8Str.from_unicode(u'\uFFFD') class EncodeDecodeError(Exception): @@ -139,7 +140,7 @@ errorcb, namecb, stringdata) src = pypy_cjk_dec_outbuf(decodebuf) length = pypy_cjk_dec_outlen(decodebuf) -return rffi.wcharpsize2unicode(src, length) +return Utf8Str.from_wcharpsize(src, length) # finally: rffi.free_nonmovingbuffer(stringdata, inbuf) @@ -164,18 +165,18 @@ if errors == strict: raise EncodeDecodeError(start, end, reason) elif errors == ignore: -replace = u +replace = Utf8Str() elif errors == replace: replace = UNICODE_REPLACEMENT_CHARACTER else: assert errorcb replace, end = errorcb(errors, namecb, reason, stringdata, start, end) -inbuf = rffi.get_nonmoving_unicodebuffer(replace) +inbuf = replace.copy_to_wcharp() try: r = pypy_cjk_dec_replace_on_error(decodebuf, inbuf, len(replace), end) finally: -rffi.free_nonmoving_unicodebuffer(replace, inbuf) +rffi.free_wcharp(inbuf) if r == MBERR_NOMEMORY: raise MemoryError @@ -222,7 +223,7 @@ def encodeex(encodebuf, unicodedata, errors=strict, errorcb=None, namecb=None, ignore_error=0): inleft = len(unicodedata) -inbuf = rffi.get_nonmoving_unicodebuffer(unicodedata) +inbuf = unicodedata.copy_to_wcharp() try: if pypy_cjk_enc_init(encodebuf, inbuf, inleft) 0: raise MemoryError @@ -247,7 +248,7 @@ return rffi.charpsize2str(src, length) # finally: -rffi.free_nonmoving_unicodebuffer(unicodedata, inbuf) +rffi.free_wcharp(inbuf) def multibytecodec_encerror(encodebuf, e, errors, errorcb, namecb, unicodedata): @@ -273,7 +274,7 @@ elif errors == replace: codec = pypy_cjk_enc_getcodec(encodebuf) try: -replace = encode(codec, u?) +replace = encode(codec, Utf8Str(?)) except EncodeDecodeError: replace = ? else: diff --git a/pypy/module/_multibytecodec/test/test_c_codecs.py b/pypy/module/_multibytecodec/test/test_c_codecs.py --- a/pypy/module/_multibytecodec/test/test_c_codecs.py +++ b/pypy/module/_multibytecodec/test/test_c_codecs.py @@ -1,4 +1,5 @@ import py +from pypy.interpreter.utf8 import Utf8Str from pypy.module._multibytecodec.c_codecs import getcodec, codecs from pypy.module._multibytecodec.c_codecs import decode, encode from pypy.module._multibytecodec.c_codecs import EncodeDecodeError @@ -95,37 +96,38 @@ def test_encode_hz(): c = getcodec(hz) -s = encode(c, u'foobar') +s = encode(c, Utf8Str('foobar')) assert s == 'foobar' and type(s) is str -s = encode(c, u'\u5f95\u6cef') +s = encode(c, Utf8Str.from_unicode(u'\u5f95\u6cef')) assert s == '~{abc}~}'
[pypy-commit] pypy utf8-unicode2: Fix _cffi_backend
Author: Tyler Wade way...@gmail.com Branch: utf8-unicode2 Changeset: r72469:fbbabe9aebd1 Date: 2014-07-17 05:23 -0500 http://bitbucket.org/pypy/pypy/changeset/fbbabe9aebd1/ Log:Fix _cffi_backend diff --git a/pypy/interpreter/test/test_utf8.py b/pypy/interpreter/test/test_utf8.py --- a/pypy/interpreter/test/test_utf8.py +++ b/pypy/interpreter/test/test_utf8.py @@ -195,18 +195,21 @@ assert s.rsplit(' ', 2) == u.rsplit(' ', 2) assert s.rsplit('\n') == [s] -def test_copy_to_wcharp(): +def test_copy_to_new_wcharp(): s = build_utf8str() if sys.maxunicode 0x1 and rffi.sizeof(rffi.WCHAR_T) == 4: # The last character requires a surrogate pair on narrow builds and # so won't be converted correctly by rffi.wcharp2unicode s = s[:-1] -wcharp = s.copy_to_wcharp() +wcharp = s.copy_to_new_wcharp() u = rffi.wcharp2unicode(wcharp) rffi.free_wcharp(wcharp) assert s == u +with s.scoped_wcharp_copy(): +assert s == u + def test_from_wcharp(): def check(u): wcharp = rffi.unicode2wcharp(u) diff --git a/pypy/interpreter/utf8.py b/pypy/interpreter/utf8.py --- a/pypy/interpreter/utf8.py +++ b/pypy/interpreter/utf8.py @@ -422,7 +422,7 @@ byte_pos -= 1 return byte_pos -def copy_to_wcharp(self, track_allocation=True): +def copy_to_new_wcharp(self, track_allocation=True): length = len(self) + 1 if rffi.sizeof(rffi.WCHAR_T) == 2: for c in self.codepoint_iter(): @@ -431,24 +431,34 @@ array = lltype.malloc(WCHAR_INTP.TO, length, flavor='raw', track_allocation=track_allocation) + +self.copy_to_wcharp(array, 0, length) +array[length - 1] = wchar_rint(0) + +array = rffi.cast(rffi.CWCHARP, array) +return array + +def copy_to_wcharp(self, dst, dststart, length): from pypy.interpreter.utf8_codecs import create_surrogate_pair i = 0; for c in self.codepoint_iter(): +if i == length: +break + if rffi.sizeof(rffi.WCHAR_T) == 2: c1, c2 = create_surrogate_pair(c) -array[i] = wchar_rint(c1) +dst[i + dststart] = wchar_rint(c1) if c2: i += 1 -array[i] = wchar_rint(c2) +dst[i + dststart] = wchar_rint(c2) else: -array[i] = wchar_rint(c) +dst[i + dststart] = wchar_rint(c) i += 1 -array[i] = wchar_rint(0) -array = rffi.cast(rffi.CWCHARP, array) -return array +def scoped_wcharp_copy(self): +return WCharContextManager(self) @staticmethod def from_wcharp(wcharp): @@ -600,6 +610,15 @@ def build(self): return Utf8Str(self._builder.build(), self._is_ascii) +class WCharContextManager(object): +def __init__(self, str): +self.str = str +def __enter__(self): +self.data = self.str.copy_to_new_wcharp() +return self.data +def __exit__(self, *args): +rffi.free_wcharp(self.data) + # ___ # iter.current is the current (ie the last returned) element diff --git a/pypy/module/__pypy__/interp_builders.py b/pypy/module/__pypy__/interp_builders.py --- a/pypy/module/__pypy__/interp_builders.py +++ b/pypy/module/__pypy__/interp_builders.py @@ -2,7 +2,8 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.typedef import TypeDef -from rpython.rlib.rstring import UnicodeBuilder, StringBuilder +from pypy.interpreter.utf8 import Utf8Builder +from rpython.rlib.rstring import StringBuilder from rpython.tool.sourcetools import func_with_new_name @@ -62,4 +63,4 @@ return W_Builder W_StringBuilder = create_builder(StringBuilder, str, StringBuilder) -W_UnicodeBuilder = create_builder(UnicodeBuilder, unicode, UnicodeBuilder) +W_UnicodeBuilder = create_builder(UnicodeBuilder, unicode, Utf8Builder) diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -9,7 +9,9 @@ from rpython.rlib import jit from rpython.rtyper.lltypesystem import lltype, rffi +from pypy.interpreter import utf8 from pypy.interpreter.error import oefmt +from pypy.interpreter.utf8 import Utf8Str, utf8ord from pypy.module._cffi_backend import cdataobj, misc from pypy.module._cffi_backend.ctypeobj import W_CType @@ -46,7 +48,7 @@ raise oefmt(space.w_TypeError, cannot cast unicode string of length %d to ctype '%s', len(s), self.name) -return ord(s[0]) +return utf8ord(s) def cast(self, w_ob): from pypy.module._cffi_backend import ctypeptr @@
[pypy-commit] pypy utf8-unicode2: Remove some stray unicode literals
Author: Tyler Wade way...@gmail.com Branch: utf8-unicode2 Changeset: r72472:821f21a34f0a Date: 2014-07-19 07:41 -0500 http://bitbucket.org/pypy/pypy/changeset/821f21a34f0a/ Log:Remove some stray unicode literals diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -1551,7 +1551,7 @@ Like unicode_w, but rejects strings with NUL bytes. from rpython.rlib import rstring result = w_obj.unicode_w(self) -if u'\x00' in result: +if Utf8Str('\x00') in result: raise OperationError(self.w_TypeError, self.wrap( 'argument must be a unicode string without NUL characters')) return rstring.assert_str0(result) diff --git a/pypy/interpreter/utf8_codecs.py b/pypy/interpreter/utf8_codecs.py --- a/pypy/interpreter/utf8_codecs.py +++ b/pypy/interpreter/utf8_codecs.py @@ -727,7 +727,7 @@ else: bo = 1 if size == 0: -return u'', 0, bo +return Utf8Str(''), 0, bo if bo == -1: # force little endian ihi = 1 @@ -911,7 +911,7 @@ else: bo = 1 if size == 0: -return u'', 0, bo +return Utf8Str(''), 0, bo if bo == -1: # force little endian iorder = [0, 1, 2, 3] @@ -1285,7 +1285,7 @@ if errorhandler is None: errorhandler = default_unicode_error_decode if size == 0: -return u'', 0 +return Utf8Str(''), 0 pos = 0 result = Utf8Builder(size) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3k: fix bytes result
Author: Philip Jenvey pjen...@underboss.org Branch: py3k Changeset: r72473:e2fd970b748f Date: 2014-07-18 16:48 -0700 http://bitbucket.org/pypy/pypy/changeset/e2fd970b748f/ Log:fix bytes result diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py --- a/pypy/module/array/interp_array.py +++ b/pypy/module/array/interp_array.py @@ -244,7 +244,7 @@ size = self.len if size == 0: -return space.wrap('') +return space.wrapbytes('') cbuf = self._charbuf_start() s = rffi.charpsize2str(cbuf, size * self.itemsize) self._charbuf_stop() ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3k: issue1556: cache json object keys (cpython issue7451) in _pypyjson and
Author: Philip Jenvey pjen...@underboss.org Branch: py3k Changeset: r72474:ed9ae55d00c8 Date: 2014-07-18 16:48 -0700 http://bitbucket.org/pypy/pypy/changeset/ed9ae55d00c8/ Log:issue1556: cache json object keys (cpython issue7451) in _pypyjson and re-enable it now that it fully passes test_json diff --git a/lib-python/3/json/__init__.py b/lib-python/3/json/__init__.py --- a/lib-python/3/json/__init__.py +++ b/lib-python/3/json/__init__.py @@ -107,6 +107,12 @@ __author__ = 'Bob Ippolito b...@redivi.com' +try: +# PyPy speedup, the interface is different than CPython's _json +import _pypyjson +except ImportError: +_pypyjson = None + from .decoder import JSONDecoder from .encoder import JSONEncoder @@ -316,7 +322,7 @@ if (cls is None and object_hook is None and parse_int is None and parse_float is None and parse_constant is None and object_pairs_hook is None and not kw): -return _default_decoder.decode(s) +return _pypyjson.loads(s) if _pypyjson else _default_decoder.decode(s) if cls is None: cls = JSONDecoder if object_hook is not None: diff --git a/pypy/module/_pypyjson/interp_decoder.py b/pypy/module/_pypyjson/interp_decoder.py --- a/pypy/module/_pypyjson/interp_decoder.py +++ b/pypy/module/_pypyjson/interp_decoder.py @@ -56,6 +56,7 @@ self.end_ptr = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw') self.pos = 0 self.last_type = TYPE_UNKNOWN +self.memo = {} def close(self): rffi.free_charp(self.ll_chars) @@ -261,6 +262,8 @@ w_name = self.decode_any(i) if self.last_type != TYPE_STRING: self._raise(Key name must be string for object starting at char %d, start) +w_name = self.memo.setdefault(self.space.unicode_w(w_name), w_name) + i = self.skip_whitespace(self.pos) ch = self.ll_chars[i] if ch != ':': diff --git a/pypy/module/_pypyjson/test/test__pypyjson.py b/pypy/module/_pypyjson/test/test__pypyjson.py --- a/pypy/module/_pypyjson/test/test__pypyjson.py +++ b/pypy/module/_pypyjson/test/test__pypyjson.py @@ -187,4 +187,12 @@ import _pypyjson # http://json.org/JSON_checker/test/fail25.json s = '[\ttab\tcharacter\tin\tstring\t]' -raises(ValueError, _pypyjson.loads(s)) \ No newline at end of file +raises(ValueError, _pypyjson.loads(s)) + +def test_keys_reuse(self): +import _pypyjson +s = '[{a_key: 1, b_\xe9: 2}, {a_key: 3, b_\xe9: 4}]' +rval = _pypyjson.loads(s) +(a, b), (c, d) = sorted(rval[0]), sorted(rval[1]) +assert a is c +assert b is d ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3k: merge default
Author: Philip Jenvey pjen...@underboss.org Branch: py3k Changeset: r72475:8064c75eb975 Date: 2014-07-19 11:35 -0700 http://bitbucket.org/pypy/pypy/changeset/8064c75eb975/ Log:merge default diff --git a/pypy/interpreter/test/test_generator.py b/pypy/interpreter/test/test_generator.py --- a/pypy/interpreter/test/test_generator.py +++ b/pypy/interpreter/test/test_generator.py @@ -307,13 +307,13 @@ w_co = space.appexec([], '''(): def g(x): yield x + 5 -return g.func_code +return g.__code__ ''') assert should_not_inline(w_co) == False w_co = space.appexec([], '''(): def g(x): yield x + 5 yield x + 6 -return g.func_code +return g.__code__ ''') assert should_not_inline(w_co) == True ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit