Thank you for testing that. I dug through the change log, and found bpo-12022: https://bugs.python.org/issue12022 It *has* been fixed in 3.11, but not mentioned in the What's New document. Should it be?
On Sun, Sep 5, 2021, 5:49 PM Chris Angelico <ros...@gmail.com> wrote: > On Mon, Sep 6, 2021 at 9:37 AM Finn Mason <finnjavie...@gmail.com> wrote: > > > > Hello all, > > > > In Python 3.10 and 3.11, exception tracebacks are being greatly > improved. I noticed that there's nothing related to a fairly common (in my > personal experience) cryptic traceback relating to the `with` statement: > > > > >>> with ContextManager as ctx: > > ... # do something with `ctx` > > ... > > Traceback (most recent call last): > > File "<stdin>", line 1, in <module> > > AttributeError: __enter__ > > I'm seeing a different message, so it looks like something HAS been > improved: > > Python 3.11.0a0 (heads/main:ed524b4569, Aug 14 2021, 11:29:01) [GCC > 8.3.0] on linux > Type "help", "copyright", "credits" or "license" for more information. > >>> import contextlib > >>> with contextlib.ExitStack: ... > ... > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > TypeError: 'ABCMeta' object does not support the context manager protocol > > > > This occurs when one forgets to use a instance of a context manager > class and uses the class itself. It's obviously not a very helpful > traceback. ("Is it not a context manager?" "Is it the wrong class?") > Something like the following would be better. > > > > >>> with ContextManager as ctx: > > ... # do something with `ctx` > > ... > > Traceback (most recent call last): > > File "<stdin>", line 1, in <module> > > AttributeError: <type Context manager> is not a context manager. Did you > mean "with ContextManager()..."? > > > > The actual traceback message should probably be more specific than > "<type Context manager> is not a context manager". > > Thoughts? > > > > The "did you mean" part depends on or assumes that it can figure out > that calling it would have given a viable context manager. This could > be done by probing whether thing.__enter__ exists, but I'm not sure > that'd be entirely safe. Also, it won't catch those made from > generators: > > >>> @contextlib.contextmanager > ... def foo(): yield > ... > >>> with foo: ... > ... > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > TypeError: 'function' object does not support the context manager protocol > >>> with foo(): ... > ... > Ellipsis > >>> foo > <function foo at 0x7fdeb0321bc0> > > > In any case, the biggest advantage (IMO) comes from naming the type, > which will make it easy to distinguish the object from its type. > > ChrisA > _______________________________________________ > Python-ideas mailing list -- python-ideas@python.org > To unsubscribe send an email to python-ideas-le...@python.org > https://mail.python.org/mailman3/lists/python-ideas.python.org/ > Message archived at > https://mail.python.org/archives/list/python-ideas@python.org/message/NGP5LQSRS2XPNHIRBN3O76UGMEB623TW/ > Code of Conduct: http://python.org/psf/codeofconduct/ >
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/56MVDUFOD6GLSTCWIKZBJQO65P3HHJ6N/ Code of Conduct: http://python.org/psf/codeofconduct/