Commit a0016938 authored by Kirill Smelkov's avatar Kirill Smelkov

gpython: Implement -W

We'll need warnings control in the next patch to fix Pytest integration
wrt python3-dbg with `-W ignore::DeprecationWarning`.
parent b47edf42
...@@ -50,6 +50,7 @@ def pymain(argv): ...@@ -50,6 +50,7 @@ def pymain(argv):
from six.moves import input as raw_input from six.moves import input as raw_input
run = None # function to run according to -c/-m/file/interactive run = None # function to run according to -c/-m/file/interactive
warnoptions = [] # collected `-W arg`
while len(argv) > 0: while len(argv) > 0:
# -V / --version # -V / --version
...@@ -117,6 +118,15 @@ def pymain(argv): ...@@ -117,6 +118,15 @@ def pymain(argv):
run_name='__main__', alter_sys=True) run_name='__main__', alter_sys=True)
break break
# -W arg (warning control)
elif argv[0].startswith('-W'):
wopt = argv[0][2:] # -W<arg> also works
argv = argv[1:]
if wopt == '':
wopt = argv[0]
argv = argv[1:]
warnoptions.append(wopt)
elif argv[0].startswith('-'): elif argv[0].startswith('-'):
print("unknown option: '%s'" % argv[0], file=sys.stderr) print("unknown option: '%s'" % argv[0], file=sys.stderr)
sys.exit(2) sys.exit(2)
...@@ -125,6 +135,7 @@ def pymain(argv): ...@@ -125,6 +135,7 @@ def pymain(argv):
else: else:
sys.argv = argv sys.argv = argv
filepath = argv[0] filepath = argv[0]
sys.path.insert(0, dirname(filepath)) sys.path.insert(0, dirname(filepath))
def run(): def run():
# exec with same globals `python file.py` does # exec with same globals `python file.py` does
...@@ -160,6 +171,19 @@ def pymain(argv): ...@@ -160,6 +171,19 @@ def pymain(argv):
console.interact() console.interact()
# init warnings
if len(warnoptions) > 0:
# NOTE warnings might be already imported by code that calls pymain.
# This way we cannot set `sys.warnoptions = warnoptions` and just
# import/reload warnings (if we reload warnings, it will loose all
# previous setup that pymain caller might have done to it).
# -> only amend warnings setup
#
# NOTE $PYTHONWARNINGS is handled by underlying python natively.
import warnings
sys.warnoptions += warnoptions
warnings._processoptions(warnoptions)
# execute -m/-c/file/interactive # execute -m/-c/file/interactive
run() run()
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
from __future__ import print_function, absolute_import from __future__ import print_function, absolute_import
import sys, os, platform, golang import sys, os, platform, re, golang
from golang.golang_test import pyout, _pyrun from golang.golang_test import pyout, _pyrun
from subprocess import PIPE from subprocess import PIPE
from six import PY2 from six import PY2
...@@ -182,6 +182,30 @@ def test_pymain(): ...@@ -182,6 +182,30 @@ def test_pymain():
_ = pyout(['testdata/hello.py', 'abc', 'def'], cwd=here) _ = pyout(['testdata/hello.py', 'abc', 'def'], cwd=here)
assert _ == b"hello\nworld\n['testdata/hello.py', 'abc', 'def']\n" assert _ == b"hello\nworld\n['testdata/hello.py', 'abc', 'def']\n"
# -W <opt>
_ = pyout(['-Werror', '-Whello', '-W', 'ignore::DeprecationWarning',
'testprog/print_warnings_setup.py'], cwd=here)
if PY2:
# py2 threading, which is imported after gpython startup, adds ignore
# for sys.exc_clear
_ = grepv(r'ignore:sys.exc_clear:DeprecationWarning:threading:*', _)
assert _.startswith(
b"sys.warnoptions: ['error', 'hello', 'ignore::DeprecationWarning']\n\n" + \
b"warnings.filters:\n" + \
b"- ignore::DeprecationWarning::*\n" + \
b"- error::Warning::*\n"), _
# $PYTHONWARNINGS
_ = pyout(['testprog/print_warnings_setup.py'], cwd=here,
envadj={'PYTHONWARNINGS': 'ignore,world,error::SyntaxWarning'})
if PY2:
# see ^^^
_ = grepv(r'ignore:sys.exc_clear:DeprecationWarning:threading:*', _)
assert _.startswith(
b"sys.warnoptions: ['ignore', 'world', 'error::SyntaxWarning']\n\n" + \
b"warnings.filters:\n" + \
b"- error::SyntaxWarning::*\n" + \
b"- ignore::Warning::*\n"), _
# pymain -V/--version # pymain -V/--version
# gpython_only because output differs from !gpython. # gpython_only because output differs from !gpython.
@gpython_only @gpython_only
...@@ -230,3 +254,20 @@ def test_Xruntime(runtime): ...@@ -230,3 +254,20 @@ def test_Xruntime(runtime):
out = pyout(argv, env=env) out = pyout(argv, env=env)
assert out == b'ok\n' assert out == b'ok\n'
# ---- 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)
# -*- coding: utf-8 -*-
# Copyright (C) 2020 Nexedi SA and Contributors.
# Kirill Smelkov <kirr@nexedi.com>
#
# This program is free software: you can Use, Study, Modify and Redistribute
# it under the terms of the GNU General Public License version 3, or (at your
# option) any later version, as published by the Free Software Foundation.
#
# You can also Link and Combine this program with other software covered by
# the terms of any of the Free Software licenses or any of the Open Source
# Initiative approved licenses and Convey the resulting work. Corresponding
# source of such a combination shall include the source code for all other
# software used.
#
# This program is distributed WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# See COPYING file for full licensing terms.
# See https://www.nexedi.com/licensing for rationale and options.
"""Program print_warnings_setup prints information about warnings module
configuration."""
from __future__ import print_function, absolute_import
import sys, warnings, re
def main():
print('sys.warnoptions: %s' % sys.warnoptions)
print('\nwarnings.filters:')
for f in warnings.filters:
print_filter(f)
def print_filter(f):
# see Lib/warnings.py
action, message, klass, module, line = f
message = wstr(message)
module = wstr(module)
klass = klass.__name__
if line == 0:
line = '*'
print('- %s:%s:%s:%s:%s' % (action, message, klass, module, line))
# wstr returns str corresponding to warning filter's message or module.
REPattern = re.compile('').__class__
def wstr(obj):
if obj is None:
return ''
if isinstance(obj, REPattern):
return obj.pattern
return obj
if __name__ == '__main__':
main()
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