/************************************************************************
 * This file has been generated automatically from                      *
 *                                                                      *
 * src/core/qgsfeature.h                                                *
 *                                                                      *
 * Do not edit manually ! Edit header and run scripts/sipify.py again   *
 ************************************************************************/








class QgsFeature
{
%Docstring(signature="appended")
The feature class encapsulates a single feature including its unique ID,
geometry and a list of field/values attributes.

.. note::

   :py:class:`QgsFeature` objects are implicitly shared.
%End

%TypeHeaderCode
#include "qgsfeature.h"
#if (SIP_VERSION >= 0x040900 && SIP_VERSION < 0x040c01)
#define sipType_QVariant ((sipWrapperType *) sipTypeAsPyTypeObject (sipType_QVariant))
#endif
%End
  public:
    static const QMetaObject staticMetaObject;

  public:

    SIP_PYOBJECT __iter__() /HoldGIL/;
%MethodCode
    QgsAttributes attributes = sipCpp->attributes();
    PyObject *attrs = sipConvertFromType( &attributes, sipType_QgsAttributes, Py_None );
    sipRes = PyObject_GetIter( attrs );
    // PyObject_GetIter has added a ref to attrs - we need to decrement the ref from sipConvertFromType,
    // so that the garbage collector will delete attrs when the iterator is deleted
    Py_DECREF( attrs );
%End


    SIP_PYOBJECT __getitem__( int key ) /HoldGIL/;
%MethodCode
    if ( a0 < 0 || a0 >= sipCpp->attributeCount() )
    {
      PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
      sipIsErr = 1;
    }
    else
    {
      const QVariant v = sipCpp->attribute( a0 );
      // QByteArray null handling is "special"! See null_from_qvariant_converter in conversions.sip
      if ( QgsVariantUtils::isNull( v, true ) && v.userType() != QMetaType::Type::QByteArray )
      {
        Py_INCREF( Py_None );
        sipRes = Py_None;
      }
      else
      {
        switch ( v.userType() )
        {
          case QMetaType::Type::Int:
            sipRes = PyLong_FromLong( v.toInt() );
            break;

          case QMetaType::Type::UInt:
            sipRes = PyLong_FromUnsignedLong( v.toUInt() );
            break;

          case QMetaType::Type::Long:
          case QMetaType::Type::LongLong:
            sipRes = PyLong_FromLongLong( v.toLongLong() );
            break;

          case QMetaType::Type::ULong:
          case QMetaType::Type::ULongLong:
            sipRes = PyLong_FromUnsignedLongLong( v.toULongLong() );
            break;

          case QMetaType::Type::Bool:
            sipRes = PyBool_FromLong( v.toBool() ? 1 : 0 );
            break;

          case QMetaType::Type::Float:
          case QMetaType::Type::Double:
            sipRes = PyFloat_FromDouble( v.toDouble() );
            break;

          case QMetaType::Type::QString:
            sipRes = PyUnicode_FromString( v.toString().toUtf8().constData() );
            break;

          default:
          {
            QVariant *newV = new QVariant( v );
            sipRes = sipConvertFromNewType( newV, sipType_QVariant, Py_None );
            break;
          }
        }
      }
    }
%End

    SIP_PYOBJECT __getitem__( const QString &name ) /HoldGIL/;
%MethodCode
    int fieldIdx = sipCpp->fieldNameIndex( *a0 );
    if ( fieldIdx == -1 )
    {
      PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
      sipIsErr = 1;
    }
    else
    {
      const QVariant v = sipCpp->attribute( fieldIdx );
      // QByteArray null handling is "special"! See null_from_qvariant_converter in conversions.sip
      if ( QgsVariantUtils::isNull( v, true ) && v.userType() != QMetaType::Type::QByteArray )
      {
        Py_INCREF( Py_None );
        sipRes = Py_None;
      }
      else
      {
        switch ( v.userType() )
        {
          case QMetaType::Type::Int:
            sipRes = PyLong_FromLong( v.toInt() );
            break;

          case QMetaType::Type::UInt:
            sipRes = PyLong_FromUnsignedLong( v.toUInt() );
            break;

          case QMetaType::Type::Long:
          case QMetaType::Type::LongLong:
            sipRes = PyLong_FromLongLong( v.toLongLong() );
            break;

          case QMetaType::Type::ULong:
          case QMetaType::Type::ULongLong:
            sipRes = PyLong_FromUnsignedLongLong( v.toULongLong() );
            break;

          case QMetaType::Type::Bool:
            sipRes = PyBool_FromLong( v.toBool() ? 1 : 0 );
            break;

          case QMetaType::Type::Float:
          case QMetaType::Type::Double:
            sipRes = PyFloat_FromDouble( v.toDouble() );
            break;

          case QMetaType::Type::QString:
            sipRes = PyUnicode_FromString( v.toString().toUtf8().constData() );
            break;

          default:
          {
            QVariant *newV = new QVariant( v );
            sipRes = sipConvertFromNewType( newV, sipType_QVariant, Py_None );
            break;
          }
        }
      }
    }
%End

