Fix sip tests

This commit is contained in:
Julien Cabieces 2023-12-11 10:18:23 +01:00 committed by Nyall Dawson
parent 92cc39f86e
commit 388de8cedd
7 changed files with 557 additions and 72 deletions

View File

@ -38,49 +38,50 @@ else
fi
sources=(HDRS MOC_HDRS SRCS)
for module in "${modules[@]}"; do
file=${DIR}/python/${module}/${module}_auto.sip
echo "Creating python/${module}/${module}_auto.sip"
echo "// Include auto-generated SIP files" > $file
for root_dir in python python/PyQt6; do
for module in "${modules[@]}"; do
file=${DIR}/$root_dir/${module}/${module}_auto.sip
echo "Creating $root_dir/${module}/${module}_auto.sip"
echo "// Include auto-generated SIP files" > $file
headers=$(
for source in "${sources[@]}"; do
echo "QGIS_${module^^}_${source}"
${GP}sed -r -n -e "/^\s*set\s*\(QGIS_${module^^}_${source}/,/\)\$/{ /^\s*set\s*\(QGIS_${module^^}_${source}/d; /\)\$/d; p; }" src/${module}/CMakeLists.txt | \
${GP}sed -r -e '/\.cc?$/d' `# remove c and cc extensions` \
-e 's/\.cpp$/.h/' `# rename cpp file as headers` \
-e '/^\s*\$\{CMAKE_(CURRENT_)?BINARY_DIR\}/d' \
-e '/^\s*#/d' `# remove commented lines` \
-e 's/\$\{.*\}//g' `# remove CMake variable append` \
-e 's/^\s+//' `# remove leading spaces` \
-e '/^\s*$/d' `# remove blank lines`
done | cat -n | sort -uk2 | sort -nk1 | cut -f2- # remove duplicated lines without sorting
)
for header in ${headers}; do
if [ ! -f src/${module}/$header ]; then
# if no header, no sip file!
#echo "src/${module}/$header not found"
continue
fi
if ! grep -xq -E '^(#define +)?SIP_NO_FILE' src/${module}/${header}; then
sip=$(${GP}sed -r 's/(.*)\.h$/\1.sip/' <<< ${header})
if_cond=$(grep -x -E '^(#define +)?SIP_IF_MODULE\((.*)\)$' src/${module}/${header} | \
${GP}sed -r -e 's/(#define +)?SIP_IF_MODULE\((.*)\)/%If (\2)/')
if [[ -n $if_cond ]]; then
echo "$if_cond" >> $file
headers=$(
for source in "${sources[@]}"; do
echo "QGIS_${module^^}_${source}"
${GP}sed -r -n -e "/^\s*set\s*\(QGIS_${module^^}_${source}/,/\)\$/{ /^\s*set\s*\(QGIS_${module^^}_${source}/d; /\)\$/d; p; }" src/${module}/CMakeLists.txt | \
${GP}sed -r -e '/\.cc?$/d' `# remove c and cc extensions` \
-e 's/\.cpp$/.h/' `# rename cpp file as headers` \
-e '/^\s*\$\{CMAKE_(CURRENT_)?BINARY_DIR\}/d' \
-e '/^\s*#/d' `# remove commented lines` \
-e 's/\$\{.*\}//g' `# remove CMake variable append` \
-e 's/^\s+//' `# remove leading spaces` \
-e '/^\s*$/d' `# remove blank lines`
done | cat -n | sort -uk2 | sort -nk1 | cut -f2- # remove duplicated lines without sorting
)
for header in ${headers}; do
if [ ! -f src/${module}/$header ]; then
# if no header, no sip file!
#echo "src/${module}/$header not found"
continue
fi
if [[ "$sip" == [0-9]* ]]; then
# unfortunately SIP parser does not accept relative paths starting with a number
# so "%Include 3d/xxxx.sip" is a syntax error but everything works with "%Include ./3d/xxxx.sip"
sip="./$sip"
if ! grep -xq -E '^(#define +)?SIP_NO_FILE' src/${module}/${header}; then
sip=$(${GP}sed -r 's/(.*)\.h$/\1.sip/' <<< ${header})
if_cond=$(grep -x -E '^(#define +)?SIP_IF_MODULE\((.*)\)$' src/${module}/${header} | \
${GP}sed -r -e 's/(#define +)?SIP_IF_MODULE\((.*)\)/%If (\2)/')
if [[ -n $if_cond ]]; then
echo "$if_cond" >> $file
fi
if [[ "$sip" == [0-9]* ]]; then
# unfortunately SIP parser does not accept relative paths starting with a number
# so "%Include 3d/xxxx.sip" is a syntax error but everything works with "%Include ./3d/xxxx.sip"
sip="./$sip"
fi
echo "%Include auto_generated/$sip" >> $file
if [[ -n $if_cond ]]; then
echo "%End" >> $file
fi
fi
echo "%Include auto_generated/$sip" >> $file
if [[ -n $if_cond ]]; then
echo "%End" >> $file
fi
fi
done
done
done
popd > /dev/null

