Skip to content

Commit 8be00c5

Browse files
committed
Fix object instantiation when passed data is not a real one but is instead parsed by the object
1 parent e51194f commit 8be00c5

1 file changed

Lines changed: 50 additions & 23 deletions

File tree

bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Node.cpp

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ py::object addObjectKwargs(Node* self, const std::string& type, const py::kwargs
316316
py::list parametersToCopy;
317317
py::list parametersToLink;
318318

319-
processKwargsForObjectCreation(kwargs, parametersToLink, parametersToCopy, desc);
319+
processKwargsForObjectCreation( kwargs, parametersToLink, parametersToCopy, desc);
320320
auto object = ObjectFactory::getInstance()->createObject(self, &desc);
321321

322322
// After calling createObject the returned value can be either a nullptr
@@ -343,8 +343,6 @@ py::object addObjectKwargs(Node* self, const std::string& type, const py::kwargs
343343

344344
setFieldsFromPythonValues(object.get(), kwargs);
345345

346-
checkParamUsage(desc, object.get());
347-
348346
// Convert the logged messages in the object's internal logging into python exception.
349347
// this is not a very fast way to do that...but well...python is slow anyway. And serious
350348
// error management has a very high priority. If performance becomes an issue we will fix it
@@ -359,27 +357,37 @@ py::object addObjectKwargs(Node* self, const std::string& type, const py::kwargs
359357
{
360358
const std::string dataName = py::cast<std::string>(a.first);
361359
BaseData * d = object->findData(dataName);
360+
BaseLink * l = object->findLink(dataName);
362361

363-
if (d)
362+
if (d)
363+
{
364+
if (parametersToLink.contains(a.first))
365+
d->setParent(a.second.cast<BaseData*>());
366+
else if(parametersToCopy.contains(a.first))
364367
{
365-
if (parametersToLink.contains(a.first))
366-
d->setParent(a.second.cast<BaseData*>());
367-
else if(parametersToCopy.contains(a.first))
368+
try
368369
{
369-
try
370-
{
371-
PythonFactory::fromPython(d, py::cast<py::object>(a.second));
372-
}
373-
catch (std::exception& e)
374-
{
375-
msg_warning(self)<<"Creating " << type << " named " << name <<". An exception of type \""<<e.what()<<"\" was received while copying value input for data " << dataName << ". To fix this please reshape the list you are providing to fit the real intended data structure. \n The compatibility layer will try to create the data by converting the input to string.";
376-
377-
d->read(toSofaParsableString(a.second));
378-
}
370+
PythonFactory::fromPython(d, py::cast<py::object>(a.second));
371+
}
372+
catch (std::exception& e)
373+
{
374+
msg_warning(self)<<"Creating " << type << " at " << object->getPathName() <<". An exception of type \""<<e.what()<<"\" was received while copying value input for data " << dataName << ". To fix this please reshape the list you are providing to fit the real intended data structure. \n The compatibility layer will try to create the data by converting the input to string.";
375+
376+
if ( !d->read(toSofaParsableString(a.second)))
377+
throw py::value_error("Cannot convert the input \""+ toSofaParsableString(a.second)+"\" to a valid value for data " + object->getPathName() + "." + dataName );
379378
}
380-
d->setPersistent(true);
381379
}
380+
d->setPersistent(true);
381+
}
382+
else if (l == nullptr && parametersToCopy.contains(a.first))
383+
{
384+
desc.setAttribute(dataName,toSofaParsableString(a.second) );
385+
}
382386
}
387+
388+
object->parse(&desc);
389+
checkParamUsage(desc, object.get());
390+
383391
return PythonFactory::toPython(object.get());
384392
}
385393

@@ -461,21 +469,40 @@ py::object addChildKwargs(Node* self, const std::string& name, const py::kwargs&
461469
node->setInstanciationSourceFileName(finfo->filename);
462470
node->setInstanciationSourceFilePos(finfo->line);
463471

464-
checkParamUsage(desc, node.get());
465-
466472
for(auto a : kwargs)
467473
{
468-
BaseData* d = node->findData(py::cast<std::string>(a.first));
469-
if(d)
474+
const std::string dataName = py::cast<std::string>(a.first);
475+
BaseData * d = node->findData(dataName);
476+
BaseLink * l = node->findLink(dataName);
477+
478+
if (d)
470479
{
471480
if (parametersToLink.contains(a.first))
472481
d->setParent(a.second.cast<BaseData*>());
473482
else if(parametersToCopy.contains(a.first))
474-
PythonFactory::fromPython(d, py::cast<py::object>(a.second));
483+
{
484+
try
485+
{
486+
PythonFactory::fromPython(d, py::cast<py::object>(a.second));
487+
}
488+
catch (std::exception& e)
489+
{
490+
msg_warning(self)<<"Creating Node at " << node->getPathName() <<". An exception of type \""<<e.what()<<"\" was received while copying value input for data " << dataName << ". To fix this please reshape the list you are providing to fit the real intended data structure. \n The compatibility layer will try to create the data by converting the input to string.";
491+
492+
if ( !d->read(toSofaParsableString(a.second)))
493+
throw py::value_error("Cannot convert the input \""+ toSofaParsableString(a.second)+"\" to a valid value for data " + node->getPathName() + "." + dataName );
494+
}
495+
}
475496
d->setPersistent(true);
476497
}
498+
else if (l == nullptr && parametersToCopy.contains(a.first))
499+
{
500+
desc.setAttribute(dataName,toSofaParsableString(a.second) );
501+
}
477502
}
478503

504+
node->parse(&desc);
505+
checkParamUsage(desc, node.get());
479506
return py::cast(node);
480507
}
481508

0 commit comments

Comments
 (0)