[Python-3000] PEP to change how the main module is delineated

Steven Bethard steven.bethard at gmail.com
Mon Apr 23 06:43:21 CEST 2007

On 4/22/07, Brett Cannon <brett at python.org> wrote:
> Implementation
> ==============
> When the ``-m`` option is used, ``sys.main`` will be set to the
> argument passed in.  ``sys.argv`` will be adjusted as it is currently.
> Then the equivalent of ``__import__(self.main)`` will occur.  This
> differs from current semantics as the ``runpy`` module fetches the
> code object for the file specified by the module name in order to
> explicitly set ``__name__`` and other attributes.  This is no longer
> needed as import can perform its normal operation in this situation.
> If a file name is specified, then ``sys.main`` will be set to
> ``"__main__"``.  The specified file will then be read and have a code
> object created and then be executed with ``__name__`` set to
> ``"__main__"``.  This mirrors current semantics.

So __name__ will still sometimes be "__main__". That's disappointing.

To clarify, assuming that the foo.bar module contains something like
"from . import baz", this PEP only addresses the following situation::

    python -mfoo.bar

and all of the following will still raise ImportErrors::

    ~> python foo/bar
    ~/grok> python ../foo/bar
    ~/foo> python bar


If that's right, I'm -1 on the proposal. It's complicating the
standard "am I the main module?" idiom to solve a tiny little problem
with "-m". The "am I the main module?" idiom has been around much
longer than the "-m" flag, and I'd prefer to see a more compelling
reason to change it.

Two reasons that would be compelling for me:

* Simplifying the "am I the main module?" idiom, e.g. with the
rejected ``if __main__`` proposal.

* Getting rid of the "__main__" value for __name__ entirely. This
would require code like the following to determine the name of a
module given at the command line::

    def get_name(path):
        sys_path_set = set(sys.path)
        path, _ = os.path.splitext(path)
        path = os.path.abspath(path)
        parts = path.split(os.path.sep)
        for i in range(1, len(parts)):
            sub_path = os.path.sep.join(parts[:i])
            if sub_path in sys_path_set:
                return '.'.join(parts[i:])
        return parts[-1]

  Even if we can't do the name resolution perfectly, if the flaws are
documented (e.g. when '..' and symbolic links are combined) I think
that would be enough better than the current situation to merit
changing the standard "am I the current module?" idiom.

I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a
tiny blip on the distant coast of sanity.
        --- Bucky Katt, Get Fuzzy

More information about the Python-3000 mailing list