bugpyFormex - Bugs: bug #47418, Formex and Mesh are exported as...

 
 

bug #47418: Formex and Mesh are exported as global variables after creation

Submitter:  gianluca de santis <gianlucadesi>
Submitted:  Tue 15 Mar 2016 02:08:17 PM UTC
   
 
Category:  Core Severity:  1 - Wish
Item Group:  Feature request Status:  Fixed
Privacy:  Public Assigned to:  bverheg
Open/Closed:  Closed
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Mon 23 May 2016 07:18:37 AM UTC, comment #13: 

Bug closed, since it is fixed.

Benedict Verhegghe <bverheg>
Group administrator
Wed 06 Apr 2016 05:36:32 PM UTC, comment #12: 

Just to make this thread more readable: since commit 9095364 the variable 'autoglobals' can contain a list of names to export as well as classes.

Concerning your comment https://savannah.nongnu.org/bugs/?47418#comment11 :

Nothing strange about that. Remember that the globals are exported after your script has finished. The Mesh you created in the first example then does not exist anymore. It is deleted by Python as soon as you bind the name M to another object.
In the second case, the Mesh still exists at the end of your script.

This is the expected behavior for Python programmers, and trying to do otherwise would probably require us to change the Python language.
Think of it in the following way: you script runs to create some data, stored in the global variables of that script. Since you finish with some data left in memory, pyFormex supposes you want to use it for something, and stores some of them for later use (by default, all Geometry, but you can now customize what).
All locals and temporary data used during the execution of your script are already lost. If you want to keep something, you have to explicitely export them during the execution of your script.

Benedict Verhegghe <bverheg>
Group administrator
Wed 06 Apr 2016 04:16:20 PM UTC, comment #11: 

Nearly perfect, but still one strange thing after commit 9095364:

autoglobals = [Mesh]
M = Mesh([[1.,1.,1.]],[[0]])
M = Formex([[[0.,0.,0.]]])

This does not export 'M': it seems that the order makes the difference, because this below works fine:

autoglobals = [Mesh]
M = Formex([[[0.,0.,0.]]])
M = Mesh([[1.,1.,1.]],[[0]])




gianluca de santis <gianlucadesi>
Group Member
Wed 06 Apr 2016 08:57:07 AM UTC, comment #10: 

I have tested it:

autoglobals = True and False works fine

autoglobals =[some names] does NOT work and also breaks the GUI
autoclasses = [Geometry] does NOT work and also breaks the GUI


I would suggest to only leave the autoglobals = True / False, with True exporting all geometry objects.

In doc we should say that: if autoglobals is True, every time a geometry object is created it is also exported (e.g. M = Mesh() will create a global 'M'). If a global already exists (because of previous geometry creation or previous  - export{'M':'book'} -) it is silently overwritten.

gianluca de santis <gianlucadesi>
Group Member
Mon 04 Apr 2016 05:43:20 PM UTC, comment #9: 

The ideas of https://savannah.nongnu.org/bugs/?47418#comment8 have been implemented in commit 825e304.

The implementation is slightly different than suggest above:

autoglobals = False | True | [ list of names ]
autoclasses = [ list of classes ]

The default is set to match the old behavior:

autoglobals = True
autoclasses = [ Geometry ]


Benedict Verhegghe <bverheg>
Group administrator
Thu 24 Mar 2016 09:02:05 AM UTC, comment #8: 

I would advice against changing general configuration variables in your script/app.
Because the pf.cfg variable is session-wide, the change will influence the working of every next script you run in the same session.

I think we would need to have variables with scope limited to the script/app itself. I do not think we need another level of config dict for that, but maybe just some predefined global variables in the script. Thus, e.g., include

autoglobals=False

in you script to not export automatically. Or

autoglobals = [ Formex ]

to only export Formex type.


Benedict Verhegghe <bverheg>
Group administrator
Wed 23 Mar 2016 08:50:53 AM UTC, comment #7: 

Thanks Benedict, this is what I was looking for!
It is enough to put at the beginning of your script:

pf.cfg['autoglobals'] = False

To make this option visible to everybody I would include it (maybe even commented) in the 'Create new script' template. I would also include the clear and the chdir.

def run():
    """Main function.

    This is automatically executed on each run of an app.
    """
    print("This is the pyFormex template script/app")
    # pf.cfg['autoglobals'] = False
    # chdir(_file_)
    # clear()

NB: Of course you could also set it from the GUI/Settings/Settings Dialog/General/Auto Globals but then if you Accept and Save it will state False by default and you may have problems to share your scripts with other people or run scripts of other people.

gianluca de santis <gianlucadesi>
Group Member
Wed 16 Mar 2016 07:06:29 AM UTC, comment #6: 

Note also that the auto export feature is configurable by the config variable 'autoglobals'. It can be set from the general settings dialog.

In my opinion though, you should not switch it off globally.
Maybe we should provide a way to switch it off per script/app.

Benedict Verhegghe <bverheg>
Group administrator
Tue 15 Mar 2016 04:01:47 PM UTC, comment #5: 

It is actually the other way around: If we would NOT export automatically, the value in the GUI would be different than the (last) value it had in your script. The auto-export precisely aims at displaying the same as was (lastly) computed.

Python does not forget global variables. Therefore it is good practice to use global variables only scarcely. The same holds for pyFormex scripts. The auto-export of globals fits into this philosophy.

As said previously, it is easy to avoid the auto-export. Where I have a need  for large global data, I collect them into a complex structure (dict, list, object), so that they are not exported.
Or else delete them at the end of your script.
And in explicit exports, I normally use special unique names,
not just 'F' or 'M', to avoid them being overwritten by other scripts.

So I think there are many ways to obtain what you want.
An an extra for die-hard linear global programmers, we could add a configuration variable for the classes that are auto-exported.
Currently this is hardcoded to the Geometry class (and all its subclasses).


Benedict Verhegghe <bverheg>
Group administrator
Tue 15 Mar 2016 03:28:49 PM UTC, comment #4: 

Thanks for the reply. Actually, I was not aware of this (recent?) auto-export functionality. Here my few concerns:

- I remember that some years ago the variables were exported when drawing, and that this non-requested export was then removed. Now I see that is somehow the standard when generating a drawable. Why?

- I do not expect that when creating a Mesh (or a Formex) pyFormex silently overwrites some other variables explicitly exported (e.g. from a previous script).

- It is confusing to see that a variable in the GUI has a different value that the same variable in the script

- Why do we need to export everything to the GUI (including large models that are too large to be drawn)?

- python saves memory by forgetting what is no longer needed. What pyFormex should silently export variables?


Maybe we could have an 'preference option' to avoid the auto-export functionality? Can we set this 'preference option' it at the beginning of a script?

Thanks

gianluca de santis <gianlucadesi>
Group Member
Tue 15 Mar 2016 03:09:12 PM UTC, comment #3: 

This is not unstable. This is the normal behavior of a dynamic language as Python. Anything you redefine is... redefined.

Since the purpose of pyFormex is to create geometry, a beginning user would certainly expect to find the latest value in the GUI, not some earlier value that was already erased.

You just have to remember that in pyFormex, at the end of a script/app run, all remaining global variables that are of type 'Mesh' or 'Formex', are automatically exported to the GUI.
So in the case of your script, an export of M (now a Mesh) is done after running the script.

This feature should probably be better documented. I think there is even a way to change this behavior, by defining the types that should be auto-exported.

A well written large script will use most of its intermediate data in a function, so that they are automatically destroyed and memory is recollected by Python.
 
In a script like your example, what could be the use of creating a final Mesh in the variable M, since nothing can make further use of it. If you created the variable at some intermediate step, it would suffice to destroy it after use:
M = None
(but creating it in a function would still be better).



Benedict Verhegghe <bverheg>
Group administrator
Tue 15 Mar 2016 02:45:06 PM UTC, comment #2: 

OK,
But it seems to be unstable. Check second example: export_bug_2.py

Is this behaviour documented?

(file #36652)

gianluca de santis <gianlucadesi>
Group Member
Tue 15 Mar 2016 02:29:00 PM UTC, comment #1: 

This is a design feature rather than a bug.
It is intended to facilitate the use of the GUI on objects created by your script.

Only global variables in your script will be saved.
If you have a large script, using a lot of intermediate objects, these will normally be in local variables in functions, or be collected somewhere in a global data structure that is more complex that a Formex/Mesh.

So a well written application should not be hindered by this design.

And in any case, if you have memory problems, your script can delete its globals before finishing (and/or delete pyFormex globals at startup).

Benedict Verhegghe <bverheg>
Group administrator
Tue 15 Mar 2016 02:08:17 PM UTC, original submission:  

If you create Formex or Mesh in a script the variable is exported as global (run script in attachment).

Some years ago the problem raised only when drawing a geometry whereas now it seems independent of the draw function.

This is of course very bad, because it overwrites existing global variables and because it takes memory!

gianluca de santis <gianlucadesi>
Group Member

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

Attached Files
file #36652:  export_bug_2.py added by gianlucadesi (994B - text/x-python)
file #36651:  silent_export_bug.py added by gianlucadesi (894B - text/x-python)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by bverheg (Posted a comment)
  • -email is unavailable- added by gianlucadesi (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.

     

    Follow 12 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2016-05-23 bverheg StatusReady For Test Fixed
        Open/ClosedOpen Closed
    2016-04-04 bverheg StatusWorks For Me Ready For Test
    2016-03-23 gianlucadesi StatusIn Progress Works For Me
    2016-03-16 bverheg Severity4 - Important 1 - Wish
        StatusWont Fix In Progress
    2016-03-15 gianlucadesi Attached File- Added export_bug_2.py, #36652
        Severity1 - Wish 4 - Important
    2016-03-15 bverheg Severity4 - Important 1 - Wish
        Item GroupFunctionality error Feature request
        StatusNone Wont Fix
    2016-03-15 gianlucadesi Attached File- Added silent_export_bug.py, #36651

    Back to the top

    Powered by Savane 3.13-4448.
    Corresponding source code