Introducción
************

La interfaz del programador de aplicaciones (API) con Python brinda a
los programadores de C y C++ acceso al intérprete de Python en una
variedad de niveles. La API es igualmente utilizable desde C++, pero
por brevedad generalmente se conoce como la API Python/C. Hay dos
razones fundamentalmente diferentes para usar la API Python/C. La
primera razón es escribir *módulos de extensión* para propósitos
específicos; Estos son módulos C que extienden el intérprete de
Python. Este es probablemente el uso más común. La segunda razón es
usar Python como componente en una aplicación más grande; Esta técnica
se conoce generalmente como integración (*embedding*) Python en una
aplicación.

Escribir un módulo de extensión es un proceso relativamente bien
entendido, donde un enfoque de "libro de cocina" (*cookbook*) funciona
bien. Hay varias herramientas que automatizan el proceso hasta cierto
punto. Si bien las personas han integrado Python en otras aplicaciones
desde su existencia temprana, el proceso de integrar Python es menos
sencillo que escribir una extensión.

Muchas funciones API son útiles independientemente de si está
integrando o extendiendo Python; Además, la mayoría de las
aplicaciones que integran Python también necesitarán proporcionar una
extensión personalizada, por lo que probablemente sea una buena idea
familiarizarse con la escritura de una extensión antes de intentar
integrar Python en una aplicación real.


Estándares de codificación
==========================

Si está escribiendo código C para su inclusión en CPython, **debe**
seguir las pautas y estándares definidos en **PEP 7**. Estas pautas se
aplican independientemente de la versión de Python a la que esté
contribuyendo. Seguir estas convenciones no es necesario para sus
propios módulos de extensión de terceros, a menos que eventualmente
espere contribuir con ellos a Python.


Archivos de cabecera (*Include*)
================================

Todas las definiciones de función, tipo y macro necesarias para usar
la API Python/C se incluyen en su código mediante la siguiente línea:

   #define PY_SSIZE_T_CLEAN
   #include <Python.h>

Esto implica la inclusión de los siguientes archivos de encabezado
estándar: "<stdio.h>", "<string.h>", "<errno.h>", "<limits.h>",
"<assert.h>" y "<stdlib.h>" (si está disponible).

Nota:

  Dado que Python puede definir algunas definiciones de preprocesador
  que afectan los encabezados estándar en algunos sistemas, *debe*
  incluir "Python.h" antes de incluir encabezados estándar.Se
  recomienda definir siempre "PY_SSIZE_T_CLEAN" antes de incluir
  "Python.h". Consulte Analizando argumentos y construyendo valores
  para obtener una descripción de este macro.

Todos los nombres visibles del usuario definidos por "Python.h"
(excepto los definidos por los encabezados estándar incluidos) tienen
uno de los prefijos "Py" o "_Py". Los nombres que comienzan con "_Py"
son para uso interno de la implementación de Python y no deben ser
utilizados por escritores de extensiones. Los nombres de miembros de
estructura no tienen un prefijo reservado.

Nota:

  El código de usuario nunca debe definir nombres que comiencen con
  "Py" o "_Py". Esto confunde al lector y pone en peligro la
  portabilidad del código de usuario para futuras versiones de Python,
  que pueden definir nombres adicionales que comienzan con uno de
  estos prefijos.

Los archivos de encabezado generalmente se instalan con Python. En
Unix, estos se encuentran en los directorios
"*prefix*/include/pythonversion/" y
"*exec_prefix*/include/pythonversion/", donde "prefix" y "exec_prefix"
están definidos por los parámetros correspondientes al programa de
Python **configure** y *version* es "'%d.%d' % sys.version_info[:2]".
En Windows, los encabezados se instalan en "*prefix*/include", donde
"prefix" es el directorio de instalación especificado para el
instalador.

Para incluir los encabezados, coloque ambos directorios (si son
diferentes) en la ruta de búsqueda de su compilador para incluir. *No*
coloque los directorios principales en la ruta de búsqueda y luego use
"#include <pythonX.Y/Python.h>"; esto se romperá en las compilaciones
multiplataforma ya que los encabezados independientes de la plataforma
bajo "prefix" incluyen los encabezados específicos de la plataforma de
"exec_prefix".

Los usuarios de C++ deben tener en cuenta que aunque la API se define
completamente usando C, los archivos de encabezado declaran
correctamente que los puntos de entrada son "extern "C"". Como
resultado, no es necesario hacer nada especial para usar la API desde
C++.


Macros útiles
=============

Varias macros útiles se definen en los archivos de encabezado de
Python. Muchos se definen más cerca de donde son útiles (por ejemplo
"Py_RETURN_NONE"). Otros de una utilidad más general se definen aquí.
Esto no es necesariamente una lista completa.

Py_UNREACHABLE()

   Use esto cuando tenga una ruta de código a la que no se pueda
   acceder por diseño. Por ejemplo, en la cláusula "default:" en una
   declaración "switch" para la cual todos los valores posibles están
   cubiertos en declaraciones "case". Use esto en lugares donde podría
   tener la tentación de poner una llamada "assert(0)" o "abort()".

   En el modo de lanzamiento, la macro ayuda al compilador a optimizar
   el código y evita una advertencia sobre el código inalcanzable. Por
   ejemplo, la macro se implementa con "__builtin_unreachable()" en
   GCC en modo de lanzamiento.

   Un uso de "Py_UNREACHABLE()" es seguir una llamada a una función
   que nunca retorna pero que no está declarada "_Py_NO_RETURN".

   Si una ruta de código es un código muy poco probable pero se puede
   acceder en casos excepcionales, esta macro no debe utilizarse. Por
   ejemplo, en condiciones de poca memoria o si una llamada al sistema
   retorna un valor fuera del rango esperado. En este caso, es mejor
   informar el error a la persona que llama. Si no se puede informar
   del error a la persona que llama, se puede utilizar
   "Py_FatalError()".

   Nuevo en la versión 3.7.

Py_ABS(x)

   Retorna el valor absoluto de "x".

   Nuevo en la versión 3.3.

Py_MIN(x, y)

   Retorna el valor mínimo entre "x" e "y".

   Nuevo en la versión 3.3.

Py_MAX(x, y)

   Retorna el valor máximo entre "x" e "y".

   Nuevo en la versión 3.3.

Py_STRINGIFY(x)

   Convierte "x" en una cadena de caracteres C. Por ejemplo,
   "Py_STRINGIFY(123)" retorna ""123"".

   Nuevo en la versión 3.4.

Py_MEMBER_SIZE(type, member)

   Retorna el tamaño de una estructura ("type") "member" en bytes.

   Nuevo en la versión 3.6.

Py_CHARMASK(c)

   El argumento debe ser un carácter o un número entero en el rango
   [-128, 127] o [0, 255]. Este macro retorna la conversión "c" a un
   "unsigned char".

Py_GETENV(s)

   Al igual que "getenv(s)", pero retorna "NULL" si: la opción "-E" se
   pasó en la línea de comando (es decir, si se establece
   "Py_IgnoreEnvironmentFlag").

Py_UNUSED(arg)

   Use esto para argumentos no utilizados en una definición de función
   para silenciar las advertencias del compilador. Ejemplo: "int
   func(int a, int Py_UNUSED(b)) {return a; }".

   Nuevo en la versión 3.4.

Py_DEPRECATED(version)

   Use esto para declaraciones obsoletas. El macro debe colocarse
   antes del nombre del símbolo.

   Ejemplo:

      Py_DEPRECATED(3.8) PyAPI_FUNC(int) Py_OldFunction(void);

   Distinto en la versión 3.8: Soporte para MSVC fue agregado.

PyDoc_STRVAR(name, str)

   Crea una variable con el nombre "name" que se puede usar en
   *docstrings*. Si Python se construye sin *docstrings*, el valor
   estará vacío.

   Utilice "PyDoc_STRVAR" para que los *docstrings* admitan la
   construcción de Python sin *docstrings*, como se especifica en
   **PEP 7**.

   Ejemplo:

      PyDoc_STRVAR(pop_doc, "Remove and return the rightmost element.");

      static PyMethodDef deque_methods[] = {
          // ...
          {"pop", (PyCFunction)deque_pop, METH_NOARGS, pop_doc},
          // ...
      }

PyDoc_STR(str)

   Crea un *docstring* para la cadena de caracteres de entrada dada o
   una cadena vacía si los *docstrings* están deshabilitados.

   Utilice "PyDoc_STR" al especificar *docstrings* para admitir la
   construcción de Python sin *docstrings*, como se especifica en
   **PEP 7**.

   Ejemplo:

      static PyMethodDef pysqlite_row_methods[] = {
          {"keys", (PyCFunction)pysqlite_row_keys, METH_NOARGS,
              PyDoc_STR("Returns the keys of the row.")},
          {NULL, NULL}
      };


Objetos, tipos y conteos de referencias
=======================================

La mayoría de las funciones de Python/C API tienen uno o más
argumentos, así como un valor de retorno de tipo "PyObject*". Este
tipo es un puntero a un tipo de datos opaco que representa un objeto
arbitrario de Python. Dado que todos los tipos de objetos Python son
tratados de la misma manera por el lenguaje Python en la mayoría de
las situaciones (por ejemplo, asignaciones, reglas de alcance y paso
de argumentos), es apropiado que estén representados por un solo tipo
C. Casi todos los objetos de Python viven en el montículo (*heap*):
nunca declaras una variable automática o estática de tipo "PyObject",
solo se pueden declarar variables de puntero de tipo "PyObject*". La
única excepción son los objetos tipo; como nunca deben desasignarse,
son típicamente objetos estáticos "PyTypeObject".

Todos los objetos de Python (incluso los enteros de Python) tienen un
tipo (*type*) y un conteo de referencia (*reference count*). El tipo
de un objeto determina qué tipo de objeto es (por ejemplo, un número
entero, una lista o una función definida por el usuario; hay muchos
más como se explica en Jerarquía de tipos estándar). Para cada uno de
los tipos conocidos hay un macro para verificar si un objeto es de ese
tipo; por ejemplo, "PyList_Check(a)" es verdadero si (y solo si) el
objeto al que apunta *a* es una lista de Python.


Conteo de Referencias
---------------------

El conteo de referencia es importante porque las computadoras de hoy
tienen un tamaño de memoria finito (y a menudo muy limitado); cuenta
cuántos lugares diferentes hay los cuales tienen una referencia a un
objeto. Tal lugar podría ser otro objeto, o una variable C global (o
estática), o una variable local en alguna función C. Cuando el
recuento de referencia de un objeto se convierte en cero, el objeto se
desasigna. Si contiene referencias a otros objetos, su recuento de
referencias se reduce. Esos otros objetos pueden ser desasignados a su
vez, si esta disminución hace que su recuento de referencia sea cero,
y así sucesivamente. (Hay un problema obvio con los objetos que se
refieren entre sí aquí; por ahora, la solución es "no hagas eso").

