# Wspólne struktury obiektów

Istnieje duża liczba struktur, które są używane przy definiowaniu rodzajów obiektów w Pythonie. Ten rozdział opisuje te struktury i jak są one używane.

## Base object types and macros

All Python objects ultimately share a small number of fields at the beginning of the object’s representation in memory. These are represented by the `PyObject` and `PyVarObject` types, which are defined, in turn, by the expansions of some macros also used, whether directly or indirectly, in the definition of all other Python objects.

`PyObject`

  All object types are extensions of this type. This is a type which contains the information Python needs to treat a pointer to an object as an object. In a normal „release” build, it contains only the object’s reference count and a pointer to the corresponding type object. Nothing is actually declared to be a `PyObject`, but every pointer to a Python object can be cast to a `PyObject*`. Access to the members must be done by using the macros `Py_REFCNT` and `Py_TYPE`.

`PyVarObject`

  This is an extension of `PyObject` that adds the `ob_size` field. This is only used for objects that have some notion of length. This type does not often appear in the Python/C API. Access to the members must be done by using the macros `Py_REFCNT`, `Py_TYPE`, and `Py_SIZE`.

`PyObject_HEAD`

  This is a macro used when declaring new types which represent objects without a varying length. The PyObject_HEAD macro expands to:

      PyObject ob_base;

  See documentation of `PyObject` above.

`PyObject_VAR_HEAD`

  This is a macro used when declaring new types which represent objects with a length that varies from instance to instance. The PyObject_VAR_HEAD macro expands to:

      PyVarObject ob_base;

  See documentation of `PyVarObject` above.

`Py_TYPE`(o)

  This macro is used to access the `ob_type` member of a Python object. It expands to:

      (((PyObject*)(o))->ob_type)

int `Py_IS_TYPE`(PyObject *o, PyTypeObject *type)

  Return non-zero if the object o type is type. Return zero otherwise. Equivalent to: `Py_TYPE(o) == type`.

  Nowe w wersji 3.9.

void `Py_SET_TYPE`(PyObject *o, PyTypeObject *type)

  Set the object o type to type.

  Nowe w wersji 3.9.

`Py_REFCNT`(o)

  This macro is used to access the `ob_refcnt` member of a Python object. It expands to:

      (((PyObject*)(o))->ob_refcnt)

void `Py_SET_REFCNT`(PyObject *o, Py_ssize_t refcnt)

  Set the object o reference counter to refcnt.

  Nowe w wersji 3.9.

`Py_SIZE`(o)

  This macro is used to access the `ob_size` member of a Python object. It expands to:

      (((PyVarObject*)(o))->ob_size)

void `Py_SET_SIZE`(PyVarObject *o, Py_ssize_t size)

  Set the object o size to size.

  Nowe w wersji 3.9.

`PyObject_HEAD_INIT`(type)

  This is a macro which expands to initialization values for a new `PyObject` type. This macro expands to:

      _PyObject_EXTRA_INIT
      1, type,

`PyVarObject_HEAD_INIT`(type, size)

  This is a macro which expands to initialization values for a new `PyVarObject` type, including the `ob_size` field. This macro expands to:

      _PyObject_EXTRA_INIT
      1, type, size,

## Implementing functions and methods

`PyCFunction`

  Type of the functions used to implement most Python callables in C. Functions of this type take two `PyObject*` parameters and return one such value. If the return value is `NULL`, an exception shall have been set. If not `NULL`, the return value is interpreted as the return value of the function as exposed in Python. The function must return a new reference.

  The function signature is:

      PyObject *PyCFunction(PyObject *self,
                            PyObject *args);

`PyCFunctionWithKeywords`

  Type of the functions used to implement Python callables in C with signature `METH_VARARGS | METH_KEYWORDS`. The function signature is:

      PyObject *PyCFunctionWithKeywords(PyObject *self,
                                        PyObject *args,
                                        PyObject *kwargs);

`_PyCFunctionFast`

  Type of the functions used to implement Python callables in C with signature `METH_FASTCALL`. The function signature is:

      PyObject *_PyCFunctionFast(PyObject *self,
                                 PyObject *const *args,
                                 Py_ssize_t nargs);

`_PyCFunctionFastWithKeywords`

  Type of the functions used to implement Python callables in C with signature `METH_FASTCALL | METH_KEYWORDS`. The function signature is:

      PyObject *_PyCFunctionFastWithKeywords(PyObject *self,
                                             PyObject *const *args,
                                             Py_ssize_t nargs,
                                             PyObject *kwnames);

