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

[SofaPython] Small fix & new features. #656

Merged
merged 16 commits into from
Jun 4, 2018

Conversation

damienmarchal
Copy link
Contributor

@damienmarchal damienmarchal commented May 16, 2018

This PR contains a set of small changes on SofaPython that we are using in our projects.

CHANGELOG:

  • [SofaHelper] add StringUtils::getStringCopy (because it was duplicated in several place of the plugin)
  • [SofaPython] add systematically sys.argv in PythonEnvironment
  • [SofaPython] add a very general getattr function in Binding_Node (to write node1.node2.node3.obj.data)
  • [SofaPython] add a getTarget in BaseObject (to return the plugins that contains a component)
  • [SofaPython] add a getComponentsFromTarget in the Sofa module
  • [SofaPython] add some minor function in Binding_Data
  • [SofaPython] add docstring support for the Sofa module
  • [SofaPython] change Binding_BaseContext.getObject to return None instead of a broken exception

There is tests for all features.


This PR:

  • builds with SUCCESS for all platforms on the CI.
  • does not generate new warnings.
  • does not generate new unit test failures.
  • does not generate new scene test failures.
  • does not break API compatibility.
  • is more than 1 week old (or has fast-merge label).

Reviewers will merge only if all these checks are true.

to avoid having this code duplicated all around.
The current behavior was to not set a sys.argv if there where not argument passed in
the Sofa command line. The consequence was that in the python code it was needed
to do
if hasattr(sys, "argv"):
   ...

Which is rather uncommon.

This Commit change this behavior by setting systematically sys.argv and additionally fix typos (ending white spaces)
This code brings an unified syntax to query members of a Node.
So you can write:
root.child1.child2.child3.mechanicalobject.position

instead of:
root.getChild("child1").getChild("child2").getChild("child3").getObject("mechanicalobject").position

In case of similar names the predecessance rule is:
Data, Link, Child then Object.
This returns the list of categories an object belong to (as they are defined in in the GUI & Modeler).
… no object is found.

The existing code is rising an exception (without properly setting the exception
cause) but other getSomething methods of the binding returns None when the path
query does not match so it is better not to rise en exception and be consistant.
docstring is the proper way to document python code, so let's use it.
@damienmarchal damienmarchal added enhancement About a possible enhancement pr: status to review To notify reviewers to review this pull-request labels May 16, 2018
@damienmarchal
Copy link
Contributor Author

[ci-build][with-scene-tests]

@guparan guparan requested a review from jnbrunet May 16, 2018 08:49
Copy link
Contributor

@jnbrunet jnbrunet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything seems good to me!

@hugtalbot
Copy link
Contributor

2 tests are failing is this normal ?

@damienmarchal
Copy link
Contributor Author

damienmarchal commented May 17, 2018

Cleary not. I'm investigating because I have no idea where the problem could come from.

OK. I Got it...it is an interesting one so I report the details. In the code comments.

for(const std::string& arg : arguments) {
argv.push_back(arg.c_str());
}

Py_SetProgramName((char*) argv[0]); // TODO check what it is doing exactly
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line is not correct... according to python documentation Py_SetProgramName want a char* to a persistant char* (it does not copy the data)).
This code is reading everywhere in memory but the memory access is not detected in our CI because the line is only exectued when runSofa is started with specific command line option (--argv). Which our CI does not.

In this PR we set-up the argument whatever the --argv option so the code is executed in the CI and (we are lucky) this make some tests to fails.

The fix is easy...we simply needs to have the program name in the PythonEnvironment and not a stack allocated variable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure exactly why we are setting the program name here. As per the python doc, it should be set one time before the first call to Py_Initialize and, as you said, should be persistent throughout the execution. Running a python file should not change this value as the interpreter stays the same (runSofa's internal interpreter or eventually an external one when we will be able to include the sofa lib inside an external python script).

for(const std::string& arg : arguments) {
argv.push_back(arg.c_str());
}

Py_SetProgramName((char*) argv[0]); // TODO check what it is doing exactly
PySys_SetArgv(argv.size(), (char**)argv.data());
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fear this line is also incorrect.

@damienmarchal
Copy link
Contributor Author

@hugtalbot & @jnbrunet
I fixed the problematic code and added new tests for each of the added features.

…t) which containes the component.

This is useful to build introspection tools using python.
The corresponding test is also added.
So that we can get a target without having actually a instance of an object.
ASSERT_EQ( rootNode.child1.child2.dofs.position, [[1,2,3], [4,5,6]])

## Check the 'generalized' setattr
rootNode.child1.child2.dofs.position = [[2,2,2], [4,4,4]]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how this line tests the setattr of a node? It seems to test the setattr of a MechanicalObject (and the getattr of the parent nodes).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, fixed, thanks.

@damienmarchal
Copy link
Contributor Author

[ci-build][with-scene-tests]

@jnbrunet
Copy link
Contributor

✔️ to merge with these changes

@guparan
Copy link
Contributor

