[Python-ideas] PEP for executing a module in a package containing relative imports

Brett Cannon brett at python.org
Sat Apr 21 03:35:42 CEST 2007


On 4/20/07, Steven Bethard <steven.bethard at gmail.com> wrote:
> On 4/20/07, Brett Cannon <brett at python.org> wrote:
> > On 4/19/07, Steven Bethard <steven.bethard at gmail.com> wrote:
> > > On 4/19/07, Brett Cannon <brett at python.org> wrote:
> > > > Transition Plan
> > > > ===============
> > > >
> > > > Using this solution will not work directly in Python 2.6.  Code is
> > > > dependent upon the semantics of having ``__name__`` set to
> > > > ``'__main__'``.  There is also the issue of pre-existing global
> > > > variables in a module named ``__main__``.
> > >
> > > Could you explain a bit why __main__ couldn't be inserted into modules
> > > before the module is actually executed? E.g. something like::
> > >
> > >     >>> module_text = '''\
> > >     ... __main__ = 'foo'
> > >     ... print __main__
> > >     ... '''
> > >     >>> import new
> > >     >>> mod = new.module('mod')
> > >     >>> mod.__main__ = True
> > >     >>> exec module_text in mod.__dict__
> > >     foo
> > >     >>> mod.__main__
> > >     'foo'
> > >
> > > I would have thought that if Python inserted __main__ before any of
> > > the module contents got exec'd, it would be backwards compatible
> > > because any use of __main__ would just overwrite the default one.
> >
> > That's right, and that is the problem.  That would mean if __main__
> > was false but then overwritten by a function or something, it suddenly
> > became true.  It isn't a problem in terms of whether the code will
> > run, but whether the expected semantics will occur.
>
> Sure, but I don't see how it's much different from anyone who writes::
>
>     list = [foo, bar, baz]
>
> and then later wonders why::
>
>     list(obj)
>
> gives a ``TypeError: 'list' object is not callable``.
>

Exactly.  It's just that 'list' was known about when the code was
written while __main__ was not.

> If someone doesn't understand that the __main__ they defined at the
> beginning of a module is going to be the same __main__ they use at the
> end of the module, they're going to need to go do some reading about
> how name binding works in Python anyway.
>
> Of course, I definitely think it would be valuable to have a Py3K
> deprecation warning to help users identify when they've made a silly
> mistake like this.
>
> (Note that the counter-proposal has the same problem, so this needs to
> be resolved regardless of which approach gets taken.)
>

Yep.

> I'd really like there to be a way to write Python 3.0 compatible code
> in Python 2.6 without having to run through 2to3. I think it's clear
> that __main__ can be defined (at module-level or in the builtins)
> without introducing any backwards compatibility problems right? Anyone
> that doesn't want to use the Python 3.0 idiom can still write ``if
> __name__ == '__main__'`` and it will continue to work in Python 2.X.
> And anyone who does want to use the Python 3.0 idiom is probably using
> the Py3K flag anyway, so if they make a stupid mistake, it'll get
> caught pretty quickly.

Exactly.  Python 2.6 will still have __name__ set to '__main__', but
also have __main__ set.  Python 3.0 will not change __name__ at all.
This is why the PEP is a Py3K PEP and not a 2.6 PEP.

-Brett



More information about the Python-ideas mailing list