Los conteos de referencias siempre se manipulan explícitamente. La
forma normal es usar el macro "Py_INCREF()" para incrementar el conteo
de referencia de un objeto en uno, y "Py_DECREF()" para disminuirlo en
uno. El macro "Py_DECREF()" es considerablemente más compleja que la
*incref*, ya que debe verificar si el recuento de referencia se
convierte en cero y luego hacer que se llame al desasignador
(*deallocator*) del objeto. El desasignador es un puntero de función
contenido en la estructura de tipo del objeto. El desasignador
específico del tipo se encarga de disminuir los recuentos de
referencia para otros objetos contenidos en el objeto si este es un
tipo de objeto compuesto, como una lista, así como realizar cualquier
finalización adicional que sea necesaria. No hay posibilidad de que el
conteo de referencia se desborde; se utilizan al menos tantos bits
para contener el recuento de referencia como ubicaciones de memoria
distintas en la memoria virtual (suponiendo "sizeof(Py_ssize_t) >=
sizeof(void*)"). Por lo tanto, el incremento del recuento de
referencia es una operación simple.

No es necesario incrementar el conteo de referencia de un objeto para
cada variable local que contiene un puntero a un objeto. En teoría, el
conteo de referencia del objeto aumenta en uno cuando se hace que la
variable apunte hacia él y disminuye en uno cuando la variable se sale
del alcance. Sin embargo, estos dos se cancelan entre sí, por lo que
al final el recuento de referencias no ha cambiado. La única razón
real para usar el recuento de referencia es evitar que el objeto
pierda su asignación mientras nuestra variable lo apunte. Si sabemos
que hay al menos otra referencia al objeto que vive al menos tanto
como nuestra variable, no hay necesidad de incrementar el recuento de
referencias temporalmente. Una situación importante donde esto surge
es en los objetos que se pasan como argumentos a las funciones de C en
un módulo de extensión que se llama desde Python; El mecanismo de
llamada garantiza mantener una referencia a cada argumento durante la
duración de la llamada.

Sin embargo, una trampa común es extraer un objeto de una lista y
mantenerlo por un tiempo sin incrementar su conteo de referencia. Es
posible que alguna otra operación elimine el objeto de la lista,
disminuya su conteo de referencias y posiblemente lo desasigne. El
peligro real es que las operaciones de aspecto inocente pueden invocar
código arbitrario de Python que podría hacer esto; hay una ruta de
código que permite que el control vuelva al usuario desde a
"Py_DECREF()", por lo que casi cualquier operación es potencialmente
peligrosa.

Un enfoque seguro es utilizar siempre las operaciones genéricas
(funciones cuyo nombre comienza con "PyObject_", "PyNumber_",
"PySequence_" o "PyMapping_"). Estas operaciones siempre incrementan
el recuento de referencia del objeto que retornan. Esto deja a la
persona que llama con la responsabilidad de llamar "Py_DECREF()"
cuando hayan terminado con el resultado; Esto pronto se convierte en
una segunda naturaleza.


Detalles del conteo de referencia
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

El comportamiento del conteo de referencias de funciones en la API de
Python/C se explica mejor en términos de *propiedad de las
referencias*. La propiedad pertenece a referencias, nunca a objetos
(los objetos no son propiedad: siempre se comparten). "Poseer una
referencia" significa ser responsable de llamar a "Py_DECREF" cuando
ya no se necesita la referencia. La propiedad también se puede
transferir, lo que significa que el código que recibe la propiedad de
la referencia se hace responsable de eventualmente decretarla llamando
a "Py_DECREF()" o "Py_XDECREF()" cuando ya no es necesario --- o
transmitir esta responsabilidad (generalmente a la persona que llama).
Cuando una función transfiere la propiedad de una referencia a su
llamador, se dice que el que llama recibe una *nueva* referencia.
Cuando no se transfiere ninguna propiedad, se dice que la persona que
llama *toma prestada* la referencia. No es necesario hacer nada para
obtener una referencia prestada.

Por el contrario, cuando una función de llamada pasa una referencia a
un objeto, hay dos posibilidades: la función *roba* una referencia al
objeto, o no lo hace. *Robar una referencia* significa que cuando pasa
una referencia a una función, esa función asume que ahora posee esa
referencia, y usted ya no es responsable de ella.

Pocas funciones roban referencias; las dos excepciones notables son
"PyList_SetItem()" y "PyTuple_SetItem()", que roban una referencia al
elemento (¡pero no a la tupla o lista en la que se coloca el
elemento!). Estas funciones fueron diseñadas para robar una referencia
debido a un idioma común para poblar una tupla o lista con objetos
recién creados; por ejemplo, el código para crear la tupla "(1, 2,
"tres")" podría verse así (olvidando el manejo de errores por el
momento; una mejor manera de codificar esto se muestra a
continuación):

   PyObject *t;

   t = PyTuple_New(3);
   PyTuple_SetItem(t, 0, PyLong_FromLong(1L));
   PyTuple_SetItem(t, 1, PyLong_FromLong(2L));
   PyTuple_SetItem(t, 2, PyUnicode_FromString("three"));

Aquí "PyLong_FromLong()" retorna una nueva referencia que es
inmediatamente robada por "PyTuple_SetItem()". Cuando quiera seguir
usando un objeto aunque se le robe la referencia, use "Py_INCREF()"
para tomar otra referencia antes de llamar a la función de robo de
referencias.

Por cierto, "PyTuple_SetItem()" es la *única* forma de establecer
elementos de tupla; "PySequence_SetItem()" y "PyObject_SetItem()" se
niegan a hacer esto ya que las tuplas son un tipo de datos inmutable.
Solo debe usar "PyTuple_SetItem()" para las tuplas que está creando
usted mismo.

El código equivalente para llenar una lista se puede escribir usando
"PyList_New()" y "PyList_SetItem()".

