Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Imported modules aren't re-imported when script is re-run #102

Closed
fragmuffin opened this issue Oct 8, 2017 · 13 comments
Closed

Imported modules aren't re-imported when script is re-run #102

fragmuffin opened this issue Oct 8, 2017 · 13 comments

Comments

@fragmuffin
Copy link
Member

fragmuffin commented Oct 8, 2017

When importing a module, FreeCAD needs to be re-started to successfully re-import

Steps to re-create

  1. Create a local file, like ~/temp/my_module/__init__.py with contents...
import cadquery
from Helpers import show

def foo():
    box = cadquery.Workplane('XY').box(10, 10, 10)
    show(box)
  1. start open FreeCAD, and a new cadquery script, copy this in
import sys
import os
sys.path.append(os.path.join(os.environ['HOME'], 'temp'))
from my_module import foo
foo()
  1. run it, you should be shown a cube (10x10x10)
  2. keeping FreeCAD open, change the dimensions of the box in my_module/__init__.py file
  3. re-run the script (hotkey F2) in FreeCAD

Expectation
The box should show the new dimensions

Actual Results
The box is still in the old dimensions

Work-around
Close FreeCAD, then re-open it

@jmwright
Copy link
Member

jmwright commented Oct 8, 2017

@fragmuffin Can you try the latest master, using show_object() instead of show()? You'll have to do a recursive clone because I've made the cadquery lib a git submodule now.

show_object() uses the new CadQuery Gateway Interface (CQGI). I'm curious if it handles the imports correctly.

@fragmuffin
Copy link
Member Author

@jmwright done, and the same issue.
The problem is unrelated to cadquery.
If, instead, my_module doesn't do anything CAD related, the problem persists.

for example, if ~/temp/my_module/__init__.py instead contains...

import os

def foo():
    locally_scoped_str = 'testing 123'
    with open(os.path.join(os.environ['HOME'], 'temp', 'test.txt')) as fh:
        fh.write(locally_scoped_str)

the same error can be observed when changing the value of locally_scoped_str, saving __init__.py, then re-running with F2

@jmwright
Copy link
Member

jmwright commented Oct 8, 2017

CQGI does the execution environment much differently than the module does. I was hoping that the issue was in the environment setup and tear down. I'll look into this issue. Thanks for reporting it.

@fragmuffin
Copy link
Member Author

@jmwright this may be the culprit
https://github.com/jmwright/cadquery-freecad-module/blob/98da3e9c9bc8ee8395dcf3efa0018c17e096956a/Gui/Command.py#L200:L201

# We import this way because using execfile() causes non-standard script execution in some situations
imp.load_source('temp_module', tempFile.name)

where tempFile contains the cadquery script being run.


yep, I just used that method manually, same issue.
So the question is how to "unload" a loaded module.

@jmwright
Copy link
Member

jmwright commented Oct 8, 2017

That section of code is bypassed when you use show_object() though. Did you try show_object after a fresh start of FreeCAD? CQGI sets up a separate environment each time it runs so I had expected that would fix this issue. If you ran the script with show and then immediately with show_object, the section of code you linked might still cause problems.

@fragmuffin
Copy link
Member Author

oh!, I see how that works now, so sorry.
I changed foo to return the box... then used show_object instead of `show.
same issue.

@fragmuffin
Copy link
Member Author

@jmwright

with the imp.load_source code at fault, a solution could be.

from contextlib import contextmanager
import sys

@contextmanager
def revert_sys_modules():
    modules_before = set(sys.modules.keys())
    yield
    for mod_name in sys.modules.keys():
        if mod_name not in modules_before:
            del sys.modules[mod_name]

with revert_sys_modules():
    imp.load_source('temp_module', tempFile.name)

I haven't tested it yet, but I've reeealy got to get to sleep right now 💤
I'll be busy for the next few days, but when I have time I can test it out and make a PR if it works

@jmwright
Copy link
Member

jmwright commented Oct 8, 2017

I'll be busy for the next few days, but when I have time I can test it out and make a PR if it works

That would be awesome, thanks for all your work on this.

@fragmuffin
Copy link
Member Author

My pleasure @jmwright !
I'm enjoying cadquery a lot, it's a CAD solution I've been looking for for a very long time, so I'm happy to contribute... and I'm very happy that I can contribute :)

@jmwright
Copy link
Member

jmwright commented Oct 9, 2017

@fragmuffin We're really glad that you've gotten involved. You've brought a lot to the project, and your enthusiasm is greatly appreciated. @dcowden and I are really busy with day jobs, so if we're slow to respond or miss things once in awhile, please don't take it as a sign of disinterest. We're very excited about where CadQuery is headed, and it's very encouraging when other people believe in it too and jump in with us.

@dcowden
Copy link
Member

dcowden commented Oct 9, 2017

@fragmuffin @jmwright not to just ditto Jeremy, but.. ditto!

It's so cool to have other people helping.

@jmwright
Copy link
Member

I haven't closed this because there might have been a bug introduced with this code change.

#103 (comment)

@fragmuffin
Copy link
Member Author

@jmwright I've created #104 with details on how to reproduce the bug, so this issue may be closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants