miércoles, 30 de marzo de 2011

Conoce al equipo: Benjamin Peterson

Artículo original: Meet the Team: Benjamin Peterson
Esta entrada es una más de la serie "Conoce al equipo", la cual está pensada como una pequeña introducción al equipo de desarrollo del núcleo de Python.
Nombre:Benjamin Peterson
Lugar:Minnesota (Estados Unidos)
Página Web:http://benjamin-peterson.org/
Blog:http://pybites.blogspot.com/
¿Cuánto tiempo llevas usando Python?
Tres años y medio.
¿Cuánto tiempo llevas haciendo cambios en el núcleo de Python?
Hará tres años exactamente el próximo 25 de marzo.
¿Cómo comenzaste como desarrollador del núcleo? ¿Recuerdas tu primer cambio?
Mi primer propuesta fue rechazada personalmente por Guido. Afortunadamente, insistí y conseguí que algunos de mis parches fueran aceptados. Creo que mi primer cambio fue el reordenamiento del fichero Misc/ACKS.
¿En qué partes de Python estás trabajando ahora?
Me gusta el parser, el compilador y el núcleo del intérprete, sin embargo soy conocido por tocar todas las partes en el desarrollo del núcleo de Python... ¡excepto lo referente a Windows!
¿Qué haces con Python cuando no estás trabajando en el desarrollo del núcleo?
¡Lo uso para implementar un intérprete de Python (http://pypy.org)!. Créeme, en el fondo soy un implementador de Python. :) Soy el creador de six (http://pypi.python.org/pypi/six), una biblioteca de compatibilidad de Python 2 y 3.
¿Qué haces cuando no estás programando?
Compongo música, toco el clarinete y leo libros de matemáticas. También salgo al campo de vez en cuando.

lunes, 28 de marzo de 2011

Características de Python 2.7 obsoletas en 3.x



Una reciente discusión en python-dev
puso de manifiesto un fallo en la actual política de obsolescencia (deprecation)
adoptada por los desarrolladores en la migración de 2.7 a la nueva 3.x.
En consecuencia, el equipo de desarrollo ha tenido que modificar su
política para tener en cuenta que los usuarios migrarán directamente de Python 2.7
a la última versión de 3.x, sin pasar por versiones intermedias.


Antecedentes


Python tiene un fuerte compromiso con la compatibilidad con versiones anteriores.
No se permite ningún cambio a menos que esté de acuerdo con las directrices de compatibilidad,
que en esencia dicen que programas correctos no deben fallar en versiones más modernas.
Sin embargo, esto no es siempre posible, por ejemplo, cuando una API deja de funcionar y debe ser
reemplazada por algo nuevo. En este caso, Python sigue una política de obsolescencia basada
en un periodo de transición de un año en el que las características a renovar son consideradas
formalmente obsoletas. En el periodo intermedio, se debe emitir un aviso (deprecation warning)
de forma que los programadores tengan tiempo de actualizar su código. Los detalles completos
de la política de Python están documentados en el PEP 5. Los cambios sólo se hacen
en las versiones nuevas y normalmente pasan 18 meses entre versiones; ergo la norma es
una versión en el periodo.

La única excepción ha sido Python 3. La nueva rama ha sido específicamente creada para permitir cambios que
rompieran la compatibilidad, permitiendo así a los desarrolladores de Python corregir problemas que,
simplemente, no podían solucionarse dentro de la política actual. Por ejemplo, hacer las cadenas
Unicode por defecto y devolver iteradores en lugar de listas.



Líneas paralelas de desarrollo


Sabiendo que la transción a Python 3 llevaría tiempo (unos 5 años, según varias estimaciones),
habría cierto desarrollo paralelo entre 2 y 3.

Con Python 2.7 como versión final de Python 2, se acordó que el periodo de mantenimiento
se extendería por un periodo substancial. Tarde o temprano, los desarrolladores que quieran
migrar a versiones más nuevas deberán dar el salto a Python 3.

He aquí uno de los problemas...



Obsolescencias sorpresa


En un hilo en python-dev`<http://mail.python.org/pipermail/python-dev/2011-March/109010.html>`__,
se señaló que una función específica de la API C, PyCObject_AsVoidPtr, había sido eliminada
con lo que parecían insuficientes avisos. Y, sin embargo, la política adoptada se supone que debería
proteger contra eso. ¿Qué pasó?

El cambio fue parte de una migración mayor desde una API más antigua, PyCObject, a una nueva y
mejorada, PyCapsule. El problema es que PyCObject es la predeterminada, y desde luego,
la única API disponible en Python 2.6. En 2.7 pasó a estar considerada obsoleta, y en Python 3.2
no existe, y la nueva PyCapsule debe ser usada. Esto supone un periodo de tránsito entre el
lanzamiento de 2.7 (julio del 2010) al lanzamiento de 3.2 (febrero del 2011) de siete meses; mucho
menor al mínimo de doce meses exigido, y hace más difícil dar soporte a un rango razonable de
versiones de Python.

Para alguien migrando de 3.0 a 3.1 y después a 3.2, el tránsito es correcto. Python 3.1 fue
lanzado en marzo del 2010 con la marca de obsolescencia, por tanto, en la serie 3.x hay un periodo
de casi 12 meses. Sin embargo, esto no es lo habitual: migran de 2.7 directamente a la última
versión de 3.x; en nuestro caso, 3.2, apareciendo este problema. Nunca fue la intención del equipo
de desarrollo, pero PEP 5 no se escribió para desarrollos de dos versiones en paralelo.



Entonces, ¿qué hacemos?


Dado que el problema con la API PyCObject/PyCapsule está bien definido, no es imposible
de evitar, pero al menos una persona de python-dev ha tenido algunos problemas con ello.
En resumen, esto no debería haber ocurrido.

Para el caso específico de PyCObject/PyCapsule, el problema ya existía y no había mucho
que se pudiera hacer. Reincorporar PyCObject no era una opción, dado que sólo añadiría nuevas
incompatibilidades. Sin embargo, la visión general fue que era posible, aunque tedioso, escribir
código que se adaptara a cualquier API disponible. De hecho, en Python 3.1, la API PyCObject
fue escrita como un wrapper de la PyCapsule. Había una sugerencia de que, en caso de ser necesitada,
el código de la implementación en 3.1 podría ser extraído y ser usado como código para terceros.
Adicionalmente, se acordó que se escribiría un PEP "retroactivo" cubriendo el cambio, para describir
las razones tras el cambio y documentar los recursos que ayudarían a los programadores a migrar.

El equipo de Python ahora está al tanto de los problemas y trabajará para evitar que vuelvan a ocurrir.
Guido publicó una reseña
de la situación y sugirió que Python 3 debería ser conservativo dejando características obsoletas
por el momento. Como mínimo, las API consideradas obsoletas se conservarán más tiempo antes de ser
eliminadas, para dar a los programadores migrando desde 2.7 un camino más fácil.

Más indirectamente, el hilo mostró el problema de cómo comunicar de forma más efectiva los cambios
en Python a una audiencia mayor, de forma más oportuna; una de las razones de ser de este blog.



¿Qué significa todo esto?


En primer lugar, significa que los desarrolladores de Python no lo hacen todo bien. Nadie
quiere hacer la vida de los programadores más difícil, simplemente no fue algo que se viera a tiempo.

En segundo lugar, arreglar el problema puede hacer aún más daño, así que PyCObject no se
reincorporará. Aunque eso ayudaría a los programadores afectados por el cambio, en global haría los problemas
de compatibilidad más complejos. Mientras tanto, tendremos que sobreponernos al problema y seguir adelante.
La lección está aprendida, y no volveremos a cometer el mismo error de nuevo.

Una hecho positivo puesto de manifiesto es que el equipo de Python escucha lo que sus usarios tienen que decirles.
La compatibilidad es muy importante, y se pone todo el esfuerzo en hacer la transición a nuevas versiones
tan indolora como sea posible. En particular, los desarrolladores de bibliotecas deberían ser
capaces de soportar varias versiones de Python con un nivel adecuado de esfuerzo.

Finalmente, los desarrolladores no han abandonado 2.7. No se implementarán nuevas características
y no existirá 2.8, pero la visión de los usuarios de 2.7 todavía es importante. Estar seguros de
que los usuarios pueden migrar a 3.x cuando estén listos es de vital importancia para la comunidad de Python.


jueves, 24 de marzo de 2011

Acerca de muestreos, módulo futures y ejecución en paralelo

Artículo original: Of polling, futures and parallel execution

Una de las mayores preocupaciones en la computación moderna es el ahorro de energía. Es muy importante en dispositivos portátiles (portátiles, tabletas, móviles). Una CPU moderna es capaz de entrar en un número variado de estados de ahorro de energía cuando está ociosa. Cuanto mayor tiempo se mantenga en estado ocioso, más profundo será el estado de ahorro de energía y menor será la energía consumida y por lo tanto, la duración de la batería será más larga en cada carga.

Los estados de ahorro de energía tienen un enemigo: los muestreos. Cuando una tarea activa la CPU periódicamente, incluso por algo tan trivial como leer una dirección de memoria para verificar si ha habido cambios potenciales, la CPU abandona el estado de ahorro de energía, activa a todas sus estructuras internas y solo volverá a entrar en este estado mucho después de haber terminado su labor causada por esa activación de poca importancia. Esto acaba con la vida de la batería. La propia Intel está preocupada por esto.

Python 3.2 viene con un nuevo módulo estándar para lanzar tareas concurrentes y esperar que terminen: el módulo concurrent.futures. Mientras hojeaba su código, noté que usaba muestreos en algunos de sus hilos y procesos trabajadores. Y digo «algunos de» ya que la implementación de ThreadPoolExecutor (basada en hilos) es diferente que la implementación de ProcessPoolExecutor (basada en procesos). El primero hace muestreos en cada uno de los hilos trabajadores, mientras que el último solo lo hace en un único hilo llamado el hilo de gestión de la cola, el cual se usa para comunicarse con el proceso que realiza el trabajo.

Los muestreos se usaron aquí para una sola cuestión: detectar cuando debería empezar el procedimiento de apagado. Otras tareas, como encolar objetos que puedan ser invocados o buscar los resultados de uno de esos objetos encolado previamente, usan objetos sincronizados de tipo cola. Estos objetos proceden bien del módulo threading o bien del multiprocessing, dependiendo de la implementación del ejecutor que se esté utilizando.

Así que se me ocurrió una solución simple: Sustituí el muestreo por un centinela, el centinela None ya integrado. Cuando una cola recibe None, un trabajador en espera se activa de forma natural y verifica si se debería apagar o no. En el ProcessPoolExecutor hay una pequeña complicación ya que necesitamos activar hasta N procesos trabajadores además del hilo de gestión de colas.

En mi parche inicial, todavía había un tiempo de espera de muestreo muy largo (10 minutos) de manera que los trabajadores pudieran activarse en algún momento. Este largo tiempo de espera existía por si acaso el código contenía bugs y no recibían una notificación de apagado cuando debían a través del ya mencionado centinela. Por curiosidad, me sumergí en el código fuente de multiprocessing y llegué a otra observación interesante: bajo Windows, multiprocessing.Queue.get() con un tiempo de espera no nulo y finito usaba ... muestreo (por lo cual abrí el asunto 11668). Utiliza un tipo de muestreo de alta frecuencia muy interesante, ya que se comienza con un tiempo de espera de un milisegundo el cual se incrementa en cada iteración.

No hace falta mencionar que aunque usara un tiempo de espera muy grande, haría mi parche inútil en Windows ya que la forma en que el tiempo de espera está implementado implicaría activaciones en cada milisegundo. Así que no me quedó más remedio y eliminar el enorme tiempo de muestreo. Mi último parche ni siquiera utiliza un tiempo de espera, y por lo tanto no debería causar activaciones periódicas, independientemente de la plataforma.

Echando un vistazo atrás, antes de Python 3.2, toda estructura para esperas en el módulo threading, y por lo tanto en muchas partes del módulo multiprocessing ya que él mismo utiliza hilos trabajadores para varias tareas, usaba muestreo. Esto se corrigió en el asunto 7316.

Informe de la Cumbre Language Summit de 2011



La Language Summit de este año tuvo lugar el jueves 10 de marzo en Atlanta, el
día anterior al comienzo de las conferencias de PyCon. Asistieron representantes
de las implementaciones CPython, PyPy, Jython,
IronPython, y Parrot; desarrolladores de los paquetes para Fedora,
Ubuntu, y Debian; desarrolladores del proyecto Twisted , y muchos otros.


Blog de desarrollo


Uno de los primeros asuntos tratados fue este mismo blog, iniciado
por el Responsable de Comunicaciones de la PSF, Doug Hellmann.
La lista de correo de python-dev tiene mucho tráfico,
y a menudo muy intenso, por lo que nace este blog. Pretende ser una forma
más sencilla para los usuarios de seguir las novedades del desarrollo.
Pensamos cubrir los PEP, todas las decisiones importantes, nuevas
características y bugs críticos; y se incluirá una cobertura informal de qué
está pasando en el proceso de desarrollo.

La publicación en el blog está abierta a todas las implementaciones de Python.
Por ejemplo, aunque PyPy ya tiene su propio blog activo,
estaremos encantados de que publiquen aquí también sus novedades. Una discusión paralela
conduce a implementaciones alternativas, también mencionadas en la
página de descargas de python.org. Las nuevas versiones
liberadas también serán recogidas como nuevos elementos en la página principal de
python.org



Advertencias de compatibilidad


Con 3.2 introducimos ResourceWarning para que los usuarios pudieran
encontrar áreas de código dependientes del recuento de referencias de CPython. La
advertencia no sólo ayuda a los usuarios a escribir un mejor código, sino que
además les permite escribir código más portable entre diferentes máquinas virtuales.
Para mayor compatibilidad entre implementaciones, se sugirió un nuevo tipo de aviso: CompatibilityWarning

La idea surgió gracias a un bug en CPython recientemente archivado, encontrado por
los desarrolladores de PyPy (Issue #11455 )
Se explica una situación donde CPython permite al usuario crear un tipo con claves
no de cadena en su __dict, que al menos PyPy y Jython no soportan. Idealmente,
los usuarios podrían activar una advertencia para detectar estos casos, tal y como
hacen con ResourceWarning.



Biblioteca Estándar independiente


Ahora que la transición del código de Cpython de Subversion a Mercurial ha sido
completada, ha resurgido la idea de separar la biblioteca estándar a su propio
repositorio. Los desarrolladores de las implementaciones alternativas están muy
interesados, ya que esto simplificaría enromemente su proceso de desarrollo.
A día de hoy, toman una instantánea de CPython y le aplican cualquier
implementación específica, reemplazan algunas extensiones en C con versiones
de Python puro, etc.

La conversión tendrá que ser definida en un próximo PEP. Uno de los
puntos de la discusión es cómo se implementará el control de versiones.
Dado que la biblioteca vivirá fuera de cualquiera de las implementaciones,
es probable que sea controlada por sí misma, y las pruebas necesitarán considerar
también la versión.

Otra asunto a tratar en la separación de la biblioteca es la implementación en
Python puro o sus equivalentes en C. Maciej Fijalkowski, del proyecto PyPy,
mencionó que con el tiempo, algunos módulos han tenido pequeñas diferencias
entre sus versiones en C y Python. Mientras la discusión sobre esta separación continúa,
el equipo ha sugerido un enfoque más estricto a los cambios en dichos módulos
para no penalizar el uso de uno u otro. Se prefirió, además, la implementación en Python,
reservando las versiones en C sólo para los casos en los que se obtenga una mejora en el rendimiento.



Página de logros de rendimiento


El Speed Center de PyPy ha hecho un gran trabajo mostrando los resultados del
rendimiento de PyPy, y sugirió cierta discusión sobre si alojar un sitio similar
en python.org, posiblemente performance.python.org, para todas las máquinas virtuales
que tomen parte. Además de los logros de rendimiento, se deberán considerar cosas como
uso de memoria, tests pasados y compatibilidad del lenguage. Actualmente se compara
PyPy y CPython, por lo que se necesitará cierto trabajo para adaptar la infraestructura
para trabajar con otras implementaciones.

El nuevo Speed Center podría vivir en el Laboratorio de Código Abierto
en la Oregon State University
(Allison Randal pertenece a su junta
directiva). Jesse Noller mencionó el esfuerzo que supone obtener máquinas de alto rendimiento
para instalar. ¡Las donaciones son bienvenidas!

Si tú o tu organización estáis interesados en donar para esta causa, u otras, por favor
contactad con la Python Software Foundation, y visitad
nuestra página de donaciones.



Levantamiento de la moratoria


Con el comienzo del desarrollo de CPython 3.3, la moratoria en los cambios del
lenguaje se ha levantado. Aunque no hay límites definidos, se espera que los cambios
sean conservativos. Al intentar reducir el ritmo de cambio, permitimos que las
implementaciones alternativas se pongan al día. Si bien ninguna logró llegar a
la familia 3.x, gracias a la moratoria, PyPy y IronPython alcanzaron recientemente
la compatibilidad con 2.7, e IronPython ha comenzado su andadura hacia 3.x.

En cuanto a los cambios que se esperan en 3.3, esperamos que el
PEP 380 sea aceptado. Este PEP introduce
una nueva sintaxis para yield from <expr>, permitiendo a un generador devolver mediante un yield
otro generador. Aparte de esto, no se esperan más cambios en el futuro cercano.



Atributos de las excepciones


El siguiente tema fue una rápida discusión sobre las excepciones. Éstas deberían proporcionar
mejores atributos, en lugar de forzar a los usuarios a confiar en mensajes en strings. Por ejemplo,
en un ImportError, sería útil tener fácil acceso al import que ha fallado, en lugar de tener que analizarlo
para identificarlo.

La implementación se basará probablemente en un argumento palabra clave cuando se inicialize
el objeto excepción. Actualmente existe un parche para el caso del
ImportError.



Acuerdos de contribución


Los acuerdos de contribución fueron también mencionados, y algunos acuerdos electrónicos están en marcha.
El acuerdo de contribución individual
de Google fue una de las múltiples inspiraciones sobre el funcionamiento del nuevo sistema.
El asunto ha sido extensamente discutido, y mucha gente está deseando una resolución en este área.
Adicionalmente, se está investigando para asegurar que cualquier un acuerdo electrónico sea válido en
jurisdicciones fuera de EE.UU.



Google Summer of Code


Martin von Lšwis dedicó un minuto para introducir otro año del Google Summer of Code, bajo el paraguas
de la PSF. Se anima a los desarrolladores a actuar no sólo como maestros, sino también proponiendo
proyectos en los que trabajar a los estudiantes (y recordar que sugerir un proyecto no implica que lo
vayas a supervisar tú). Si estás interesado en ayudar en cualquier forma, visita la
convocatoria para proyectos y mentores.
de la PSF.



Distutils


Le llegó el turno a Distutils2, y Tarek ZiadŽ mencionó que su objetivo a corto plazo es terminar
la migración a Python 3 y prepararlo para la consiguiente fusión de nuevo en la biblioteca estándar de Python.
Adicionalmente, con la nueva fusión viene un nuevo nombre: packaging. El equipo de packaging también planea
proeveer un paquete independiente, todavía llamado Distutils2, soportando desde Python 2.4 hasta 3.2.

El resultado del sprint de packaging, que fue uno de los mayores grupos de la PyCon, fue muy bueno. Sus resultados están
en Bitbucket, esperando su fusión con la biblioteca estándar.



El futuro de las máquinas virtuales alternativas


IronPython comentó sus planes de futuro, y el lanzamiento de la 3.x está próximo.
Anunciaron el de su versión 2.7.0 en la PyCon, su primera versión basada
en la comunidad desde que el proyecto fue cedido por Microsoft, y comenzarán el trabajo
hacia la 3.x en los siguientes meses.

Jython publicó recientemente la versión 2.5.2, y ha comenzado a planear la 2.6.
Algunos han sugerido que salten a la 2.7, ya que las diferencias entre ambas no son
grandes; pero el salto podría retrasar la primera liberación. La frase "libera pronto, libera a menudo"
fue citada en la charla. Podrían ser capaces de dar el salto de la 2.6 a 3.x y considerar
las diferencias entre 2.6 y 2.7 después.



Financiación del desarrollo


Aparte de los planes para la 3.x, está el asunto de la financiación del desarrollo y cómo
facilitar el que alguna de las implementaciones alternativas alcance la serie 3.x.
En cualquier caso, se debe hacer una propuesta a la PSF antes de que nada pueda ser
discutido. Aquellos interesados en recibir becas por su trabajo, deberían contactar la Junta de la PSF.



Meta de Python


Jim Fulton comenzó una discusión sobre lo que él llamó la "meta" de Python. En su
experiencia desplegando aplicaciones de Python, se ha encontrado con que el sistema
es impredecible y dificil de manejar. Con expertos en empaquetado de Fedora y
Ubuntu/Debian a mano, fuimos capaces de echar una mirada crítica a por qué las cosas
son como son.

En Fedora, la instalación básica de Python está basada en el Live CD, por lo que
es una versión mínima con pocas dependencias, los mínimos exigibles para que el sistema
pueda correr. Otras diferencias que se ven son la eliminación de
módulos de la biblioteca estándar, como distutils, o que la distribución incluye bibliotecas
desfasadas.

No parece que a día de hoy haya una solución clara, pero las partes implicadas
continuarán trabajando en el problema.



Características de la 3.3


Srgieron algunas ideas para la 3.3, incluyendo dos PEP.
El
PEP 382, acerca de los espacios
de nombres en paquetes debería aparecer en algún punto del ciclo. También
fue mencionado durante la discusión de la fusión de distutils.

El PEP 393, que define una representación
flexible de las strings, fue también discutido, y despertó el interés de algunos estudiantes
como proyecto GSoC. Junto con las implementaciones, se necesitará dedicar cierto esfuerzo
para caracterizar el rendimiento y uso de memoria para ver si pueden ser aceptados.



Unladen Swallow


Unladen Swallow (golondrina sin carga) está a día de hoy en un estado de "reposo"
y no se incluirá en CPython 3.3. Para progresar, necesitaremos la ayuda de
más desarrolladores, ya que los expertos actuales son insuficientes para realizar
el trabajo. Durante la discusión, se comentó de nuevo que si la financiación es lo que
empujaría Undaden Swallow al siguiente nivel, los interesados deberían contactar con la PSF.

Aunque Unladen Swallow esté en estado de reposo y su futuro sea incierto, el proyecto
ha proporcionado múltiples beneficios a Python y a la comunidad de código abierto en general.
Por ejemplo, el conjunto de herramientas de pruebas de rendimiento usado por Unladen Swallow es muy útil para
probar implementaciones alternativas. Además, desarrolladores de Unladen Swallow han contribuído
a LLVM y Clang.

Otras dos ideas de rendimiento fueron discutidas brevemente, incluyendo la propuesta de
Dave Malcom de incluir el código de funciones en el propio cuerpo (inlining). Martin von Lšwis
comentó que está trabajando en un módulo de compilación al vuelo, aunque los desarrolladores de PyPy
expresaron su escepticismo acerca de la efectividad de este tipo de sistemas.



Pavimentando el camino a los frameworks asíncronos


Al final del día hubo una discusión acerca del nivel de integración de Twisted
en la biblioteca estándar. La idea principal es que existe una alternativa a asyncore
que permite una una transición más fácil a Twisted o otros frameworks de programación
asíncronos.

El proceso se llevará a cabo en un PEP, que algunos han sugerido servirá para un propósito
similar a la WSGI, pero para bucles de eventos asíncronos. Junto con los autores del PEP,
el proyecto Twisted y otros necesitarán esforzarse en asegurarse de que todo el mundo está
en el mismo lado.



Más información


Para más información, lee las notas de
Nick Coghlan
(desarrollador de CPython) y
lo más destacado (en inglés).


miércoles, 23 de marzo de 2011

¡Bienvenido a Python Insider!



Python Insider es la traducción del blog oficial del equipo de
desarrollo del core de Python. Es un resumen de los asuntos tratados en la
lista de correo de los desarrolladores, con especial hincapié en
los cambios que sobrevendrán a Python. Haremos un resumen de la actividad
de Python-Dev, como la reciente migración a Mercurial, los últimos
Python Enhancement Proposals (PEP) aprobados, cambios en la API
y otros asuntos relevantes en el desarrollo del núcleo de Python.

El blog, más que un substituto, será un complemento de la lista de
correo python-dev y de los blogs personales de los desarrolladores (véase
los enlaces en la barra lateral). Servirá de canal para hablar públicamente
de los proyectos una vez completados, o cuando llegue el momento en el que necesiten
más voluntarios. Agradecemos la discusión en el blog, pero esperamos que aquellos
interesados se una a la lista de correo y puedan seguir las discusiones directamente.

El idioma común a todos los desarrolladores es el inglés, así que siempre que sea posible,
usa los canales originales para que tu opinión pueda llegar a donde debe.

Puedes pensar en este blog como una ventana a la evolución de Python.


Cómo suscribirte


Hay varias formas de seguir Python Insider:




Se busca ayuda


Aunque disponemos de un equipo dedicado a escribir entradas para el blog,
estamos buscando a alguien con habilidades en diseño web para trabajar en la
plantilla de Blogger. También estamos buscando gente dispuesta a traducir a otros idiomas.
Si puedes ayudar mejorando el aspecto del blog o traduciendo, por favor
contacta con Doug Hellmann (doug dot hellmann en gmail).