R
Rafe
Hi,
This seems to be an old question, and I've read back a bit, but rather
than assume the answer is "you can't do that", I'd thought I'd post my
version of the question along with a reproducible error to illustrate
my confusion.
My problem is that I'm using Python inside XSI (a 3D graphics
application). If I want to restart Python, I have to restart XSI. This
is no small amount of time wasted.
The solution would be to somehow unload modules and all references and
allow my imports to rebuild the cache. I suppose it would be great to
clear the python session completely, but the 3D application might have
added something to the session at startup (I doubt this though as I
don't see any imported modules outside the norm).
I've tried to use reload with a very simple algorithm. Simply run
through every imported module, ignoring anything that is "None" or on
the C: drive (all of our python is on a network drive so this hack
works for me for now) and reload() it. I've come to realize that this
isn't near intelligent enough to handle sub-packages.
Before I post the repro, my questions are:
1) Does anyone have a work-flow for my situation that doesn't use
Reload, and doesn't involve restarting the app for every edit/fix
2) Can anyone help point me in the right direction to build a
dependable algorithm to cleanly reload all loaded modules? NOTE: I
don't need to maintain anything in memory (i.e. instances, pointers,
etc.) Everything will be initialized again each time. I'm not asking
for code. Just some ideas or pseudo-code would do nicely.
Here is a "simple" repro...
Package Structure:
---------------------------
inheritRepro
__init__.py
baseLib.py
child
__init__.py
__init__.py:
----------------
import sys, os
def reloadModules():
"""
Reload all imported modules that are not on the C: drive.
"""
print "Reloading Python Modules..."
# Iterate over all IMPORTED modules
modules = sys.modules
for modName in modules:
mod = modules[modName]
# Skip None types and other itesm we don't care about
if modName == "__main__" or not hasattr(mod,"__file__"):
continue
# Get the drive and skip anything on the C: drive
drive = os.path.splitdrive(mod.__file__)[0]
if drive != "C:":
reload(mod)
print "Reloaded %s" % mod
baseLib.py:
---------------
class BaseClassA(object):
pass
class BaseClassB(BaseClassA):
def __init__(self):
super(BaseClassB, self).__init__()
child.__init__.py:
------------------------
import inheritRepro.baseLib as baseLib
class ChildClass(baseLib.BaseClassB):
def __init__(self):
super(ChildClass, self).__init__()
RUN:
-------Traceback (most recent call last):
File "<console>", line 0, in <module>
File "\\nas6tb\PROJECTS\tech\users\rafe.sacks\python\inheritRepro
\child\__init__.py", line 5, in __init__
super(ChildClass, self).__init__()
File "\\nas6tb\PROJECTS\tech\users\rafe.sacks\python\inheritRepro
\baseLib.py", line 6, in __init__
super(BaseClassB, self).__init__()
TypeError: super(type, obj): obj must be an instance or subtype of
type
NOTE: this works if I don't use a sub-package for 'child' (child.py
instead). Is it overly simple to assume reloading by file structure
might work?
Right now I'm getting around this by reload()-ing the right package
after running reloadModules() if an error occurs. It's a bit
frustrating that it cost me two days of work before I realized it was
reload() causing this error and not super() or some other unknown-to-
me inheritance/package structure problem. I rebuilt my code module by
module until I noticed, quite by accident, that the thing worked once
and then never again! ....oh well, these are the joys of learning the
hard way.
I know this was a long one. If you made it this far, thanks for
reading,
- Rafe
This seems to be an old question, and I've read back a bit, but rather
than assume the answer is "you can't do that", I'd thought I'd post my
version of the question along with a reproducible error to illustrate
my confusion.
My problem is that I'm using Python inside XSI (a 3D graphics
application). If I want to restart Python, I have to restart XSI. This
is no small amount of time wasted.
The solution would be to somehow unload modules and all references and
allow my imports to rebuild the cache. I suppose it would be great to
clear the python session completely, but the 3D application might have
added something to the session at startup (I doubt this though as I
don't see any imported modules outside the norm).
I've tried to use reload with a very simple algorithm. Simply run
through every imported module, ignoring anything that is "None" or on
the C: drive (all of our python is on a network drive so this hack
works for me for now) and reload() it. I've come to realize that this
isn't near intelligent enough to handle sub-packages.
Before I post the repro, my questions are:
1) Does anyone have a work-flow for my situation that doesn't use
Reload, and doesn't involve restarting the app for every edit/fix
2) Can anyone help point me in the right direction to build a
dependable algorithm to cleanly reload all loaded modules? NOTE: I
don't need to maintain anything in memory (i.e. instances, pointers,
etc.) Everything will be initialized again each time. I'm not asking
for code. Just some ideas or pseudo-code would do nicely.
Here is a "simple" repro...
Package Structure:
---------------------------
inheritRepro
__init__.py
baseLib.py
child
__init__.py
__init__.py:
----------------
import sys, os
def reloadModules():
"""
Reload all imported modules that are not on the C: drive.
"""
print "Reloading Python Modules..."
# Iterate over all IMPORTED modules
modules = sys.modules
for modName in modules:
mod = modules[modName]
# Skip None types and other itesm we don't care about
if modName == "__main__" or not hasattr(mod,"__file__"):
continue
# Get the drive and skip anything on the C: drive
drive = os.path.splitdrive(mod.__file__)[0]
if drive != "C:":
reload(mod)
print "Reloaded %s" % mod
baseLib.py:
---------------
class BaseClassA(object):
pass
class BaseClassB(BaseClassA):
def __init__(self):
super(BaseClassB, self).__init__()
child.__init__.py:
------------------------
import inheritRepro.baseLib as baseLib
class ChildClass(baseLib.BaseClassB):
def __init__(self):
super(ChildClass, self).__init__()
RUN:
-------Traceback (most recent call last):
File "<console>", line 0, in <module>
File "\\nas6tb\PROJECTS\tech\users\rafe.sacks\python\inheritRepro
\child\__init__.py", line 5, in __init__
super(ChildClass, self).__init__()
File "\\nas6tb\PROJECTS\tech\users\rafe.sacks\python\inheritRepro
\baseLib.py", line 6, in __init__
super(BaseClassB, self).__init__()
TypeError: super(type, obj): obj must be an instance or subtype of
type
NOTE: this works if I don't use a sub-package for 'child' (child.py
instead). Is it overly simple to assume reloading by file structure
might work?
Right now I'm getting around this by reload()-ing the right package
after running reloadModules() if an error occurs. It's a bit
frustrating that it cost me two days of work before I realized it was
reload() causing this error and not super() or some other unknown-to-
me inheritance/package structure problem. I rebuilt my code module by
module until I noticed, quite by accident, that the thing worked once
and then never again! ....oh well, these are the joys of learning the
hard way.
I know this was a long one. If you made it this far, thanks for
reading,
- Rafe