guparan commented May 23, 2018

Output of the failing test on MacOS:

[----------] 1 test from Batch/Python_scene_test
[ RUN      ] Batch/Python_scene_test.sofa_python_scene_tests/0
[INFO]    [SofaPython] Added '/Users/sofa/jenkins_2/workspace/mac_clang-3.4_options_pr2/pr/all/applications/plugins/Compliant/python' to sys.path
[INFO]    [SofaPython] Added '/Users/sofa/jenkins_2/workspace/mac_clang-3.4_options_pr2/pr/all/applications/plugins/Flexible/python' to sys.path
[INFO]    [SofaPython] Added '/Users/sofa/jenkins_2/workspace/mac_clang-3.4_options_pr2/pr/all/applications/plugins/image/python' to sys.path
[INFO]    [SofaPython] Added '/Users/sofa/jenkins_2/workspace/mac_clang-3.4_options_pr2/pr/all/applications/plugins/Registration/python' to sys.path
[INFO]    [SofaPython] Added '/Users/sofa/jenkins_2/workspace/mac_clang-3.4_options_pr2/pr/all/applications/plugins/RigidScale/python' to sys.path
[INFO]    [SofaPython] Added '/Users/sofa/jenkins_2/workspace/mac_clang-3.4_options_pr2/pr/all/applications/plugins/SofaPython/python' to sys.path
[INFO]    [SofaPython] Added '/Users/sofa/jenkins_2/workspace/mac_clang-3.4_options_pr2/pr/all/applications/plugins/SofaTest/python' to sys.path
[INFO]    [PluginManager] Loaded plugin: /Users/sofa/jenkins_2/workspace/mac_clang-3.4_options_pr2/pr/all/build/lib/libSofaPython.dylib
[INFO]    [Python_scene_test] running /Users/sofa/jenkins_2/workspace/mac_clang-3.4_options_pr2/pr/all/applications/plugins/SofaTest/SofaTest_test/scenes/damping.py
ERROR: wrong number of arguments
[ERROR]   [PythonScript] IndexError: list index out of range
  File "/Users/sofa/jenkins_2/workspace/mac_clang-3.4_options_pr2/pr/all/applications/plugins/SofaTest/SofaTest_test/scenes/damping.py", line 15, in <module>
    DAMPING_COEF = float( sys.argv[1] )

[ERROR]   [SofaPython] Script (file:damping) import error
[ERROR]   [PythonScriptController(PythonScriptController)]  load error (file '/Users/sofa/jenkins_2/workspace/mac_clang-3.4_options_pr2/pr/all/applications/plugins/SofaTest/SofaTest_test/scenes/damping.py' not parsable)
../applications/plugins/SofaTest/Python_test.cpp:263: Failure
Failed
python error
[  FAILED  ] Batch/Python_scene_test.sofa_python_scene_tests/0, where GetParam() = 48-byte object <81-00 00-00 00-00 00-00 7E-00 00-00 00-00 00-00 00-4D 60-FA C4-7F 00-00 80-4D 60-FA C4-7F 00-00 10-4E 60-FA C4-7F 00-00 10-4E 60-FA C4-7F 00-00> (1051 ms)
[----------] 1 test from Batch/Python_scene_test (1051 ms total)

@hugtalbot
Copy link
Contributor

One last test is failing (indice out of range) for Python_test

The problem was that runFile is used either in the SceneLoader and to load
a controller but the behavior should be different regarding the way
the sys.argv have been set.  The solution was to revert (with small refactoring)
to the initial runFile behavior but adding a call to setArgument in the python
SceneLoader.
@damienmarchal
Copy link
Contributor Author

I don't understand why the compilation is failing...
I wonder if this is not a CI problem related to bad interaction with this PR https://github.com/sofa-framework/sofa/pull/659/files

@guparan
Copy link
Contributor

guparan commented May 24, 2018

[ci-build][with-scene-tests]

@damienmarchal
Copy link
Contributor Author

The failing tests are now fixed... ready when the compile is over ?

@damienmarchal
Copy link
Contributor Author

@guparan & @hugtalbot ready to merge ?

@hugtalbot hugtalbot added pr: status ready Approved a pull-request, ready to be squashed and removed pr: status to review To notify reviewers to review this pull-request labels May 30, 2018
@damienmarchal
Copy link
Contributor Author

damienmarchal commented May 31, 2018

I restart [ci-build][with-scene-tests] to take into account the recent merge in master.
Then merge. if ok.

@damienmarchal
Copy link
Contributor Author

So it is time to merge.

@damienmarchal
Copy link
Contributor Author

[ci-build][with-scene-tests]

@damienmarchal damienmarchal merged commit 89071ab into sofa-framework:master Jun 4, 2018
@guparan guparan added this to the v18.06 milestone Jun 18, 2018
@damienmarchal damienmarchal deleted the newFeatureSofaPython branch August 6, 2018 15:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement About a possible enhancement pr: status ready Approved a pull-request, ready to be squashed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants