This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Add an Error / Exception / Warning when contextlib.suppress() is entered with no specified exception(s) to suppress
Type: Stage: resolved
Components: Library (Lib) Versions: Python 3.11
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: cooperlees, ncoghlan, serhiy.storchaka, yselivanov, zach.ware
Priority: normal Keywords:

Created on 2022-02-21 17:26 by cooperlees, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (10)
msg413663 - (view) Author: Cooper Lees (cooperlees) * Date: 2022-02-21 17:26
Today if you enter a `contextlib.suppress()` context and specify no exceptions there is no error or warning (I didn't check pywarnings to be fair). Isn't this a useless context then? If not, please explain why and close.

If it is, I'd love to discuss possibly raising a new NoSupressionError or at least a warning to let people know they executing an unneeded context.

Example code that 3.11 does not error on:

```python
cooper@home1:~$ python3.11
Python 3.11.0a5+ (main, Feb 21 2022, 08:52:10) [GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import contextlib
>>> with contextlib.suppress():
...   print("Foo")
...
Foo
```

This was reported to `flake8-bugbear` and if this is not accepted I may accept adding this to the linter. But feel this could be fixable in cpython itself.
msg413667 - (view) Author: Zachary Ware (zach.ware) * (Python committer) Date: 2022-02-21 18:32
I'm -1 on this suggestion; consider the following:

```
exceptions_to_suppress = []
if some_condition:
    exceptions_to_suppress.append(ValueError)

with contextlib.suppress(*exceptions_to_suppress):
    do_a_thing()
```

This seems a reasonable case to support and would require quite some gymnastics to continue supporting while also warning on an empty set.
msg413681 - (view) Author: Cooper Lees (cooperlees) * Date: 2022-02-21 21:18
Totally agree with your example use case. There you have a chance for it being useful under certain conditions. In that example there is a passed argument.  In my example there is no passed argument. Thus, I believe that this will generally always be developer error, again, unless I'm missing something here.

My main suggestion here is to just error/warn when no argument at all is passed to `contextlib.suppress` and this this context is *never* a chance of it being useful. If someone passes None or an empty `Sequence` (or anything non truthy) I propose we stay behaving the same as today.

Please feel free to edit the title if that's not clear enough etc.
msg413724 - (view) Author: Zachary Ware (zach.ware) * (Python committer) Date: 2022-02-22 18:02
But `suppress` takes varargs; from `suppress`'s perspective, there is no difference between `suppress()` and `l=[];suppress(*l)`.  There would be a difference at the AST level, but trying to find it within `suppress` to issue a warning seems unfeasible.  Certainly possible for a linter, though :)
msg413728 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2022-02-22 18:11
I concur with Zachary.

Note that suppress without arguments corresponds to "except" and isinstance() with empty tuple.
msg413731 - (view) Author: Cooper Lees (cooperlees) * Date: 2022-02-22 18:19
Ok thanks. Looks like the warning in flake8-bugbear is the right place then, unfortunately.

And just to be sure:

> Note that suppress without arguments corresponds to "except" and isinstance() with empty tuple.

Are you saying that `contextlib.suppress()` should effectively `except BaseException` (cause this is not the behavior from my tests) and suppress all or suppress nothing? I believe the empty tuple makes it except nothing?

```python
cooper@home1:~$ python3.11
Python 3.11.0a5+ (main, Feb 22 2022, 08:51:50) [GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import contextlib
>>> with contextlib.suppress():
...   raise ValueError("I raise ...")
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ValueError: I raise ...
>>>
```
msg413732 - (view) Author: Zachary Ware (zach.ware) * (Python committer) Date: 2022-02-22 18:24
>>> try:
...     raise ValueError("I raise...")
... except ():
...     pass
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ValueError: I raise...
msg413733 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2022-02-22 18:27
No, I say that

    with suppress():
        ...

is equivalent to

    try:
        ...
    except ():
        pass

or

    try:
        ...
    except BaseException as err:
        if not isinstance(err, ()):
            raise

If you want to suppress all exceptions (it is not very clever idea), use suppress(BaseException).
msg413736 - (view) Author: Cooper Lees (cooperlees) * Date: 2022-02-22 18:29
I would never want to do that ... I understand it's bad. Just questioning things before adding lints so we put things in the right places and more importantly making sure I understand.

Thanks for the discussion all.
msg413737 - (view) Author: Cooper Lees (cooperlees) * Date: 2022-02-22 18:30
FWIW - Will be looking to add to flake8-bugbear here: https://github.com/PyCQA/flake8-bugbear/issues/222
History
Date User Action Args
2022-04-11 14:59:56adminsetgithub: 90975
2022-02-22 18:30:01cooperleessetmessages: + msg413737
2022-02-22 18:29:26cooperleessetmessages: + msg413736
2022-02-22 18:27:02serhiy.storchakasetmessages: + msg413733
2022-02-22 18:24:02zach.waresetmessages: + msg413732
2022-02-22 18:19:47cooperleessetmessages: + msg413731
2022-02-22 18:11:19serhiy.storchakasetstatus: open -> closed

nosy: + serhiy.storchaka
messages: + msg413728

resolution: not a bug
stage: resolved
2022-02-22 18:02:51zach.waresetmessages: + msg413724
2022-02-21 21:18:39cooperleessetmessages: + msg413681
2022-02-21 18:32:56zach.waresetnosy: + yselivanov, ncoghlan, zach.ware
messages: + msg413667
2022-02-21 17:26:24cooperleescreate