reloading modules and isinstance()

T

Tlis

I am using a software system with an embedded Python interpreter
(version 2.3) for scripting. The KcsPoint2D.py module contains a
Point2D class with the following method:

def SetFromMidpoint(self, p1, p2):
if not isinstance(p1, Point2D) or not isinstance(p2, Point2D):
raise TypeError, 'some error message'
---

The problem is that after I launch my script once, and then use the
'Reload modules' button (presumably it calls reload() on all loaded
modules), the isinstance() tests shown above fails, even though the
expressions:

type(self)
type(p1)
type(p2)

all show: class 'KcsPoint2D.Point2D'

Could you explain, please what is going on? Why the isinstance()
function returns False?
 
D

Diez B. Roggisch

Tlis said:
I am using a software system with an embedded Python interpreter
(version 2.3) for scripting. The KcsPoint2D.py module contains a
Point2D class with the following method:

def SetFromMidpoint(self, p1, p2):
if not isinstance(p1, Point2D) or not isinstance(p2, Point2D):
raise TypeError, 'some error message'
---

The problem is that after I launch my script once, and then use the
'Reload modules' button (presumably it calls reload() on all loaded
modules), the isinstance() tests shown above fails, even though the
expressions:

type(self)
type(p1)
type(p2)

all show: class 'KcsPoint2D.Point2D'

Could you explain, please what is going on? Why the isinstance()
function returns False?

You just discovered one reason why reload() is a bad idea and IMHO shouldn't
be used at all - as tempting it might be.

Reload will re-execute the importing of the module and perform all necessary
initializations there, overwrite names in the module namespace and such.

But it _won't_ magically change classes or other objects being referred to
from other code that have been created prior to the reloading. Consider
this example:

class A(object):
foo = 10

a = A()

class A(object):
foo = 20

print a.foo

All that happens is that the name A is bound to a new class. So all
subsequent instantiations are of the new type. But not the old instances -
because the refer to their class not by NAME, but just have a pointer to
it.

Diez
 
S

Steven D'Aprano

You just discovered one reason why reload() is a bad idea and IMHO
shouldn't be used at all - as tempting it might be.


I disagree -- I find reload() extremely useful for interactively testing
modules. But I would never dream of using it in production code!
 
D

Diez B. Roggisch

Steven said:
I disagree -- I find reload() extremely useful for interactively testing
modules. But I would never dream of using it in production code!

I find short scripts I write & start on the commandline much more helpful -
and if I need interactivity, throwing in a

import pdb; pdb.set_trace()

or

python -i <script>

do what I want. But I certainly don't have time to hunt down bugs introduced
by reloading in the first place...

YMMV - and it seems it does :)

Diez
 
T

Tlis

I disagree -- I find reload() extremely useful for interactively testing
modules. But I would never dream of using it in production code!

Please note, that I was using the 'Reload modules' functionality of
the software system in use, rather than the reload() function
directly. I admit, though, that in the background it just may call
reload() ...

With all the problems of the reload() function, I still hope, that
there should be possible to write a safe module 'reloader', that would
fix the references, as required (e.g. by changing the
variable.__class__ references). This should be provided by every
serious Python development environment.
 
C

Chris Mellon

Please note, that I was using the 'Reload modules' functionality of
the software system in use, rather than the reload() function
directly. I admit, though, that in the background it just may call
reload() ...

With all the problems of the reload() function, I still hope, that
there should be possible to write a safe module 'reloader', that would
fix the references, as required (e.g. by changing the
variable.__class__ references). This should be provided by every
serious Python development environment.

It's very nice to say that until you actually think about what it
entails - it's an extraordinarily hard problem. I challenge you to
write one (you don't need to have much more than a beginner knowledge
of Python to start on one) and then come back with your experiences.
 
G

Gabriel Genellina

With all the problems of the reload() function, I still hope, that
there should be possible to write a safe module 'reloader', that would
fix the references, as required (e.g. by changing the
variable.__class__ references). This should be provided by every
serious Python development environment.

Unfortunately that's not so simple, given the dynamic nature of Python.
With some help from the programmer, reload may perform better; by example,
if you never ever do "from module import xxx", and always do "import
module" and use module.xxx everywhere. But it gets rather annoying, and
still has many problems.
 
D

Diez B. Roggisch

Tlis said:
Please note, that I was using the 'Reload modules' functionality of
the software system in use, rather than the reload() function
directly. I admit, though, that in the background it just may call
reload() ...

With all the problems of the reload() function, I still hope, that
there should be possible to write a safe module 'reloader', that would
fix the references, as required (e.g. by changing the
variable.__class__ references). This should be provided by every
serious Python development environment.

Wishful thinking. If I do

foo = {}
foo['some_key'] = somemodule.SomeClass

somewhere in my code, how do you suppose is reload(somemodule) to know
where in all the world I keep references to that class? Thus it would
essentially have to scan all references to anything, all list contents,
all class-properties, all everything. Which is not feasible.

reload() can be convenient, if you know its limitiations. But it has
some, and they are deeply rooted in the way python works. So you gonna
have to live with it.


Diez
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top