Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add sip VirtualCatcherCode to avoid algorithm copies being
destroyed by the python garbage collector

The code generated with the /Factory/ annotation was not sufficient
to correctly transfer the ownership of objects created in Python
back to c++ (despite mailing list messages which hint that it
is).

Anyway, this awful abomination works. Let's all move on to more
useful ways to spend our time...
  • Loading branch information
nyalldawson committed Jul 10, 2017
1 parent 03275bb commit fc221a6
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 2 deletions.
1 change: 1 addition & 0 deletions cmake_templates/Doxyfile.in
Expand Up @@ -2073,6 +2073,7 @@ EXPAND_AS_DEFINED = "SIP_ABSTRACT" \
"SIP_TRANSFER" \
"SIP_TRANSFERBACK" \
"SIP_TRANSFERTHIS" \
"SIP_VIRTUAL_CATCHER_CODE" \
"SIP_VIRTUALERRORHANDLER" \
"SIP_WHEN_FEATURE"

Expand Down
8 changes: 7 additions & 1 deletion python/core/processing/qgsprocessingalgorithm.sip
Expand Up @@ -331,13 +331,19 @@ class QgsProcessingAlgorithm

protected:

virtual QgsProcessingAlgorithm *createInstance() const = 0 /Factory/;
virtual QgsProcessingAlgorithm *createInstance() const = 0;
%Docstring
Creates a new instance of the algorithm class.

This method should return a 'pristine' instance of the algorithm class.
:rtype: QgsProcessingAlgorithm
%End
%VirtualCatcherCode
PyObject *resObj = sipCallMethod( 0, sipMethod, "" );
sipIsErr = !resObj || sipParseResult( 0, sipMethod, resObj, "H2", sipType_QgsProcessingAlgorithm, &sipRes ) < 0;
if ( !sipIsErr )
sipTransferTo( resObj, Py_None );
%End

bool addParameter( QgsProcessingParameterDefinition *parameterDefinition /Transfer/ );
%Docstring
Expand Down
4 changes: 4 additions & 0 deletions scripts/sipify.pl
Expand Up @@ -310,6 +310,10 @@ sub detect_comment_block{
$LINE = "%ConvertToSubClassCode$1";
# do not go next, let run the "do not process SIP code"
}
if ($LINE =~ m/^\s*SIP_VIRTUAL_CATCHER_CODE(.*)$/){
$LINE = "%VirtualCatcherCode$1";
# do not go next, let run the "do not process SIP code"
}

if ($LINE =~ m/^\s*SIP_END(.*)$/){
write_output("SEN", "%End$1\n");
Expand Down
10 changes: 9 additions & 1 deletion src/core/processing/qgsprocessingalgorithm.h
Expand Up @@ -322,7 +322,15 @@ class CORE_EXPORT QgsProcessingAlgorithm
*
* This method should return a 'pristine' instance of the algorithm class.
*/
virtual QgsProcessingAlgorithm *createInstance() const = 0 SIP_FACTORY;
virtual QgsProcessingAlgorithm *createInstance() const = 0;
#ifdef SIP_RUN
SIP_VIRTUAL_CATCHER_CODE
PyObject *resObj = sipCallMethod( 0, sipMethod, "" );
sipIsErr = !resObj || sipParseResult( 0, sipMethod, resObj, "H2", sipType_QgsProcessingAlgorithm, &sipRes ) < 0;
if ( !sipIsErr )
sipTransferTo( resObj, Py_None );
SIP_END
#endif

/**
* Adds a parameter \a definition to the algorithm. Ownership of the definition is transferred to the algorithm.
Expand Down
4 changes: 4 additions & 0 deletions src/core/qgis_sip.h
Expand Up @@ -179,5 +179,9 @@
*/
#define SIP_ABSTRACT

/*
* Virtual catcher code
*/
#define SIP_VIRTUAL_CATCHER_CODE(code)

#endif // QGIS_SIP_H

0 comments on commit fc221a6

Please sign in to comment.