[pypy-commit] pypy py3.7: merge py3.6
Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98611:d024eab5de59 Date: 2020-01-31 14:07 +0100 http://bitbucket.org/pypy/pypy/changeset/d024eab5de59/ Log:merge py3.6 diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py --- a/pypy/module/mmap/interp_mmap.py +++ b/pypy/module/mmap/interp_mmap.py @@ -190,8 +190,10 @@ return space.newbytes(self.mmap.getslice(start, length)) else: b = StringBuilder(length) -for i in range(start, stop, step): -b.append(self.mmap.getitem(i)) +index = start +for i in range(length): +b.append(self.mmap.getitem(index)) +index += step return space.newbytes(b.build()) def descr_setitem(self, w_index, w_value): diff --git a/pypy/module/mmap/test/test_mmap.py b/pypy/module/mmap/test/test_mmap.py --- a/pypy/module/mmap/test/test_mmap.py +++ b/pypy/module/mmap/test/test_mmap.py @@ -431,6 +431,15 @@ m.close() f.close() +def test_get_crash(self): +import sys +from mmap import mmap +s = b'hallo!!!' +m = mmap(-1, len(s)) +m[:] = s +assert m[1:None:sys.maxsize] == b'a' +m.close() + def test_set_item(self): import mmap ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.6: merge default
Author: Carl Friedrich Bolz-Tereick Branch: py3.6 Changeset: r98610:f0843db5a3a6 Date: 2020-01-31 14:06 +0100 http://bitbucket.org/pypy/pypy/changeset/f0843db5a3a6/ Log:merge default diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py --- a/pypy/module/mmap/interp_mmap.py +++ b/pypy/module/mmap/interp_mmap.py @@ -190,8 +190,10 @@ return space.newbytes(self.mmap.getslice(start, length)) else: b = StringBuilder(length) -for i in range(start, stop, step): -b.append(self.mmap.getitem(i)) +index = start +for i in range(length): +b.append(self.mmap.getitem(index)) +index += step return space.newbytes(b.build()) def descr_setitem(self, w_index, w_value): diff --git a/pypy/module/mmap/test/test_mmap.py b/pypy/module/mmap/test/test_mmap.py --- a/pypy/module/mmap/test/test_mmap.py +++ b/pypy/module/mmap/test/test_mmap.py @@ -431,6 +431,15 @@ m.close() f.close() +def test_get_crash(self): +import sys +from mmap import mmap +s = b'hallo!!!' +m = mmap(-1, len(s)) +m[:] = s +assert m[1:None:sys.maxsize] == b'a' +m.close() + def test_set_item(self): import mmap ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.6: merge default
Author: Carl Friedrich Bolz-Tereick Branch: py3.6 Changeset: r98605:0115587c02f4 Date: 2020-01-30 14:45 +0100 http://bitbucket.org/pypy/pypy/changeset/0115587c02f4/ Log:merge default diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py --- a/pypy/objspace/std/newformat.py +++ b/pypy/objspace/std/newformat.py @@ -802,7 +802,7 @@ digits = self._upcase_string(digits) out.append(digits) if spec.n_decimal: -out.append(self._lit(".")[0]) +out.append(self._lit(self._loc_dec)[0]) if spec.n_remainder: out.append(num[to_remainder:]) if spec.n_rpadding: diff --git a/pypy/objspace/std/test/test_newformat.py b/pypy/objspace/std/test/test_newformat.py --- a/pypy/objspace/std/test/test_newformat.py +++ b/pypy/objspace/std/test/test_newformat.py @@ -404,6 +404,24 @@ finally: locale.setlocale(locale.LC_NUMERIC, 'C') +def test_locale_german(self): +import locale +for name in ['de_DE', 'de_DE.utf8']: +try: +locale.setlocale(locale.LC_NUMERIC, name) +break +except locale.Error: +pass +else: +skip("no german locale") +x = 1234.567890 +try: +assert locale.format('%g', x, grouping=True) == '1.234,57' +assert format(x, 'n') == '1.234,57' +assert format(12345678901234, 'n') == '12.345.678.901.234' +finally: +locale.setlocale(locale.LC_NUMERIC, 'C') + def test_dont_switch_to_g(self): skip("must fix when float formatting is figured out") assert len(format(1.1234e90, "f")) == 98 ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.7: make get/set_coroutine_wrapper emit a DeprecationWarning
Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98607:66293dfd6fd3 Date: 2020-01-30 15:41 +0100 http://bitbucket.org/pypy/pypy/changeset/66293dfd6fd3/ Log:make get/set_coroutine_wrapper emit a DeprecationWarning diff --git a/pypy/interpreter/test/apptest_coroutine.py b/pypy/interpreter/test/apptest_coroutine.py --- a/pypy/interpreter/test/apptest_coroutine.py +++ b/pypy/interpreter/test/apptest_coroutine.py @@ -123,6 +123,18 @@ sys.set_coroutine_wrapper(None) assert sys.get_coroutine_wrapper() is None +def test_get_set_coroutine_wrapper_deprecated(): +import warnings +def my_wrapper(cr): +return 1 +with warnings.catch_warnings(record=True) as l: +warnings.simplefilter('always', category=DeprecationWarning) +sys.get_coroutine_wrapper() +sys.set_coroutine_wrapper(my_wrapper) +sys.set_coroutine_wrapper(None) +print(l) +assert len(l) == 3 + def test_async_with(): seen = [] class X: diff --git a/pypy/module/sys/vm.py b/pypy/module/sys/vm.py --- a/pypy/module/sys/vm.py +++ b/pypy/module/sys/vm.py @@ -343,12 +343,14 @@ def get_coroutine_wrapper(space): "Return the wrapper for coroutine objects set by sys.set_coroutine_wrapper." +space.warn(space.newtext("get_coroutine_wrapper is deprecated"), space.w_DeprecationWarning) ec = space.getexecutioncontext() if ec.w_coroutine_wrapper_fn is None: return space.w_None return ec.w_coroutine_wrapper_fn def set_coroutine_wrapper(space, w_wrapper): +space.warn(space.newtext("set_coroutine_wrapper is deprecated"), space.w_DeprecationWarning) "Set a wrapper for coroutine objects." ec = space.getexecutioncontext() if space.is_w(w_wrapper, space.w_None): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.7: only async *generator* expressions should work, not other comprehensions!
Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98608:30f0db9aea2b Date: 2020-01-30 16:00 +0100 http://bitbucket.org/pypy/pypy/changeset/30f0db9aea2b/ Log:only async *generator* expressions should work, not other comprehensions! diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py --- a/pypy/interpreter/astcompiler/codegen.py +++ b/pypy/interpreter/astcompiler/codegen.py @@ -1567,7 +1567,11 @@ def _compile_comprehension(self, node, name, sub_scope): is_async_function = self.scope.is_coroutine code, qualname = self.sub_scope(sub_scope, name, node, node.lineno) -is_async_generator = self.symbols.find_scope(node).is_coroutine +is_async_comprehension = self.symbols.find_scope(node).is_coroutine +if is_async_comprehension and not is_async_function: +if not isinstance(node, ast.GeneratorExp): +self.error("asynchronous comprehension outside of " + "an asynchronous function", node) self.update_position(node.lineno) self._make_function(code, qualname=qualname) @@ -1581,7 +1585,7 @@ else: self.emit_op(ops.GET_ITER) self.emit_op_arg(ops.CALL_FUNCTION, 1) -if is_async_generator and sub_scope is not GenExpCodeGenerator: +if is_async_comprehension and sub_scope is not GenExpCodeGenerator: self.emit_op(ops.GET_AWAITABLE) self.load_const(self.space.w_None) self.emit_op(ops.YIELD_FROM) diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py --- a/pypy/interpreter/astcompiler/test/test_compiler.py +++ b/pypy/interpreter/astcompiler/test/test_compiler.py @@ -1231,6 +1231,33 @@ """ e = py.test.raises(SyntaxError, self.simple_test, source, "None", None) +def test_async_in_nested(self): +source = """if 1: +async def foo(): +def bar(): +[i async for i in items] +""" +e = py.test.raises(SyntaxError, self.simple_test, source, "None", None) +source = """if 1: +async def foo(): +def bar(): +{i async for i in items} +""" +e = py.test.raises(SyntaxError, self.simple_test, source, "None", None) +source = """if 1: +async def foo(): +def bar(): +{i: i+1 async for i in items} +""" +e = py.test.raises(SyntaxError, self.simple_test, source, "None", None) +source = """if 1: +async def foo(): +def bar(): +(i async for i in items) +""" +# ok! +self.simple_test(source, "None", None) + def test_load_classderef(self): source = """if 1: def f(): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.7: merge py3.6
Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98606:c5c4cd76ef44 Date: 2020-01-30 14:45 +0100 http://bitbucket.org/pypy/pypy/changeset/c5c4cd76ef44/ Log:merge py3.6 diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py --- a/pypy/objspace/std/newformat.py +++ b/pypy/objspace/std/newformat.py @@ -802,7 +802,7 @@ digits = self._upcase_string(digits) out.append(digits) if spec.n_decimal: -out.append(self._lit(".")[0]) +out.append(self._lit(self._loc_dec)[0]) if spec.n_remainder: out.append(num[to_remainder:]) if spec.n_rpadding: diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py --- a/pypy/objspace/std/setobject.py +++ b/pypy/objspace/std/setobject.py @@ -247,10 +247,16 @@ return space.w_NotImplemented return self.difference(w_other) +def descr_rsub(self, space, w_other): +if not isinstance(w_other, W_BaseSetObject): +return space.w_NotImplemented +return w_other.difference(self) + def descr_and(self, space, w_other): if not isinstance(w_other, W_BaseSetObject): return space.w_NotImplemented return self.intersect(w_other) +descr_rand = descr_and # symmetric def descr_or(self, space, w_other): if not isinstance(w_other, W_BaseSetObject): @@ -258,11 +264,13 @@ w_copy = self.copy_real() w_copy.update(w_other) return w_copy +descr_ror = descr_or # symmetric def descr_xor(self, space, w_other): if not isinstance(w_other, W_BaseSetObject): return space.w_NotImplemented return self.symmetric_difference(w_other) +descr_rxor = descr_xor # symmetric def descr_inplace_sub(self, space, w_other): if not isinstance(w_other, W_BaseSetObject): @@ -528,9 +536,13 @@ __iter__ = gateway.interp2app(W_BaseSetObject.descr_iter), __contains__ = gateway.interp2app(W_BaseSetObject.descr_contains), __sub__ = gateway.interp2app(W_BaseSetObject.descr_sub), +__rsub__ = gateway.interp2app(W_BaseSetObject.descr_rsub), __and__ = gateway.interp2app(W_BaseSetObject.descr_and), +__rand__ = gateway.interp2app(W_BaseSetObject.descr_rand), __or__ = gateway.interp2app(W_BaseSetObject.descr_or), +__ror__ = gateway.interp2app(W_BaseSetObject.descr_ror), __xor__ = gateway.interp2app(W_BaseSetObject.descr_xor), +__rxor__ = gateway.interp2app(W_BaseSetObject.descr_rxor), # mutating operators __isub__ = gateway.interp2app(W_BaseSetObject.descr_inplace_sub), @@ -644,9 +656,13 @@ __iter__ = gateway.interp2app(W_BaseSetObject.descr_iter), __contains__ = gateway.interp2app(W_BaseSetObject.descr_contains), __sub__ = gateway.interp2app(W_BaseSetObject.descr_sub), +__rsub__ = gateway.interp2app(W_BaseSetObject.descr_rsub), __and__ = gateway.interp2app(W_BaseSetObject.descr_and), +__rand__ = gateway.interp2app(W_BaseSetObject.descr_rand), __or__ = gateway.interp2app(W_BaseSetObject.descr_or), +__ror__ = gateway.interp2app(W_BaseSetObject.descr_ror), __xor__ = gateway.interp2app(W_BaseSetObject.descr_xor), +__rxor__ = gateway.interp2app(W_BaseSetObject.descr_rxor), # non-mutating methods __reduce__ = gateway.interp2app(W_BaseSetObject.descr_reduce), diff --git a/pypy/objspace/std/test/test_newformat.py b/pypy/objspace/std/test/test_newformat.py --- a/pypy/objspace/std/test/test_newformat.py +++ b/pypy/objspace/std/test/test_newformat.py @@ -404,6 +404,24 @@ finally: locale.setlocale(locale.LC_NUMERIC, 'C') +def test_locale_german(self): +import locale +for name in ['de_DE', 'de_DE.utf8']: +try: +locale.setlocale(locale.LC_NUMERIC, name) +break +except locale.Error: +pass +else: +skip("no german locale") +x = 1234.567890 +try: +assert locale.format('%g', x, grouping=True) == '1.234,57' +assert format(x, 'n') == '1.234,57' +assert format(12345678901234, 'n') == '12.345.678.901.234' +finally: +locale.setlocale(locale.LC_NUMERIC, 'C') + def test_dont_switch_to_g(self): skip("must fix when float formatting is figured out") assert len(format(1.1234e90, "f")) == 98 diff --git a/pypy/objspace/std/test/test_setobject.py b/pypy/objspace/std/test/test_setobject.py --- a/pypy/objspace/std/test/test_setobject.py +++ b/pypy/objspace/std/test/test_setobject.py @@ -650,6 +650,40 @@ assert type(t) is base assert not hasattr(t, 'x') +def test_reverse_ops(self): +assert set.__rxor__ +assert frozenset.__rxor__ +assert set.__ror__ +assert frozenset.__ror__ +assert set.__rand__ +
[pypy-commit] pypy default: merge heads
Author: Carl Friedrich Bolz-Tereick Branch: Changeset: r98612:39bcfae01bee Date: 2020-01-31 14:10 +0100 http://bitbucket.org/pypy/pypy/changeset/39bcfae01bee/ Log:merge heads diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py --- a/pypy/module/mmap/interp_mmap.py +++ b/pypy/module/mmap/interp_mmap.py @@ -177,8 +177,10 @@ return space.newbytes(self.mmap.getslice(start, length)) else: b = StringBuilder(length) -for i in range(start, stop, step): -b.append(self.mmap.getitem(i)) +index = start +for i in range(length): +b.append(self.mmap.getitem(index)) +index += step return space.newbytes(b.build()) def descr_setitem(self, w_index, w_value): diff --git a/pypy/module/mmap/test/test_mmap.py b/pypy/module/mmap/test/test_mmap.py --- a/pypy/module/mmap/test/test_mmap.py +++ b/pypy/module/mmap/test/test_mmap.py @@ -433,6 +433,15 @@ m.close() f.close() +def test_get_crash(self): +import sys +from mmap import mmap +s = b'hallo!!!' +m = mmap(-1, len(s)) +m[:] = s +assert m[1:None:sys.maxsize] == b'a' +m.close() + def test_set_item(self): import mmap diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py --- a/pypy/objspace/std/newformat.py +++ b/pypy/objspace/std/newformat.py @@ -772,7 +772,7 @@ digits = self._upcase_string(digits) out.append(digits) if spec.n_decimal: -out.append(self._lit(".")[0]) +out.append(self._lit(self._loc_dec)[0]) if spec.n_remainder: out.append(num[to_remainder:]) if spec.n_rpadding: diff --git a/pypy/objspace/std/test/test_newformat.py b/pypy/objspace/std/test/test_newformat.py --- a/pypy/objspace/std/test/test_newformat.py +++ b/pypy/objspace/std/test/test_newformat.py @@ -389,6 +389,24 @@ finally: locale.setlocale(locale.LC_NUMERIC, 'C') +def test_locale_german(self): +import locale +for name in ['de_DE', 'de_DE.utf8']: +try: +locale.setlocale(locale.LC_NUMERIC, name) +break +except locale.Error: +pass +else: +skip("no german locale") +x = 1234.567890 +try: +assert locale.format('%g', x, grouping=True) == '1.234,57' +assert format(x, 'n') == '1.234,57' +assert format(12345678901234, 'n') == '12.345.678.901.234' +finally: +locale.setlocale(locale.LC_NUMERIC, 'C') + def test_dont_switch_to_g(self): skip("must fix when float formatting is figured out") assert len(format(1.1234e90, "f")) == 98 ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: argh, fix bug in locale-specific string formatting: the thousands separator was always '.' :-(
Author: Carl Friedrich Bolz-Tereick Branch: Changeset: r98604:b6af70ef2dfb Date: 2020-01-30 14:44 +0100 http://bitbucket.org/pypy/pypy/changeset/b6af70ef2dfb/ Log:argh, fix bug in locale-specific string formatting: the thousands separator was always '.' :-( diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py --- a/pypy/objspace/std/newformat.py +++ b/pypy/objspace/std/newformat.py @@ -772,7 +772,7 @@ digits = self._upcase_string(digits) out.append(digits) if spec.n_decimal: -out.append(self._lit(".")[0]) +out.append(self._lit(self._loc_dec)[0]) if spec.n_remainder: out.append(num[to_remainder:]) if spec.n_rpadding: diff --git a/pypy/objspace/std/test/test_newformat.py b/pypy/objspace/std/test/test_newformat.py --- a/pypy/objspace/std/test/test_newformat.py +++ b/pypy/objspace/std/test/test_newformat.py @@ -389,6 +389,24 @@ finally: locale.setlocale(locale.LC_NUMERIC, 'C') +def test_locale_german(self): +import locale +for name in ['de_DE', 'de_DE.utf8']: +try: +locale.setlocale(locale.LC_NUMERIC, name) +break +except locale.Error: +pass +else: +skip("no german locale") +x = 1234.567890 +try: +assert locale.format('%g', x, grouping=True) == '1.234,57' +assert format(x, 'n') == '1.234,57' +assert format(12345678901234, 'n') == '12.345.678.901.234' +finally: +locale.setlocale(locale.LC_NUMERIC, 'C') + def test_dont_switch_to_g(self): skip("must fix when float formatting is figured out") assert len(format(1.1234e90, "f")) == 98 ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: issue #3065 strikes again! fix segfault in mmap
Author: Carl Friedrich Bolz-Tereick Branch: Changeset: r98609:d22a7659ed80 Date: 2020-01-31 14:04 +0100 http://bitbucket.org/pypy/pypy/changeset/d22a7659ed80/ Log:issue #3065 strikes again! fix segfault in mmap diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py --- a/pypy/module/mmap/interp_mmap.py +++ b/pypy/module/mmap/interp_mmap.py @@ -177,8 +177,10 @@ return space.newbytes(self.mmap.getslice(start, length)) else: b = StringBuilder(length) -for i in range(start, stop, step): -b.append(self.mmap.getitem(i)) +index = start +for i in range(length): +b.append(self.mmap.getitem(index)) +index += step return space.newbytes(b.build()) def descr_setitem(self, w_index, w_value): diff --git a/pypy/module/mmap/test/test_mmap.py b/pypy/module/mmap/test/test_mmap.py --- a/pypy/module/mmap/test/test_mmap.py +++ b/pypy/module/mmap/test/test_mmap.py @@ -433,6 +433,15 @@ m.close() f.close() +def test_get_crash(self): +import sys +from mmap import mmap +s = b'hallo!!!' +m = mmap(-1, len(s)) +m[:] = s +assert m[1:None:sys.maxsize] == b'a' +m.close() + def test_set_item(self): import mmap ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.7: kill dead attributes
Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98614:784f171f4094 Date: 2020-01-31 15:38 +0100 http://bitbucket.org/pypy/pypy/changeset/784f171f4094/ Log:kill dead attributes diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py --- a/pypy/interpreter/generator.py +++ b/pypy/interpreter/generator.py @@ -301,7 +301,6 @@ class GeneratorIterator(GeneratorOrCoroutine): "An iterator created by a generator." KIND = "generator" -KIND_U = u"generator" def descr__iter__(self): """Implement iter(self).""" @@ -348,7 +347,6 @@ class Coroutine(GeneratorOrCoroutine): "A coroutine object." KIND = "coroutine" -KIND_U = u"coroutine" def descr__await__(self, space): return CoroutineWrapper(self) @@ -502,7 +500,6 @@ class AsyncGenerator(GeneratorOrCoroutine): "An async generator (i.e. a coroutine with a 'yield')" KIND = "async generator" -KIND_U = u"async_generator" def __init__(self, frame, name=None, qualname=None): self.hooks_inited = False ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.7: generator_stop is not the default
Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98613:cac6a157cae7 Date: 2020-01-31 15:37 +0100 http://bitbucket.org/pypy/pypy/changeset/cac6a157cae7/ Log:generator_stop is not the default diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py --- a/pypy/interpreter/generator.py +++ b/pypy/interpreter/generator.py @@ -163,23 +163,14 @@ self.frame.w_yielding_from = w_delegate def _leak_stopiteration(self, e): -# Check for __future__ generator_stop and conditionally turn -# a leaking StopIteration into RuntimeError (with its cause -# set appropriately). +# turn a leaking StopIteration into RuntimeError (with its cause set +# appropriately). space = self.space -if self.pycode.co_flags & (consts.CO_FUTURE_GENERATOR_STOP | - consts.CO_COROUTINE | - consts.CO_ITERABLE_COROUTINE | - consts.CO_ASYNC_GENERATOR): -e2 = OperationError(space.w_RuntimeError, -space.newtext("%s raised StopIteration" % - self.KIND)) -e2.chain_exceptions_from_cause(space, e) -raise e2 -else: -space.warn(space.newtext("generator '%s' raised StopIteration" -% self.get_qualname()), - space.w_DeprecationWarning) +e2 = OperationError(space.w_RuntimeError, +space.newtext("%s raised StopIteration" % + self.KIND)) +e2.chain_exceptions_from_cause(space, e) +raise e2 def _leak_stopasynciteration(self, e): space = self.space diff --git a/pypy/interpreter/test/apptest_generator.py b/pypy/interpreter/test/apptest_generator.py --- a/pypy/interpreter/test/apptest_generator.py +++ b/pypy/interpreter/test/apptest_generator.py @@ -221,16 +221,6 @@ g = f() assert g.close() is None -def test_close2(): -def f(): -try: -yield 1 -except GeneratorExit: -raise StopIteration -g = f() -next(g) -assert g.close() is None - def test_close3(): def f(): try: @@ -275,21 +265,6 @@ with raises(TypeError): g.send(1) # not started, must send None -def test_generator_explicit_stopiteration(): -def f(): -yield 1 -raise StopIteration -g = f() -assert [x for x in g] == [1] - -def test_generator_propagate_stopiteration(): -def f(): -it = iter([1]) -while 1: -yield next(it) -g = f() -assert [x for x in g] == [1] - def test_generator_restart(): def g(): i = next(me) @@ -325,12 +300,6 @@ assert set(g) == set() assert set(i for i in range(0)) == set() -def test_explicit_stop_iteration_unpackiterable(): -def f(): -yield 1 -raise StopIteration -assert tuple(f()) == (1,) - def test_exception_is_cleared_by_yield(): def f(): try: @@ -826,34 +795,18 @@ assert isinstance(excinfo.value.__context__, ValueError) -def test_past_generator_stop(): -# how it works without 'from __future__' import generator_stop -def f(x): -raise StopIteration +def test_stopiteration_turned_into_runtime_error(): +def badgenerator(x): +if x == 5: +raise StopIteration yield x -with raises(StopIteration): -next(f(5)) - -def test_future_generator_stop(): -d = {} -exec("""from __future__ import generator_stop - -def f(x): -raise StopIteration -yield x -""", d) -f = d['f'] with raises(RuntimeError): -next(f(5)) +next(badgenerator(5)) def test_generator_stop_cause(): -d = {} -exec("""from __future__ import generator_stop - -def gen1(): -yield 42 -""", d) -my_gen = d['gen1']() +def gen1(): +yield 42 +my_gen = gen1() assert next(my_gen) == 42 stop_exc = StopIteration('spam') with raises(RuntimeError) as e: ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.7: implement coroutine origin tracking
Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98615:5c1dc1c61dcc Date: 2020-01-31 20:28 +0100 http://bitbucket.org/pypy/pypy/changeset/5c1dc1c61dcc/ Log:implement coroutine origin tracking diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -45,6 +45,7 @@ self.w_asyncgen_firstiter_fn = None self.w_asyncgen_finalizer_fn = None self.contextvar_context = None +self.coroutine_origin_tracking_depth = 0 @staticmethod def _mark_thread_disappeared(space): diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py --- a/pypy/interpreter/generator.py +++ b/pypy/interpreter/generator.py @@ -348,17 +348,42 @@ "A coroutine object." KIND = "coroutine" +def __init__(self, frame, name=None, qualname=None): +GeneratorOrCoroutine.__init__(self, frame, name, qualname) +self.w_cr_origin = self.space.w_None + +def capture_origin(self, ec): +if not ec.coroutine_origin_tracking_depth: +return +self._capture_origin(ec) + +def _capture_origin(self, ec): +space = self.space +frames_w = [] +frame = ec.gettopframe_nohidden() +for i in range(ec.coroutine_origin_tracking_depth): +frames_w.append( +space.newtuple([ +frame.pycode.w_filename, +frame.fget_f_lineno(space), +space.newtext(frame.pycode.co_name)])) +frame = ec.getnextframe_nohidden(frame) +if frame is None: +break +self.w_cr_origin = space.newtuple(frames_w) + def descr__await__(self, space): return CoroutineWrapper(self) def _finalize_(self): # If coroutine was never awaited on issue a RuntimeWarning. -if self.pycode is not None and \ - self.frame is not None and \ - self.frame.last_instr == -1: +if (self.pycode is not None and +self.frame is not None and +self.frame.last_instr == -1): space = self.space -msg = "coroutine '%s' was never awaited" % self.get_qualname() -space.warn(space.newtext(msg), space.w_RuntimeWarning) +w_mod = space.getbuiltinmodule("_warnings") +w_f = space.getattr(w_mod, space.newtext("_warn_unawaited_coroutine")) +space.call_function(w_f, self) GeneratorOrCoroutine._finalize_(self) diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py --- a/pypy/interpreter/pyframe.py +++ b/pypy/interpreter/pyframe.py @@ -266,6 +266,7 @@ gen = Coroutine(self, name, qualname) ec = space.getexecutioncontext() w_wrapper = ec.w_coroutine_wrapper_fn +gen.capture_origin(ec) elif flags & pycode.CO_ASYNC_GENERATOR: from pypy.interpreter.generator import AsyncGenerator gen = AsyncGenerator(self, name, qualname) diff --git a/pypy/interpreter/test/apptest_coroutine.py b/pypy/interpreter/test/apptest_coroutine.py --- a/pypy/interpreter/test/apptest_coroutine.py +++ b/pypy/interpreter/test/apptest_coroutine.py @@ -840,3 +840,65 @@ assert finalized == 2 finally: sys.set_asyncgen_hooks(*old_hooks) + +def test_coroutine_capture_origin(): +import contextlib + +def here(): +f = sys._getframe().f_back +return (f.f_code.co_filename, f.f_lineno) + +try: +async def corofn(): +pass + +with contextlib.closing(corofn()) as coro: +assert coro.cr_origin is None + +sys.set_coroutine_origin_tracking_depth(1) + +fname, lineno = here() +with contextlib.closing(corofn()) as coro: +print(coro.cr_origin) +assert coro.cr_origin == ( +(fname, lineno + 1, "test_coroutine_capture_origin"),) + + +sys.set_coroutine_origin_tracking_depth(2) + +def nested(): +return (here(), corofn()) +fname, lineno = here() +((nested_fname, nested_lineno), coro) = nested() +with contextlib.closing(coro): +print(coro.cr_origin) +assert coro.cr_origin == ( +(nested_fname, nested_lineno, "nested"), +(fname, lineno + 1, "test_coroutine_capture_origin")) + +# Check we handle running out of frames correctly +sys.set_coroutine_origin_tracking_depth(1000) +with contextlib.closing(corofn()) as coro: +print(coro.cr_origin) +assert 1 <= len(coro.cr_origin) < 1000 +finally: +sys.set_coroutine_origin_tracking_depth(0) + +def test_runtime_warning_origin_tracking(): +import gc, warnings # XXX: importing warnings is expensive untranslated +async def foobaz(): +pass +gc.collect()
[pypy-commit] pypy py3.7: slight variant in error msg
Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98620:8d3b5e787554 Date: 2020-01-31 22:33 +0100 http://bitbucket.org/pypy/pypy/changeset/8d3b5e787554/ Log:slight variant in error msg diff --git a/lib-python/3/test/test_dataclasses.py b/lib-python/3/test/test_dataclasses.py --- a/lib-python/3/test/test_dataclasses.py +++ b/lib-python/3/test/test_dataclasses.py @@ -3015,7 +3015,7 @@ lambda x:x, ]: with self.subTest(bad_field=bad_field): -with self.assertRaisesRegex(TypeError, r'has no len\(\)'): +with self.assertRaisesRegex(TypeError, r'has no len.*'): make_dataclass('C', ['a', bad_field]) def test_duplicate_field_names(self): ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.7: skip cpython only test
Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98616:98cbf9a6e204 Date: 2020-01-31 21:22 +0100 http://bitbucket.org/pypy/pypy/changeset/98cbf9a6e204/ Log:skip cpython only test diff --git a/lib-python/3/test/test_coroutines.py b/lib-python/3/test/test_coroutines.py --- a/lib-python/3/test/test_coroutines.py +++ b/lib-python/3/test/test_coroutines.py @@ -2276,6 +2276,7 @@ finally: sys.set_coroutine_origin_tracking_depth(orig_depth) +@support.cpython_only # pypy has this function in _warnings def test_unawaited_warning_when_module_broken(self): # Make sure we don't blow up too bad if # warnings._warn_unawaited_coroutine is broken somehow (e.g. because ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.7: fix error msg
Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98619:4e018a19da74 Date: 2020-01-31 22:31 +0100 http://bitbucket.org/pypy/pypy/changeset/4e018a19da74/ Log:fix error msg diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py --- a/pypy/objspace/descroperation.py +++ b/pypy/objspace/descroperation.py @@ -598,6 +598,8 @@ left, right = specialnames op = getattr(operator, left) def comparison_impl(space, w_obj1, w_obj2): +w_orig_obj1 = w_obj1 +w_orig_obj2 = w_obj2 w_typ1 = space.type(w_obj1) w_typ2 = space.type(w_obj2) w_left_src, w_left_impl = space.lookup_in_type_where(w_typ1, left) @@ -637,7 +639,7 @@ # if we arrived here, they are unorderable raise oefmt(space.w_TypeError, "'%s' not supported between instances of '%T' and '%T'", -symbol, w_obj1, w_obj2) +symbol, w_orig_obj1, w_orig_obj2) return func_with_new_name(comparison_impl, 'comparison_%s_impl'%left.strip('_')) diff --git a/pypy/objspace/test/test_descroperation.py b/pypy/objspace/test/test_descroperation.py --- a/pypy/objspace/test/test_descroperation.py +++ b/pypy/objspace/test/test_descroperation.py @@ -343,6 +343,19 @@ raises(TypeError, "0.0 < zz()") raises(TypeError, "0j < zz()") +def test_correct_order_error_msg(self): +class A(object): +def __lt__(self, other): +return NotImplemented +__gt__ = __lt__ + +class B(A): +pass + +with raises(TypeError) as e: +A() < B() +assert str(e.value) == "'<' not supported between instances of 'A' and 'B'" + def test_equality_among_different_types(self): class A(object): pass class zz(object): pass ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.7: implement opcode tracing, make it possible to turn off line tracing
Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98617:e446a354c3d0 Date: 2020-01-31 22:04 +0100 http://bitbucket.org/pypy/pypy/changeset/e446a354c3d0/ Log:implement opcode tracing, make it possible to turn off line tracing diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -183,7 +183,8 @@ if d.instr_lb <= frame.last_instr < d.instr_ub: if frame.last_instr < d.instr_prev_plus_one: # We jumped backwards in the same line. -self._trace(frame, 'line', self.space.w_None) +if d.f_trace_lines: +self._trace(frame, 'line', self.space.w_None) else: size = len(code.co_lnotab) / 2 addr = 0 @@ -219,7 +220,10 @@ if d.instr_lb == frame.last_instr: # At start of line! d.f_lineno = line -self._trace(frame, 'line', self.space.w_None) +if d.f_trace_lines: +self._trace(frame, 'line', self.space.w_None) +if d.f_trace_opcodes: +self._trace(frame, 'opcode', self.space.w_None) d.instr_prev_plus_one = frame.last_instr + 1 diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py --- a/pypy/interpreter/pyframe.py +++ b/pypy/interpreter/pyframe.py @@ -36,6 +36,8 @@ f_lineno = 0 # current lineno for tracing is_being_profiled= False is_in_line_tracing = False +f_trace_lines= True +f_trace_opcodes = False w_locals = None hidden_operationerr = None @@ -148,6 +150,18 @@ return None return d.w_locals +def get_f_trace_lines(self): +d = self.getdebug() +if d is None: +return True +return d.f_trace_lines + +def get_f_trace_opcodes(self): +d = self.getdebug() +if d is None: +return False +return d.f_trace_opcodes + @not_rpython def __repr__(self): # useful in tracebacks @@ -898,10 +912,17 @@ def fdel_f_trace(self, space): self.getorcreatedebug().w_f_trace = None -def fget_f_restricted(self, space): -if space.config.objspace.honor__builtins__: -return space.newbool(self.builtin is not space.builtin) -return space.w_False +def fget_f_trace_lines(self, space): +return space.newbool(self.get_f_trace_lines()) + +def fset_f_trace_lines(self, space, w_trace): +self.getorcreatedebug().f_trace_lines = space.is_true(w_trace) + +def fget_f_trace_opcodes(self, space): +return space.newbool(self.get_f_trace_opcodes()) + +def fset_f_trace_opcodes(self, space, w_trace): +self.getorcreatedebug().f_trace_opcodes = space.is_true(w_trace) def get_generator(self): if self.space.config.translation.rweakref: diff --git a/pypy/interpreter/test/apptest_pyframe.py b/pypy/interpreter/test/apptest_pyframe.py --- a/pypy/interpreter/test/apptest_pyframe.py +++ b/pypy/interpreter/test/apptest_pyframe.py @@ -584,6 +584,63 @@ sys.settrace(None) assert res == 10 +def test_disable_line_tracing(): +import sys +assert sys._getframe().f_trace_lines + +l = [] +def trace(frame, event, arg): +l.append((frame.f_code.co_name, event, arg, frame.f_lineno - frame.f_code.co_firstlineno)) +frame.f_trace_lines = False +return trace +def g(n): +return n + 2 +def f(n): +n = g(n) +return n * 7 +sys.settrace(trace) +x = f(4) +sys.settrace(None) +print(l) +assert l == [('f', 'call', None, 0), ('g', 'call', None, 0), ('g', 'return', 6, 1), ('f', 'return', 42, 2)] + +test_disable_line_tracing() + +def test_opcode_tracing(): +import sys +assert not sys._getframe().f_trace_opcodes + +l = [] +def trace(frame, event, arg): +l.append((frame.f_code.co_name, event, arg, frame.f_lasti, frame.f_lineno - frame.f_code.co_firstlineno)) +frame.f_trace_opcodes = True +return trace +def g(n): +return n + 2 +def f(n): +return g(n) +sys.settrace(trace) +x = f(4) +sys.settrace(None) +print(l) +assert l == [ +('f', 'call', None, -1, 0), +('f', 'line', None, 0, 1), +('f', 'opcode', None, 0, 1), +('f', 'opcode', None, 2, 1), +('f', 'opcode', None, 4, 1), +('g', 'call', None, -1, 0), +('g', 'line', None, 0, 1), +('g', 'opcode', None, 0, 1), +('g', 'opcode', None, 2, 1), +('g', 'opcode', None, 4, 1), +('g', 'opcode', None, 6, 1), +('g', 'return', 6, 6, 1), +('f', 'opcode', None, 6, 1), +('f', 'return', 6, 6, 1)] + +test_opcode_tracing() + def test_preserve_exc_state_in_generators():
[pypy-commit] pypy py3.7: we happily pass these...
Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98618:bf0519b39ac6 Date: 2020-01-31 22:11 +0100 http://bitbucket.org/pypy/pypy/changeset/bf0519b39ac6/ Log:we happily pass these... diff --git a/lib-python/3/test/test_sys_settrace.py b/lib-python/3/test/test_sys_settrace.py --- a/lib-python/3/test/test_sys_settrace.py +++ b/lib-python/3/test/test_sys_settrace.py @@ -473,7 +473,6 @@ return Tracer(trace_line_events=False) -@support.cpython_only class TraceOpcodesTestCase(TraceTestCase): """Repeat the trace tests, but with per-opcodes events enabled""" ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.7: skip an implementation detail
Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98621:cd4e6f012629 Date: 2020-01-31 22:52 +0100 http://bitbucket.org/pypy/pypy/changeset/cd4e6f012629/ Log:skip an implementation detail diff --git a/lib-python/3/test/test_types.py b/lib-python/3/test/test_types.py --- a/lib-python/3/test/test_types.py +++ b/lib-python/3/test/test_types.py @@ -590,6 +590,7 @@ self.assertIsInstance(object().__lt__, types.MethodWrapperType) self.assertIsInstance((42).__lt__, types.MethodWrapperType) +@impl_detail def test_method_descriptor_types(self): self.assertIsInstance(str.join, types.MethodDescriptorType) self.assertIsInstance(list.append, types.MethodDescriptorType) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.7: gah! turning StopIteration to RuntimeError in generators broke the applevel
Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98622:7a0cdcf24b94 Date: 2020-01-31 23:01 +0100 http://bitbucket.org/pypy/pypy/changeset/7a0cdcf24b94/ Log:gah! turning StopIteration to RuntimeError in generators broke the applevel implementation of iter with sentinel! diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py --- a/pypy/interpreter/generator.py +++ b/pypy/interpreter/generator.py @@ -163,6 +163,7 @@ self.frame.w_yielding_from = w_delegate def _leak_stopiteration(self, e): +import pdb; pdb.set_trace() # turn a leaking StopIteration into RuntimeError (with its cause set # appropriately). space = self.space diff --git a/pypy/interpreter/test/apptest_generator.py b/pypy/interpreter/test/apptest_generator.py --- a/pypy/interpreter/test/apptest_generator.py +++ b/pypy/interpreter/test/apptest_generator.py @@ -803,6 +803,21 @@ with raises(RuntimeError): next(badgenerator(5)) +def test_stopiteration_can_be_caught(): +def g(): +raise StopIteration +def finegenerator(x): +yield x +if x == 5: +try: +g() +except StopIteration: +pass +yield x +gen = finegenerator(5) +next(gen) # fine +next(gen) # fine + def test_generator_stop_cause(): def gen1(): yield 42 diff --git a/pypy/module/__builtin__/operation.py b/pypy/module/__builtin__/operation.py --- a/pypy/module/__builtin__/operation.py +++ b/pypy/module/__builtin__/operation.py @@ -126,7 +126,10 @@ def iter_generator(callable_, sentinel): while 1: -result = callable_() +try: +result = callable_() +except StopIteration: +return if result == sentinel: return yield result diff --git a/pypy/module/__builtin__/test/test_builtin.py b/pypy/module/__builtin__/test/test_builtin.py --- a/pypy/module/__builtin__/test/test_builtin.py +++ b/pypy/module/__builtin__/test/test_builtin.py @@ -286,17 +286,20 @@ self.value = 0 def __call__(self): self.value += 1 +if self.value > 10: +raise StopIteration return self.value -# XXX Raising errors is quite slow -- -#uncomment these lines when fixed -#self.assertRaises(TypeError,iter,3,5) -#self.assertRaises(TypeError,iter,[],5) -#self.assertRaises(TypeError,iter,{},5) +with raises(TypeError): +iter(3, 5) + x = iter(count(),3) assert next(x) ==1 assert next(x) ==2 raises(StopIteration, next, x) +# a case that runs till the end +assert list(iter(count(), 100)) == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + def test_enumerate(self): import sys seq = range(2,4) ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3.7: make putenv complain about bad names (test already existed)
Author: Carl Friedrich Bolz-Tereick Branch: py3.7 Changeset: r98624:89255ed57e9f Date: 2020-01-31 23:29 +0100 http://bitbucket.org/pypy/pypy/changeset/89255ed57e9f/ Log:make putenv complain about bad names (test already existed) diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -935,9 +935,21 @@ def putenv(space, w_name, w_value): """Change or add an environment variable.""" try: -dispatch_filename_2(rposix.putenv)(space, w_name, w_value) +dispatch_filename_2(putenv_impl)(space, w_name, w_value) except OSError as e: raise wrap_oserror(space, e, eintr_retry=False) +except ValueError: +raise oefmt(space.w_ValueError, +"illegal environment variable name") + +@specialize.argtype(0, 1) +def putenv_impl(name, value): +from rpython.rlib.rposix import _as_bytes +name = _as_bytes(name) +value = _as_bytes(value) +if "=" in name: +raise ValueError +return rposix.putenv(name, value) def unsetenv(space, w_name): """Delete an environment variable.""" ___ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit