We have a contractor for our Android contract!

Publicado por Russell Keith-Magee en 26 November 2019

A couple of months ago, we announced that the BeeWare project had received a grant from the PSF to improve our support for Android. At that time, we issued a call for contractors to help us complete this work.

We're very happy to announce that we've now selected a contractor: Asheesh Laroia.

Asheesh is a regular speaker at Python events, where he has delved into a range of detailed and complex topics. He also impressed us with the list of unconventional engineering integration projects he's been involved with in a professional and casual capacity.

When asked why he applied to work with BeeWare on this contract, Asheesh said: "I use an Android phone every day, and I'm honored to be able to help implement the BeeWare vision of using Python to build first-class, native applications."

Asheesh will be starting work in mid December, and if all goes well, we should start seeing significant results by mid to late February. If you'd like to keep track of progress, you can follow BeeWare on Twitter; we'll also post larger updates on this blog.

BeeWare Project Awarded a PSF Education Grant

Publicado por Russell Keith-Magee en 25 September 2019

The BeeWare Project wants to make it possible for all Python developers to write native apps for desktop and mobile platforms. We have solid support for most desktop operating systems and iOS, but we know our Android support is lacking. The BeeWare core team knows what needs to be done to address the problem - what we’ve been missing are time and resources.

Thanks to the PSF Education Grants group, that’s no longer an issue. We’ve been awarded a US$50,000 grant to bring BeeWare’s Android support to a level comparable with our iOS support. We currently don’t have the time to do the work ourselves, so we’re calling for contractors to help us deliver this support.

This is a paid contract, which we anticipate lasting 3-6 months (depending on the experience of the winning contractor). You don’t have to be based in the US or Europe, either; the opportunity is open to anyone who can meet the requirements of the contract.

Unfortunately, the task calls for some sophisticated skills, and we’re not in a position to provide extensive mentoring. A successful bid is likely to require some prior experience, and a history with the technologies involved.

A full role description and scope of work for the contract is available. To register your interest, please forward your resume and cover email to contracts@beeware.org.

We look forward to being able to announce full Android support in the near future!

2018 Google Summer of Code - VOC Optimization

Publicado por Patience Shyu en 14 August 2018

Google Summer of Code is coming to an end. I've spent the summer working on optimizing the VOC compiler, and I’m super excited to share the results.


There are a couple of ways to evaluate the performance improvement from my project.


Firstly, we introduced a microbenchmarking suite. Each microbenchmark is a small piece of Python code that tests a single and specific Python construct, or datatype, or control flow. The benchmarking infrastructure itself is crude (essentially it just tells you the total amount of processor time it took to run, with no fancy statistics) but it has been extremely useful to me while working on performance features to verify performance gain.

The idea is that the benchmarking suite is not to be run as part of the full test suite, but rather as needed and manually whenever an optimization is implemented. It also provides a way to check and prevent performance regression, especially on the "optimized" parts of VOC. While it doesn't really make sense to record specific numbers, as they will always vary from machine to machine, it should be reasonably easy to compare two versions of VOC. Benchmark numbers are included on each optimization-related PR I've worked on this summer (see PR log below), and I hope that more benchmarks will be added as more performance efforts are carried out in the future.


Pystone is a Python Dhrystone, a standard benchmark for testing the performance of Python on a machine. Here are the before and after results on my machine:

May 10th, 2018:

$ python setup.py test -s tests.test_pystone test_pystone (tests.test_pystone.PystoneTest) ... Pystone(1.2) time for 50000 passes = 101.833 This machine benchmarks at 490.998 pystones/second

$ python setup.py test -s tests.test_pystone test_pystone (tests.test_pystone.PystoneTest) ... Pystone(1.2) time for 50000 passes = 101.298 This machine benchmarks at 493.595 pystones/second

$ python setup.py test -s tests.test_pystone test_pystone (tests.test_pystone.PystoneTest) ... Pystone(1.2) time for 50000 passes = 102.247 This machine benchmarks at 489.014 pystones/second

On current master (Aug 14th, 2018):

$ python setup.py test -s tests.test_pystone test_pystone (tests.test_pystone.PystoneTest) ... Pystone(1.2) time for 50000 passes = 11.2300 This machine benchmarks at 4452.37 pystones/second

$ python setup.py test -s tests.test_pystone test_pystone (tests.test_pystone.PystoneTest) ... Pystone(1.2) time for 50000 passes = 10.9833 This machine benchmarks at 4552.36 pystones/second

$ python setup.py test -s tests.test_pystone pystone (tests.test_pystone.PystoneTest) ... Pystone(1.2) time for 50000 passes = 10.9498 This machine benchmarks at 4566.29 pystones/second


Some things that I learned about VOC while working on this project:

1. Object creation in the JVM is expensive. This definitely does not mean that the VOC user writing Python should think about minimizing the number of objects that she creates, but rather that any time we can non-trivially reduce the number of objects created during bytecode transpilation or in VOC-defined function calls, we can expect to see a huge performance boost. Integer and boolean preallocation, which is about reusing objects that have already been created, was one of the most significant improvements we made this summer.

2. Method calls in VOC are expensive. This is essentially due to the process of invoking a callable: you have to check that the method is defined on the object, then construct it (read: object creation!), and check the arguments, before it can actually be called. (This is done using reflection, which is super interesting and confusing in itself.) And this is the reason why refactoring the Python comparison functions made such a big performance impact, because we were able to circumvent this process.

3. Exception-heavy code is expensive. Again, this is not to say that the programmer is on the hook for being frugal when throwing exceptions, but that VOC benefits greatly by avoiding the use of exceptions internally except when strictly necessary. For instance, Python uses StopIteration exceptions to signal the end of a for loop, and they quickly rack up when you have nested loops (everything is ultimately related to object creation!). That was the motivation for the nested loops optimization.

If I may be a bit more reflective here, one of the a-ha! moments I had this summer was realizing that to really optimize something, you have to understand where its biggest problems are first. I remember pitching to Russ at the start of the summer things like loop unrolling, constant folding, even converting to SSA-form (you know, stuff I heard about optimzation in my compilers class) and he was saying to me, think simpler. While working on my project, I used a profiler to understand exactly which parts of VOC were slow, and that information drove the changes we implemented. I think it worked out pretty well!

Future Work

  • Minimize boxing of primitive types like String and Int. As VOC is written half in Python, half in Java, a single integer can be found in various representations on its way through the compiler -- as a Python object, unboxed to a primitive Java int, then packaged back up to a Python object. This problem was (somewhat incoherently) addressed in my proposal, but ultimately we couldn't come up with a good abstraction to support it.
  • Build a peephole optimizer. CPython's peephole optimizer scans generated bytecode to identify sequences of bytecode that can be optimized, VOC could benefit from this too.
  • Hook up more benchmarks, which serve as both proof of the kinds of programs VOC can currently compile and areas ripe for performance improvement.

Thank you

I will wrap this up by giving big thanks to Russ, my mentor. The time you spent helping me form my ideas, patiently answering my questions and reviewing my work was invaluable to me. It couldn't have been easy keeping up with what I was doing especially since I started improvising halfway through the summer. I am so grateful for your help, thank you.

2018 Google Summer of Code - Implement asyncio support in VOC

Publicado por Yap Boon Peng en 11 August 2018

In the blink of an eye, Google Summer of Code (GSoC) 2018 has come to an end. During the three months long coding period, I have contributed several patches in VOC repository of BeeWare, all working towards the ultimate end goal of running asyncio module in VOC. In this blog post (which is my first actual blog post by the way 😄), I will document what I have done so far, why I couldn't make it to the end goal (yea, unfortunately I couldn't get asyncio to work at the end of GSoC 2018), and what's left that needs to be done in order to achieve the end goal (or at least make part of asyncio work).

Building Foundation

The first error that the transpiler throws when attempting to compile asyncio module was "No handler for YieldFrom", so it makes sense to start from this issue first.

Another feature related to generator was Yield expression. Before GSoC 2018, Yield statement in VOC was just a statement, meaning yield could not be used as expression. Generator methods such as generator.send, generator.throw and generator.close were not supported as well. Those features are what make asynchronous programming with generator possible, so I spent a few weeks to extend generator functionality in VOC, laying down the path to asyncio module.

PRs related to generator are listed below:

  • PR #821 : Added support for Yield from statement (merged)
  • PR #823 : Added generator send method (merged)
  • PR #831 : Support exceptions handling in generator (merged)

Nonlocal Statement

Nonlocal statement was another syntax not supported by VOC. After completion of generator's features, implementing this is the next step towards compiling asyncio module.

Implementing this feature took about 3 ~ 4 weeks as this is not as trivial as it seems. I took several approaches on this, while some of them do work, the code is not pretty and hacky, which could come back to bite me/other contributors in the long run. After many discussions with Russell, I refactored the closure mechanism in VOC and took a much cleaner approach in nonlocal implementations. I must admit that I took some short-cuts for the sake of "making nonlocal works" in the process of implementing nonlocal statement, resulting in poor design and messy codes. Many thanks to Russell, who helped me to improve my coding style and told me not to be discouraged when I'm stuck. 😄

Related PRs:

  • PR #854 : Nonlocal statement support (merged)
  • PR #873 : Added closure related test cases (merged)

The Collections Module

Next item on my hit list was pure Java implementations of the collections module. asyncio module depends on 3 data structures from collections, namely defauldict, Deque and OrderedDict. Two of them (defaultdict and Deque) are implemented in C in CPython, plus they have good analog in Java, so it makes senses to implement the module in Java. Porting defauldict, Deque and OrderedDict to Java in VOC is relatively straight-forward, taking about 1.5 weeks to complete.

Related PRs:

  • PR #874 : Implement collections.defauldict (merged)
  • PR #896 : Implements collections.Deque (merged)
  • PR #897 : Implements collections.OrderedDict` (merged)

Other PRs submitted during GSoC 2018

  • PR #817 : Added coroutine related exception class [WIP] (closed due to not needed)
  • PR #836 : Changed Bool construction to use getBool instead (merged)
  • PR #847 : Add custom exceptions test cases (closed due to more comprehensive handling in PR #844)
  • PR #849 : Fixed Unknown constant type <class 'frozenset'> in function definition (merged)
  • PR #858 : Added test case for Issue #857 (merged)
  • PR #860 : Added test case for Issue #859 (merged)
  • PR #862 : Added test case for Issue #861 (merged)
  • PR #867 : Fixed Issue #866 RunTimeError when generator is nested in more than 1 level of function definition (merged)
  • PR #868 : Fixed Issue #861 Redefining nested function from other function overrides original nested function (merged)
  • PR #879 : Fixed Incompatible Stack Height caused by expression statement (merged)
  • PR #901 : Added test case for Issue #900 (merged)
  • PR #788 : Implements asyncio.coroutines [WIP] (open, the dream 😎)

Issues submitted during GSoC 2018

  • Issue #861 : Redefining nested function from other function overrides original nested function (fixed in PR #868)
  • Issue #866 : RunTimeError when generator is nested in more than 1 level of function definition (fixed in PR #867)
  • Issue #828 : Finally block of generator is not executed during garbage collection (open)
  • Issue #857 : Complex datatype in set cause java.lang.StackOverflowError (open)
  • Issue #859 : Duplicated values of equivalent but different data types in set (open)
  • Issue #900 : Exception in nested try-catch suite is 'leaked' to another enclosing try-catch suite (open)
  • Issue #827 : Maps reserved Java keywords to Python built-in function/method call (closed)

Towards The Ultimate End Goal

Unfortunately, three months of GSoC coding period was not enough for me to bring asyncio module to VOC. The nonlocal statement implementation was the biggest blocker for me mainly because I didn't think thoroughly before writing code. If I were to plan carefully and lay out a general coding direction, I would've completed it in much shorter time and have time for other implementations. An advice for the aspiring and upcoming GSoC-er, don't rush your code, make sure you know 100% about what you're doing before diving into the codes.

With that said, following are the list of modules to be implemented/ported to Java before asyncio will work in VOC:

  • socket module (a bit tricky since Java doesn't support Unix domain socket natively)
  • selectors module (high level I/O operations)
  • threading module (might be easier to implement this first since threading in Python is an emulation of Java's Thread)
  • time module (partially implemented in VOC)

Final Thoughts

Huge thanks to my mentor, Russell Keith-Magee for accepting my proposal, providing guidance and encouraging me when things didn't go as intended. It is truly an honor to be a part of the BeeWare community. I had a blast contributing to BeeWare project, and I'm sure I will stick around as a regular contributor. Also shout out to the BeeWare community for answering my queries and reviewing my pull requests. 😄

Proyecto destacado: Colosseum

Publicado por Russell Keith-Magee en 6 October 2017

Este artículo fue publicado originalmente en la lista de correo de Entusiastas BeeWare. Si deseas recibir actualizaciones periódicas sobre el proyecto BeeWare, ¿Por qué no suscribirse?

Cuando diseñas una aplicación de interfaz gráfica, ya sea para escritorio, dispositivos móviles o navegador, una de las tareas más fundamentales es describir cómo colocar widgets en la pantalla. La mayoría de los kits de herramientas de widgets usarán un modelo de empaquetamiento de cuadrícula o caja de algún tipo para resolver este problema. Estos modelos tienden a ser relativamente fáciles al comienzo, pero se desmoronan rápidamente cuando tienes necesidades complejas de diseño o cuando tienes diseños que necesitan adaptarse a diferentes tamaños de pantalla.

En lugar de inventar un nuevo modelo de cuadrícula o de caja, el kit de herramientas del widget Toga widget toolkit adopta un enfoque diferente, utilizando un esquema conocido para diseñar contenido: Cascading Style Sheets, o CSS. Aunque CSS es más conocido por especificar el diseño en las páginas web, no hay nada intrínsecamente específico de la web al respecto. Al final del día, es un sistema para describir el diseño de una colección jerárquica de nodos de contenido. Sin embargo, hasta la fecha, cada implementación de CSS está vinculada a un navegador, por lo que la percepción es que CSS es un estándar específico del navegador.

Ahí es donde entra Colosseum. Colosseum es una implementación independiente del navegador de un motor de renderizado CSS. Toma un árbol de "nodos" de contenido, como un DOM de un documento HTML y aplica instrucciones de diseño CSS para diseñar esos nodos como cuadros en la pantalla. En el caso de Toga, en lugar de diseñar los elementos <div> y <span>, diseñas objetos Box y Button. Esto le permite especificar diseños adaptativos increíblemente complejos para aplicaciones Toga.

Pero Colosseum como proyecto tiene muchos otros posibles usos. Se puede usar en cualquier lugar donde exista la necesidad de describir el diseño fuera del contexto de un navegador. Por ejemplo, Colosseum podría ser la piedra angular de un renderizador de HTML a PDF que no requiere el uso de un navegador. También podría usarse como una librería de pruebas e implementación de referencia para la especificación CSS en sí misma, proporcionando una forma ligera de codificar y probar los cambios propuestos a la especificación.

La implementación actual se basa en el proyecto de Facebook yoga: originalmente era un código portado de JavaScript a Python línea a línea. Sin embargo, yoga solo implementa la sección de Flexbox de la especificación CSS3.

Esta semana, comenzamos un gran proyecto: reescribir Colosseum para que sea un motor de CSS totalmente compatible. El trabajo hasta ahora se puede encontrar en la rama globo del repositorio Colosseum en Github. El primer objetivo es el cumplimiento de CSS2.1, con una implementación del modelo de caja de CSS tradicional y el diseño de flujo. Una vez que tengamos una implementación razonable de eso, buscaremos agregar diseños Grid y FlexBox desde el conjunto de especificaciones CSS3.

Esto es obviamente un trabajo grande. CSS es una gran especificación, por lo que hay mucho trabajo por hacer, ¡pero eso también significa que hay muchos lugares para contribuir! Elije un párrafo de la especificación CSS, construye algunos casos de prueba que demuestren los casos descritos en ese párrafo y envía un parche que implemente ese comportamiento!

Esto resalta por que tu apoyo financiero es muy importante. Si bien podríamos hacer esto completamente con un esfuerzo voluntario, vamos a progresar mucho más rápido si un pequeño grupo de personas pudiera enfocarse en este proyecto de tiempo completo. El apoyo financiero permitiría aumentar significativamente la velocidad de desarrollo de Colosseum y el resto de la suite BeeWare.

Si deseas que Colosseum y el resto de BeeWare se desarrollen hasta el punto en que puedan utilizarse para aplicaciones comerciales, considera apoyar a BeeWare financieramente. Y si tienes alguna idea para fuentes de financiación potenciales más grandes, por favor ponte en contacto.

2017 Google Summer of Code - Portar Cricket a Toga, en lugar de Tkinter

Publicado por Dayanne Fernandes en 25 August 2017

Después de casi 4 meses de trabajo en Google Summer of Code 2017, finalmente estoy completando mi propuesta. Cada migración de widget y cada commit / PR / Issues / discusión con mis mentores sobre Cricket, Toga y rubicon-objc fueron detallados en el Issue 58.

"Comer su propia comida para perros"

La mejor manera de demostrar que un producto es confiable para los clientes es usarlo. Por lo tanto, la forma de demostrar que Toga es una herramienta eficaz para construir una interfaz gráfica de usuario es construir una aplicación completa que la utilice.

Cricket es una herramienta gráfica que le ayuda a ejecutar sus suites de prueba. Su versión actual se implementa utilizando Tkinter como el marco de la interfaz gráfica principal. Entonces, ¿por qué no probar Toga dentro de otro producto de BeeWare? Eso es lo que he logrado durante mi trabajo de GSoC.


La propuesta se centra no sólo en el puerto de Tkinter a Toga, sino en la asignación de los widgets necesarios para una aplicación real utilizando Toga. Para ayudarme a mapear esto he estudiado más sobre Tkinter, Toga, Colosseum, rubicon-objc, Objective-C, Cocoa y CSS.

El trabajo que hice durante GSoC se envió a través del PR 65, el informe en el Issue 58 y la demostración final se puede ver en este link. Había widgets utilizados en Cricket que no estaban listos todavía en Toga, por lo que era necesario hacer algunas mejoras en Toga para que pudiera usarlas en Cricket. En resumen, aquí hay algunos PR que contribuí para hacer mi trabajo en Cricket:

PR abierto enviado a Toga:

  • PR 201 : [Core][Cocoa] Refactoring of the Tree widget

PRs emergidos enviados Toga:

  • PR 112 : [Core][Cocoa] Enable/disable state for buttons, solved Issue 91
  • PR 170 : [Cocoa] Content and retry status for stack trace dialog
  • PR 172 : [Cocoa] Window resize
  • PR 173 : [Core][Cocoa] Button color
  • PR 174 : [Doc] Examples folder and button features example
  • PR 178 : [Doc] Fix tutorial 2 setup
  • PR 180 : [Doc] Update Toga widgets roadmap
  • PR 182 : [Cocoa] Update the label of the Stack trace button for critical dialog
  • PR 184 : [Core][Cocoa] Hide/show boxes widget
  • PR 188 : [Cocoa] Fix error on MultilineTextInput widget, solved Issue 187
  • PR 204 : [Core][Cocoa] Clear method to MultilineTextInput widget, solved Issue 203
  • PR 206 : [Core][Cocoa] Readonly and placeholder for MultilineTextInput widget
  • PR 208 : [Cocoa] Fix apply style to a SplitContainer widget, solved Issue 207

PRs emergidos enviados Cricket:

PRs emergidos enviados rubicon-objc:

  • PR 34 : [Doc] Add reference to NSObject

Tiquetes abiertos enviados a Toga:

  • Issue 175 : [Core] Add more properties for Label and Font widgets
  • Issue 176 : [Core] Add "rehint()" on the background of the widget after changing font size
  • Issue 186 : [Core] Set initial position of the divisor of a SplitContainer
  • Issue 197 : [Core] Get the id of the selected Tab View on the OptionContainer

Tiquetes cerrados en Toga:

Tiquetes cerrados que no reporté pero que resolví en Toga:

  • Issue 91 : API to disable buttons?
  • Issue 205 : adding MultiviewTextInput results in TypeError

Tiquete cerrado que reporté a Cricket:

  • Issue 59 : Run selected doesn't count/ runs every test selected in a test module, was fixed by me

Tiquete abierto que reporté a rubicon-objc Jonas Obrist repository:

  • Issue 1 : Seg Fault when iterate through a NSIndexSet using block notation

Planes futuros

Hay algunas características en Cricket que quiero ayudar a desarrollar en un futuro próximo, por ejemplo:

  • Un botón para actualizar todo el árbol de pruebas
  • Configuración de Cricket

Además, hay algunos problemas que quedaron después de la migración a Toga. Estos problemas se arreglarán en Toga en un futuro próximo, por ejemplo:

  • Una brecha entre la salida y los cuadros de error cuando no hay mensaje de salida
  • Ejecutar una prueba si el usuario haga clic en ella

Realmente creo que Toga será el framework oficial en Python para construir GUI para aplicaciones multi-plataforma, así que seguiré contribuyendo a este proyecto porque quiero usar en todas las aplicaciones que necesitaría una GUI.

Consideraciones finales

Me gustaría agradecer a mis mentores Russell Keith-Magee y Elias Dorneles por guíarme y ayudarme tanto durante este período. La oportunidad de ser parte de esta comunidad fue un gran honor para mí, muchas gracias por aceptarme en este programa Russell Keith-Magee. Además, quiero agradecer a Philip James que hizo algunas reseñas en mis PRs y Jonas Schell quienes arreglaron un tema que envié a Toga.

2017 Google Summer of Code - Mejoras en Batavia

Publicado por Adam Boniecki en 23 August 2017

Con el programa Google Summer of Code 2017 llegando a su fin, es hora de resumir lo que hice durante el verano trabajando en Batavia.

Batavia es una parte de la colección de proyectos de BeeWare. Como todavía está en su primera etapa de desarrollo, por mi parte me ofreció implementar una serie de características que faltaban en Batavia, que van desde tipos de datos elementales, a través de la manipulación JSON y construcciones de lenguaje como generadores. Publiqué mi propuesta en este hilo de GitHub y lo mantuve actualizado con mi progreso semanalmente.

Ten en cuenta que al final de GSoC, hemos decidido divergir de la propuesta inicial y renunciar a la aplicación de contextlib en favor de la compatibilidad con Python 3.6, que usa op-codes de 2 bytes.

En general, fue una gran experiencia de aprendizaje y diversión. Muchas gracias a mis mentores Russell Keith-Magee y Katie McLaughlin, y a toda la comunidad de BeeWare.

2017 Google Summer of Code - Probando Toga / API de configuración

Publicado por Jonas Schell en 22 August 2017

Google Summer of Code 2017 está llegando a su fin. Después de tres meses de trabajo en el proyecto BeeWare, quisiera resumir mi trabajo y compartir mis experiencias.

"Ningún plan de batalla sobrevive al primer contacto".

Esta fue una de las primeras cosas que Russell me dijo después de que decidimos fundamentalmente reestructurar mi calendario y metas de GSoC propuestos. Durante el período inicial con la comunidad descubrimos que Toga era aún más difícil de probar como esperábamos. El estrecho acoplamiento entre el código independiente de la plataforma en Toga-Core y las implementaciones dependientes de la plataforma para (Windows, MacOS, iOS, Linux, Android, Django, ...) nos estaba dando problemas para escribir pruebas significativas.

Esperamos que Toga se convierta en un proyecto de tamaño decente, por lo tanto queremos que tenga una base sólida y bien probada. Por esta razón, decidimos que pasaría la mayor parte de GSoC para reestructurar Toga para que ejecutar pruebas resultara más fácil de hacer. Además de eso, también añadiría pruebas de implementación para comprobar si un backend dado se implementa de la manera correcta. Si terminara antes del final del verano, empezaría con mi propuesta de proyecto original.

La gran reestructuración de Toga

Con los nuevos objetivos y una nueva rama comencé el viaje para reestructurar el proyecto Toga para hacerlo más fácil de probar.

Después de hackear y probar diferentes cosas en una rama separada. Identifiqué que las dependencias entrelazadas de la plataforma son el problema principal. Para separar el módulo Toga-Core de sus implementaciones de backend decidimos usar el patrón de fábrica en lugar del modelo de herencia que teníamos antes. Ahora cada backend tiene su propia fábrica que produce los widgets adecuados para la plataforma en la que se está ejecutando. De esta manera tenemos una clara separación entre Toga-Core y el nivel de implementación. Las dependencias de la plataforma ahora están incluidas en el nivel de implementación.

Después de que la nueva estructura fuera clara porté Toga-Core así como los backends para el Cocoa, iOS y GTK. Hice esto en la rama de Toga (La gran reestructuración de Toga [WIP] # 185).

En la práctica, esto significaba que tenía que tocar manualmente casi todos los widgets de todos los backends para conectarlos al nuevo patrón de fábrica.


Toga habla con los frameworks nativos GUI, por lo tanto tuve que tener un buen entendimiento acerca de los principios y conceptos detrás de cada uno de estos marcos. A veces me sentía abrumado por la complejidad combinada de todas las partes que componen Toga. La siguiente es la lista:

  • Cada backend de Toga se envuelve alrededor de un marco existente y único. Para envolver el marco que tiene que entender el marco.
  • "Me encanta Python, ¿por qué tengo que entender Objetive C"? Para trabajar eficazmente en los backends de iOS y macOS, tenía que aprender los conceptos básicos del Objetivo C, aunque sólo fuera para leer los documentos de Apple.
  • Toga tiene un montón de partes móviles. Hay backends, marcos, librerías para hablar con backends, librerías para realizar el diseño de la interfaz de usuario y más. Me tomó una buena cantidad de tiempo para entender todas estas partes. Lo siguiente es sólo una visión general de los conocimientos recién adquiridos durante GSoC:
  • Rubicon-ObjC para hablar con los backends de iOS y macOS.
  • Colosseum para entender y solucionar problemas de diseño.
  • Módulo AST para realizar las pruebas de implementación.
  • El uso de patrones de diseño
  • Cómo estructurar grandes proyectos.
  • Leer y entender grandes y complejos pedazos de código.

Otro trabajo que realicé

Futuro trabajo por hacer

  • Todo mi trabajo se encuentra en el PR "La gran reestructuración de Toga [WIP]". Después de que los backends que faltan, a saber, Windows y Android, se incluyan, todo se puede emerger con la rama master. Tenemos que esperar a los backends que faltan, porque el nuevo esquema es incompatible con las versiones antiguas y no pueden coexistir.
  • La API de configuración de mi propuesta original no se ha terminado debido a las razones mencionadas anteriormente. Tengo un primer borrador de trabajo y seguiré trabajando en él después de GSoC en este Pull Request.

"Shout out"

Me gustaría dar las gracias a Russell Keith-Magee por ser un Mentor impresionante y por todo el tiempo que invirtió en mí durante GSoC. También quiero agradecer a la comunidad BeeWare por ayudarme cuando alguna vez tuve un problema. ¡Gracias!

Un nuevo yak para el rebaño: BeeKeeper

Publicado por Russell Keith-Magee en 31 July 2017

Escribir suites de pruebas es una habilidad que es una parte vital del entrenamiento de los programadores. Aprender a escribir buenas pruebas le ayuda a escribir un código más robusto y asegura que cuando haya escrito un código que funcione, siga trabajando durante mucho tiempo en el futuro. También puede ayudarle a escribir mejor código en primer lugar. Resulta que el código bien diseñado, con alta cohesión y bajo acoplamiento, también es fácil de probar - por lo que escribir código que sea fácil de probar casi siempre dará como resultado una mejor calidad total del código.

Un paso importante en la "nivelación" de su experiencia de pruebas es comenzar a usar un servicio de integración continua o CI. Un servicio de CI es una herramienta que ejecuta automáticamente su suite de pruebas cada vez que alguien realiza un cambio o cada vez que alguien propone un cambio en forma de una solicitud de PR. El uso de un servicio de CI garantiza que su código siempre pase su suite de pruebas - no puede introducirse accidentalmente en un cambio que rompe una prueba, porque obtendrá una notificación de advertencia roja grande.

Un CI es un servicio tan importante que muchas empresas sólo existen para proporcionar CI-as-a-service. El proyecto BeeWare ha utilizado, para diversos proyectos, TravisCI y CircleCI. Ambas herramientas proporcionan niveles gratuitos para proyectos de código abierto y han patrocinado generosamente BeeWare con actualizaciones de capacidad en varias ocasiones.

Sin embargo, BeeWare ha tenido una relación interesante con los servicios comerciales de CI. Esto es por dos razones.

En primer lugar, nuestros conjuntos de pruebas, especialmente para VOC y Batavia - toman mucho tiempo para ejecutarse. Estos dos proyectos requieren pruebas que inician y cierran repetidamente las máquinas virtuales (para Java y JavaScript, respectivamente), y no importa cuánto se optimice el código que se está probando, el tiempo de inicio y apagado de una máquina virtual eventualmente se acumula. También necesitamos ejecutar nuestras suites de prueba en múltiples versiones de Python - en la actualidad, soportamos Python 3.4, 3.5 y 3.6, con 3.7 en el horizonte. También hay cambios sutiles en versiones micro que pueden requerir pruebas.

Hemos sido capaces de acelerar las prueba, dividiendo la suite de pruebas y ejecutando partes de la suite en paralelo, pero eso nos obliga a enfrentarnos al segundo problema. Los servicios comerciales de CI suelen operar en un modelo de suscripción; mayores suscripciones que proporcionan más recursos simultáneos. Sin embargo, nuestro patrón de uso es muy inusual. La mayor parte del año, recibimos un goteo lento de solicitudes de PRs que requieren pruebas. Sin embargo, un par de veces al año, tenemos un gran sprint, y tenemos una avalancha de contribuciones durante un corto período de tiempo. En PyCon EE.UU., hemos tenido grupos de 40 personas presentando parches - y todos ellos necesitan sus PRs probados por CI. Y el tiempo es un factor - los sprints sólo duran un par de días, por lo que un rápido cambio en las pruebas es esencial.

Si tuviéramos que suscribir a los niveles de suscripción de nivel superior de CircleCi y TravisCI, todavía no tendríamos suficientes recursos para soportar un sprint - pero estaríamos masivamente sobre abastecidos en recursos durante el resto del año. También tendríamos que pagar $ 750 o más por mes por este servicio, que es un presupuesto que no podemos permitirnos.

Así que tuvimos un problema. Para ejecutar nuestra suite de pruebas de manera eficaz, necesitábamos recursos paralelizados masivamente para ejecutar una suite de pruebas rápidamente; y en ciertas épocas del año, necesitamos un número extremadamente grande de estos recursos.

También teníamos otras tareas automatizadas que queríamos realizar. Queríamos hacer linting del código (comprobación automatizada de estilo de código) antes de que se probara un PR. Queríamos verificar la ortografía de la documentación. Y queríamos que estas tareas se retroalimentaran en GitHub como comentarios automatizados y marcadores de estado de revisión de código específicos, informando a los colaboradores no sólo de que se había producido un problema, sino de qué problema y dónde estaban en su código.

También queríamos administrar las compilaciones de pipeline - no tiene sentido hacer una prueba completa de varias versiones de Python una vez que haya establecido que las pruebas están fallando en una versión. Y no hay punto en hacer pruebas en absoluto si hay problemas de estilo de código.

También queríamos hacer cosas que no eran sólo pruebas. Queríamos verificar que se firmaron acuerdos de contribución. Queríamos automatizar el despliegue de sitios web y documentación.

Lo que teníamos no era sólo un problema de CI. Era un problema donde queríamos ejecutar automáticamente código arbitrario, de manera segura, en respuesta a un evento GitHub.

He estado tratando de encontrar un servicio de CI que pueda satisfacer nuestras necesidades durante más de un año. Pero durante el último año, algunos pensamientos comenzaron a congelarse en mi cabeza.

  • Amazon proporciona una API (EC2) que le permite arrancar máquinas de complejidad variable (hasta 64 CPUs, con casi 500 GB de RAM) y pagar por minuto para ese uso.
  • Docker proporciona las herramientas para configurar, lanzar y ejecutar código de manera aislada
  • Amazon también proporciona una API (ECS) para controlar la ejecución de los contenedores Docker.

No hay nada específico acerca de AWS EC2 o ECS tampoco - se podría utilizar Linode y Kubernetes, o Docker Swarm o Microsoft Azure ... simplemente se necesita tener la capacidad de filtrar fácilmente las máquinas y ejecutar un contenedor Docker. Después de todo: un conjunto de pruebas es sólo un contenedor Docker que ejecuta un script que inicia su suite de pruebas. Una revisión de linting es un contenedor de Docker que ejecuta un script que lints su código. Una verificación de acuerdo de contribuyente es un contenedor de Docker que comprueba los metadatos asociados con una solicitud de extracción.

Todo lo que necesita es un sitio web que puede recibir las notificaciones de eventos de GitHub e iniciar los contenedores de Docker en respuesta.

A principios de julio, me encontré entre trabajos, y pronuncié la fatídica pregunta: "¿Cuán difícil podría ser?" Y así, hoy, estoy anunciando BeeKeeper - el propio servicio de CI de BeeWare.

BeeKeeper se despliega como un sitio web de Heroku, escrito con Django. Después de configurarlo con las credenciales de Github y AWS, escucha los webhooks de Github. Cuando se detecta una solicitud de pull o Push, BeeKeeper crea una solicitud de generación; que la solicitud de construcción inspecciona el código en el repositorio en busca de un archivo de configuración beekeeper.yml. Ese archivo de configuración describe el pipeline de tareas que se van a realizar, y para cada tarea, el tipo de máquina que se debe usar, las variables de entorno que se requieran y la imagen de Docker que se utilizará.

BeeKeeper también permite al administrador del sitio describir qué recursos se utilizarán para satisfacer las compilaciones. Una tarea puede decir que necesita una instancia de "Alta CPU"; pero la instancia BeeKeeper puede determinar lo que significa "alta CPU" - ¿es 4 CPUs o 32? ¿Cuándo esas máquinas son coladas hacia arriba, cuánto tiempo se les permitirá sentarse inactivo antes de ser apagado de nuevo? ¿Cuántas máquinas deben estar permanentemente en el grupo de trabajo? ¿Y cuál es el límite superior de las máquinas que se iniciará?

Una herramienta complementaria para BeeKeeper es Waggle. Waggle es una herramienta que prepara una definición local de una tarea para que pueda ser utilizada por BeeKeeper - compila la imagen de Docker y la carga en ECS para que pueda ser referenciada por tareas. (Se llama "Waggle" porque cuando las abejas obreras descubren una buena fuente de néctar, regresan a la colmena y hacen una 'danza' que le dice a otras abejas cómo hacer para encontrar esa fuente).

También hemos proporcionado un repositorio llamado Comb (nombrado después del peine de miel, las abejas del lugar almacenan todo el néctar que encuentran) que define las configuraciones de la tarea que una instancia de BeeKeeper puedo usar. Hemos proporcionado algunas definiciones simples como parte del repositorio base de Comb; cada implementación de BeeKeeper debe tener uno de estos repositorios propios.

Todavía hay mucho trabajo por hacer, pero ya estamos usando BeeKeeper con Batavia y VOC, y la próxima PyCon AU sprints será nuestra primera en condiciones de alta carga. Algunos cálculos de respaldo prevén que por alrededor de $50, podremos proporcionar suficientes recursos de CPU para cada ejecución de prueba para completar su ejecución en 10 minutos o menos, soportando un sprint de decenas de personas.

Aunque BeeKeeper fue escrito para satisfacer las necesidades del proyecto BeeWare, es una herramienta de código abierto disponible para cualquier persona. Si desea tomar BeeKeeper para darle una prueba, vaya a los sprints, o revise el código en GitHub.

BeeKeeper también es un ejemplo del tipo de producto que vería más si el desarrollo de BeeWare se financiara a tiempo completo. Fui capaz de construir BeeKeeper porque tenía un par de semanas de descanso entre los trabajos. No hay fin para las herramientas y bibliotecas como BeeKeeper y Waggle que podrían ser construidas para soportar el proceso de desarrollo de software - todo lo que falta son los recursos necesarios para desarrollar esas herramientas. Si desea ver más herramientas como BeeKeeper en el mundo, considere la posibilidad de unirse al proyecto BeeWare como miembro financiero. Cada pedacito ayuda, y si podemos alcanzar a una masa crítica de patrocinadores, podré comenzar a trabajar en BeeWare a tiempo completo.

Una solicitud de ayuda

Publicado por Russell Keith-Magee en 5 April 2017

Hace unos 4 años, hice el primer commit con Cricket - la primera herramienta que eventualmente se convertiría en parte de la suite BeeWare. Desde entonces, el proyecto BeeWare ha crecido para abarcar soporte para plataformas móviles, dos implementaciones alternativas de Python y un conjunto de widgets multi-plataforma, así como las herramientas de desarrollo que iniciaron el proyecto originalmente.

Durante la mayor parte de este tiempo, BeeWare ha sido un esfuerzo voluntario. Inicialmente, fue un proyecto en solitario; sin embargo, en el último año en particular, el número de personas que han contribuido a BeeWare ha crecido rápidamente. Más de 300 personas han hecho contribuciones a las diversas herramientas y librerías de BeeWare, debido, al menos en parte, a las Monedas de Desafío que hemos estado ofreciendo en los sprints.

Cabe destacar el equipo de 7 personas que se han unido al proyecto como apicultores, ayudando a compartir la carga de mantenimiento del proyecto. No puedo agradecer a estas personas lo suficiente - sin su ayuda, no se habría logrado tanto progreso durante el último año.

Tu debes haber notado que en los últimos meses, el progreso ha sido especialmente rápido. Esto se debe a que, durante los últimos seis meses, el desarrollo de BeeWare ha sido parcialmente financiado por empleadores muy complacientes en Jambon Software. Mi contrato con Jambon me permitió pasar largos periodos de tiempo pagados para trabajar en BeeWare - y, no es sorprendente, es posible hacer un enorme progreso como resultado. Los últimos 6 meses han visto:

  • Amplias mejoras a Batavia y VOC;
  • Un backend Android para Toga;
  • Un backend de Django para Toga, permitiendo que las aplicaciones de Toga se implementen como aplicaciones web;
  • Un backend de Winforms para Toga, permitiendo que las aplicaciones de Toga funcionen en Windows con un aspecto moderno;

Desafortunadamente, mi contrato con Jambon está llegando a su fin - lo que significa que mis contribuciones a BeeWare volverán a ser lo que mi tiempo libre permite.

Esto también significa que la tasa de progreso también se ralentizará. Todavía hay mucho por hacer: hay un montón de la librería estándar de Python para portar a Batavia y VOC; Toga necesita un mucho más amplio soporte de widgets; Colosseum necesita ser extendido para que sea compatible con el modelo de caja CSS completo, no sólo CSS3 Flexbox; y las herramientas que lo iniciaron todo - Cricket, Bugjar, Duvet, y otros - todos necesitan ser portados a Toga.

Me gustaría poder trabajar en BeeWare a tiempo completo. Sin embargo, la simple realidad es que a menos que pueda encontrar una manera de pagar por este trabajo, sólo será capaz de contribuir en mi tiempo libre.

Así que - esto es un llamado para ti - la comunidad de Python. Si estás entusiasmado con la perspectiva de tener acceso a Python en plataformas móviles, o te gustaría escribir aplicaciones en Python que tengan interfaces de usuario completamente nativas - Necesito tu ayuda.

Por sólo US $ 10 al mes, puedes unirte al proyecto BeeWare como miembro y ayudar a que este sueño se convierta en realidad. Si puedo encontrar 1000 personas en la comunidad de Python que quieran estas herramientas y estén dispuestos a apoyar financieramente su desarrollo, puedo comenzar a trabajar en BeeWare a tiempo completo. Por supuesto, este objetivo es aún más fácil si las empresas se involucran y patrocinan en los niveles más altos.

Si puedo encontrar a más de 1000 personas, entonces mucho más es posible. La opción obvia sería contratar a otros desarrolladores con experiencia para ayudar con el trabajo. La idea de tener a otros para compartir ideas durante el proceso de desarrollo es muy atractiva. Sin embargo, también podemos usar esto como una oportunidad para hacer un bien social.

Durante algún tiempo, he tenido una oferta abierta para ser mentor a cualquiera que quiera involucrarse con la contribución de Coódigo Abierto usando el proyecto BeeWare. Sin embargo, no mucha gente ha podido tomar seriamente esta oferta, porque el tiempo requerido para tomar seriamente la oferta es prohibitivo. Me gustaría poder extender mi oferta a algo más que una relación casual de tutoría. Me gustaría poder contratar - y pagar - uno o más desarrolladores junior para el proyecto BeeWare, y enfocarme en dar esa oportunidad a personas de demografía subrepresentada.

Aún son los primeros días para BeeWare. El apoyo financiero significa un progreso más rápido. Más widgets. Mejor documentación. Más de todo lo que has visto hasta ahora de BeeWare. Si puedo encontrar financiación a tiempo completo para mí -o mejor aún, para mí y para un equipo pequeño-, no tengo dudas de que la suite BeeWare se convertirá en una alternativa viable para proyectos comerciales en muy poco tiempo. Lo mejor de todo, seremos capaces de hacer esto sin tener que renunciar a los ideales del movimiento de código abierto.

Estoy emocionado por lo que le depara el futuro a BeeWare. Espero que nos acompañes en este viaje.

(Y si tu estás pensando en registrarte, y vienes a PyCon US en Portland este mes de mayo, déjame dejar una pista suave ... inscríbete ahora. Vale la pena #cryptic)