Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

168
Vistas
¿Puedes cambiar con seguridad el tipo de un objeto de Python en una extensión de C?

Pregunta

Supongamos que implementé dos tipos de Python usando la API de extensión de C y que los tipos son idénticos (mismo diseño de datos/ struct C) con la excepción de sus nombres y algunos métodos. Suponiendo que todos los métodos respeten el diseño de los datos, ¿puede cambiar con seguridad el tipo de un objeto de uno de estos tipos al otro en una función de C?

En particular, a partir de Python 3.9, parece haber una función Py_SET_TYPE , pero la documentación no aclara si es seguro hacerlo ni cuándo. Estoy interesado en saber cómo usar esta función de manera segura y si los tipos se pueden cambiar de manera segura antes de la versión 3.9.

Motivación

Estoy escribiendo una extensión de Python C para implementar un Persistent Hash Array Mapped Trie (PHAMT); en caso de que sea útil, el código fuente está aquí (al momento de escribir, está en este compromiso ). Una característica que me gustaría agregar es la capacidad de crear un Trie mapeado de matriz hash transitoria (THAMT) a partir de un PHAMT. Los THAMT se pueden crear a partir de PHAMT en tiempo O(1) y se pueden mutar en el lugar de manera eficiente. Fundamentalmente, los THAMT tienen exactamente la misma estructura de datos C subyacente que los PHAMT: la única diferencia real entre un PHAMT y un THAMT son algunos métodos encapsulados por sus tipos de Python. Esta estructura común permite convertir de manera muy eficiente un THAMT en un PHAMT una vez que se ha terminado de realizar una serie de ediciones. (Este patrón generalmente reduce la cantidad de asignaciones de memoria cuando se realiza una gran cantidad de actualizaciones en un PHAMT).

Una forma muy conveniente de implementar la conversión de THAMT a PHAMT sería simplemente cambiar los punteros de tipo de los objetos THAMT del tipo THAMT al tipo PHAMT. Estoy seguro de que puedo escribir código que navegue con seguridad este cambio, pero puedo imaginar que hacerlo podría, por ejemplo, romper el recolector de basura de Python.

(Para ser claros: la motivación es solo el contexto de cómo surgió la pregunta. No busco ayuda para implementar las estructuras descritas en la Motivación , busco una respuesta a la Pregunta anterior).

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

De acuerdo con la referencia del lenguaje, capítulo 3 "Modelo de datos" (ver aquí ):

El tipo de un objeto determina las operaciones que admite el objeto (por ejemplo, "¿tiene una longitud?") y también define los valores posibles para los objetos de ese tipo. La función type() devuelve el tipo de un objeto (que es un objeto en sí mismo). Al igual que su identidad, el tipo de un objeto también es inmutable.[1]

lo cual, en mi opinión, establece que el tipo nunca debe cambiar, y cambiarlo sería ilegal ya que rompería la especificación del idioma. Sin embargo, la nota a pie de página establece que

[1] Es posible en algunos casos cambiar el tipo de un objeto, bajo ciertas condiciones controladas. Sin embargo, generalmente no es una buena idea, ya que puede provocar un comportamiento muy extraño si se maneja incorrectamente.

No conozco ningún método para cambiar el tipo de un objeto desde Python, por lo que "posible" puede referirse a la función CPython.

Por lo que puedo ver, un PyObject se define internamente como un

 struct _object { _PyObject_HEAD_EXTRA Py_ssize_t ob_refcnt; PyTypeObject *ob_type; };

Entonces, el conteo de referencias aún debería funcionar. Por otro lado, generará una falla de segmento en el intérprete si establece el tipo en algo que no sea PyTypeObject , o si el puntero está free() d, por lo que las advertencias habituales.

Aparte de eso, estoy de acuerdo en que la especificación es un poco ambigua, pero la cuestión de la "legalidad" puede no tener una buena respuesta. En resumidas cuentas, me parece que "no cambie los tipos a menos que sepa lo que está haciendo, y si no está pirateando CPython, no sabe lo que está haciendo".

Editar: la función Py_SET_TYPE se agregó en Python 3.9 en función de este compromiso. Aparentemente, la gente solía configurar el tipo usando

 Py_TYPE(obj) = typeobj;

Entonces, la inclusión (sin haber sido anunciada anteriormente, por lo que puedo ver) es más parecida a agregar una función de conveniencia.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda