53

I'm issuing lots of warnings in a validator, and I'd like to suppress everything in stdout except the message that is supplied to warnings.warn().

I.e., now I see this:

./file.py:123: UserWarning: My looong warning message
some Python code

I'd like to see this:

My looong warning message

Edit 2: Overriding warnings.showwarning() turned out to work:

def _warning(
    message,
    category = UserWarning,
    filename = '',
    lineno = -1):
    print(message)
...
warnings.showwarning = _warning
warnings.warn('foo')
Tim Stack
  • 3,170
  • 3
  • 16
  • 35
l0b0
  • 52,149
  • 24
  • 132
  • 195

4 Answers4

41

There is always monkeypatching:

import warnings

def custom_formatwarning(msg, *args, **kwargs):
    # ignore everything except the message
    return str(msg) + '\n'

warnings.formatwarning = custom_formatwarning
warnings.warn("achtung")
Asclepius
  • 49,954
  • 14
  • 144
  • 128
Otto Allmendinger
  • 26,468
  • 7
  • 65
  • 79
  • on Python 3.6 I get TypeError: custom_formatwarning() got an unexpected keyword argument 'line'. So I changed function signature to: `def custom_formatwarning(message, category, filename, lineno, line='')` – Noam Manos Sep 04 '17 at 06:54
  • I had the "same got an unexpected keyword argument 'line'" in Python 3.6, but I just changed the signature to `def custom_formatwarning(msg, *a, **b):` so it also catches keyword args. – SuperGeo Jan 25 '18 at 18:44
  • 9
    I know this thread is old, but, you can also do this with a lambda instead of a function: `warnings.formatwarning = lambda msg, *args, **kwargs: f'{msg}\n'` – Craig Nov 06 '18 at 16:13
  • this should be the accepted answer, not the other one – DataMan Sep 10 '20 at 01:08
  • How do I get the warning type like `DeprecationWarning`? I tried `category` but it contains nothing – reddy Mar 01 '21 at 10:24
20

Monkeypatch warnings.showwarning() with your own custom function.

Ignacio Vazquez-Abrams
  • 740,318
  • 145
  • 1,296
  • 1,325
12

Use the logging module instead of warnings.

Geoff Reedy
  • 33,491
  • 3
  • 53
  • 76
  • 2
    This is what I have ended up with in the vast majority of situations where I originally tried to use `warnings`. If you are struggling with `warnings`, you should consider this option. Seriously. – tripleee Apr 08 '17 at 07:48
  • 1
    there's some subtlety in choosing warnings over logging.warn https://stackoverflow.com/a/14762106/5335565 – Izana Jun 09 '20 at 22:33
10

Here's what I'm doing to omit just the source code line. This is by and large as suggested by the documentation, but it was a bit of a struggle to figure out what exactly to change. (In particular, I tried in various ways to keep the source line out of showwarnings but couldn't get it to work the way I wanted.)

# Force warnings.warn() to omit the source code line in the message
formatwarning_orig = warnings.formatwarning
warnings.formatwarning = lambda message, category, filename, lineno, line=None: \
    formatwarning_orig(message, category, filename, lineno, line='')

Just passing line=None would cause Python to use filename and lineno to figure out a value for line automagically, but passing an empty string instead fixes that.

tripleee
  • 158,107
  • 27
  • 234
  • 292
  • I know this is super old but I've done a similar thing and that also worked. However if I do this inside a function, the warning behavior changes on the global scope. Every warning comes after calling that function adopts the modified behavior. Do you know a way to limit its effect? – percusse Oct 05 '17 at 13:14
  • Hmm, I only ever used this in global context. As a freak workaround, you could define a global variable which is used inside the `lambda` to decide whether or not the `line` value is overridden or not. (At that point, maybe use a named function rather than a `lambda`?) – tripleee Oct 05 '17 at 15:22
  • Unfortunately it didn't matter where I did these things. I also tried the original defeinition saving and restoring but no avail yet. – percusse Oct 05 '17 at 15:36
  • Nevermind this is a known issue apparently https://bugs.python.org/issue18081#msg191342. It is indeed annoying – percusse Oct 06 '17 at 14:47