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 on splitting it from there. I noticed at some point that in my tracebacks I get:
Traceback (most recent call last):
File "<string>", line 656, in DoItemMenu
File "bash\balt.py", line 2109, in PopupMenu
link.AppendToMenu(menu,parent,*args)
File "bash\balt.py", line 2225, in AppendToMenu
for link in self.links: link.AppendToMenu(subMenu,window,data)
...
where the lines in File "<string>"
correspond to the particular package/__init__.py
module. Moreover PyCharm's debugger displays a "frame not available" line and does not step into the lines in the __init__.py
. Why? Is it related to the import pattern?
The code is imported by a launcher class:
class UnicodeImporter(object):
def find_module(self,fullname,path=None):
if isinstance(fullname,unicode):
fullname = fullname.replace(u'.',u'\\')
exts = (u'.pyc',u'.pyo',u'.py')
else:
fullname = fullname.replace('.','\\')
exts = ('.pyc','.pyo','.py')
if os.path.exists(fullname) and os.path.isdir(fullname):
return self
for ext in exts:
if os.path.exists(fullname+ext):
return self
def load_module(self,fullname):
if fullname in sys.modules:
return sys.modules[fullname]
else:
sys.modules[fullname] = imp.new_module(fullname)
if isinstance(fullname,unicode):
filename = fullname.replace(u'.',u'\\')
ext = u'.py'
initfile = u'__init__'
else:
filename = fullname.replace('.','\\')
ext = '.py'
initfile = '__init__'
if os.path.exists(filename+ext):
try:
with open(filename+ext,'U') as fp:
mod = imp.load_source(fullname,filename+ext,fp)
sys.modules[fullname] = mod
mod.__loader__ = self
return mod
except:
print 'fail', filename+ext
raise
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
basher/__init__.py
it did not load a string though... – Brokenhearted__init__.py
– Brokenheartedimp.load_source()
and only afterwards sets a__file__
attribute on the module object. That is why your__init__
is listed as loaded from<string>
and PyCharm cannot debug it without a filename. – Highballexec code in mod.__dict__
line; and I also notice theimp.load_source()
call including a filename. The latter discounts theload_source()
call as the source, but theexec
call will definitely lead to the behaviour you see. – Highball