Sin embargo, en la práctica, rara vez utilizará estas formas de crear
y completar una tupla o lista. Hay una función genérica,
"Py_BuildValue()", que puede crear los objetos más comunes a partir de
valores C, dirigidos por un una cadena de caracteres de formato
(*format string*). Por ejemplo, los dos bloques de código anteriores
podrían reemplazarse por lo siguiente (que también se ocupa de la
comprobación de errores):

   PyObject *tuple, *list;

   tuple = Py_BuildValue("(iis)", 1, 2, "three");
   list = Py_BuildValue("[iis]", 1, 2, "three");

Es mucho más común usar "PyObject_SetItem()" y amigos con elementos
cuyas referencias solo está prestando, como argumentos que se pasaron
a la función que está escribiendo. En ese caso, su comportamiento con
respecto a los recuentos de referencias es mucho más sensato, ya que
no tiene que incrementar un recuento de referencias para poder regalar
una referencia ("robarla"). Por ejemplo, esta función establece todos
los elementos de una lista (en realidad, cualquier secuencia mutable)
en un elemento dado:

   int
   set_all(PyObject *target, PyObject *item)
   {
       Py_ssize_t i, n;

       n = PyObject_Length(target);
       if (n < 0)
           return -1;
       for (i = 0; i < n; i++) {
           PyObject *index = PyLong_FromSsize_t(i);
           if (!index)
               return -1;
           if (PyObject_SetItem(target, index, item) < 0) {
               Py_DECREF(index);
               return -1;
           }
           Py_DECREF(index);
       }
       return 0;
   }

La situación es ligeramente diferente para los valores de retorno de
la función. Si bien pasar una referencia a la mayoría de las funciones
no cambia sus responsabilidades de propiedad para esa referencia,
muchas funciones que retornan una referencia a un objeto le otorgan la
propiedad de la referencia. La razón es simple: en muchos casos, el
objeto retornado se crea sobre la marcha, y la referencia que obtiene
es la única referencia al objeto. Por lo tanto, las funciones
genéricas que retornan referencias de objeto, como
"PyObject_GetItem()" y "PySequence_GetItem()", siempre retornan una
nueva referencia (la entidad que llama se convierte en el propietario
de la referencia).

Es importante darse cuenta de que si posee una referencia retornada
por una función depende de a qué función llame únicamente --- *el
plumaje* (el tipo del objeto pasado como argumento a la función) *no
entra en él!* Por lo tanto, si extrae un elemento de una lista usando
"PyList_GetItem()", no posee la referencia --- pero si obtiene el
mismo elemento de la misma lista usando "PySequence_GetItem()" (que
toma exactamente los mismos argumentos), usted posee una referencia al
objeto retornado.

Aquí hay un ejemplo de cómo podría escribir una función que calcule la
suma de los elementos en una lista de enteros; una vez usando
"PyList_GetItem()", y una vez usando "PySequence_GetItem()".

   long
   sum_list(PyObject *list)
   {
       Py_ssize_t i, n;
       long total = 0, value;
       PyObject *item;

       n = PyList_Size(list);
       if (n < 0)
           return -1; /* Not a list */
       for (i = 0; i < n; i++) {
           item = PyList_GetItem(list, i); /* Can't fail */
           if (!PyLong_Check(item)) continue; /* Skip non-integers */
           value = PyLong_AsLong(item);
           if (value == -1 && PyErr_Occurred())
               /* Integer too big to fit in a C long, bail out */
               return -1;
           total += value;
       }
       return total;
   }

   long
   sum_sequence(PyObject *sequence)
   {
       Py_ssize_t i, n;
       long total = 0, value;
       PyObject *item;
       n = PySequence_Length(sequence);
       if (n < 0)
           return -1; /* Has no length */
       for (i = 0; i < n; i++) {
           item = PySequence_GetItem(sequence, i);
           if (item == NULL)
               return -1; /* Not a sequence, or other failure */
           if (PyLong_Check(item)) {
               value = PyLong_AsLong(item);
               Py_DECREF(item);
               if (value == -1 && PyErr_Occurred())
                   /* Integer too big to fit in a C long, bail out */
                   return -1;
               total += value;
           }
           else {
               Py_DECREF(item); /* Discard reference ownership */
           }
       }
       return total;
   }


Tipos
-----

Hay algunos otros tipos de datos que juegan un papel importante en la
API de Python/C; la mayoría son tipos C simples como "int", "long",
"double" y "char*". Algunos tipos de estructura se usan para describir
tablas estáticas que se usan para enumerar las funciones exportadas
por un módulo o los atributos de datos de un nuevo tipo de objeto, y
otro se usa para describir el valor de un número complejo. Estos serán
discutidos junto con las funciones que los usan.

Py_ssize_t

   A signed integral type such that "sizeof(Py_ssize_t) ==
   sizeof(size_t)". C99 doesn't define such a thing directly (size_t
   is an unsigned integral type). See **PEP 353** for details.
   "PY_SSIZE_T_MAX" is the largest positive value of type
   "Py_ssize_t".


Excepciones
===========

El programador de Python solo necesita lidiar con excepciones si se
requiere un manejo específico de errores; las excepciones no manejadas
se propagan automáticamente a la persona que llama, luego a la persona
que llama, y así sucesivamente, hasta que llegan al intérprete de
nivel superior, donde se informan al usuario acompañado de un
seguimiento de pila (*stack traceback*).

Para los programadores de C, sin embargo, la comprobación de errores
siempre tiene que ser explícita. Todas las funciones en la API
Python/C pueden generar excepciones, a menos que se señale
explícitamente en la documentación de una función. En general, cuando
una función encuentra un error, establece una excepción, descarta
cualquier referencia de objeto que posea y retorna un indicador de
error. Si no se documenta lo contrario, este indicador es "NULL" o
"-1", dependiendo del tipo de retorno de la función. Algunas funciones
retornan un resultado booleano verdadero/falso, con falso que indica
un error. Muy pocas funciones no retornan ningún indicador de error
explícito o tienen un valor de retorno ambiguo, y requieren pruebas
explícitas de errores con "PyErr_Occurred()". Estas excepciones
siempre se documentan explícitamente.

El estado de excepción se mantiene en el almacenamiento por subproceso
(esto es equivalente a usar el almacenamiento global en una aplicación
sin subprocesos). Un subproceso puede estar en uno de dos estados: se
ha producido una excepción o no. La función "PyErr_Occurred()" puede
usarse para verificar esto: retorna una referencia prestada al objeto
de tipo de excepción cuando se produce una excepción, y "NULL" de lo
contrario. Hay una serie de funciones para establecer el estado de
excepción: "PyErr_SetString()" es la función más común (aunque no la
más general) para establecer el estado de excepción, y "PyErr_Clear()"
borra la excepción estado.

El estado de excepción completo consta de tres objetos (todos los
cuales pueden ser "NULL"): el tipo de excepción, el valor de excepción
correspondiente y el rastreo. Estos tienen los mismos significados que
el resultado de Python de "sys.exc_info()"; sin embargo, no son lo
mismo: los objetos Python representan la última excepción manejada por
una declaración de Python "try" ... "except", mientras que el estado
de excepción de nivel C solo existe mientras se está pasando una
excepción entre las funciones de C hasta que llega al bucle principal
del intérprete de código de bytes (*bytecode*) de Python, que se
encarga de transferirlo a "sys.exc_info()" y amigos.

Tenga en cuenta que a partir de Python 1.5, la forma preferida y
segura de subprocesos para acceder al estado de excepción desde el
código de Python es llamar a la función "sys.exc_info()", que retorna
el estado de excepción por subproceso para el código de Python.
Además, la semántica de ambas formas de acceder al estado de excepción
ha cambiado de modo que una función que detecta una excepción guardará
y restaurará el estado de excepción de su hilo para preservar el
estado de excepción de su llamador. Esto evita errores comunes en el
código de manejo de excepciones causado por una función de aspecto
inocente que sobrescribe la excepción que se maneja; También reduce la
extensión de vida útil a menudo no deseada para los objetos a los que
hacen referencia los marcos de pila en el rastreo.

Como principio general, una función que llama a otra función para
realizar alguna tarea debe verificar si la función llamada generó una
excepción y, de ser así, pasar el estado de excepción a quien la llama
(*caller*). Debe descartar cualquier referencia de objeto que posea y
retornar un indicador de error, pero *no* debe establecer otra
excepción --- que sobrescribirá la excepción que se acaba de generar y
perderá información importante sobre la causa exacta del error.

Un ejemplo simple de detectar excepciones y pasarlas se muestra en el
ejemplo "sum_sequence()" anterior. Sucede que este ejemplo no necesita
limpiar ninguna referencia de propiedad cuando detecta un error. La
siguiente función de ejemplo muestra algunos errores de limpieza.
Primero, para recordar por qué le gusta Python, le mostramos el código
Python equivalente:

   def incr_item(dict, key):
       try:
           item = dict[key]
       except KeyError:
           item = 0
       dict[key] = item + 1

Aquí está el código C correspondiente, en todo su esplendor:

   int
   incr_item(PyObject *dict, PyObject *key)
   {
       /* Objects all initialized to NULL for Py_XDECREF */
       PyObject *item = NULL, *const_one = NULL, *incremented_item = NULL;
       int rv = -1; /* Return value initialized to -1 (failure) */

       item = PyObject_GetItem(dict, key);
       if (item == NULL) {
           /* Handle KeyError only: */
           if (!PyErr_ExceptionMatches(PyExc_KeyError))
               goto error;

           /* Clear the error and use zero: */
           PyErr_Clear();
           item = PyLong_FromLong(0L);
           if (item == NULL)
               goto error;
       }
       const_one = PyLong_FromLong(1L);
       if (const_one == NULL)
           goto error;

       incremented_item = PyNumber_Add(item, const_one);
       if (incremented_item == NULL)
           goto error;

       if (PyObject_SetItem(dict, key, incremented_item) < 0)
           goto error;
       rv = 0; /* Success */
       /* Continue with cleanup code */

    error:
       /* Cleanup code, shared by success and failure path */

       /* Use Py_XDECREF() to ignore NULL references */
       Py_XDECREF(item);
       Py_XDECREF(const_one);
       Py_XDECREF(incremented_item);

       return rv; /* -1 for error, 0 for success */
   }

Este ejemplo representa un uso aprobado de la declaración "goto" en C!
Ilustra el uso de "PyErr_ExceptionMatches()" y "PyErr_Clear()" para
manejar excepciones específicas, y el uso de "Py_XDECREF()" para
eliminar referencias propias que pueden ser "NULL" (tenga en cuenta la
"'X'"' en el nombre; "Py_DECREF()" se bloqueará cuando se enfrente con
una referencia "NULL"). Es importante que las variables utilizadas
para contener referencias propias se inicialicen en "NULL" para que
esto funcione; Del mismo modo, el valor de retorno propuesto se
inicializa a "-1" (falla) y solo se establece en éxito después de que
la última llamada realizada sea exitosa.


Integración de Python
=====================

La única tarea importante de la que solo tienen que preocuparse los
integradores (a diferencia de los escritores de extensión) del
intérprete de Python es la inicialización, y posiblemente la
finalización, del intérprete de Python. La mayor parte de la
funcionalidad del intérprete solo se puede usar después de que el
intérprete se haya inicializado.

La función básica de inicialización es "Py_Initialize()". Esto
inicializa la tabla de módulos cargados y crea los módulos
fundamentales "builtins", "__main__", y "sys". También inicializa la
ruta de búsqueda del módulo ("sys.path").

"Py_Initialize()" no establece la "lista de argumentos de script"
("sys.argv"). Si el código de Python necesita esta variable que se
ejecutará más adelante, debe establecerse explícitamente con una
llamada a "PySys_SetArgvEx(argc, argv, updatepath)" después de la
llamada a "Py_Initialize()".

En la mayoría de los sistemas (en particular, en Unix y Windows,
aunque los detalles son ligeramente diferentes), "Py_Initialize()"
calcula la ruta de búsqueda del módulo basándose en su mejor
estimación de la ubicación del ejecutable del intérprete de Python
estándar, suponiendo que la biblioteca de Python se encuentra en una
ubicación fija en relación con el ejecutable del intérprete de Python.
En particular, busca un directorio llamado "lib/python*X.Y*" relativo
al directorio padre donde se encuentra el ejecutable llamado "python"
en la ruta de búsqueda del comando *shell* (la variable de entorno
"PATH").

Por ejemplo, si el ejecutable de Python se encuentra en
"/usr/local/bin/python", se supondrá que las bibliotecas están en
"/usr/local/lib/python*X.Y*". (De hecho, esta ruta particular también
es la ubicación "alternativa", utilizada cuando no se encuentra un
archivo ejecutable llamado "python" junto con "PATH".) El usuario
puede anular este comportamiento configurando la variable de entorno
"PYTHONHOME", o inserte directorios adicionales delante de la ruta
estándar estableciendo "PYTHONPATH".

