From 03baeea083bfc038c28aa6e5d47788ad0f5c2dd6 Mon Sep 17 00:00:00 2001 From: "Juergen E. Fischer" Date: Sun, 27 Oct 2019 13:29:02 +0100 Subject: [PATCH] fix python constructor for QgsPoint (does not accept QgsPointXY & QPointF anymore) fixes #32443 --- .../auto_generated/geometry/qgspoint.sip.in | 82 +++++++++---------- src/core/geometry/qgspoint.h | 80 +++++++++--------- src/providers/wfs/CMakeLists.txt | 1 - tests/src/python/test_qgseditformconfig.py | 2 +- tests/src/python/test_qgspoint.py | 36 +++++++- 5 files changed, 115 insertions(+), 86 deletions(-) diff --git a/python/core/auto_generated/geometry/qgspoint.sip.in b/python/core/auto_generated/geometry/qgspoint.sip.in index 2ad36159d42..3a4d336a5fc 100644 --- a/python/core/auto_generated/geometry/qgspoint.sip.in +++ b/python/core/auto_generated/geometry/qgspoint.sip.in @@ -26,7 +26,7 @@ Point geometry type, with support for z-dimension and m-values. public: - QgsPoint( SIP_PYOBJECT x = Py_None, SIP_PYOBJECT y = Py_None, SIP_PYOBJECT z = Py_None, SIP_PYOBJECT m = Py_None, QgsWkbTypes::Type wkbType = QgsWkbTypes::Unknown ) [( double x = 0.0, double y = 0.0, double z = 0.0, double m = 0.0, QgsWkbTypes::Type wkbType = QgsWkbTypes::Unknown )]; + QgsPoint( SIP_PYOBJECT x = Py_None, SIP_PYOBJECT y = Py_None, SIP_PYOBJECT z = Py_None, SIP_PYOBJECT m = Py_None, SIP_PYOBJECT wkbType = Py_None ) [( double x = 0.0, double y = 0.0, double z = 0.0, double m = 0.0, QgsWkbTypes::Type wkbType = QgsWkbTypes::Unknown )]; %Docstring Construct a point with the provided initial coordinate values. @@ -53,59 +53,53 @@ based on the following rules: pt.wkbType() # QgsWkbTypes.PointZ %End %MethodCode - double x; - double y; - double z; - double m; + if ( sipCanConvertToType( a0, sipType_QgsPointXY, SIP_NOT_NONE ) && a1 == Py_None && a2 == Py_None && a3 == Py_None && a4 == Py_None ) + { + int state; + int sipIsErr = 0; - if ( a0 == Py_None ) - { - x = std::numeric_limits::quiet_NaN(); + QgsPointXY *p = reinterpret_cast( sipConvertToType( a0, sipType_QgsPointXY, 0, SIP_NOT_NONE, &state, &sipIsErr ) ); + if ( sipIsErr ) + { + sipReleaseType( p, sipType_QgsPointXY, state ); + } + else + { + sipCpp = new sipQgsPoint( QgsPoint( *p ) ); + } } - else + else if ( sipCanConvertToType( a0, sipType_QPointF, SIP_NOT_NONE ) && a1 == Py_None && a2 == Py_None && a3 == Py_None && a4 == Py_None ) { - x = PyFloat_AsDouble( a0 ); - } + int state; + int sipIsErr = 0; - if ( a1 == Py_None ) - { - y = std::numeric_limits::quiet_NaN(); + QPointF *p = reinterpret_cast( sipConvertToType( a0, sipType_QPointF, 0, SIP_NOT_NONE, &state, &sipIsErr ) ); + if ( sipIsErr ) + { + sipReleaseType( p, sipType_QPointF, state ); + } + else + { + sipCpp = new sipQgsPoint( QgsPoint( *p ) ); + } } - else + else if ( + ( a0 == Py_None || PyFloat_AsDouble( a0 ) != -1.0 || !PyErr_Occurred() ) && + ( a1 == Py_None || PyFloat_AsDouble( a1 ) != -1.0 || !PyErr_Occurred() ) && + ( a2 == Py_None || PyFloat_AsDouble( a2 ) != -1.0 || !PyErr_Occurred() ) && + ( a3 == Py_None || PyFloat_AsDouble( a3 ) != -1.0 || !PyErr_Occurred() ) && + ( a4 == Py_None || sipCanConvertToEnum( a4, sipType_QgsWkbTypes_Type ) ) ) { - y = PyFloat_AsDouble( a1 ); + double x = a0 == Py_None ? std::numeric_limits::quiet_NaN() : PyFloat_AsDouble( a0 ); + double y = a1 == Py_None ? std::numeric_limits::quiet_NaN() : PyFloat_AsDouble( a1 ); + double z = a2 == Py_None ? std::numeric_limits::quiet_NaN() : PyFloat_AsDouble( a2 ); + double m = a3 == Py_None ? std::numeric_limits::quiet_NaN() : PyFloat_AsDouble( a3 ); + QgsWkbTypes::Type wkbType = a4 == Py_None ? QgsWkbTypes::Unknown : static_cast( sipConvertToEnum( a4, sipType_QgsWkbTypes_Type ) ); + sipCpp = new sipQgsPoint( QgsPoint( x, y, z, m, wkbType ) ); } - - if ( a2 == Py_None ) - { - z = std::numeric_limits::quiet_NaN(); - } - else - { - z = PyFloat_AsDouble( a2 ); - } - - if ( a3 == Py_None ) - { - m = std::numeric_limits::quiet_NaN(); - } - else - { - m = PyFloat_AsDouble( a3 ); - } - - sipCpp = new sipQgsPoint( x, y, z, m, a4 ); %End - explicit QgsPoint( const QgsPointXY &p ); -%Docstring -Construct a QgsPoint from a QgsPointXY object -%End - explicit QgsPoint( QPointF p ); -%Docstring -Construct a QgsPoint from a QPointF -%End virtual bool operator==( const QgsAbstractGeometry &other ) const; diff --git a/src/core/geometry/qgspoint.h b/src/core/geometry/qgspoint.h index 8579b3bfec5..9dd7d2013a8 100644 --- a/src/core/geometry/qgspoint.h +++ b/src/core/geometry/qgspoint.h @@ -32,7 +32,7 @@ /** * \ingroup core * \brief Point geometry type, with support for z-dimension and m-values. - * \since QGIS 3.0, (previously QgsPointv2 since QGIS 2.10) + * \since QGIS 3.0, (previously QgsPointV2 since QGIS 2.10) */ class CORE_EXPORT QgsPoint: public QgsAbstractGeometry { @@ -73,62 +73,64 @@ class CORE_EXPORT QgsPoint: public QgsAbstractGeometry #ifndef SIP_RUN QgsPoint( double x = std::numeric_limits::quiet_NaN(), double y = std::numeric_limits::quiet_NaN(), double z = std::numeric_limits::quiet_NaN(), double m = std::numeric_limits::quiet_NaN(), QgsWkbTypes::Type wkbType = QgsWkbTypes::Unknown ); #else - QgsPoint( SIP_PYOBJECT x = Py_None, SIP_PYOBJECT y = Py_None, SIP_PYOBJECT z = Py_None, SIP_PYOBJECT m = Py_None, QgsWkbTypes::Type wkbType = QgsWkbTypes::Unknown ) [( double x = 0.0, double y = 0.0, double z = 0.0, double m = 0.0, QgsWkbTypes::Type wkbType = QgsWkbTypes::Unknown )]; + QgsPoint( SIP_PYOBJECT x = Py_None, SIP_PYOBJECT y = Py_None, SIP_PYOBJECT z = Py_None, SIP_PYOBJECT m = Py_None, SIP_PYOBJECT wkbType = Py_None ) [( double x = 0.0, double y = 0.0, double z = 0.0, double m = 0.0, QgsWkbTypes::Type wkbType = QgsWkbTypes::Unknown )]; % MethodCode - double x; - double y; - double z; - double m; + if ( sipCanConvertToType( a0, sipType_QgsPointXY, SIP_NOT_NONE ) && a1 == Py_None && a2 == Py_None && a3 == Py_None && a4 == Py_None ) + { + int state; + int sipIsErr = 0; - if ( a0 == Py_None ) - { - x = std::numeric_limits::quiet_NaN(); + QgsPointXY *p = reinterpret_cast( sipConvertToType( a0, sipType_QgsPointXY, 0, SIP_NOT_NONE, &state, &sipIsErr ) ); + if ( sipIsErr ) + { + sipReleaseType( p, sipType_QgsPointXY, state ); + } + else + { + sipCpp = new sipQgsPoint( QgsPoint( *p ) ); + } } - else + else if ( sipCanConvertToType( a0, sipType_QPointF, SIP_NOT_NONE ) && a1 == Py_None && a2 == Py_None && a3 == Py_None && a4 == Py_None ) { - x = PyFloat_AsDouble( a0 ); - } + int state; + int sipIsErr = 0; - if ( a1 == Py_None ) - { - y = std::numeric_limits::quiet_NaN(); + QPointF *p = reinterpret_cast( sipConvertToType( a0, sipType_QPointF, 0, SIP_NOT_NONE, &state, &sipIsErr ) ); + if ( sipIsErr ) + { + sipReleaseType( p, sipType_QPointF, state ); + } + else + { + sipCpp = new sipQgsPoint( QgsPoint( *p ) ); + } } - else + else if ( + ( a0 == Py_None || PyFloat_AsDouble( a0 ) != -1.0 || !PyErr_Occurred() ) && + ( a1 == Py_None || PyFloat_AsDouble( a1 ) != -1.0 || !PyErr_Occurred() ) && + ( a2 == Py_None || PyFloat_AsDouble( a2 ) != -1.0 || !PyErr_Occurred() ) && + ( a3 == Py_None || PyFloat_AsDouble( a3 ) != -1.0 || !PyErr_Occurred() ) && + ( a4 == Py_None || sipCanConvertToEnum( a4, sipType_QgsWkbTypes_Type ) ) ) { - y = PyFloat_AsDouble( a1 ); + double x = a0 == Py_None ? std::numeric_limits::quiet_NaN() : PyFloat_AsDouble( a0 ); + double y = a1 == Py_None ? std::numeric_limits::quiet_NaN() : PyFloat_AsDouble( a1 ); + double z = a2 == Py_None ? std::numeric_limits::quiet_NaN() : PyFloat_AsDouble( a2 ); + double m = a3 == Py_None ? std::numeric_limits::quiet_NaN() : PyFloat_AsDouble( a3 ); + QgsWkbTypes::Type wkbType = a4 == Py_None ? QgsWkbTypes::Unknown : static_cast( sipConvertToEnum( a4, sipType_QgsWkbTypes_Type ) ); + sipCpp = new sipQgsPoint( QgsPoint( x, y, z, m, wkbType ) ); } - - if ( a2 == Py_None ) - { - z = std::numeric_limits::quiet_NaN(); - } - else - { - z = PyFloat_AsDouble( a2 ); - } - - if ( a3 == Py_None ) - { - m = std::numeric_limits::quiet_NaN(); - } - else - { - m = PyFloat_AsDouble( a3 ); - } - - sipCpp = new sipQgsPoint( x, y, z, m, a4 ); % End #endif /** * Construct a QgsPoint from a QgsPointXY object */ - explicit QgsPoint( const QgsPointXY &p ); + explicit QgsPoint( const QgsPointXY &p ) SIP_SKIP; /** * Construct a QgsPoint from a QPointF */ - explicit QgsPoint( QPointF p ); + explicit QgsPoint( QPointF p ) SIP_SKIP; /** * Create a new point with the given wkbtype and values. diff --git a/src/providers/wfs/CMakeLists.txt b/src/providers/wfs/CMakeLists.txt index 063d1d3bf55..67c667d38e1 100644 --- a/src/providers/wfs/CMakeLists.txt +++ b/src/providers/wfs/CMakeLists.txt @@ -39,7 +39,6 @@ SET (WFS_MOC_HDRS qgswfsdescribefeaturetype.h qgswfstransactionrequest.h qgswfsshareddata.h - qgswfsutils.h qgsbackgroundcachedfeatureiterator.h qgscachedirectorymanager.h qgsoapiflandingpagerequest.h diff --git a/tests/src/python/test_qgseditformconfig.py b/tests/src/python/test_qgseditformconfig.py index a6835f566d1..f13e7a5ba64 100644 --- a/tests/src/python/test_qgseditformconfig.py +++ b/tests/src/python/test_qgseditformconfig.py @@ -106,7 +106,7 @@ class TestQgsEditFormConfig(unittest.TestCase): app.processEvents() self.assertEqual(content.status(), QgsFetchedContent.Finished) - # Failing on Travis, seg faut in event loop, no idea why + # Failing on Travis, seg fault in event loop, no idea why """ @unittest.expectedFailure def testFormPy(self): diff --git a/tests/src/python/test_qgspoint.py b/tests/src/python/test_qgspoint.py index d8fcd9b0884..ba844e982c3 100644 --- a/tests/src/python/test_qgspoint.py +++ b/tests/src/python/test_qgspoint.py @@ -12,7 +12,8 @@ __copyright__ = 'Copyright 2012, The QGIS Project' import qgis # NOQA -from qgis.core import QgsPointXY +from qgis.core import QgsPointXY, QgsPoint, QgsWkbTypes +from qgis.PyQt.QtCore import QPointF from qgis.testing import start_app, unittest @@ -52,6 +53,39 @@ class TestQgsPointXY(unittest.TestCase): mySet = set([a, b, c, d, e]) assert len(mySet) == 4 + def test_issue_32443(self): + p = QgsPoint() + assert p.wkbType() == QgsWkbTypes.Point and p.x() != p.x() and p.y() != p.y() + + # ctor from QgsPointXY should be available + p = QgsPoint(QgsPointXY(1, 2)) + assert p.wkbType() == QgsWkbTypes.Point and p.x() == 1 and p.y() == 2 + + # ctor from QPointF should be available + p = QgsPoint(QPointF(1, 2)) + assert p.wkbType() == QgsWkbTypes.Point and p.x() == 1 and p.y() == 2 + + p = QgsPoint(1, 2) + assert p.wkbType() == QgsWkbTypes.Point and p.x() == 1 and p.y() == 2 + + p = QgsPoint(1, 2, 3) + assert p.wkbType() == QgsWkbTypes.PointZ and p.x() == 1 and p.y() == 2 and p.z() == 3 + + p = QgsPoint(1, 2, z=3) + assert p.wkbType() == QgsWkbTypes.PointZ and p.x() == 1 and p.y() == 2 and p.z() == 3 + + p = QgsPoint(1, 2, m=3) + assert p.wkbType() == QgsWkbTypes.PointM and p.x() == 1 and p.y() == 2 and p.m() == 3 + + p = QgsPoint(1, 2, wkbType=QgsWkbTypes.PointM) + assert p.wkbType() == QgsWkbTypes.PointM and p.x() == 1 and p.y() == 2 and p.m() != p.m() + + p = QgsPoint(1, 2, 3, 4) + assert p.wkbType() == QgsWkbTypes.PointZM and p.x() == 1 and p.y() == 2 and p.z() == 3 and p.m() == 4 + + p = QgsPoint(1, 2, m=4, z=3) + assert p.wkbType() == QgsWkbTypes.PointZM and p.x() == 1 and p.y() == 2 and p.z() == 3 and p.m() == 4 + if __name__ == '__main__': unittest.main()