[Python-Dev] confusing exec error message in 3.0

Steven D'Aprano steve at pearwood.info
Thu Aug 28 07:14:40 CEST 2008

On Thu, 28 Aug 2008 01:38:14 pm Guido van Rossum wrote:
> On Wed, Aug 27, 2008 at 6:21 PM, Steven D'Aprano <steve at pearwood.info> 
> > I don't think M.__file__ should lie and say it was loaded from a
> > file that it wasn't loaded from. It's useful to be able to look at
> > a module and see what file it was actually loaded from.
> While appreciate the use case, there are way more use cases where
> there's code that must painstakingly strip the trailing 'c' or 'o'
> from __file__ in order to read the source code. Perhaps we should
> have a separate API for finding out whether a module was loaded from
> source or from a .pyc file; but I think it would be better to have
> such an API somewhere in the imp module. It's also possible to follow
> what goes on by watching the verbose -v output.

Thinking more about it, I'm quite enthusiastic about Brett Cannon's 
suggestion that modules should grow a __source__ attribute as well as 

One disadvantage of a separate API is that it's relatively hard to 
discover, compared to dir(module) or help(module). I don't think I 
would have thought to look at a module "imp" (implementation?) when I 
needed that information. But perhaps that's a separate issue.

How would such an API work? Knowing nothing concrete about the 
implementation, I can think of two ways:

(1) Look at the module object and extract information from it that 
recorded what file it came from at the time, even if the Python path 
(or its contents) changed. This is the 2.x semantics of __file__.

(2) Look at the Python path as it exists now, and try to predict 
(postdict?) which file might have been used to import the module.

Of the two, I feel that postdiction is the worse solution. I imagine 
that this behaviour would be undesirable:

# not real code
>>> sys.path.append('somewhere')
>>> import parrot  # imports from 'somewhere/parrot.pyc'
>>> parrot.__file__
>>> del sys.path[-1]
>>> sys.path.append('somewhere_else/different')
>>> imp.where_from(parrot)

But maybe that can't happen and I'm worrying for nothing.

So what happens now? Does this need a PEP for further discussion?


More information about the Python-Dev mailing list