Introdução
**********

A Interface de Programação de Aplicações (API) para Python fornece aos
programadores C e C++ acesso ao interpretador Python em uma variedade
de níveis. A API pode ser usada igualmente em C++, mas, para abreviar,
geralmente é chamada de API Python/C. Existem dois motivos
fundamentalmente diferentes para usar a API Python/C. A primeira razão
é escrever *módulos de extensão* para propósitos específicos; esses
são módulos C que estendem o interpretador Python. Este é
provavelmente o uso mais comum. O segundo motivo é usar Python como um
componente em uma aplicação maior; esta técnica é geralmente referida
como *incorporação* Python em uma aplicação.

Writing an extension module is a relatively well-understood process,
where a "cookbook" approach works well.  There are several tools  that
automate the process to some extent.  While people have embedded
Python in other applications since its early existence, the process of
embedding Python is less straightforward than writing an extension.

Muitas funções da API são úteis independentemente de você estar
incorporando ou estendendo o Python; além disso, a maioria das
aplicações que incorporam Python também precisará fornecer uma
extensão customizada, portanto, é provavelmente uma boa ideia se
familiarizar com a escrita de uma extensão antes de tentar incorporar
Python em uma aplicação real.


Incluir Arquivos
================

Todas as definições de função, tipo e macro necessárias para usar a
API Python/C estão incluídas em seu código pela seguinte linha:

   #include "Python.h"

Isso implica a inclusão dos seguintes cabeçalhos padrão: "<stdio.h>",
"<string.h>", "<errno.h>", "<limits.h>", "<assert.h>" e "<stdlib.h>"
(se disponível).

Nota:

  Uma vez que Python pode definir algumas definições de
  pré-processador que afetam os cabeçalhos padrão em alguns sistemas,
  você *deve* incluir "Python.h" antes de quaisquer cabeçalhos padrão
  serem incluídos.

Todos os nomes visíveis ao usuário definidos por Python.h (exceto
aqueles definidos pelos cabeçalhos padrão incluídos) têm um dos
prefixos "Py" ou "_Py". Nomes começando com "_Py" são para uso interno
pela implementação Python e não devem ser usados por escritores de
extensão. Os nomes dos membros da estrutura não têm um prefixo
reservado.

**Important:** user code should never define names that begin with
"Py" or "_Py".  This confuses the reader, and jeopardizes the
portability of the user code to future Python versions, which may
define additional names beginning with one of these prefixes.

Os arquivos de cabeçalho são normalmente instalados com Python. No
Unix, eles estão localizados nos diretórios
"*prefix*/include/pythonversion/" e
"*exec_prefix*/include/pythonversion/", onde "prefix" e "exec_prefix"
são definidos pelos parâmetros correspondentes ao script **configure**
e *version* do Python é "'%d.%d' % sys.version_info[:2]". No Windows,
os cabeçalhos são instalados em "*prefix*/include", onde "prefix" é o
diretório de instalação especificado para o instalador.

Para incluir os cabeçalhos, coloque os dois diretórios (se diferentes)
no caminho de pesquisa do compilador para as inclusões. *Não* coloque
os diretórios pais no caminho de busca e então use "#include
<pythonX.Y/Python.h>"; isto irá quebrar em compilações
multiplataforma, uma vez que os cabeçalhos independentes da plataforma
em "prefix" incluem os cabeçalhos específicos da plataforma de
"exec_prefix".

C++ users should note that though the API is defined entirely using C,
the header files do properly declare the entry points to be "extern
"C"", so there is no need to do anything special to use the API from
C++.


Objetos, tipos e contagens de referência
========================================

Most Python/C API functions have one or more arguments as well as a
return value of type "PyObject*".  This type is a pointer to an opaque
data type representing an arbitrary Python object.  Since all Python
object types are treated the same way by the Python language in most
situations (e.g., assignments, scope rules, and argument passing), it
is only fitting that they should be represented by a single C type.
Almost all Python objects live on the heap: you never declare an
automatic or static variable of type "PyObject", only pointer
variables of type "PyObject*" can  be declared.  The sole exception
are the type objects; since these must never be deallocated, they are
typically static "PyTypeObject" objects.

Todos os objetos Python (mesmo inteiros Python) têm um *tipo* e uma
*contagem de referências*. O tipo de um objeto determina que tipo de
objeto ele é (por exemplo, um número inteiro, uma lista ou uma função
definida pelo usuário; existem muitos mais, conforme explicado em A
hierarquia de tipos padrão). Para cada um dos tipos conhecidos, há uma
macro para verificar se um objeto é desse tipo; por exemplo,
"PyList_Check(a)" é verdadeiro se (e somente se) o objeto apontado por
*a* for uma lista Python.


Contagens de referência
-----------------------

A contagem de referência é importante porque os computadores de hoje
têm um tamanho de memória finito (e geralmente muito limitado); Conta
quantos lugares diferentes existem que têm uma referência a um objeto.
Esse local poderia ser outro objeto, uma variável C global (ou
estática) ou uma variável local em alguma função C. Quando a contagem
de referência de um objeto se torna zero, o objeto é desalocado. Se
contiver referências a outros objetos, sua contagem de referência será
diminuída. Esses outros objetos podem ser desalocados, por sua vez, se
esse decremento fizer com que sua contagem de referência se torne zero
e assim por diante. (Há um problema óbvio com objetos que fazem
referência um ao outro aqui; por enquanto, a solução é "não faça
isso").

As contagens de referências são sempre manipuladas explicitamente. A
maneira normal é usar a macro "Py_INCREF()" para incrementar a
contagem de referências de um objeto em um, e "Py_DECREF()" para
diminuí-la em um. A macro "Py_DECREF()" é consideravelmente mais
complexa que a "incref", uma vez que deve verificar se a contagem de
referências torna-se zero e então fazer com que o desalocador do
objeto seja chamado. O desalocador é um ponteiro de função contido na
estrutura de tipo do objeto. O desalocador específico do tipo se
encarrega de diminuir as contagens de referências para outros objetos
contidos no objeto se este for um tipo de objeto composto, como uma
lista, bem como realizar qualquer finalização adicional necessária.
Não há chance de que a contagem de referências possa estourar; pelo
menos tantos bits são usados ​​para manter a contagem de referência
quanto há locais de memória distintos na memória virtual (assumindo
"sizeof(Py_ssize_t) >= sizeof(void*)"). Portanto, o incremento da
contagem de referências é uma operação simples.

Não é necessário incrementar a contagem de referências de um objeto
para cada variável local que contém um ponteiro para um objeto. Em
teoria, a contagem de referências do objeto aumenta em um quando a
variável é feita para apontar para ele e diminui em um quando a
variável sai do escopo. No entanto, esses dois se cancelam, portanto,
no final, a contagem de referências não mudou. A única razão real para
usar a contagem de referências é evitar que o objeto seja desalocado
enquanto nossa variável estiver apontando para ele. Se sabemos que
existe pelo menos uma outra referência ao objeto que vive pelo menos
tanto quanto nossa variável, não há necessidade de incrementar a
contagem de referências temporariamente. Uma situação importante em
que isso ocorre é em objetos que são passados como argumentos para
funções C em um módulo de extensão que são chamados de Python; o
mecanismo de chamada garante manter uma referência a todos os
argumentos durante a chamada.

However, a common pitfall is to extract an object from a list and hold
on to it for a while without incrementing its reference count. Some
other operation might conceivably remove the object from the list,
decrementing its reference count and possible deallocating it. The
real danger is that innocent-looking operations may invoke arbitrary
Python code which could do this; there is a code path which allows
control to flow back to the user from a "Py_DECREF()", so almost any
operation is potentially dangerous.

Uma abordagem segura é sempre usar as operações genéricas (funções
cujo nome começa com "PyObject_", "PyNumber_", "PySequence_" or
"PyMapping_"). Essas operações sempre incrementam a contagem de
referências do objeto que retornam. Isso deixa o chamador com a
responsabilidade de chamar "Py_DECREF()" quando terminar com o
resultado; isso logo se torna uma segunda natureza.


Detalhes da contagem de referência
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

O comportamento da contagem de referências de funções na API Python/C
é melhor explicado em termos de *propriedade de referências*. A
propriedade pertence às referências, nunca aos objetos (os objetos não
são possuídos: eles são sempre compartilhados). "Possuir uma
referência" significa ser responsável por chamar Py_DECREF nela quando
a referência não for mais necessária. A propriedade também pode ser
transferida, o que significa que o código que recebe a propriedade da
referência torna-se responsável por eventualmente efetuar um decref
nela chamando "Py_DECREF()" ou "Py_XDECREF()" quando não é mais
necessário --- ou passando essa responsabilidade (geralmente para o
responsável pela chamada). Quando uma função passa a propriedade de
uma referência para seu chamador, diz-se que o chamador recebe uma
*nova* referência. Quando nenhuma propriedade é transferida, diz-se
que o chamador *toma emprestado* a referência. Nada precisa ser feito
para uma referência emprestada.

Por outro lado, quando uma função de chamada passa uma referência a um
objeto, há duas possibilidades: a função *rouba* uma referência ao
objeto, ou não. *Roubar uma referência* significa que quando você
passa uma referência para uma função, essa função assume que agora ela
possui essa referência e você não é mais responsável por ela.

Poucas funções roubam referências; as duas exceções notáveis são
"PyList_SetItem()" e "PyTuple_SetItem()", que roubam uma referência
para o item (mas não para a tupla ou lista na qual o item é
colocado!). Essas funções foram projetadas para roubar uma referência
devido a um idioma comum para preencher uma tupla ou lista com objetos
recém-criados; por exemplo, o código para criar a tupla "(1, 2,
"three")" pode ser parecido com isto (esquecendo o tratamento de erros
por enquanto; uma maneira melhor de codificar isso é mostrada abaixo):

   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"));

Aqui, "PyLong_FromLong()" retorna uma nova referência que é
imediatamente roubada por "PyTuple_SetItem()". Quando você quiser
continuar usando um objeto, embora a referência a ele seja roubada,
use "Py_INCREF()" para obter outra referência antes de chamar a função
de roubo de referência.

A propósito, "PyTuple_SetItem()" é a *única* maneira de definir itens
de tupla; "PySequence_SetItem()" e "PyObject_SetItem()" se recusam a
fazer isso, pois tuplas são um tipo de dados imutável. Você só deve
usar "PyTuple_SetItem()" para tuplas que você mesmo está criando.

O código equivalente para preencher uma lista pode ser escrita usando
"PyList_New()" e "PyList_SetItem()".

No entanto, na prática, você raramente usará essas maneiras de criar e
preencher uma tupla ou lista. Existe uma função genérica,
"Py_BuildValue()", que pode criar objetos mais comuns a partir de
valores C, dirigidos por uma *string de formato*. Por exemplo, os dois
blocos de código acima podem ser substituídos pelos seguintes (que
também cuidam da verificação de erros):

   PyObject *tuple, *list;

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

É muito mais comum usar "PyObject_SetItem()" e amigos com itens cujas
referências você está apenas pegando emprestado, como argumentos que
foram passados para a função que você está escrevendo. Nesse caso, o
comportamento deles em relação às contagens de referência é muito mais
são, já que você não precisa incrementar uma contagem de referências
para que possa dar uma referência ("mande-a ser roubada"). Por
exemplo, esta função define todos os itens de uma lista (na verdade,
qualquer sequência mutável) para um determinado item:

   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;
   }

A situação é ligeiramente diferente para os valores de retorno da
função. Embora passar uma referência para a maioria das funções não
altere suas responsabilidades de propriedade para aquela referência,
muitas funções que retornam uma referência a um objeto fornecem a
propriedade da referência. O motivo é simples: em muitos casos, o
objeto retornado é criado instantaneamente e a referência que você
obtém é a única referência ao objeto. Portanto, as funções genéricas
que retornam referências a objetos, como "PyObject_GetItem()" e
"PySequence_GetItem()", sempre retornam uma nova referência (o
chamador torna-se o dono da referência).

É importante perceber que se você possui uma referência retornada por
uma função depende de qual função você chama apenas --- *a plumagem*
(o tipo do objeto passado como um argumento para a função) *não entra
nela!* Assim, se você extrair um item de uma lista usando
"PyList_GetItem()", você não possui a referência --- mas se obtiver o
mesmo item da mesma lista usando "PySequence_GetItem()" (que leva
exatamente os mesmos argumentos), você possui uma referência ao objeto
retornado.

Aqui está um exemplo de como você poderia escrever uma função que
calcula a soma dos itens em uma lista de inteiros; uma vez usando
"PyList_GetItem()", e uma 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
-----

There are few other data types that play a significant role in  the
Python/C API; most are simple C types such as "int",  "long", "double"
and "char*".  A few structure types  are used to describe static
tables used to list the functions exported  by a module or the data
attributes of a new object type, and another is used to describe the
value of a complex number.  These will  be discussed together with the
functions that use them.


Exceções
========

O programador Python só precisa lidar com exceções se o tratamento de
erros específico for necessário; as exceções não tratadas são
propagadas automaticamente para o chamador, depois para o chamador e
assim por diante, até chegarem ao interpretador de nível superior,
onde são relatadas ao usuário acompanhadas por um traceback (situação
da pilha de execução).

For C programmers, however, error checking always has to be explicit.
All functions in the Python/C API can raise exceptions, unless an
explicit claim is made otherwise in a function's documentation.  In
general, when a function encounters an error, it sets an exception,
discards any object references that it owns, and returns an error
indicator.  If not documented otherwise, this indicator is either
*NULL* or "-1", depending on the function's return type. A few
functions return a Boolean true/false result, with false indicating an
error.  Very few functions return no explicit error indicator or have
an ambiguous return value, and require explicit testing for errors
with "PyErr_Occurred()".  These exceptions are always explicitly
documented.

Exception state is maintained in per-thread storage (this is
equivalent to using global storage in an unthreaded application).  A
thread can be in one of two states: an exception has occurred, or not.
The function "PyErr_Occurred()" can be used to check for this: it
returns a borrowed reference to the exception type object when an
exception has occurred, and *NULL* otherwise.  There are a number of
functions to set the exception state: "PyErr_SetString()" is the most
common (though not the most general) function to set the exception
state, and "PyErr_Clear()" clears the exception state.

The full exception state consists of three objects (all of which can
be *NULL*): the exception type, the corresponding exception  value,
and the traceback.  These have the same meanings as the Python result
of "sys.exc_info()"; however, they are not the same: the Python
objects represent the last exception being handled by a Python  "try"
... "except" statement, while the C level exception state only exists
while an exception is being passed on between C functions until it
reaches the Python bytecode interpreter's  main loop, which takes care
of transferring it to "sys.exc_info()" and friends.

Observe que a partir do Python 1.5, a maneira preferida e segura para
thread para acessar o estado de exceção do código Python é chamar a
função "sys.exc_info()", que retorna o estado de exceção por thread
para o código Python. Além disso, a semântica de ambas as maneiras de
acessar o estado de exceção mudou, de modo que uma função que captura
uma exceção salvará e restaurará o estado de exceção de seu segmento
de modo a preservar o estado de exceção de seu chamador. Isso evita
bugs comuns no código de tratamento de exceções causados por uma
função aparentemente inocente sobrescrevendo a exceção sendo tratada;
também reduz a extensão da vida útil frequentemente indesejada para
objetos que são referenciados pelos quadros de pilha no traceback.

Como princípio geral, uma função que chama outra função para realizar
alguma tarefa deve verificar se a função chamada levantou uma exceção
e, em caso afirmativo, passar o estado da exceção para seu chamador.
Ele deve descartar todas as referências de objeto que possui e
retornar um indicador de erro, mas *não* deve definir outra exceção
--- que sobrescreveria a exceção que acabou de ser gerada e perderia
informações importantes sobre a causa exata do erro.

Um exemplo simples de detecção de exceções e transmiti-las é mostrado
no exemplo "sum_sequence()" acima. Acontece que este exemplo não
precisa limpar nenhuma referência de propriedade quando detecta um
erro. A função de exemplo a seguir mostra alguma limpeza de erro.
Primeiro, para lembrar por que você gosta de Python, mostramos o
código Python equivalente:

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

Aqui está o código C correspondente, em toda sua glória:

   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 */
   }

This example represents an endorsed use of the "goto" statement  in C!
It illustrates the use of "PyErr_ExceptionMatches()" and
"PyErr_Clear()" to handle specific exceptions, and the use of
"Py_XDECREF()" to dispose of owned references that may be *NULL* (note
the "'X'" in the name; "Py_DECREF()" would crash when confronted with
a *NULL* reference).  It is important that the variables used to hold
owned references are initialized to *NULL* for this to work; likewise,
the proposed return value is initialized to "-1" (failure) and only
set to success after the final call made is successful.


Incorporando Python
===================

A única tarefa importante com a qual apenas os incorporadores (em
oposição aos escritores de extensão) do interpretador Python precisam
se preocupar é a inicialização e, possivelmente, a finalização do
interpretador Python. A maior parte da funcionalidade do interpretador
só pode ser usada após a inicialização do interpretador.

A função de inicialização básica é "Py_Initialize()". Isso inicializa
a tabela de módulos carregados e cria os módulos fundamentais
"builtins", "__main__" e "sys". Ela também inicializa o caminho de
pesquisa de módulos ("sys.path").

"Py_Initialize()" não define a "lista de argumentos de script"
("sys.argv"). Se esta variável for necessária para o código Python que
será executado posteriormente, ela deve ser definida explicitamente
com uma chamada com "PySys_SetArgvEx(argc, argv, updatepath)" após a
chamada de "Py_Initialize()".

Na maioria dos sistemas (em particular, no Unix e no Windows, embora
os detalhes sejam ligeiramente diferentes), "Py_Initialize()" calcula
o caminho de pesquisa do módulo com base em sua melhor estimativa para
a localização do executável do interpretador Python padrão, assumindo
que a biblioteca Python é encontrada em um local fixo em relação ao
executável do interpretador Python. Em particular, ele procura por um
diretório chamado "lib/python*X.Y*" relativo ao diretório pai onde o
executável chamado "python" é encontrado no caminho de pesquisa de
comandos do shell (a variável de ambiente "PATH").

Por exemplo, se o executável Python for encontrado em
"/usr/local/bin/python", ele presumirá que as bibliotecas estão em
"/usr/local/lib/python*X.Y*". (Na verdade, este caminho particular
também é o local reserva, usado quando nenhum arquivo executável
chamado "python" é encontrado ao longo de "PATH".) O usuário pode
substituir este comportamento definindo a variável de ambiente
"PYTHONHOME", ou insira diretórios adicionais na frente do caminho
padrão definindo "PYTHONPATH".

A aplicação de incorporação pode orientar a pesquisa chamando
"Py_SetProgramName(file)" *antes* de chamar "Py_Initialize()". Observe
que "PYTHONHOME" ainda substitui isso e "PYTHONPATH" ainda é inserido
na frente do caminho padrão. Uma aplicação que requer controle total
deve fornecer sua própria implementação de "Py_GetPath()",
"Py_GetPrefix()", "Py_GetExecPrefix()" e "Py_GetProgramFullPath()"
(todas definidas em "Modules/getpath.c").

Às vezes, é desejável "desinicializar" o Python. Por exemplo, a
aplicação pode querer iniciar novamente (fazer outra chamada para
"Py_Initialize()") ou a aplicação simplesmente termina com o uso de
Python e deseja liberar memória alocada pelo Python. Isso pode ser
feito chamando "Py_FinalizeEx()". A função "Py_IsInitialized()"
retorna verdadeiro se o Python está atualmente no estado inicializado.
Mais informações sobre essas funções são fornecidas em um capítulo
posterior. Observe que "Py_FinalizeEx()" *não* libera toda a memória
alocada pelo interpretador Python, por exemplo, a memória alocada por
módulos de extensão atualmente não pode ser liberada.


Construções de Depuração
========================

Python pode ser compilado com várias macros para permitir verificações
extras do interpretador e módulos de extensão. Essas verificações
tendem a adicionar uma grande quantidade de sobrecarga ao tempo de
execução, portanto, não são habilitadas por padrão.

Uma lista completa dos vários tipos de compilações de depuração está
no arquivo "Misc/SpecialBuilds.txt" na distribuição do código-fonte do
Python. Estão disponíveis compilações que oferecem suporte ao
rastreamento de contagens de referências, depuração do alocador de
memória ou criação de perfil de baixo nível do loop do interpretador
principal. Apenas as compilações usadas com mais frequência serão
descritas no restante desta seção.

Compilar o interpretador com a macro "Py_DEBUG" definida produz o que
geralmente se entende por "uma compilação de depuração" do Python.
"Py_DEBUG" é habilitada na compilação Unix adicionando "--with-
pydebug" ao comando "./configure". Também está implícito na presença
da macro não específica do Python "_DEBUG". Quando "Py_DEBUG" está
habilitado na compilação do Unix, a otimização do compilador é
desabilitada.

Além da depuração de contagem de referência descrita abaixo, as
seguintes verificações extras são executadas:

* Verificações extras são adicionadas ao alocador de objetos.

* Verificações extras são adicionadas ao analisador e ao compilador.

* Downcasts de tipos amplos para tipos restritos são verificados
  quanto à perda de informações.

* Uma série de asserções são adicionadas ao dicionário e
  implementações definidas. Além disso, o objeto definido adquire um
  método "test_c_api()".

* As verificações de integridade dos argumentos de entrada são
  adicionadas à criação de quadros.

* O armazenamento para ints é inicializado com um padrão inválido
  conhecido para capturar a referência a dígitos não inicializados.

* O rastreamento de baixo nível e a verificação de exceções extras são
  adicionados à máquina virtual de tempo de execução.

* Verificações extras são adicionadas à implementação da arena de
  memória.

* Depuração extra é adicionada ao módulo de thread.

Pode haver verificações adicionais não mencionadas aqui.

Definir "Py_TRACE_REFS" habilita o rastreamento de referência. Quando
definida, uma lista circular duplamente vinculada de objetos ativos é
mantida adicionando dois campos extras a cada "PyObject". As alocações
totais também são rastreadas. Ao sair, todas as referências existentes
são impressas. (No modo interativo, isso acontece após cada instrução
executada pelo interpretador.) Implicado por "Py_DEBUG".

Consulte "Misc/SpecialBuilds.txt" na distribuição do código-fonte
Python para informações mais detalhadas.
