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/