On Wed, Jan 10, 2018 at 08:02:24PM -0600, boB Stepp wrote:

> I am still puzzling over things from the thread, "Why does
> os.path.realpath('test_main.py') give different results for unittest
> than for testing statement in interpreter?"  The basic question I am
> trying to answer is how to determine the path to a particular module
> that is being run.  For the experiments I have run thus far, the
> module attribute, "__file__", has so far reliably given me the
> absolute path to the module being run.  But the documentation suggests
> that this attribute is optional.  So what can I rely on here with
> "__file__"?  The first sentence of the cited quote is not illuminating
> this sufficiently for me.

Modules which are loaded from a .py or .pyc file on disk should always 
have __file__ set. If they don't, that's a bug in the interpreter.

Modules which are loaded from a .dll or .so binary file also should have 
__file__ set.

Modules that you create on the fly like this:

py> from types import ModuleType
py> module = ModuleType('module')
py> module.__file__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'module' has no attribute '__file__'


will not have __file__ set unless you manually set it yourself. Such 
hand-made modules can be stored in databases and retrieved later, in 
which case they still won't have a __file__ attribute.

Module objects which are built into the interpreter itself, like sys, 
also won't have a __file__ attribute:

py> sys.__file__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'sys' has no attribute '__file__'


One tricky, but unusual case, is that Python supports importing 
and running modules loaded from zip files. Very few people know this 
feature even exists -- it is one of Python's best kept secrets -- and 
even fewer know how it works. I'm not sure what happens when you load a 
module from a zip file, whether it will have a __file__ or not.

Basically, if you still to reading module.__file__ for modules which 
come from a .py file, you should be absolutely fine. But to practice 
defensive programming, something like:

try:
    path = module.__file__
except AttributeError:
    print('handle the case where the module doesn't exist on disk')
else:
    print('handle the case where the module does exist on disk')
    

might be appropriate.



-- 
Steve
_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Reply via email to