`PyCMethod`

  Type of the functions used to implement Python callables in C with signature `METH_METHOD | METH_FASTCALL | METH_KEYWORDS`. The function signature is:

      PyObject *PyCMethod(PyObject *self,
                          PyTypeObject *defining_class,
                          PyObject *const *args,
                          Py_ssize_t nargs,
                          PyObject *kwnames)

  Nowe w wersji 3.9.

`PyMethodDef`

  Structure used to describe a method of an extension type. This structure has four fields:

  Field | typ języka C | Znaczenie
  --- | --- | ---
  `ml_name` | const char * | name of the method
  `ml_meth` | PyCFunction | pointer to the C implementation
  `ml_flags` | int | flag bits indicating how the call should be constructed
  `ml_doc` | const char * | points to the contents of the docstring

The `ml_meth` is a C function pointer. The functions may be of different types, but they always return `PyObject*`. If the function is not of the `PyCFunction`, the compiler will require a cast in the method table. Even though `PyCFunction` defines the first parameter as `PyObject*`, it is common that the method implementation uses the specific C type of the self object.

The `ml_flags` field is a bitfield which can include the following flags. The individual flags indicate either a calling convention or a binding convention.

There are these calling conventions:

`METH_VARARGS`

  This is the typical calling convention, where the methods have the type `PyCFunction`. The function expects two `PyObject*` values. The first one is the self object for methods; for module functions, it is the module object. The second parameter (often called args) is a tuple object representing all arguments. This parameter is typically processed using `PyArg_ParseTuple()` or `PyArg_UnpackTuple()`.

`METH_VARARGS | METH_KEYWORDS`

  Methods with these flags must be of type `PyCFunctionWithKeywords`. The function expects three parameters: self, args, kwargs where kwargs is a dictionary of all the keyword arguments or possibly `NULL` if there are no keyword arguments. The parameters are typically processed using `PyArg_ParseTupleAndKeywords()`.

`METH_FASTCALL`

  Fast calling convention supporting only positional arguments. The methods have the type `_PyCFunctionFast`. The first parameter is self, the second parameter is a C array of `PyObject*` values indicating the arguments and the third parameter is the number of arguments (the length of the array).

  This is not part of the limited API.

  Nowe w wersji 3.7.

`METH_FASTCALL | METH_KEYWORDS`

  Extension of `METH_FASTCALL` supporting also keyword arguments, with methods of type `_PyCFunctionFastWithKeywords`. Keyword arguments are passed the same way as in the vectorcall protocol: there is an additional fourth `PyObject*` parameter which is a tuple representing the names of the keyword arguments (which are guaranteed to be strings) or possibly `NULL` if there are no keywords. The values of the keyword arguments are stored in the args array, after the positional arguments.

  This is not part of the limited API.

  Nowe w wersji 3.7.

`METH_METHOD | METH_FASTCALL | METH_KEYWORDS`

  Extension of `METH_FASTCALL | METH_KEYWORDS` supporting the defining class, that is, the class that contains the method in question. The defining class might be a superclass of `Py_TYPE(self)`.

  The method needs to be of type `PyCMethod`, the same as for `METH_FASTCALL | METH_KEYWORDS` with `defining_class` argument added after `self`.

  Nowe w wersji 3.9.

`METH_NOARGS`

  Methods without parameters don’t need to check whether arguments are given if they are listed with the `METH_NOARGS` flag. They need to be of type `PyCFunction`. The first parameter is typically named self and will hold a reference to the module or object instance. In all cases the second parameter will be `NULL`.

`METH_O`

  Methods with a single object argument can be listed with the `METH_O` flag, instead of invoking `PyArg_ParseTuple()` with a `"O"` argument. They have the type `PyCFunction`, with the self parameter, and a `PyObject*` parameter representing the single argument.

Te dwie stałe nie są używane do zaznaczania konwencji wywoływania, ale wiążą gdy są używane z metodami klas. Nie mogą być one używane dla funkcji określonych dla modułów. Co najwyżej jedna z tych flag może być ustawiona dla dowolnej danej metody.

`METH_CLASS`

  Metodzie zostanie przekazany typ obiektu jako pierwszy parametr zamiast instancji tego typu. Jest to używane aby tworzyć metody klasowe, podobnie do tego, co jest tworzone przy użyciu wbudowanej funkcji `classmethod()`.

`METH_STATIC`

  The method will be passed `NULL` as the first parameter rather than an instance of the type. This is used to create static methods, similar to what is created when using the `staticmethod()` built-in function.

Jedna pozostała stała kontroluje czy metoda jest ładowana w miejscu innej definicji o tej samej nazwie metody.

