Commit 2cce2770 authored by Kirill Smelkov's avatar Kirill Smelkov

Merge branch 'master' into y/bstr+x/gpystr

* master:
  golang: Fix `@func(cls) def name` not to set `name` in calling context
  gpython: tests: Remove grepv utility
  gpython: tests: Fix test of warning filters.
parents 58f86b12 30f06b4a
Pipeline #35471 failed with stage
in 0 seconds
...@@ -86,11 +86,29 @@ def _meth(cls, fcall): ...@@ -86,11 +86,29 @@ def _meth(cls, fcall):
if already is not missing: if already is not missing:
return already return already
# FIXME try to arrange so that python does not set anything on caller's # arrange so that python eventually does not set anything on caller's
# namespace[func_name] (currently it sets that to implicitly returned None) # namespace[func_name] (it unconditionally sets what decorator returns, even implicit None)
#
# _DelAttrAfterMeth.__del__ is invoked:
# * on cpython: right after namespace[func_name] = returned _meth_leftover
# * on pypy: eventually on next GC
fcall.f_locals[func_name] = _DelAttrAfterMeth(fcall.f_locals, func_name)
return _meth_leftover
return deco return deco
# _DelAttrAfterMeth serves _meth by unsetting f_locals[meth] that python
# unconditionally sets after `@func(cls) def meth()`.
_meth_leftover = object()
class _DelAttrAfterMeth(object):
def __init__(self, f_locals, name):
self.f_locals = f_locals
self.name = name
def __del__(self):
obj = self.f_locals.get(self.name)
if obj is _meth_leftover:
del self.f_locals[self.name]
# _func serves @func. # _func serves @func.
def _func(f): def _func(f):
# @staticmethod & friends require special care: # @staticmethod & friends require special care:
......
...@@ -1004,12 +1004,20 @@ def test_func(): ...@@ -1004,12 +1004,20 @@ def test_func():
assert mcls is mcls_orig assert mcls is mcls_orig
assert mcls == 'mcls' assert mcls == 'mcls'
# FIXME undefined var after `@func(cls) def var` should be not set # undefined var after `@func(cls) def var` should be not set
assert 'var' not in locals()
@func(MyClass)
def var(self, v):
assert v == 8
return v + 1
gc.collect() # pypy needs this to trigger _DelAttrAfterMeth GC
assert 'var' not in locals()
obj = MyClass(4) obj = MyClass(4)
assert obj.zzz(4) == 4 + 1 assert obj.zzz(4) == 4 + 1
assert obj.mstatic(5) == 5 + 1 assert obj.mstatic(5) == 5 + 1
assert obj.mcls(7) == 7 + 1 assert obj.mcls(7) == 7 + 1
assert obj.var(8) == 8 + 1
# this tests that @func (used by @func(cls)) preserves decorated function signature # this tests that @func (used by @func(cls)) preserves decorated function signature
assert fmtargspec(MyClass.zzz) == '(self, v, x=2, **kkkkwww)' assert fmtargspec(MyClass.zzz) == '(self, v, x=2, **kkkkwww)'
...@@ -1023,6 +1031,8 @@ def test_func(): ...@@ -1023,6 +1031,8 @@ def test_func():
assert MyClass.mcls.__module__ == __name__ assert MyClass.mcls.__module__ == __name__
assert MyClass.mcls.__name__ == 'mcls' assert MyClass.mcls.__name__ == 'mcls'
assert MyClass.var.__module__ == __name__
assert MyClass.var.__name__ == 'var'
# @func overhead at def time. # @func overhead at def time.
def bench_def(b): def bench_def(b):
......
...@@ -260,26 +260,27 @@ def test_pymain(): ...@@ -260,26 +260,27 @@ def test_pymain():
# -W <opt> # -W <opt>
_ = pyout(['-Werror', '-Whello', '-W', 'ignore::DeprecationWarning', _ = pyout(['-Werror', '-Whello', '-W', 'ignore::DeprecationWarning',
'testprog/print_warnings_setup.py'], cwd=here) 'testprog/print_warnings_setup.py'], cwd=here)
if PY2: assert re.match(
# py2 threading, which is imported after gpython startup, adds ignore br"sys\.warnoptions: \['error', 'hello', 'ignore::DeprecationWarning'\]\n\n"
# for sys.exc_clear br"warnings\.filters:\n"
_ = grepv(r'ignore:sys.exc_clear:DeprecationWarning:threading:*', _) br"(- [^\n]+\n)*" # Additional filters added by automatically imported modules
assert _.startswith( br"- ignore::DeprecationWarning::\*\n"
b"sys.warnoptions: ['error', 'hello', 'ignore::DeprecationWarning']\n\n" + \ br"- error::Warning::\*\n"
b"warnings.filters:\n" + \ br"(- [^\n]+\n)*", # Remaining filters
b"- ignore::DeprecationWarning::*\n" + \ _,
b"- error::Warning::*\n"), _ )
# $PYTHONWARNINGS # $PYTHONWARNINGS
_ = pyout(['testprog/print_warnings_setup.py'], cwd=here, _ = pyout(['testprog/print_warnings_setup.py'], cwd=here,
envadj={'PYTHONWARNINGS': 'ignore,world,error::SyntaxWarning'}) envadj={'PYTHONWARNINGS': 'ignore,world,error::SyntaxWarning'})
if PY2: assert re.match(
# see ^^^ br"sys\.warnoptions: \['ignore', 'world', 'error::SyntaxWarning'\]\n\n"
_ = grepv(r'ignore:sys.exc_clear:DeprecationWarning:threading:*', _) br"warnings\.filters:\n"
assert _.startswith( br"(- [^\n]+\n)*" # Additional filters added by automatically imported modules
b"sys.warnoptions: ['ignore', 'world', 'error::SyntaxWarning']\n\n" + \ br"- error::SyntaxWarning::\*\n"
b"warnings.filters:\n" + \ br"- ignore::Warning::\*\n"
b"- error::SyntaxWarning::*\n" + \ br"(- [^\n]+\n)*", # Remaining filters
b"- ignore::Warning::*\n"), _ _,
)
def test_pymain_print_function_future(): def test_pymain_print_function_future():
...@@ -439,20 +440,6 @@ def _xopt_assert_in_subprocess(xopt, xval, tfunc): ...@@ -439,20 +440,6 @@ def _xopt_assert_in_subprocess(xopt, xval, tfunc):
# ---- misc ---- # ---- misc ----
# grepv filters out lines matching pattern from text.
def grepv(pattern, text): # -> text
if isinstance(text, bytes):
t = b''
else:
t = ''
p = re.compile(pattern)
v = []
for l in text.splitlines(True):
m = p.search(l)
if not m:
v.append(l)
return t.join(v)
# check_gpy_vs_py verifies that gpython output matches underlying python output. # check_gpy_vs_py verifies that gpython output matches underlying python output.
def check_gpy_vs_py(argv, postprocessf=None, **kw): def check_gpy_vs_py(argv, postprocessf=None, **kw):
gpyout = u(pyout(argv, **kw)) gpyout = u(pyout(argv, **kw))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment