git.net

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

pre-edit stuff persists in a reloaded a module


Friedrich Rentsch wrote:

> 
> 
> On 10/5/19 2:48 PM, Peter Otten wrote:
>> Friedrich Rentsch wrote:
>>
>>> Hi all,
>>>
>>> Python 2.7. I habitually work interactively in an Idle window.
>>> Occasionally I correct code, reload and find that edits fail to load. I
>>> understand that reloading is not guaranteed to reload everything, but I
>>> don't understand the exact mechanism and would appreciate some
>>> illumination. Right now I am totally bewildered, having deleted and
>>> garbage collected a module and an object, reloaded the module and remade
>>> the object and when I inspect the corrected source (inspect.getsource
>>> (Object.run)) I see the uncorrected source, which isn't even on the disk
>>> anymore. The command 'reload' correctly displays the name of the source,
>>> ending '.py', indicating that it recognizes the source being newer than
>>> the compile ending '.pyc'. After the reload, the pyc-file is newer,
>>> indicating that it has been recompiled. But the runtime error persist.
>>> So the recompile must have used the uncorrected old code. I could kill
>>> python with signal 15, but would prefer a targeted purge that doesn't
>>> wipe clean my Idle workbench. (I know I should upgrade to version 3. I
>>> will as soon as I get around to it. Hopefully that will fix the
>>> problem.)
>>>
>>> Thanks for comments
>> (1) stay away from reload()
>> (2) inspect.getsource() uses a cache that you should be able to clear
>> with linecache.clear():
>>
>> $ echo 'def f(): return "old"' > tmp.py
>> $ python
>> [...]
>>>>> import inspect, tmp
>>>>> inspect.getsource(tmp.f)
>> 'def f(): return "old"\n'
>> [1]+  Angehalten              python
>> $ echo 'def f(): return "new"' > tmp.py
>> $ fg
>> python
>> reload(tmp)
>> reload(tmp)
>> <module 'tmp' from 'tmp.py'>
>>>>> inspect.getsource(tmp.f)
>> 'def f(): return "old"\n'
>>>>> import linecache; linecache.clearcache()
>>>>> inspect.getsource(tmp.f)
>> 'def f(): return "new"\n'
>>
>> (3) see 1 ;)
>>
> Thank you, Peter. I guess, then, that not only 'inspect', but the
> compiler as well reads source off the line cache and clearing the latter
> would make 'reload' work as expected.

I don't think so. My understanding may be incomplete, but my working 
assumption is that the module is reloaded from file, compiled, and new 
bindings overwrite old ones.

However, every name bound to something from the old version will not be 
updated, i. e.

import module
obj = module.obj
reload(module)
assert obj is not module.obj

> Are there other snags lurking,
> that you advise against using 'reload'? 

The above scenario is enough for me to forego reload().
You are actually lucky when something fails as an apparently successful 
change may fail in a fresh interpreter.

> What are the alternatives for
> developing iteratively, alternating between running and editing?

Keep the part under development small so that is doesn't hurt to rerun.