Author: Amaury Forgeot d'Arc <amaur...@gmail.com> Branch: py3.6 Changeset: r93625:dbcd63982736 Date: 2018-01-04 09:15 +0100 http://bitbucket.org/pypy/pypy/changeset/dbcd63982736/
Log: warnings.warn() now has a "source" argument. In the future, ResourceWarnings might log the traceback where this object was allocated (when tracemalloc works on PyPy) In the mean time, this fixes the last failures in test_io. diff --git a/pypy/module/_warnings/interp_warnings.py b/pypy/module/_warnings/interp_warnings.py --- a/pypy/module/_warnings/interp_warnings.py +++ b/pypy/module/_warnings/interp_warnings.py @@ -276,12 +276,12 @@ break space.call_method(w_stderr, "write", space.newunicode(message)) -def do_warn(space, w_message, w_category, stacklevel): +def do_warn(space, w_message, w_category, stacklevel, w_source=None): context_w = setup_context(space, stacklevel) - do_warn_explicit(space, w_category, w_message, context_w) + do_warn_explicit(space, w_category, w_message, context_w, w_source=w_source) def do_warn_explicit(space, w_category, w_message, context_w, - w_sourceline=None): + w_sourceline=None, w_source=None): w_filename, lineno, w_module, w_registry = context_w # normalize module @@ -342,19 +342,32 @@ if warned: # Already warned for this module return - w_show_fxn = get_warnings_attr(space, "showwarning") - if w_show_fxn is None: + + w_show_fn = get_warnings_attr(space, "_showwarnmsg") + if w_show_fn is None: show_warning(space, w_filename, lineno, w_text, w_category, w_sourceline) - else: - space.call_function( - w_show_fxn, w_message, w_category, w_filename, w_lineno) + return + + if not space.is_true(space.callable(w_show_fn)): + raise oefmt(space.w_TypeError, + "warnings._showwarnmsg() must be set to a callable") + w_message_cls = get_warnings_attr(space, "WarningMessage") + if w_message_cls is None: + raise oefmt(space.w_RuntimeError, + "unable to get warnings.WarningMessage") + w_source = w_source or space.w_None + w_msg = space.call_function( + w_message_cls, w_message, w_category, + w_filename, w_lineno, space.w_None, space.w_None, w_source) + space.call_function(w_show_fn, w_msg) + @unwrap_spec(stacklevel=int) -def warn(space, w_message, w_category=None, stacklevel=1): +def warn(space, w_message, w_category=None, stacklevel=1, w_source=None): "Issue a warning, or maybe ignore it or raise an exception." w_category = get_category(space, w_message, w_category); - do_warn(space, w_message, w_category, stacklevel) + do_warn(space, w_message, w_category, stacklevel, w_source) def get_source_line(space, w_globals, lineno): @@ -394,14 +407,15 @@ w_registry = WrappedDefault(None), w_module_globals = WrappedDefault(None)) def warn_explicit(space, w_message, w_category, w_filename, lineno, - w_module=None, w_registry=None, w_module_globals=None): + w_module=None, w_registry=None, w_module_globals=None, + w_source=None): "Low-level inferface to warnings functionality." w_source_line = get_source_line(space, w_module_globals, lineno) do_warn_explicit(space, w_category, w_message, (w_filename, lineno, w_module, w_registry), - w_source_line) + w_source_line, w_source) def filters_mutated(space): space.fromcache(State).filters_mutated(space) diff --git a/pypy/module/_warnings/test/test_warnings.py b/pypy/module/_warnings/test/test_warnings.py --- a/pypy/module/_warnings/test/test_warnings.py +++ b/pypy/module/_warnings/test/test_warnings.py @@ -42,6 +42,13 @@ _warnings.warn_explicit("some message", Warning, "<string>", 1, module_globals=globals()) + def test_with_source(self): + import warnings, _warnings + source = [] + with warnings.catch_warnings(record=True) as w: + _warnings.warn("some message", Warning, source=source) + assert w[0].source is source + def test_default_action(self): import warnings, _warnings warnings.defaultaction = 'ignore' _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit