# Manejo de excepciones

Las funciones descritas en este capítulo le permitirán manejar y aumentar las excepciones de Python. Es importante comprender algunos de los conceptos básicos del manejo de excepciones de Python. Funciona de manera similar a la variable POSIX `errno`: hay un indicador global (por subproceso) del último error que ocurrió. La mayoría de las funciones de C API no borran esto en caso de éxito, pero lo configurarán para indicar la causa del error en caso de falla. La mayoría de las funciones de C API también retornan un indicador de error, generalmente `NULL` si se supone que retornan un puntero, o `-1` si retornan un número entero (excepción: las funciones `PyArg_*()` retornan `1` para el éxito y `0` para el fracaso).

Concretamente, el indicador de error consta de tres punteros de objeto: el tipo de excepción, el valor de la excepción y el objeto de rastreo. Cualquiera de esos punteros puede ser `NULL` si no está configurado (aunque algunas combinaciones están prohibidas, por ejemplo, no puede tener un rastreo no `NULL` si el tipo de excepción es `NULL`).

Cuando una función debe fallar porque alguna función que llamó falló, generalmente no establece el indicador de error; la función que llamó ya lo configuró. Es responsable de manejar el error y borrar la excepción o regresar después de limpiar cualquier recurso que tenga (como referencias de objetos o asignaciones de memoria); debería no continuar normalmente si no está preparado para manejar el error. Si regresa debido a un error, es importante indicarle a la persona que llama que se ha establecido un error. Si el error no se maneja o se propaga cuidadosamente, es posible que las llamadas adicionales a la API de Python/C no se comporten como se espera y pueden fallar de manera misteriosa.

Nota

El indicador de error es no el resultado de `sys.exc_info()`. El primero corresponde a una excepción que aún no se detecta (y, por lo tanto, todavía se está propagando), mientras que el segundo retorna una excepción después de que se detecta (y, por lo tanto, ha dejado de propagarse).

## Impresión y limpieza

void `PyErr_Clear`()

  Borra el indicador de error. Si el indicador de error no está configurado, no hay efecto.

void `PyErr_PrintEx`(int set_sys_last_vars)

  Imprime un rastreo estándar en `sys.stderr` y borra el indicador de error. A menos que el error sea un `Salida del sistema`, en ese caso no se imprime ningún rastreo y el proceso de Python se cerrará con el código de error especificado por la instancia de `Salida del sistema`.

  Llame a esta función solo cuando el indicador de error está configurado. De lo contrario, provocará un error fatal!

  Si set_sys_last_vars no es cero, las variables `sys.last_type`, `sys.last_value` y `sys.last_traceback` se establecerán en el tipo, valor y rastreo de la excepción impresa, respectivamente.

void `PyErr_Print`()

  Alias para `PyErr_PrintEx(1)`.

void `PyErr_WriteUnraisable`(PyObject *obj)

  Llama `sys.unraisablehook()` utilizando la excepción actual y el argumento obj.

  Esta función de utilidad imprime un mensaje de advertencia en `sys.stderr` cuando se ha establecido una excepción, pero es imposible que el intérprete la active. Se usa, por ejemplo, cuando ocurre una excepción en un método `__del__()`.

  La función se llama con un solo argumento obj que identifica el contexto en el que ocurrió la excepción que no se evalúa. Si es posible, la repr obj se imprimirá en el mensaje de advertencia.

  Se debe establecer una excepción al llamar a esta función.

## Lanzando excepciones

Estas funciones lo ayudan a configurar el indicador de error del hilo actual. Por conveniencia, algunas de estas funciones siempre retornarán un puntero `NULL` para usar en una declaración `return`.

void `PyErr_SetString`(PyObject *type, const char *message)

  Esta es la forma más común de configurar el indicador de error. El primer argumento especifica el tipo de excepción; Normalmente es una de las excepciones estándar, por ejemplo `PyExc_RuntimeError`. No necesita incrementar su recuento de referencia. El segundo argumento es un mensaje de error; se decodifica a partir de `'utf-8'`.

void `PyErr_SetObject`(PyObject *type, PyObject *value)

  Esta función es similar a `PyErr_SetString()` pero le permite especificar un objeto Python arbitrario para el «valor» de la excepción.

PyObject* `PyErr_Format`(PyObject *exception, const char *format, ...)
  Return value: Always NULL.

  Esta función establece el indicador de error y retorna `NULL`. exception debe ser una clase de excepción Python. El format y los parámetros posteriores ayudan a formatear el mensaje de error; tienen el mismo significado y valores que en `PyUnicode_FromFormat()`. format es una cadena de caracteres codificada en ASCII.

PyObject* `PyErr_FormatV`(PyObject *exception, const char *format, va_list vargs)
  Return value: Always NULL.

  Igual que `PyErr_Format()`, pero tomando un argumento `va_list` en lugar de un número variable de argumentos.

  Nuevo en la versión 3.5.

void `PyErr_SetNone`(PyObject *type)

  Esta es una abreviatura de `PyErr_SetObject(type, Py_None)`.

int `PyErr_BadArgument`()

  Esta es una abreviatura de `PyErr_SetString(PyExc_TypeError, message)`, donde message indica que se invocó una operación incorporada con un argumento ilegal. Es principalmente para uso interno.

PyObject* `PyErr_NoMemory`()
  Return value: Always NULL.

  Esta es una abreviatura de `PyErr_SetNone(PyExc_MemoryError)`; retorna `NULL` para que una función de asignación de objetos pueda escribir `return PyErr_NoMemory();` cuando se queda sin memoria.

PyObject* `PyErr_SetFromErrno`(PyObject *type)
  Return value: Always NULL.

  Esta es una función conveniente para generar una excepción cuando una función de biblioteca C ha retornado un error y establece la variable C `errno`. Construye un objeto tupla cuyo primer elemento es el valor entero `errno` y cuyo segundo elemento es el mensaje de error correspondiente (obtenido de `strerror()`), y luego llama a `PyErr_SetObject(type , objeto)`. En Unix, cuando el valor `errno` es `EINTR`, que indica una llamada interrumpida del sistema, esto llama `PyErr_CheckSignals()`, y si eso establece el indicador de error, lo deja configurado a ese. La función siempre retorna `NULL`, por lo que una función envolvente alrededor de una llamada del sistema puede escribir `return PyErr_SetFromErrno (type);` cuando la llamada del sistema retorna un error.

PyObject* `PyErr_SetFromErrnoWithFilenameObject`(PyObject *type, PyObject *filenameObject)
  Return value: Always NULL.

  Similar a `PyErr_SetFromErrno()`, con el comportamiento adicional de que si filenameObject * no es ``NULL``, se pasa al constructor de *type como tercer parámetro. En el caso de la excepción `OSError`, se utiliza para definir el atributo `filename` de la instancia de excepción.

PyObject* `PyErr_SetFromErrnoWithFilenameObjects`(PyObject *type, PyObject *filenameObject, PyObject *filenameObject2)
  Return value: Always NULL.

  Similar a `PyErr_SetFromErrnoWithFilenameObject()`, pero toma un segundo objeto de nombre de archivo, para generar errores cuando falla una función que toma dos nombres de archivo.

  Nuevo en la versión 3.4.

PyObject* `PyErr_SetFromErrnoWithFilename`(PyObject *type, const char *filename)
  Return value: Always NULL.

  Similar a `PyErr_SetFromErrnoWithFilenameObject()`, pero el nombre del archivo se da como una cadena de caracteres de C. filename se decodifica a partir de la codificación del sistema de archivos (`os.fsdecode()`).

PyObject* `PyErr_SetFromWindowsErr`(int ierr)
  Return value: Always NULL.

  Esta es una función conveniente para subir `WindowsError`. Si se llama con ierr de `0`, el código de error retornado por una llamada a `GetLastError()` se usa en su lugar. Llama a la función Win32 `FormatMessage()` para recuperar la descripción de Windows del código de error proporcionado por ierr o `GetLastError()`, luego construye un objeto de tupla cuyo primer elemento es el ierr valor y cuyo segundo elemento es el mensaje de error correspondiente (obtenido de `FormatMessage()`), y luego llama a `PyErr_SetObject(PyExc_WindowsError, object)`. Esta función siempre retorna `NULL`.

  Disponibilidad: Windows.

PyObject* `PyErr_SetExcFromWindowsErr`(PyObject *type, int ierr)
  Return value: Always NULL.

  Similar a `PyErr_SetFromWindowsErr()`, con un parámetro adicional que especifica el tipo de excepción que se generará.

  Disponibilidad: Windows.

PyObject* `PyErr_SetFromWindowsErrWithFilename`(int ierr, const char *filename)
  Return value: Always NULL.

  Similar a `PyErr_SetFromWindowsErrWithFilenameObject()`, pero el nombre del archivo se da como una cadena de caracteres de C. filename se decodifica a partir de la codificación del sistema de archivos (`os.fsdecode()`).

  Disponibilidad: Windows.

PyObject* `PyErr_SetExcFromWindowsErrWithFilenameObject`(PyObject *type, int ierr, PyObject *filename)
  Return value: Always NULL.

  Similar a `PyErr_SetFromWindowsErrWithFilenameObject()`, con un parámetro adicional que especifica el tipo de excepción que se generará.

  Disponibilidad: Windows.

PyObject* `PyErr_SetExcFromWindowsErrWithFilenameObjects`(PyObject *type, int ierr, PyObject *filename, PyObject *filename2)
  Return value: Always NULL.

  Similar a `PyErr_SetExcFromWindowsErrWithFilenameObject()`, pero acepta un segundo objeto de nombre de archivo.

  Disponibilidad: Windows.

  Nuevo en la versión 3.4.

PyObject* `PyErr_SetExcFromWindowsErrWithFilename`(PyObject *type, int ierr, const char *filename)
  Return value: Always NULL.

  Similar a `PyErr_SetFromWindowsErrWithFilename()`, con un parámetro adicional que especifica el tipo de excepción que se generará.

  Disponibilidad: Windows.

PyObject* `PyErr_SetImportError`(PyObject *msg, PyObject *name, PyObject *path)
  Return value: Always NULL.

  Esta es una función conveniente para subir `ImportError`. msg se establecerá como la cadena de mensaje de la excepción. name y path, que pueden ser `NULL`, se establecerán como atributos respectivos `name` y `path` de `ImportError`.

  Nuevo en la versión 3.3.

void `PyErr_SyntaxLocationObject`(PyObject *filename, int lineno, int col_offset)

  Establece información de archivo, línea y desplazamiento para la excepción actual. Si la excepción actual no es un `SyntaxError`, establece atributos adicionales, lo que hace que el sub sistema de impresión de excepciones piense que la excepción es `SyntaxError`.

  Nuevo en la versión 3.4.

void `PyErr_SyntaxLocationEx`(const char *filename, int lineno, int col_offset)

  Como `PyErr_SyntaxLocationObject()`, pero filename es una cadena de bytes decodificada a partir de la codificación del sistema de archivos (`os.fsdecode()`).

  Nuevo en la versión 3.2.

void `PyErr_SyntaxLocation`(const char *filename, int lineno)

  Como `PyErr_SyntaxLocationEx()`, pero se omite el parámetro col_offset.

void `PyErr_BadInternalCall`()

  Esta es una abreviatura de `PyErr_SetString(PyExc_SystemError, message)`, donde message indica que se invocó una operación interna (por ejemplo, una función de Python/C API) con un argumento ilegal. Es principalmente para uso interno.

## Emitir advertencias

Use estas funciones para emitir advertencias desde el código C. Reflejan funciones similares exportadas por el módulo Python `warnings`. Normalmente imprimen un mensaje de advertencia a sys.stderr; sin embargo, también es posible que el usuario haya especificado que las advertencias se conviertan en errores, y en ese caso generarán una excepción. También es posible que las funciones generen una excepción debido a un problema con la maquinaria de advertencia. El valor de retorno es `0` si no se genera una excepción, o `-1` si se genera una excepción. (No es posible determinar si realmente se imprime un mensaje de advertencia, ni cuál es el motivo de la excepción; esto es intencional). Si se produce una excepción, la persona que llama debe hacer su manejo normal de excepciones (por ejemplo, referencias propiedad de `Py_DECREF()` y retornan un valor de error).

int `PyErr_WarnEx`(PyObject *category, const char *message, Py_ssize_t stack_level)

  Emite un mensaje de advertencia. El argumento category es una categoría de advertencia (ver más abajo) o `NULL`; el argumento message es una cadena de caracteres codificada en UTF-8. stack_level es un número positivo que proporciona una cantidad de marcos de pila; la advertencia se emitirá desde la línea de código que se está ejecutando actualmente en ese marco de pila. Un stack_level de 1 es la función que llama `PyErr_WarnEx()`, 2 es la función por encima de eso, y así sucesivamente.

  Las categorías de advertencia deben ser subclases de `PyExc_Warning`; `PyExc_Warning` es una subclase de `PyExc_Exception`; la categoría de advertencia predeterminada es `PyExc_RuntimeWarning`. Las categorías de advertencia estándar de Python están disponibles como variables globales cuyos nombres se enumeran en Categorías de advertencia estándar.

  Para obtener información sobre el control de advertencia, consulte la documentación del módulo `warnings` y la opción `-W` en la documentación de la línea de comandos. No hay API de C para el control de advertencia.

PyObject* `PyErr_SetImportErrorSubclass`(PyObject *exception, PyObject *msg, PyObject *name, PyObject *path)
  Return value: Always NULL.

  Al igual que `PyErr_SetImportError()` pero esta función permite especificar una subclase de `ImportError` para aumentar.

  Nuevo en la versión 3.6.

int `PyErr_WarnExplicitObject`(PyObject *category, PyObject *message, PyObject *filename, int lineno, PyObject *module, PyObject *registry)

  Emite un mensaje de advertencia con control explícito sobre todos los atributos de advertencia. Este es un contenedor sencillo alrededor de la función Python `warnings.warn_explicit()`, consulte allí para obtener más información. Los argumentos module y registry pueden establecerse en `NULL` para obtener el efecto predeterminado que se describe allí.

  Nuevo en la versión 3.4.

int `PyErr_WarnExplicit`(PyObject *category, const char *message, const char *filename, int lineno, const char *module, PyObject *registry)

  Similar a `PyErr_WarnExplicitObject()` excepto que message y module son cadenas codificadas UTF-8, y filename se decodifica de la codificación del sistema de archivos (`os.fsdecode()`).

int `PyErr_WarnFormat`(PyObject *category, Py_ssize_t stack_level, const char *format, ...)

  Función similar a `PyErr_WarnEx()`, pero usa `PyUnicode_FromFormat()` para formatear el mensaje de advertencia. format es una cadena de caracteres codificada en ASCII.

  Nuevo en la versión 3.2.

int `PyErr_ResourceWarning`(PyObject *source, Py_ssize_t stack_level, const char *format, ...)

  Función similar a `PyErr_WarnFormat()`, pero category es `ResourceWarning` y pasa source a `warnings.WarningMessage()`.

  Nuevo en la versión 3.6.

## Consultando el indicador de error

PyObject* `PyErr_Occurred`()
  Return value: Borrowed reference.

  Prueba si el indicador de error está configurado. Si se establece, retorna la excepción type (el primer argumento de la última llamada a una de las funciones `PyErr_Set*()` o `PyErr_Restore()`). Si no está configurado, retorna `NULL`. No posee una referencia al valor de retorno, por lo que no necesita usar `Py_DECREF()`.

  Nota

  No compare el valor de retorno con una excepción específica; use `PyErr_ExceptionMatches()` en su lugar, como se muestra a continuación. (La comparación podría fallar fácilmente ya que la excepción puede ser una instancia en lugar de una clase, en el caso de una excepción de clase, o puede ser una subclase de la excepción esperada).

int `PyErr_ExceptionMatches`(PyObject *exc)

  Equivalente a `PyErr_GivenExceptionMatches(PyErr_Occurred(), exc)`. Esto solo debería llamarse cuando se establece una excepción; se producirá una infracción de acceso a la memoria si no se ha producido ninguna excepción.

int `PyErr_GivenExceptionMatches`(PyObject *given, PyObject *exc)

  Retorna verdadero si la excepción dada coincide con el tipo de excepción en exc. Si exc es un objeto de clase, esto también retorna verdadero cuando dado es una instancia de una subclase. Si exc es una tupla, se busca una coincidencia en todos los tipos de excepción en la tupla (y recursivamente en sub tuplas).

void `PyErr_Fetch`(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback)

  Recupere el indicador de error en tres variables cuyas direcciones se pasan. Si el indicador de error no está configurado, configure las tres variables en `NULL`. Si está configurado, se borrará y usted tendrá una referencia a cada objeto recuperado. El objeto de valor y rastreo puede ser `NULL` incluso cuando el objeto de tipo no lo es.

  Nota

  Normalmente, esta función solo la usa el código que necesita capturar excepciones o el código que necesita guardar y restaurar el indicador de error temporalmente, por ejemplo:

      {
         PyObject *type, *value, *traceback;
         PyErr_Fetch(&type, &value, &traceback);

         /* ... code that might produce other errors ... */

         PyErr_Restore(type, value, traceback);
      }

void `PyErr_Restore`(PyObject *type, PyObject *value, PyObject *traceback)

  Establece el indicador de error de los tres objetos. Si el indicador de error ya está configurado, se borra primero. Si los objetos son `NULL`, el indicador de error se borra. No pase un tipo `NULL` y un valor o rastreo no `NULL`. El tipo de excepción debería ser una clase. No pase un tipo o valor de excepción no válido. (Violar estas reglas causará problemas sutiles más adelante). Esta llamada quita una referencia a cada objeto: debe tener una referencia a cada objeto antes de la llamada y después de la llamada ya no posee estas referencias. (Si no comprende esto, no use esta función. Se lo advertí).

  Nota

  Normalmente, esta función solo la usa el código que necesita guardar y restaurar el indicador de error temporalmente. Use `PyErr_Fetch()` para guardar el indicador de error actual.

void `PyErr_NormalizeException`(PyObject**exc, PyObject**val, PyObject**tb)

  Bajo ciertas circunstancias, los valores retornados por `PyErr_Fetch()` a continuación pueden ser «no normalizados», lo que significa que `*exc` es un objeto de clase pero `*val` no es una instancia de la misma clase . Esta función se puede utilizar para crear instancias de la clase en ese caso. Si los valores ya están normalizados, no pasa nada. La normalización retrasada se implementa para mejorar el rendimiento.

  Nota

  Esta función no establece implícitamente el atributo `__traceback__` en el valor de excepción. Si se desea establecer el rastreo de manera adecuada, se necesita el siguiente fragmento adicional:

      if (tb != NULL) {
        PyException_SetTraceback(val, tb);
      }

void `PyErr_GetExcInfo`(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback)

  Recupere la información de excepción, como se conoce de `sys.exc_info()`. Esto se refiere a una excepción que ya fue capturada, no a una excepción que se planteó recientemente. Retorna nuevas referencias para los tres objetos, cualquiera de los cuales puede ser `NULL`. No modifica el estado de información de excepción.

  Nota

  Esta función normalmente no es utilizada por el código que quiere manejar excepciones. En cambio, se puede usar cuando el código necesita guardar y restaurar el estado de excepción temporalmente. Use `PyErr_SetExcInfo()` para restaurar o borrar el estado de excepción.

  Nuevo en la versión 3.3.

void `PyErr_SetExcInfo`(PyObject *type, PyObject *value, PyObject *traceback)

  Establezca la información de excepción, como se conoce de `sys.exc_info()`. Esto se refiere a una excepción que ya fue capturada, no a una excepción que se planteó recientemente. Esta función roba las referencias de los argumentos. Para borrar el estado de excepción, pase `NULL` para los tres argumentos. Para ver las reglas generales sobre los tres argumentos, consulte `PyErr_Restore()`.

  Nota

  Esta función normalmente no es utilizada por el código que quiere manejar excepciones. En cambio, se puede usar cuando el código necesita guardar y restaurar el estado de excepción temporalmente. Use `PyErr_GetExcInfo()` para leer el estado de excepción.

  Nuevo en la versión 3.3.

## Manejo de señal

int `PyErr_CheckSignals`()

  Esta función interactúa con el manejo de la señal de Python. Comprueba si se ha enviado una señal a los procesos y, de ser así, invoca el controlador de señal correspondiente. Si el módulo `signal` es compatible, esto puede invocar un controlador de señal escrito en Python. En todos los casos, el efecto predeterminado para `SIGINT` es aumentar la excepción `KeyboardInterrupt`. Si se produce una excepción, se establece el indicador de error y la función retorna `-1`; de lo contrario, la función retorna `0`. El indicador de error puede o no borrarse si se configuró previamente.

void `PyErr_SetInterrupt`()

  Simule el efecto de la llegada de una señal `SIGINT`. La próxima vez se llama `PyErr_CheckSignals()`, se llamará al manejador de señal de Python para `SIGINT`.

  Si `SIGINT` no es manejado por Python (se configuró en `signal.SIG_DFL` o `signal.SIG_IGN`), esta función no hace nada.

int `PySignal_SetWakeupFd`(int fd)

  Esta función de utilidad especifica un descriptor de archivo en el que el número de señal se escribe como un solo byte cada vez que se recibe una señal. fd debe ser sin bloqueo. retorna el descriptor de archivo anterior.

  El valor `-1` desactiva la función; Este es el estado inicial. Esto es equivalente a `signal.set_wakeup_fd()` en Python, pero sin verificación de errores. fd debe ser un descriptor de archivo válido. La función solo debe llamarse desde el hilo principal.

  Distinto en la versión 3.5: En Windows, la función ahora también admite controladores de socket.

## Clases de Excepción

PyObject* `PyErr_NewException`(const char *name, PyObject *base, PyObject *dict)
  Return value: New reference.

  Esta función de utilidad crea y retorna una nueva clase de excepción. El argumento name debe ser el nombre de la nueva excepción, una cadena de caracteres en C de la forma `module.classname`. Los argumentos base y dict son normalmente `NULL`. Esto crea un objeto de clase derivado de `Exception` (accesible en C como `PyExc_Exception`).

  El atributo `__module__` de la nueva clase se establece en la primera parte (hasta el último punto) del argumento name, y el nombre de la clase se establece en la última parte (después del último punto). El argumento base se puede usar para especificar clases base alternativas; puede ser solo una clase o una tupla de clases. El argumento dict se puede usar para especificar un diccionario de variables de clase y métodos.

PyObject* `PyErr_NewExceptionWithDoc`(const char *name, const char *doc, PyObject *base, PyObject *dict)
  Return value: New reference.

  Igual que `PyErr_NewException()`, excepto que la nueva clase de excepción puede recibir fácilmente una cadena de documentación: si doc no es `NULL`, se utilizará como la cadena de documentación para la clase de excepción.

  Nuevo en la versión 3.2.

## Objetos Excepción

PyObject* `PyException_GetTraceback`(PyObject *ex)
  Return value: New reference.

  Retorna el rastreo asociado con la excepción como una nueva referencia, accesible desde Python a través de `__traceback__`. Si no hay un rastreo asociado, esto retorna `NULL`.

int `PyException_SetTraceback`(PyObject *ex, PyObject *tb)

  Establezca el rastreo asociado con la excepción a tb. Use `Py_None` para borrarlo.

PyObject* `PyException_GetContext`(PyObject *ex)
  Return value: New reference.

  Retorna el contexto (otra instancia de excepción durante cuyo manejo ex se generó) asociado con la excepción como una nueva referencia, accesible desde Python a través de `__context__`. Si no hay un contexto asociado, esto retorna `NULL`.

void `PyException_SetContext`(PyObject *ex, PyObject *ctx)

  Establece el contexto asociado con la excepción a ctx. Use `NULL` para borrarlo. No hay verificación de tipo para asegurarse de que ctx es una instancia de excepción. Esto roba una referencia a ctx.

PyObject* `PyException_GetCause`(PyObject *ex)
  Return value: New reference.

  Retorna la causa (ya sea una instancia de excepción, o `None`, establecida por `raise ... from ...`) asociada con la excepción como una nueva referencia, como accesible desde Python a través de `__causa__`.

void `PyException_SetCause`(PyObject *ex, PyObject *cause)

  Establece la causa asociada con la excepción a cause. Use `NULL` para borrarlo. No hay verificación de tipo para asegurarse de que cause sea una instancia de excepción o `None`. Esto roba una referencia a cause.

  `__suppress_context__` es implícitamente establecido en `True` por esta función.

## Objectos Unicode de Excepción

Las siguientes funciones se utilizan para crear y modificar excepciones Unicode de C.

PyObject* `PyUnicodeDecodeError_Create`(const char *encoding, const char *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)
  Return value: New reference.

  Crea un objeto `UnicodeDecodeError` con los atributos encoding, object, length, start, end y reason. encoding y reason son cadenas codificadas UTF-8.

PyObject* `PyUnicodeEncodeError_Create`(const char *encoding, const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)
  Return value: New reference.

  Crea un objeto `UnicodeEncodeError` con los atributos encoding, object, length, start, end y reason. encoding y reason son cadenas codificadas UTF-8.

  Obsoleto desde la versión 3.3: 3.11

  `Py_UNICODE` is deprecated since Python 3.3. Please migrate to `PyObject_CallFunction(PyExc_UnicodeEncodeError, "sOnns", ...)`.

PyObject* `PyUnicodeTranslateError_Create`(const Py_UNICODE *object, Py_ssize_t length, Py_ssize_t start, Py_ssize_t end, const char *reason)
  Return value: New reference.

  Crea un objeto `UnicodeTranslateError` con los atributos encoding, object, length, start, end y reason. encoding y reason son cadenas codificadas UTF-8.

  Obsoleto desde la versión 3.3: 3.11

  `Py_UNICODE` is deprecated since Python 3.3. Please migrate to `PyObject_CallFunction(PyExc_UnicodeTranslateError, "Onns", ...)`.

PyObject* `PyUnicodeDecodeError_GetEncoding`(PyObject *exc)
PyObject* `PyUnicodeEncodeError_GetEncoding`(PyObject *exc)
  Return value: New reference.

  retorna el atributo encoding del objeto de excepción dado.

PyObject* `PyUnicodeDecodeError_GetObject`(PyObject *exc)
PyObject* `PyUnicodeEncodeError_GetObject`(PyObject *exc)
PyObject* `PyUnicodeTranslateError_GetObject`(PyObject *exc)
  Return value: New reference.

  Retorna el atributo object del objeto de excepción dado.

int `PyUnicodeDecodeError_GetStart`(PyObject *exc, Py_ssize_t *start)
int `PyUnicodeEncodeError_GetStart`(PyObject *exc, Py_ssize_t *start)
int `PyUnicodeTranslateError_GetStart`(PyObject *exc, Py_ssize_t *start)

  Obtiene el atributo start del objeto de excepción dado y lo coloca en *start. start no debe ser `NULL`. retorna `0` en caso de éxito, `-1` en caso de error.

int `PyUnicodeDecodeError_SetStart`(PyObject *exc, Py_ssize_t start)
int `PyUnicodeEncodeError_SetStart`(PyObject *exc, Py_ssize_t start)
int `PyUnicodeTranslateError_SetStart`(PyObject *exc, Py_ssize_t start)

  Establece el atributo start del objeto de excepción dado en start. Retorna `0` en caso de éxito, `-1` en caso de error.

int `PyUnicodeDecodeError_GetEnd`(PyObject *exc, Py_ssize_t *end)
int `PyUnicodeEncodeError_GetEnd`(PyObject *exc, Py_ssize_t *end)
int `PyUnicodeTranslateError_GetEnd`(PyObject *exc, Py_ssize_t *end)

  Obtiene el atributo end del objeto de excepción dado y lo coloca en *end. end no debe ser `NULL`. retorna `0` en caso de éxito, `-1` en caso de error.