    void __setitem__( int key, SIP_PYOBJECT value /TypeHint="Optional[Union[bool, int, float, str, QVariant]]"/ ) /HoldGIL/;
%MethodCode
    bool rv;

    if ( a1 == Py_None )
    {
      rv = sipCpp->setAttribute( a0, QVariant( QVariant::Int ) );
    }
    else if ( PyBool_Check( a1 ) )
    {
      rv = sipCpp->setAttribute( a0, QVariant( PyObject_IsTrue( a1 ) == 1 ) );
    }
    else if ( PyLong_Check( a1 ) )
    {
      rv = sipCpp->setAttribute( a0, QVariant( PyLong_AsLongLong( a1 ) ) );
    }
    else if ( PyFloat_Check( a1 ) )
    {
      rv = sipCpp->setAttribute( a0, QVariant( PyFloat_AsDouble( a1 ) ) );
    }
    else if ( PyUnicode_Check( a1 ) )
    {
      rv = sipCpp->setAttribute( a0, QVariant( QString::fromUtf8( PyUnicode_AsUTF8( a1 ) ) ) );
    }
    else if ( sipCanConvertToType( a1, sipType_QVariant, SIP_NOT_NONE ) )
    {
      int state;
      QVariant *qvariant = reinterpret_cast<QVariant *>( sipConvertToType( a1, sipType_QVariant, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
      if ( sipIsErr )
      {
        rv = false;
      }
      else
      {
        rv = sipCpp->setAttribute( a0, *qvariant );
      }
      sipReleaseType( qvariant, sipType_QVariant, state );
    }
    else
    {
      rv = false;
    }

    if ( !rv )
    {
      PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
      sipIsErr = 1;
    }
%End

    void __setitem__( const QString &key, SIP_PYOBJECT value /TypeHint="Optional[Union[bool, int, float, str, QVariant]]"/ ) /HoldGIL/;
%MethodCode
    int fieldIdx = sipCpp->fieldNameIndex( *a0 );
    if ( fieldIdx == -1 )
    {
      PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
      sipIsErr = 1;
    }
    else
    {
      if ( a1 == Py_None )
      {
        sipCpp->setAttribute( fieldIdx, QVariant( QVariant::Int ) );
      }
      else if ( PyBool_Check( a1 ) )
      {
        sipCpp->setAttribute( fieldIdx, QVariant( PyObject_IsTrue( a1 ) == 1 ) );
      }
      else if ( PyLong_Check( a1 ) )
      {
        sipCpp->setAttribute( fieldIdx, QVariant( PyLong_AsLongLong( a1 ) ) );
      }
      else if ( PyFloat_Check( a1 ) )
      {
        sipCpp->setAttribute( fieldIdx, QVariant( PyFloat_AsDouble( a1 ) ) );
      }
      else if ( PyUnicode_Check( a1 ) )
      {
        sipCpp->setAttribute( fieldIdx, QVariant( QString::fromUtf8( PyUnicode_AsUTF8( a1 ) ) ) );
      }
      else if ( sipCanConvertToType( a1, sipType_QVariant, SIP_NOT_NONE ) )
      {
        int state;
        QVariant *qvariant = reinterpret_cast<QVariant *>( sipConvertToType( a1, sipType_QVariant, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
        if ( !sipIsErr )
        {
          sipCpp->setAttribute( fieldIdx, *qvariant );
        }
        sipReleaseType( qvariant, sipType_QVariant, state );
      }
      else
      {
        sipIsErr = 1;
      }
    }
%End

    void __delitem__( int key ) /HoldGIL/;
%MethodCode
    if ( a0 >= 0 && a0 < sipCpp->attributeCount() )
      sipCpp->deleteAttribute( a0 );
    else
    {
      PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
      sipIsErr = 1;
    }
%End

    void __delitem__( const QString &name ) /HoldGIL/;
%MethodCode
    int fieldIdx = sipCpp->fieldNameIndex( *a0 );
    if ( fieldIdx == -1 )
    {
      PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
      sipIsErr = 1;
    }
    else
      sipCpp->deleteAttribute( fieldIdx );
%End

    Py_hash_t __hash__() const /HoldGIL/;
%MethodCode
    sipRes = qHash( *sipCpp );
%End

    QgsFeature( qint64 id = FID_NULL ) /HoldGIL/;
%Docstring
Constructor for QgsFeature

:param id: unique feature ID
%End

    QgsFeature( const QgsFields &fields, qint64 id = FID_NULL ) /HoldGIL/;
%Docstring
Constructor for QgsFeature

:param fields: feature's fields
:param id: unique feature ID
%End

    QgsFeature( const QgsFeature &rhs ) /HoldGIL/;
    bool operator==( const QgsFeature &other ) const /HoldGIL/;
    bool operator!=( const QgsFeature &other ) const /HoldGIL/;

    virtual ~QgsFeature();

    QgsFeatureId id() const /HoldGIL/;
%Docstring
Returns the feature ID for this feature.

.. seealso:: :py:func:`setId`
%End

    void setId( QgsFeatureId id ) /HoldGIL/;
%Docstring
Sets the feature ``id`` for this feature.

:param id: feature id

.. seealso:: :py:func:`id`

.. warning::

   Feature IDs will be automatically changed whenever a feature is added to vector layer or data provider.
   This method is not designed to allow a specific feature ID to be assigned to a feature which will be added to a
   layer or data provider, and the results will be unpredictable
%End

    QgsAttributes attributes() const /HoldGIL/;
%Docstring
Returns the feature's attributes.

Alternatively, in Python it is possible to directly iterate over a
feature in order to retrieve its attributes:

.. code-block:: python

       feature = QgsFeature()
       feature.setAttributes([11, 'string value', 55.5])
       for attr in feature:
           print(attr)

.. seealso:: :py:func:`setAttributes`

.. seealso:: :py:func:`attributeMap`
%End


    SIP_PYOBJECT attributeMap() const /HoldGIL,TypeHint="Dict[str, Optional[object]]"/;
%Docstring
Returns the feature's attributes as a map of field name to value.

.. note::

   The fields definition must be associated with the feature using :py:func:`~QgsFeature.setFields` before this method can be used.

:raises ValueError: if the field definition is unset or the size of the
                    fields does not match the size of the feature's
                    attributes()

.. seealso:: :py:func:`attributes`

.. seealso:: :py:func:`setAttributes`

.. versionadded:: 3.22.2
%End
%MethodCode
    const int fieldSize = sipCpp->fields().size();
    const int attributeSize = sipCpp->attributeCount();
    if ( fieldSize == 0 && attributeSize != 0 )
    {
      PyErr_SetString( PyExc_ValueError, QStringLiteral( "Field definition has not been set for feature" ).toUtf8().constData() );
      sipIsErr = 1;
    }
    else if ( fieldSize != attributeSize )
    {
      PyErr_SetString( PyExc_ValueError, QStringLiteral( "Feature attribute size (%1) does not match number of fields (%2)" ).arg( attributeSize ).arg( fieldSize ).toUtf8().constData() );
      sipIsErr = 1;
    }
    else
    {
      QVariantMap *v = new QVariantMap( sipCpp->attributeMap() );
      const sipTypeDef *qvariantmap_type = sipFindType( "QMap<QString,QVariant>" );
      sipRes = sipConvertFromNewType( v, qvariantmap_type, Py_None );
    }
%End

    int attributeCount() const /HoldGIL/;
%Docstring
Returns the number of attributes attached to the feature.

.. versionadded:: 3.18
%End

    void setAttributes( const QgsAttributes &attrs ) /HoldGIL/;
%Docstring
Sets the feature's attributes.

Calling this method will automatically set the feature as valid (see
:py:func:`~QgsFeature.isValid`).

The number of provided attributes need to exactly match the number of
the feature's fields.

:param attrs: List of attribute values

.. warning::

   If the number of provided attributes does not exactly match
   the number of the feature's fields then it will not be possible to add this feature to the corresponding data
   provider.

.. seealso:: :py:func:`setAttribute`

.. seealso:: :py:func:`attributes`
%End


    bool setAttribute( int field, SIP_PYOBJECT attr /TypeHint="Optional[Union[bool, int, float, str, QVariant]]"/ ) /HoldGIL/;
%Docstring
Sets an attribute's value by field index.

If the attribute was successfully set then the feature will be
automatically marked as valid (see :py:func:`~QgsFeature.isValid`).

Alternatively, in Python it is possible to directly set a field's value
via the field's index:

.. code-block:: python

       fields = QgsFields()
       fields.append(QgsField('my_id', QVariant.Int))
       fields.append(QgsField('name', QVariant.String))
       feature = QgsFeature(fields)

       # set the "name" field value
       feature[1] = "my name"
       # set the "my_id" field value
       feature[0] = 55

:param field: the index of the field to set
:param attr: the value of the attribute

:raises KeyError: if the field index does not exist

.. seealso:: :py:func:`setAttributes`
%End
%MethodCode
    bool rv;

    if ( a1 == Py_None )
    {
      rv = sipCpp->setAttribute( a0, QVariant( QVariant::Int ) );
    }
    else if ( PyBool_Check( a1 ) )
    {
      rv = sipCpp->setAttribute( a0, QVariant( PyObject_IsTrue( a1 ) == 1 ) );
    }
    else if ( PyLong_Check( a1 ) )
    {
      rv = sipCpp->setAttribute( a0, QVariant( PyLong_AsLongLong( a1 ) ) );
    }
    else if ( PyFloat_Check( a1 ) )
    {
      rv = sipCpp->setAttribute( a0, QVariant( PyFloat_AsDouble( a1 ) ) );
    }
    else if ( PyUnicode_Check( a1 ) )
    {
      rv = sipCpp->setAttribute( a0, QVariant( QString::fromUtf8( PyUnicode_AsUTF8( a1 ) ) ) );
    }
    else if ( sipCanConvertToType( a1, sipType_QVariant, SIP_NOT_NONE ) )
    {
      int state;
      QVariant *qvariant = reinterpret_cast<QVariant *>( sipConvertToType( a1, sipType_QVariant, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
      if ( sipIsErr )
      {
        rv = false;
      }
      else
      {
        rv = sipCpp->setAttribute( a0, *qvariant );
      }
      sipReleaseType( qvariant, sipType_QVariant, state );
    }
    else
    {
      rv = false;
    }

    if ( !rv )
    {
      PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
      sipIsErr = 1;
    }

    sipRes = rv;
%End

    void initAttributes( int fieldCount ) /HoldGIL/;
%Docstring
Initialize this feature with the given number of fields.

Discards any previously set attribute data.

:param fieldCount: Number of fields to initialize

.. seealso:: :py:func:`resizeAttributes`
%End

    void resizeAttributes( int fieldCount ) /HoldGIL/;
%Docstring
Resizes the attributes attached to this feature to the given number of
fields.

If the new ``fieldCount`` is greater than the original number of fields
then the additional attributes will be filled with NULL values. All
existing attributes will remain unchanged.

If the new ``fieldCount`` is less than the original number of fields
then the unwanted values will be discarded from the end of the existing
attributes.

.. seealso:: :py:func:`initAttributes`

.. seealso:: :py:func:`padAttributes`

.. versionadded:: 3.18
%End

    void padAttributes( int count ) /HoldGIL/;
%Docstring
Resizes the attributes attached to this feature by appending the
specified ``count`` of NULL values to the end of the existing
attributes.

.. seealso:: :py:func:`resizeAttributes`

.. versionadded:: 3.18
%End


    void deleteAttribute( int field ) /HoldGIL/;
%Docstring
Clear's an attribute's value by its index.

:param field: the index of the field

Alternatively, in Python it is possible to directly `del` an attribute
via its index:

.. code-block:: python

       feature = QgsFeature()
       feature.setAttributes([11, 'my feature', 55.5])

       # will print [11, 'my feature', 55.5]
       print(feature.attributes())

       # clear the second attribute
       del feature[1]

       # will now print [11, NONE]
       print(feature.attributes())

:raises KeyError: if the field is not found

.. seealso:: :py:func:`setAttribute`
%End
%MethodCode
    if ( a0 >= 0 && a0 < sipCpp->attributeCount() )
      sipCpp->deleteAttribute( a0 );
    else
    {
      PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
      sipIsErr = 1;
    }
%End

    bool isValid() const /HoldGIL/;
%Docstring
Returns the validity of this feature.

This is normally set by the provider to indicate some problem that makes
the feature invalid or to indicate a null feature.

.. seealso:: :py:func:`setValid`
%End

    void setValid( bool validity ) /HoldGIL/;
%Docstring
Sets the validity of the feature.

:param validity: set to ``True`` if feature is valid

.. seealso:: :py:func:`isValid`
%End

    bool hasGeometry() const /HoldGIL/;
%Docstring
Returns ``True`` if the feature has an associated geometry.

.. seealso:: :py:func:`geometry`
%End

    QgsGeometry geometry() const /HoldGIL/;
%Docstring
Returns the geometry associated with this feature. If the feature has no
geometry, an empty :py:class:`QgsGeometry` object will be returned.

.. seealso:: :py:func:`hasGeometry`

.. seealso:: :py:func:`setGeometry`
%End

    void setGeometry( const QgsGeometry &geometry ) /HoldGIL/;
%Docstring
Set the feature's geometry.

Calling this method will automatically set the feature as valid (see
:py:func:`~QgsFeature.isValid`).

:param geometry: new feature geometry

.. seealso:: :py:func:`geometry`

.. seealso:: :py:func:`clearGeometry`
%End

    void setGeometry( QgsAbstractGeometry *geometry /Transfer/ ) /HoldGIL/;
%Docstring
Set the feature's ``geometry``.

Ownership of the geometry is transferred to the feature.

Calling this method will automatically set the feature as valid (see
:py:func:`~QgsFeature.isValid`).

This method is a shortcut for calling:

.. code-block:: python

       feature.setGeometry( QgsGeometry( geometry ) )

Example
-------------------------------------

.. code-block:: python

       # Sets a feature's geometry to a point geometry
       feature.setGeometry( QgsPoint( 210, 41 ) )
       print(feature.geometry())
       # output: <QgsGeometry: Point (210 41)>

       # Sets a feature's geometry to a line string
       feature.setGeometry( QgsLineString( [ QgsPoint( 210, 41 ), QgsPoint( 301, 55 ) ] ) )
       print(feature.geometry())
       # output: <QgsGeometry: LineString (210 41, 301 55)>

.. seealso:: :py:func:`geometry`

.. seealso:: :py:func:`clearGeometry`

.. versionadded:: 3.6
%End
%MethodCode
    sipCpp->setGeometry( std::unique_ptr< QgsAbstractGeometry>( a0 ) );
%End

    void clearGeometry() /HoldGIL/;
%Docstring
Removes any geometry associated with the feature.

.. seealso:: :py:func:`setGeometry`

.. seealso:: :py:func:`hasGeometry`
%End

    void setFields( const QgsFields &fields, bool initAttributes = true  ) /HoldGIL/;
%Docstring
Assigns a field map with the feature to allow attribute access by
attribute name.

:param fields: The attribute fields which this feature holds
:param initAttributes: If ``True``, attributes are initialized. Clears
                       any data previously assigned.

.. seealso:: :py:func:`fields`
%End

    QgsFields fields() const /HoldGIL/;
%Docstring
Returns the field map associated with the feature.

.. seealso:: :py:func:`setFields`
%End


    void setAttribute( const QString &name, SIP_PYOBJECT value /TypeHint="Optional[Union[bool, int, float, str, QVariant]]"/ ) /HoldGIL/;
%Docstring
Insert a value into attribute, by field ``name``.

Field map must be associated using :py:func:`~QgsFeature.setFields`
before this method can be used.

Calling this method will automatically set the feature as valid (see
:py:func:`~QgsFeature.isValid`).

Alternatively, in Python it is possible to directly set a field's value
via the field's name:

.. code-block:: python

       fields = QgsFields()
       fields.append(QgsField('my_id', QVariant.Int))
       fields.append(QgsField('name', QVariant.String))
       feature = QgsFeature(fields)

       # set the "name" field value
       feature['name'] = "my name"
       # set the "my_id" field value
       feature['my_id'] = 55

:param name: The name of the field to set
:param value: The value to set

:raises KeyError: if the attribute name could not could not be matched.

.. seealso:: :py:func:`setFields`
%End
%MethodCode
    int fieldIdx = sipCpp->fieldNameIndex( *a0 );
    if ( fieldIdx == -1 )
    {
      PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
      sipIsErr = 1;
    }
    else
    {
      if ( a1 == Py_None )
      {
        sipCpp->setAttribute( fieldIdx, QVariant( QVariant::Int ) );
      }
      else if ( PyBool_Check( a1 ) )
      {
        sipCpp->setAttribute( fieldIdx, QVariant( PyObject_IsTrue( a1 ) == 1 ) );
      }
      else if ( PyLong_Check( a1 ) )
      {
        sipCpp->setAttribute( fieldIdx, QVariant( PyLong_AsLongLong( a1 ) ) );
      }
      else if ( PyFloat_Check( a1 ) )
      {
        sipCpp->setAttribute( fieldIdx, QVariant( PyFloat_AsDouble( a1 ) ) );
      }
      else if ( PyUnicode_Check( a1 ) )
      {
        sipCpp->setAttribute( fieldIdx, QVariant( QString::fromUtf8( PyUnicode_AsUTF8( a1 ) ) ) );
      }
      else if ( sipCanConvertToType( a1, sipType_QVariant, SIP_NOT_NONE ) )
      {
        int state;
        QVariant *qvariant = reinterpret_cast<QVariant *>( sipConvertToType( a1, sipType_QVariant, 0, SIP_NOT_NONE, &state, &sipIsErr ) );
        if ( !sipIsErr )
        {
          sipCpp->setAttribute( fieldIdx, *qvariant );
        }
        sipReleaseType( qvariant, sipType_QVariant, state );
      }
      else
      {
        sipIsErr = 1;
      }
    }
%End


    bool deleteAttribute( const QString &name ) /HoldGIL/;
%Docstring
Clear's an attribute's value by its field ``name``.

Field map must be associated using :py:func:`~QgsFeature.setFields`
before this method can be used.

Alternatively, in Python it is possible to directly `del` an attribute
via its name:

.. code-block:: python

       fields = QgsFields()
       fields.append(QgsField('my_id', QVariant.Int))
       fields.append(QgsField('name', QVariant.String))

       feature = QgsFeature(fields)
       feature.setAttributes([11, 'my feature'])

       # will print [11, 'my feature']
       print(feature.attributes())

       # clear the 'name' attribute
       del feature['name']

       # will now print [11, NULL]
       print(feature.attributes())

:param name: The name of the field to clear

:raises KeyError: if attribute name could not be matched.

.. seealso:: :py:func:`setFields`
%End
%MethodCode
    int fieldIdx = sipCpp->fieldNameIndex( *a0 );
    if ( fieldIdx == -1 )
    {
      PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
      sipIsErr = 1;
      sipRes = false;
    }
    else
    {
      sipCpp->deleteAttribute( fieldIdx );
      sipRes = true;
    }
%End


    SIP_PYOBJECT attribute( const QString &name ) const /HoldGIL/;
%Docstring
Lookup attribute value by attribute ``name``.

Field map must be associated using :py:func:`~QgsFeature.setFields`
before this method can be used.

Alternatively, in Python it is possible to directly retrieve a field's
value via the field's name:

.. code-block:: python

       fields = QgsFields()
       fields.append(QgsField('my_id', QVariant.Int))
       fields.append(QgsField('name', QVariant.String))
       feature = QgsFeature(fields)
       feature.setAttributes([11, 'my feature'])

       # print the "name" field value
       print(feature['name'])
       # print the "my_id" field value
       print(feature['my_id'])

:param name: The name of the attribute to get

:return: The value of the attribute

:raises KeyError: if the field is not found

.. seealso:: :py:func:`setFields`
%End
%MethodCode
    int fieldIdx = sipCpp->fieldNameIndex( *a0 );
    if ( fieldIdx == -1 )
    {
      PyErr_SetString( PyExc_KeyError, a0->toLatin1() );
      sipIsErr = 1;
    }
    else
    {
      QVariant *v = new QVariant( sipCpp->attribute( fieldIdx ) );
      sipRes = sipConvertFromNewType( v, sipType_QVariant, Py_None );
    }
%End


    SIP_PYOBJECT attribute( int fieldIdx ) const /HoldGIL/;
%Docstring
Lookup attribute value from its index.

Alternatively, in Python it is possible to directly retrieve a field's
value via its index:

.. code-block:: python

       feature = QgsFeature()
       feature.setAttributes([11, 'my feature', 55.5])

       # will print 11
       print(feature[0])

       # will print 'my feature'
       print(feature[1])

       # will print 55.5
       print(feature[2])

:param fieldIdx: The index of the attribute to get

:return: The value of the attribute

:raises KeyError: if the field is not found

.. seealso:: :py:func:`setFields`
%End
%MethodCode
    {
      if ( a0 < 0 || a0 >= sipCpp->attributeCount() )
      {
        PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
        sipIsErr = 1;
      }
      else
      {
        QVariant *v = new QVariant( sipCpp->attribute( a0 ) );
        sipRes = sipConvertFromNewType( v, sipType_QVariant, Py_None );
      }
    }
%End



    bool isUnsetValue( int fieldIdx ) const /HoldGIL/;
%Docstring
Returns ``True`` if the attribute at the specified index is an unset
value.

:raises KeyError: if the field is not found

.. seealso:: :py:class:`QgsUnsetAttributeValue`

.. versionadded:: 3.28
%End
%MethodCode
    {
      if ( a0 < 0 || a0 >= sipCpp->attributeCount() )
      {
        PyErr_SetString( PyExc_KeyError, QByteArray::number( a0 ) );
        sipIsErr = 1;
      }
      else
      {
        sipRes = sipCpp->isUnsetValue( a0 );
      }
    }
%End

    const QgsSymbol *embeddedSymbol() const /HoldGIL/;
%Docstring
Returns the feature's embedded symbology, or ``None`` if the feature has
no embedded symbol.

.. versionadded:: 3.20
%End

    void setEmbeddedSymbol( QgsSymbol *symbol /Transfer/ ) /HoldGIL/;
%Docstring
Sets the feature's embedded ``symbol``.

Ownership of ``symbol`` is transferred to the feature.

.. versionadded:: 3.20
%End

    int fieldNameIndex( const QString &fieldName ) const /HoldGIL/;
%Docstring
Utility method to get attribute index from name.

Field map must be associated using :py:func:`~QgsFeature.setFields`
before this method can be used.

:param fieldName: name of field to get attribute index of

:return: - 1 if field does not exist or field map is not associated.

.. seealso:: :py:func:`setFields`
%End

    int approximateMemoryUsage() const;
%Docstring
Returns the approximate RAM usage of the feature, in bytes.

This method takes into account the size of variable elements (strings,
geometry, ...), but the value returned should be considered as a lower
bound estimation.

.. versionadded:: 3.16
%End

    operator QVariant() const;

}; // class QgsFeature


typedef QMap<qint64, QMap<int, QVariant> > QgsChangedAttributesMap;


typedef QMap<qint64, QgsGeometry> QgsGeometryMap;

typedef QList<QgsFeature> QgsFeatureList;



/************************************************************************
 * This file has been generated automatically from                      *
 *                                                                      *
 * src/core/qgsfeature.h                                                *
 *                                                                      *
 * Do not edit manually ! Edit header and run scripts/sipify.py again   *
 ************************************************************************/