La aplicación de integración puede dirigir la búsqueda llamando a
"Py_SetProgramName(file)" *antes* llamando "Py_Initialize()". Tenga en
cuenta que "PYTHONHOME" todavía anula esto y "PYTHONPATH" todavía se
inserta frente a la ruta estándar. Una aplicación que requiere un
control total debe proporcionar su propia implementación de
"Py_GetPath()", "Py_GetPrefix()", "Py_GetExecPrefix()", y
"Py_GetProgramFullPath()" (todo definido en "Modules/getpath.c").

A veces, es deseable "no inicializar" Python. Por ejemplo, la
aplicación puede querer comenzar de nuevo (hacer otra llamada a
"Py_Initialize()") o la aplicación simplemente se hace con el uso de
Python y quiere liberar memoria asignada por Python. Esto se puede
lograr llamando a "Py_FinalizeEx()". La función "Py_IsInitialized()"
retorna verdadero si Python se encuentra actualmente en el estado
inicializado. Se proporciona más información sobre estas funciones en
un capítulo posterior. Tenga en cuenta que "Py_FinalizeEx()" *no*
libera toda la memoria asignada por el intérprete de Python, por
ejemplo, la memoria asignada por los módulos de extensión actualmente
no se puede liberar.


Depuración de compilaciones
===========================

Python se puede construir con varios macros para permitir
verificaciones adicionales del intérprete y los módulos de extensión.
Estas comprobaciones tienden a agregar una gran cantidad de sobrecarga
al tiempo de ejecución, por lo que no están habilitadas de forma
predeterminada.

Una lista completa de los diversos tipos de compilaciones de
depuración se encuentra en el archivo "Misc/SpecialBuilds.txt" en la
distribución fuente de Python. Hay compilaciones disponibles que
admiten el rastreo de los conteos de referencia, la depuración del
asignador de memoria o la creación de perfiles de bajo nivel del bucle
principal del intérprete. Solo las compilaciones más utilizadas se
describirán en el resto de esta sección.

Compilar el intérprete con el macro "Py_DEBUG" definido produce lo que
generalmente se entiende por "una compilación de depuración" de
Python. "Py_DEBUG" se habilita en la compilación de Unix agregando "--
with-pydebug" al comando "./configure". También está implícito en la
presencia del macro no específico de Python "_DEBUG". Cuando
"Py_DEBUG" está habilitado en la compilación de Unix, la optimización
del compilador está deshabilitada.

Además de la depuración del recuento de referencia que se describe a
continuación, se realizan las siguientes verificaciones adicionales:

* Se agregan comprobaciones adicionales al asignador de objetos.

* Se agregan verificaciones adicionales al analizador y compilador.

* Las conversiones de tipos hacia abajo (*downcasting*) de tipos
  anchos a tipos estrechos se comprueban por pérdida de información.

* Se agregan varias aserciones al diccionario y se establecen
  implementaciones. Además, el objeto set adquiere un método
  "test_c_api()".

* Las comprobaciones de cordura (*sanity checks*) de los argumentos de
  entrada se agregan a la creación del marco.

* El almacenamiento para *ints* se inicializa con un patrón no válido
  conocido para capturar referencias a dígitos no inicializados.

* El seguimiento de bajo nivel y la comprobación de excepciones
  adicionales se agregan a la máquina virtual en tiempo de ejecución.

* Se agregan verificaciones adicionales a la implementación de la
  arena de memoria.

* Se agrega depuración adicional al módulo de hilos.

Puede haber controles adicionales no mencionados aquí.

Definiendo "Py_TRACE_REFS" habilita el rastreo de referencias. Cuando
se define, se mantiene una lista circular doblemente vinculada de
objetos activos al agregar dos campos adicionales a cada "PyObject".
También se realiza un seguimiento de las asignaciones totales. Al
salir, se imprimen todas las referencias existentes. (En modo
interactivo, esto sucede después de cada declaración ejecutada por el
intérprete). Implicado por "Py_DEBUG".

Consulte "Misc/SpecialBuilds.txt" en la distribución fuente de Python
para obtener información más detallada.
