Skip to content Skip to sidebar Skip to footer

File "" In Python Traceback

I am in the middle of refactoring a huge py module to packages - to not break existing code I moved its contents to package/__init__.py module (Adding code to __init__.py) and went

Solution 1:

The code is not imported in a traditional manner; instead the launcher code uses an exec statement for loading __init__.py files.

Paring down the flow in the launcher load_module() function for a package (so not a path to a module) you get this:

# the fullname module isn't yet loaded
sys.modules[fullname] = imp.new_module(fullname)
initfile = '__init__'  # or u'__init__' if a unicode path was used

# if no .py file was found, so not a module
mod = sys.modules[fullname]
mod.__loader__ = self
mod.__file__ = os.path.join(os.getcwd(),filename)
mod.__path__ = [filename]
#init file
initfile = os.path.join(filename,initfile+ext)
if os.path.exists(initfile):
    with open(initfile,'U') as fp:
        code = fp.read()
    exec code in mod.__dict__
return mod

This creates an empty module object, loads the source manually and executes it as a string, passing in the module namespace as the globals for the executed code. The resulting code object is always going to list <string> in tracebacks:

>>> import imp
>>> mod = imp.new_module('foo.bar')
>>> mod.__file__ = r'C:\some\location\foo\bar'
>>> mod.__path__ = [r'foo\bar']
>>> exec 'raise ValueError("oops")' in mod.__dict__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
ValueError: oops

Because there is no filename associated with the code, PyCharm cannot find the original source either.

The work-around is to use the compile() function to create a code object first, and attaching a filename to that:

>>> exec compile('raise ValueError("oops")', r'C:\some\location\foo\bar\__init__.py', 'exec') in mod.__dict__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\some\location\foo\bar\__init__.py", line 1, in <module>
ValueError: oops

Note that I included __init__.py in the filename; translating that back to the launcher you'd use:

if os.path.exists(initfile):
    with open(initfile,'U') as fp:
        code = fp.read()
    exec compile(code, initfile, 'exec') in mod.__dict__

Post a Comment for "File "" In Python Traceback"