View File

@ -0,0 +1,466 @@
/************************************************************************
* This file has been generated automatically from *
* *
* tests/code_layout/sipify/sipifyheader.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsSettingsEntryEnumFlag_settingsDigitizingDefaultSnapType
{
%TypeHeaderCode
#include "sipifyheader.h"
#include "qgssettingsentry.h"
typedef QgsSettingsEntryEnumFlag<Qgis::SnappingType> QgsSettingsEntryEnumFlag_settingsDigitizingDefaultSnapType;
%End
public:
QgsSettingsEntryEnumFlag_settingsDigitizingDefaultSnapType( const QString &key, QgsSettings::Section section, const Qgis::SnappingType &defaultValue, const QString &description = QString() );
QString key( const QString &dynamicKeyPart = QString() ) const;
Qgis::SnappingType value( const QString &dynamicKeyPart = QString(), bool useDefaultValueOverride = false, const Qgis::SnappingType &defaultValueOverride = Qgis::SnappingType() ) const;
};
%ModuleHeaderCode
#include <qgsnetworkspeedstrategy.h>
#include <qgsnetworkdistancestrategy.h>
%End
typedef qint64 QgsFeatureId;
typedef QSet<qint64 > QgsFeatureIds;
typedef QMap<qint64 , QMap<int, QVariant>> QgsChangedAttributesMap;
typedef QMap<qint64, QMap<int, QVariant> > QgsChangedAttributesMap;
typedef QMap<qint64, QMap<int, QVariant>> QgsChangedAttributesMap;
typedef QVector<QVariant> QgsSuperClass;
%MappedType QgsSuperClass
{
// The annotations are modified by astyle (these will be fixed by sipify.pl)
%TypeHeaderCode
#include <qgssipifyheader.h>
%End
%ConvertFromTypeCode
// Create the list.
PyObject *l;
return l;
%End
}
typedef QtClass<QVariant> QtClassQVariantBase;
class QgsSipifyHeader : QtClassQVariantBase
{
%Docstring(signature="appended")
Documentation goes here
Here's some comment mentioning another class :py:class:`QgsAutoAwesomemater`.makeAwesome.
.. note::
some other note
.. versionadded:: 3.0
%End
%TypeHeaderCode
#include "sipifyheader.h"
#include "qtclass.h"
typedef QtClass<QVariant> QtClassQVariantBase;
%End
%ConvertToSubClassCode
if ( sipCpp->headerType() == QgsSipifyHeader::Special )
sipType = sipType_QgsSpecialSipifyHeader;
else
sipType = sipType_QgsStandardSipifyHeader;
%End
public:
enum MyEnum /BaseType=IntFlag/
{
Success,
NoSuccess,
ImaginarySuccess,
RecursiveSuccess,
SuccessCombination,
PythonName /PyName=DifferentName/,
MonkeyName,
};
typedef QFlags<QgsSipifyHeader::MyEnum> Flags;
enum OneLiner { Success, NoSuccess };
private:
void makePrivate( int a );
public:
void publicMethodBetween1();
private:
void makePrivateMultiline( int a,
int b );
public:
void publicMethodBetween2();
private:
bool makePrivateMultilineImpl( int a,
int b );
public:
const QgsSettingsEntryEnumFlag_settingsDigitizingDefaultSnapType settingsDigitizingDefaultSnapType;
struct Data
{
Data( QgsMapLayer *layer, Qstring name );
QString mName;
int mCount;
QgsMapLayer *mLayer;
QList<QAction *> contextMenuActions;
};
static const int MONTHS;
explicit QgsSipifyHeader();
%Docstring
A constructor with definition in header
%End
QgsSipifyHeader( QWidget *parent /TransferThis/ = 0 );
%Docstring
A classic constructor with arguments
%End
QgsSipifyHeader( bool a = true );
%Docstring
A constructor with no empty `()`
%End
QgsSipifyHeader( QList<Point> a, const Issues &b = Issues::weDontHaveIssues(), QgsClass *b = 0 );
%Docstring
A constructor with some special character types
%End
Constructor();
virtual ~Destructor();
Constructor( const QString &name,
bool optional = false,
const QVariant &defaultValue = QVariant() );
QgsSipifyHeader();
%Docstring
Default constructor
%End
bool operator==( const QgsSipifyHeader other );
void multilineMethod( const QgsPointXY &startPoint,
QgsFeatureId featureId,
QgsVectorLayer *vl,
Qgis::SnappingType snap_to ) const;
%Docstring
A multiline method signature
%End
void nonAnnotatedMethodFollowingSkip();
virtual QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) /Factory/;
%Docstring
Factory annotation
%End
SomeObject *createAnother() /Factory/;
virtual SomeObject *createAnother2() /Factory/;
void LongDocStringMethod();
%Docstring
My long doc string
is not very interesting!
%End
void LongDocStringMethodWithBrief();
%Docstring
some brief
My long doc ``string``
is not very interesting!
Here's some comment mentioning another class :py:class:`QgsAutoAwesomemater`.makeLessAwesome.
%End
MyPointer *pointerReturnValue();
%Docstring
I return a pointer. If something bad happens, I return ``None``.
:return: pointer to something cool
%End
bool isOKwithErrMesg( QString &ErrMsg /Out/ );
void InOutParam( bool &ok = true /In,Out/ );
void setDiagramRenderer( QgsDiagramRenderer *r /Transfer/ );
void differentDefaultValue( bool defaultValue = false , QWidget *parent = 0, QString msg = "hello" );
void differentType( QList<qint64> & list );
void complexDefaultValueAndType( QList<QPair<qint64 , QMap<int, QString>>> list = QList<QPair<qint64, QMap<int, QString>>> );
%Docstring
complex default value and type (i.e. containing commas) should be given as a string with single quotes
%End
int inlineKeyWordShouldNotAppear();
QString labelForRange( double lower, double upper ) const /PyName=labelForLowerUpper/;
void setComposition( QgsComposition *c /KeepReference/ );
void removeProxyFactory( QNetworkProxyFactory *factory /TransferBack/ );
bool removeFunctionBody( const QList<int, QString> &list, QgsVectorLayer *vl, Some::Thing _part = -1 /*default =-1*/ );
void multilineBodyAndDefinition( const QList<int,
QString> &list,
QgsVectorLayer *vl,
Some::Thing _part = -1 /*default =-1*/ );
QgsRaster::RasterBuildPyramids buildPyramidsFlag() const;
%Docstring
Removing function body with namespaced return value
%End
virtual const QgsLayerMetadata &metadata() const;
%Docstring
Removing function body with virtual const reference
%End
bool myMultiLineBody();
%Docstring
Mulitline body
%End
virtual int overriddenProperty();
virtual int overrideWithoutVirtual();
virtual void overrideWithoutVirtualMultLine( const QList<int, QString> &list1,
const QList<int, QString> &list2 );
QString returnTypeString() const;
double returnTypeDouble() const;
QList< QgsAnnotation * > returnTypeList();
QVector< QgsAnnotation > returnTypeVector();
QStringList returnTypeStringList();
QSet<QgsActionScope> returnTypeSet();
This<Member> shouldBeIncluded;
static QString invokableMethod();
bool initializedMember;
struct PublicStruct
{
explicit PublicStruct( int _part = -1, int _ring = -1, int _vertex = -1, VertexType _type = SegmentVertex );
bool isValid( const QgsAbstractGeometry *geom ) const;
int part;
int ring;
int vertex;
VertexType type;
}
class PublicMembersWithValue
{
%TypeHeaderCode
#include "sipifyheader.h"
%End
public:
double snappedDistanceAlongCurve;
double snappedHeight;
};
void combinedAnnotations() /Factory,PyName=otherName/;
void multiAnnotationArg( SomeClass **object /Out,TransferBack/, int &another /Out/ );
void simple();
%Docstring
remove argument
%End
void method();
void test();
void avoidIntersections( const QList<QgsVectorLayer *> &avoidIntersectionsLayers );
void position();
void position( bool keep );
void position( bool keep, bool keep );
void position( bool keep );
void method( bool superArg = test );
void method( bool myArg1,
bool superArg2 = test, // hola
bool myArg3 );
static SIP_PYLIST changeReturnType( QVector<int> *resultTree = 0, QVector<double> &resultCost = 0 );
Whatever &operator[]( int i ) /Factory/;
%MethodCode
....
%End
void ZshouldBeShown();
void methodCodeWithMultiLineDef();
%MethodCode
if ( QgsWkbTypes::flatType( a0 ) != QgsWkbTypes::Point )
{
multiLineDef( PyExc_ValueError,
QString( "%1 is not nice" ).arg( QgsWkbTypes::displayString( a0 ) ).toUtf8().constData() );
}
else
{
sipCpp = new sipQgsPoint( a0, a1, a2, a3, a4 );
}
%End
protected:
bool thisShouldBeListed();
private:
void privateMethodSIPRUNareShown();
public:
void FallBackToPublic();
private:
void ShowThisPrivateOne();
};
class ClassWithPrivateInheritanceOnly /Abstract/
{
%Docstring(signature="appended")
Documentation goes here
%End
%TypeHeaderCode
#include "sipifyheader.h"
%End
public:
explicit ClassWithPrivateInheritanceOnly();
%Docstring
A constructor with definition in header on several lines
%End
};
class AbstractClass /Abstract/
{
%Docstring(signature="appended")
Documentation goes here
%End
%TypeHeaderCode
#include "sipifyheader.h"
%End
public:
explicit AbstractClass();
%Docstring
A constructor
%End
};
QFlags<QgsSipifyHeader::MyEnum> operator|(QgsSipifyHeader::MyEnum f1, QFlags<QgsSipifyHeader::MyEnum> f2);
typedef QgsTemplate<Something> QgsTemplateSomethingBase;
class TemplateInheritance1 : QgsTemplateSomethingBase
{
%TypeHeaderCode
#include "sipifyheader.h"
#include "qgstemplate.h"
typedef QgsTemplate<Something> QgsTemplateSomethingBase;
%End
}
class TemplateInheritance2
{
%TypeHeaderCode
#include "sipifyheader.h"
%End
}
typedef QgsTemplate<Something> QgsTemplateSomethingBase;
class TemplateInheritance3 : QgsTemplateSomethingBase, SomethingElse
{
%TypeHeaderCode
#include "sipifyheader.h"
#include "qgstemplate.h"
typedef QgsTemplate<Something> QgsTemplateSomethingBase;
%End
}
class TemplateInheritance4 : SomethingElse1, SomethingElse2
{
%TypeHeaderCode
#include "sipifyheader.h"
%End
}
class TemplateInheritance5 : SomethingElse
{
%TypeHeaderCode
#include "sipifyheader.h"
%End
}
typedef YourSuperTemplate<Abc,Def,Ghi> YourSuperTemplateAbcDefGhiBase;
class TemplateInheritance6 : SomethingElse, YourSuperTemplateAbcDefGhiBase
{
%TypeHeaderCode
#include "sipifyheader.h"
#include "yoursupertemplate.h"
typedef YourSuperTemplate<Abc,Def,Ghi> YourSuperTemplateAbcDefGhiBase;
%End
}
/************************************************************************
* This file has been generated automatically from *
* *
* tests/code_layout/sipify/sipifyheader.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -107,7 +107,7 @@ class CORE_EXPORT QgsSipifyHeader : public QtClass<QVariant>, private Ui::QgsBas
public:
//! This is an enum
enum MyEnum
enum MyEnum : int
{
Success = 0, //!< Edit operation was successful
NoSuccess = 1, //!< Edit operation resulted in an empty geometry

View File

@ -8,23 +8,27 @@ REV=$(git -C ${srcdir} log -n1 --pretty=%H)
pushd ${DIR} > /dev/null || exit
code=0
modules=(core gui analysis server)
for module in "${modules[@]}"; do
cp python/${module}/${module}_auto.sip python/${module}/${module}_auto.sip.$REV.bak
modules=(3d core gui analysis server)
for root_dir in python python/PyQt6; do
for module in "${modules[@]}"; do
cp $root_dir/${module}/${module}_auto.sip $root_dir/${module}/${module}_auto.sip.$REV.bak
done
done
./scripts/sip_include.sh
for module in "${modules[@]}"; do
outdiff=$(diff python/${module}/${module}_auto.sip python/${module}/${module}_auto.sip.$REV.bak)
if [[ -n $outdiff ]]; then
echo -e " *** SIP include file for \x1B[33m${module}\x1B[0m not up to date."
echo "$outdiff"
code=1
mv python/${module}/${module}_auto.sip.$REV.bak python/${module}/${module}_auto.sip
else
rm python/${module}/${module}_auto.sip.$REV.bak
fi
for root_dir in python python/PyQt6; do
for module in "${modules[@]}"; do
outdiff=$(diff $root_dir/${module}/${module}_auto.sip $root_dir/${module}/${module}_auto.sip.$REV.bak)
if [[ -n $outdiff ]]; then
echo -e " *** SIP include file for \x1B[33m${module}\x1B[0m not up to date."
echo "$outdiff"
code=1
mv $root_dir/${module}/${module}_auto.sip.$REV.bak $root_dir/${module}/${module}_auto.sip
else
rm $root_dir/${module}/${module}_auto.sip.$REV.bak
fi
done
done
if [[ code -eq 1 ]]; then

View File

@ -14,37 +14,43 @@ fi
pushd ${DIR} > /dev/null || exit
modules=(core gui analysis server)
modules=(3d core gui analysis server)
code=0
for module in "${modules[@]}"; do
while read -r sipfile; do
for root_dir in python python/PyQt6; do
if [[ $root_dir == "python/PyQt6" ]]; then
IS_QT6="--qt6"
fi
for module in "${modules[@]}"; do
while read -r sipfile; do
header=$(${GP}sed -E 's@(.*)\.sip@src/\1.h@; s@auto_generated/@@' <<< $sipfile)
pyfile=$(${GP}sed -E 's@([^\/]+\/)*([^\/]+)\.sip@\2.py@;' <<< $sipfile)
if [ ! -f $header ]; then
echo "*** Missing header: $header for sipfile $sipfile"
else
outdiff=$(./scripts/sipify.pl -p python/${module}/auto_additions/${pyfile}.temp $header | diff python/$sipfile.in -)
outdiff=$(./scripts/sipify.pl $IS_QT6 -p $root_dir/${module}/auto_additions/${pyfile}.temp $header | diff $root_dir/$sipfile.in -)
if [[ -n "$outdiff" ]]; then
echo " *** SIP file not up to date: $sipfile"
echo " *** SIP file not up to date: $root_dir/$sipfile"
echo " $outdiff "
code=1
fi
if [[ -f python/${module}/auto_additions/${pyfile}.temp ]]; then
outdiff2=$(diff python/${module}/auto_additions/${pyfile} python/${module}/auto_additions/${pyfile}.temp)
if [[ -f $root_dir/${module}/auto_additions/${pyfile}.temp ]]; then
outdiff2=$(diff $root_dir/${module}/auto_additions/${pyfile} $root_dir/${module}/auto_additions/${pyfile}.temp)
if [[ -n "$outdiff2" ]]; then
echo " *** Python addition file not up to date: $sipfile"
echo " *** Python addition file not up to date: $root_dir/$sipfile"
echo " $outdiff2 "
code=1
fi
fi
fi
done < <(
${GP}sed -n -r "s@^%Include auto_generated/(.*\.sip)@${module}/auto_generated/\1@p" python/${module}/${module}_auto.sip
)
done < <(
${GP}sed -n -r "s@^%Include auto_generated/(.*\.sip)@${module}/auto_generated/\1@p" $root_dir/${module}/${module}_auto.sip
)
done
done
popd > /dev/null || exit
exit $code

View File

@ -7,11 +7,19 @@ srcdir=$(dirname $0)/../../
DIR=$(git -C ${srcdir} rev-parse --show-toplevel)
pushd ${DIR} > /dev/null || exit
outdiff=$(./scripts/sipify.pl tests/code_layout/sipify/sipifyheader.h | diff tests/code_layout/sipify/sipifyheader.expected.sip -)
popd > /dev/null || exit
for pyqt_version in 5 6; do
if [[ $outdiff ]]; then
echo " *** sipify.pl did not output expected file"
echo "$outdiff"
exit 1
fi
if [[ $pyqt_version == 6 ]]; then
IS_QT6="--qt6"
fi
outdiff=$(./scripts/sipify.pl $IS_QT6 tests/code_layout/sipify/sipifyheader.h | diff tests/code_layout/sipify/sipifyheader.expected_pyqt$pyqt_version.sip -)
if [[ $outdiff ]]; then
echo " *** sipify.pl did not output expected file"
echo "$outdiff"
popd > /dev/null || exit
exit 1
fi
done
popd > /dev/null || exit