`METH_COEXIST`

  Metoda zostanie załadowana w miejsce istniejących definicji. Bez METH_COEXIST, domyślnie pomija się powtórzone definicje. Od kiedy opakowania gniazd są ładowane przed tabelą metod, istnienie na przykład gniazda sq_contains generuje opakowaną metodę nazywaną `__contains__()` i zapobiega ładowaniu odpowiadającej funkcji PyCFunction o tej samej nazwie. Ze zdefiniowaną flagą, PyCFunction zostanie załadowana w miejsce obiektu opakowania i będzie współistniała z gniazdem. To jest pomocne ponieważ wywołania PyCFunction są zoptymalizowane bardziej niż odwołania do obiektów opakowań.

## Accessing attributes of extension types

`PyMemberDef`

  Structure which describes an attribute of a type which corresponds to a C struct member. Its fields are:

  Field | typ języka C | Znaczenie
  --- | --- | ---
  `name` | const char * | name of the member
  `type` | int | the type of the member in the C struct
  `offset` | Py_ssize_t | the offset in bytes that the member is located on the type’s object struct
  `flags` | int | flag bits indicating if the field should be read-only or writable
  `doc` | const char * | points to the contents of the docstring

  `type` can be one of many `T_` macros corresponding to various C types. When the member is accessed in Python, it will be converted to the equivalent Python type.

  Macro name | C type
  --- | ---
  T_SHORT | short
  T_INT | int
  T_LONG | long
  T_FLOAT | typ (float) zmiennoprzecinkowy pojedynczej precyzji
  T_DOUBLE | typ (double) zmiennoprzecinkowy podwójnej precyzji
  T_STRING | const char *
  T_OBJECT | PyObject *
  T_OBJECT_EX | PyObject *
  T_CHAR | char
  T_BYTE | char
  T_UBYTE | nieoznaczony typ znakowy
  T_UINT | nieoznaczony typ int
  T_USHORT | nieoznaczony typ krótki
  T_ULONG | nieoznaczony typ długi
  T_BOOL | char
  T_LONGLONG | long long
  T_ULONGLONG | unsigned long long
  T_PYSSIZET | Py_ssize_t

  `T_OBJECT` and `T_OBJECT_EX` differ in that `T_OBJECT` returns `None` if the member is `NULL` and `T_OBJECT_EX` raises an `AttributeError`. Try to use `T_OBJECT_EX` over `T_OBJECT` because `T_OBJECT_EX` handles use of the `del` statement on that attribute more correctly than `T_OBJECT`.

  `flags` can be `0` for write and read access or `READONLY` for read-only access. Using `T_STRING` for `type` implies `READONLY`. `T_STRING` data is interpreted as UTF-8. Only `T_OBJECT` and `T_OBJECT_EX` members can be deleted. (They are set to `NULL`).

  Heap allocated types (created using `PyType_FromSpec()` or similar), `PyMemberDef` may contain definitions for the special members `__dictoffset__`, `__weaklistoffset__` and `__vectorcalloffset__`, corresponding to `tp_dictoffset`, `tp_weaklistoffset` and `tp_vectorcall_offset` in type objects. These must be defined with `T_PYSSIZET` and `READONLY`, for example:

      static PyMemberDef spam_type_members[] = {
          {"__dictoffset__", T_PYSSIZET, offsetof(Spam_object, dict), READONLY},
          {NULL}  /* Sentinel */
      };

PyObject* `PyMember_GetOne`(const char *obj_addr, struct PyMemberDef *m)

  Get an attribute belonging to the object at address obj_addr. The attribute is described by `PyMemberDef` m. Returns `NULL` on error.

int `PyMember_SetOne`(char *obj_addr, struct PyMemberDef *m, PyObject *o)

  Set an attribute belonging to the object at address obj_addr to object o. The attribute to set is described by `PyMemberDef` m. Returns `0` if successful and a negative value on failure.

`PyGetSetDef`

  Structure to define property-like access for a type. See also description of the `PyTypeObject.tp_getset` slot.

  Field | typ języka C | Znaczenie
  --- | --- | ---
  name | const char * | attribute name
  get | getter | C Function to get the attribute
  set | setter | optional C function to set or delete the attribute, if omitted the attribute is readonly
  doc | const char * | optional docstring
  closure | void * | optional function pointer, providing additional data for getter and setter

  The `get` function takes one `PyObject*` parameter (the instance) and a function pointer (the associated `closure`):

      typedef PyObject *(*getter)(PyObject *, void *);

  It should return a new reference on success or `NULL` with a set exception on failure.

  `set` functions take two `PyObject*` parameters (the instance and the value to be set) and a function pointer (the associated `closure`):

      typedef int (*setter)(PyObject *, PyObject *, void *);

  In case the attribute should be deleted the second parameter is `NULL`. Should return `0` on success or `-1` with a set exception on failure.