[Python-Dev] Coding practice for context managers

Antoine Pitrou solipsis at pitrou.net
Mon Oct 21 15:52:21 CEST 2013


Le Mon, 21 Oct 2013 23:12:40 +1000,
Nick Coghlan <ncoghlan at gmail.com> a écrit :
> On 21 Oct 2013 22:10, "Antoine Pitrou" <solipsis at pitrou.net> wrote:
> >
> > Le Mon, 21 Oct 2013 20:46:39 +1000,
> > Nick Coghlan <ncoghlan at gmail.com> a écrit :
> > > On 21 Oct 2013 12:44, "Raymond Hettinger"
> > > <raymond.hettinger at gmail.com> wrote:
> > > >
> > > > Two of the new context managers in contextlib are now wrapped in
> > > pass-through factory functions.  The intent is to make the help()
> > > look cleaner.  This practice does have downsides however.
> > > >
> > > > The usual way to detect whether something is usable with a
> > > > with-statement
> > > is to check the presence of the __enter__ and __exit__ methods.
> > > Wrapping the CM in a pass-through function defeats this and other
> > > forms of introspection.
> > > >
> > > > Also, the help() output itself is worse-off.  When you run help
> > > > on a
> > > CM(), you're trying to find-out what happens on entry and what
> > > happens on exit.  If those methods had docstrings, the question
> > > would be answered directly.   The wrapper (intentionally) hides
> > > how it works.
> > > >
> > > > Since I teach intermediate and advanced python classes to
> > > > experienced
> > > Python users, I've become more sensitive to problems this practice
> > > will create.  Defeating introspection can make the help look
> > > nicer, but it isn't a clean coding practice and is something I
> > > hope doesn't catch on.
> > > >
> > > > To the extent there is a problem with the output of help(), I
> > > > think
> > > efforts should be directed at making help() better.   A lot of
> > > work needs to be done on that end -- for example abstract base
> > > classes also don't look great in help().
> > > >
> > > > There are a couple of other minor issues as well.  One is that
> > > > the
> > > wrapper function hides the class, making it harder to do type
> > > checks such as "isinstance(x, suppress)".  The other issue is
> > > that wrappers cause extra jumping around for people who are
> > > tracing code through a debugger or using a visualization tool
> > > such as pythontutor.   These aren't terribly important issues,
> > > but it does support the notion that usually the cleanest code is
> > > the best code.
> > > >
> > > > In short, I recommend that efforts be directed at improving
> > > > help() rather
> > > than limiting introspection by way of less clean coding practices.
> > >
> > > That's a fair point, but I *really* dislike exposing
> > > implementations that don't match their documentation, and both of
> > > these are currently documented as factory functions.
> >
> > Let's call them callables instead?
> >
> > > Exposing the full object oriented API is certainly a  reasonable
> > > option, but the docs should be updated accordingly, with suitable
> > > public attributes being defined (providing access to the exception
> > > tuple for suppress and the target stream for redirect_stdio).
> >
> > I don't get why adding public attributes should be related to the
> > proposed change.
> 
> Because redirect_stdout previously had undocumented attributes
> without an underscore prefix, and it was after I had already renamed
> those and was deciding whether or not to make suppress.exceptions
> public (and return self from suppress.__enter__) that I had my
> ill-advised brainwave about postponing dealing with all those
> questions by hiding the implementation of both of them behind factory
> functions.

So how about simply adding an underscore to all those attributes?

Regards

Antoine.




More information about the Python-Dev mailing list