int `PyUnicodeDecodeError_SetEnd`(PyObject *exc, Py_ssize_t end)
int `PyUnicodeEncodeError_SetEnd`(PyObject *exc, Py_ssize_t end)
int `PyUnicodeTranslateError_SetEnd`(PyObject *exc, Py_ssize_t end)

  Establece el atributo end del objeto de excepción dado en end. Retorna `0` en caso de éxito, `-1` en caso de error.

PyObject* `PyUnicodeDecodeError_GetReason`(PyObject *exc)
PyObject* `PyUnicodeEncodeError_GetReason`(PyObject *exc)
PyObject* `PyUnicodeTranslateError_GetReason`(PyObject *exc)
  Return value: New reference.

  Retorna el atributo reason del objeto de excepción dado.

int `PyUnicodeDecodeError_SetReason`(PyObject *exc, const char *reason)
int `PyUnicodeEncodeError_SetReason`(PyObject *exc, const char *reason)
int `PyUnicodeTranslateError_SetReason`(PyObject *exc, const char *reason)

  Establece el atributo reason del objeto de excepción dado en reason. Retorna `0` en caso de éxito, `-1` en caso de error.

## Control de Recursión

Estas dos funciones proporcionan una forma de realizar llamadas recursivas seguras en el nivel C, tanto en el núcleo como en los módulos de extensión. Son necesarios si el código recursivo no invoca necesariamente el código Python (que rastrea su profundidad de recursión automáticamente).

int `Py_EnterRecursiveCall`(const char *where)

  Marca un punto donde una llamada recursiva de nivel C está a punto de realizarse.

  Si `USE_STACKCHECK` está definido, esta función verifica si la pila del SO se desbordó usando `PyOS_CheckStack()`. En este caso, establece un `MemoryError` y retorna un valor distinto de cero.

  La función verifica si se alcanza el límite de recursión. Si este es el caso, se establece a `RecursionError` y se retorna un valor distinto de cero. De lo contrario, se retorna cero.

  where debería ser una cadena como `"en la comprobación de instancia"` para concatenarse con el mensaje `RecursionError` causado por el límite de profundidad de recursión.

void `Py_LeaveRecursiveCall`()

  Termina una `Py_EnterRecursiveCall()`. Se debe llamar una vez por cada invocación exitosa de `Py_EnterRecursiveCall()`.

La implementación adecuada de `tp_repr` para los tipos de contenedor requiere un manejo de recursión especial. Además de proteger la pila, `tp_repr` también necesita rastrear objetos para evitar ciclos. Las siguientes dos funciones facilitan esta funcionalidad. Efectivamente, estos son los C equivalentes a `reprlib.recursive_repr()`.

int `Py_ReprEnter`(PyObject *object)

  Llamado al comienzo de la implementación `tp_repr` para detectar ciclos.

  Si el objeto ya ha sido procesado, la función retorna un entero positivo. En ese caso, la implementación `tp_repr` debería retornar un objeto de cadena que indique un ciclo. Como ejemplos, los objetos `dict` retornan `{...}` y los objetos `list` retornan `[...]`.

  La función retornará un entero negativo si se alcanza el límite de recursión. En ese caso, la implementación `tp_repr` normalmente debería retornar `NULL`.

  De lo contrario, la función retorna cero y la implementación `tp_repr` puede continuar normalmente.

void `Py_ReprLeave`(PyObject *object)

  Termina a `Py_ReprEnter()`. Se debe llamar una vez por cada invocación de `Py_ReprEnter()` que retorna cero.

## Excepciones Estándar

All standard Python exceptions are available as global variables whose names are `PyExc_` followed by the Python exception name. These have the type `PyObject*`; they are all class objects. For completeness, here are all the variables:

Nombre en C | Nombre en Python | Notas
--- | --- | ---
`PyExc_BaseException` | `BaseException` | (1)
`PyExc_Exception` | `Exception` | (1)
`PyExc_ArithmeticError` | `ArithmeticError` | (1)
`PyExc_AssertionError` | `AssertionError` |
`PyExc_AttributeError` | `AttributeError` |
`PyExc_BlockingIOError` | `BlockingIOError` |
`PyExc_BrokenPipeError` | `BrokenPipeError` |
`PyExc_BufferError` | `BufferError` |
`PyExc_ChildProcessError` | `ChildProcessError` |
`PyExc_ConnectionAbortedError` | `ConnectionAbortedError` |
`PyExc_ConnectionError` | `ConnectionError` |
`PyExc_ConnectionRefusedError` | `ConnectionRefusedError` |
`PyExc_ConnectionResetError` | `ConnectionResetError` |
`PyExc_EOFError` | `EOFError` |
`PyExc_FileExistsError` | `FileExistsError` |
`PyExc_FileNotFoundError` | `FileNotFoundError` |
`PyExc_FloatingPointError` | `FloatingPointError` |
`PyExc_GeneratorExit` | `GeneratorExit` |
`PyExc_ImportError` | `ImportError` |
`PyExc_IndentationError` | `IndentationError` |
`PyExc_IndexError` | `IndexError` |
`PyExc_InterruptedError` | `InterruptedError` |
`PyExc_IsADirectoryError` | `IsADirectoryError` |
`PyExc_KeyError` | `KeyError` |
`PyExc_KeyboardInterrupt` | `KeyboardInterrupt` |
`PyExc_LookupError` | `LookupError` | (1)
`PyExc_MemoryError` | `MemoryError` |
`PyExc_ModuleNotFoundError` | `ModuleNotFoundError` |
`PyExc_NameError` | `NameError` |
`PyExc_NotADirectoryError` | `NotADirectoryError` |
`PyExc_NotImplementedError` | `NotImplementedError` |
`PyExc_OSError` | `OSError` | (1)
`PyExc_OverflowError` | `OverflowError` |
`PyExc_PermissionError` | `PermissionError` |
`PyExc_ProcessLookupError` | `ProcessLookupError` |
`PyExc_RecursionError` | `RecursionError` |
`PyExc_ReferenceError` | `ReferenceError` | (2)
`PyExc_RuntimeError` | `RuntimeError` |
`PyExc_StopAsyncIteration` | `StopAsyncIteration` |
`PyExc_StopIteration` | `StopIteration` |
`PyExc_SyntaxError` | `SyntaxError` |
`PyExc_SystemError` | `SystemError` |
`PyExc_SystemExit` | `SystemExit` |
`PyExc_TabError` | `TabError` |
`PyExc_TimeoutError` | `TimeoutError` |
`PyExc_TypeError` | `TypeError` |
`PyExc_UnboundLocalError` | `UnboundLocalError` |
`PyExc_UnicodeDecodeError` | `UnicodeDecodeError` |
`PyExc_UnicodeEncodeError` | `UnicodeEncodeError` |
`PyExc_UnicodeError` | `UnicodeError` |
`PyExc_UnicodeTranslateError` | `UnicodeTranslateError` |
`PyExc_ValueError` | `ValueError` |
`PyExc_ZeroDivisionError` | `ZeroDivisionError` |

Nuevo en la versión 3.3: `PyExc_BlockingIOError`, `PyExc_BrokenPipeError`, `PyExc_ChildProcessError`, `PyExc_ConnectionError`, `PyExc_ConnectionAbortedError`, `PyExc_ConnectionRefusedError`, `PyExc_ConnectionResetError`, `PyExc_FileExistsError`, `PyExc_FileNotFoundError`, `PyExc_InterruptedError`, `PyExc_IsADirectoryError`, `PyExc_NotADirectoryError`, `PyExc_PermissionError`, `PyExc_ProcessLookupError` y `PyExc_TimeoutError` fueron introducidos luego de PEP 3151.

Nuevo en la versión 3.5: `PyExc_StopAsyncIteration` y `PyExc_RecursionError`.

Nuevo en la versión 3.6: `PyExc_ModuleNotFoundError`.

Estos son alias de compatibilidad para `PyExc_OSError`:

Nombre en C | Notas
--- | ---
`PyExc_EnvironmentError` |
`PyExc_IOError` |
`PyExc_WindowsError` | (3)

Distinto en la versión 3.3: Estos alias solían ser tipos de excepción separados.

Notas:

1. Esta es una clase base para otras excepciones estándar.

2. Solo se define en Windows; proteja el código que usa esto probando que la macro del preprocesador `MS_WINDOWS` está definida.

## Categorías de advertencia estándar

All standard Python warning categories are available as global variables whose names are `PyExc_` followed by the Python exception name. These have the type `PyObject*`; they are all class objects. For completeness, here are all the variables:

Nombre en C | Nombre en Python | Notas
--- | --- | ---
`PyExc_Warning` | `Warning` | (1)
`PyExc_BytesWarning` | `BytesWarning` |
`PyExc_DeprecationWarning` | `DeprecationWarning` |
`PyExc_FutureWarning` | `FutureWarning` |
`PyExc_ImportWarning` | `ImportWarning` |
`PyExc_PendingDeprecationWarning` | `PendingDeprecationWarning` |
`PyExc_ResourceWarning` | `ResourceWarning` |
`PyExc_RuntimeWarning` | `RuntimeWarning` |
`PyExc_SyntaxWarning` | `SyntaxWarning` |
`PyExc_UnicodeWarning` | `UnicodeWarning` |
`PyExc_UserWarning` | `UserWarning` |

Nuevo en la versión 3.2: `PyExc_ResourceWarning`.

Notas:

1. Esta es una clase base para otras categorías de advertencia estándar.