The Right Bees

Artem Malyshev

@proofit404

Bugjar
Cricket
Duvet
Galley





Toga
Rubicon
Voc
Batavia

Toga

One button app

def button_handler(widget):
    print("hello")

def build(app):
    box = toga.Box()
    button = toga.Button('Hello world',
                         on_press=button_handler)
    button.style.set(margin=50)

app = toga.App('Try App', startup=build)
app.main_loop()

Platforms

  • toga-gtk, toga-cocoa, toga-win32
  • environment markers
  • import hooks
  • platform bootstrap

Colosseum

from colosseum import CSS, ROW

style = CSS(width=1000, height=1000,
            flex_direction=ROW)

style.layout

Interface

  • foo.parent
  • foo.children
  • foo.style

Problems

  • Hand written hierarchy
  • Inline CSS

index.jade

Box
  Button(label="Hello world", style="margin: 50",
         on_press=button_handler)

app.py

import colosseum
import pyjade
import toga

index = open('index.jade').read()
ast = pyjade.Parser(index).parse()

def build(nodes, parent=None):
    ...
app = toga.App('App Jade', startup=build())

Apple Python Support

Create XCode Framework from Python distribution

Rubicon

Objective-C

NSAutoreleasePool *pool = [
    [NSAutoreleasePool alloc]
  init];

Pure C

#include <CoreFoundation/CoreFoundation.h>
#include <objc/runtime.h>
#include <objc/message.h>

id pool = objc_msgSend(
    objc_msgSend(
        objc_getClass("NSAutoreleasePool"),
        sel_registerName("alloc")),
    sel_registerName("init"));

Pure Python

from rubicon.objc import ObjCClass, objc_method

NSAutoreleasePool = ObjCClass("NSAutoreleasePool")

pool = NSAutoreleasePool.alloc().init()

class MyPool(NSAutoreleasePool):
    @objc_method
    def foo(self, bar: int) -> None:
        pass

Implementation

  • Use ctypes to talk with FFI
  • Used in toga-cocoa and toga-ios
  • Can expose python methods to the Obj-C runtime

Voc

Python to Java bytecode transpiler

$ voc -v example.py

Run java class

java -classpath python-java-support.jar:. \
    python.example.__init__

Source code

foo(1, 2)

Opcode

12 LOAD_NAME      0 (foo)
15 LOAD_CONST     2 (1)
18 LOAD_CONST     3 (2)
21 CALL_FUNCTION  2 (2 positional, 0 keyword)
24 POP_TOP

Bytecode

7079 da03 6f01 0073 0200  x.py..foo....s..
0001 7205 00e9 0000 e902  ....r...........
004e 2901 0000 0100 0000  ...N).r....r....
0000 0072 0000 0000 00da  r....r....r.....
6d6f 6475 3e01 0073 0200  .....s..

Implementation

  • Modules packed as java classes
  • loadClass, getMethod, reflection and friends
  • Traceback to the android.util.Log
java -classpath python-java-support.jar:. python.example.__init__
Exception in thread "main" ZeroDivisionError: division by zero
  at org.python.types.Int.__truediv__(Int.java:285)
  at python.example.example$invoke$z.invoke(example.py:7)
  at org.python.types.Function.invoke(Function.java:390)
  at python.example.example$x$y.invoke(example.py:9)
  at python.example.__init__.x(example.py:11)
  at python.example.__init__.module$import(example.py:14)
  at python.example.__init__.main(example.py)

Java part

public class Generator extends org.python.types.Object
  implements org.python.Iterable {
    @org.python.Method(__doc__ = "Return repr(self).")
    public org.python.Object __repr__() {
        return new org.python.types.Str(
          String.format("<%s object (%s) at 0x%x>",
                        this.typeName(),
                        this.name,
                        this.hashCode()));
    }
}

Briefcase

Setuptools extension which can create Android and XCode projects from python package

Batavia

Vue.js

<div id="app">
  {{ message }}
</div>
var app = new Vue({
  el: '#app',
  data: {message: 'Hello Vue!'}
})

Python VM in the browser

import dom

Vue = dom.window.self.Vue

class options:
    el = '#app'
    class data:
        message = 'Hello Vue!'

app = Vue(options)

index.py

python -m py_compile index.py
# -> index.pyc

index.html

<script src="batavia.js"></script>
<script id="batavia-index">
  Fg0NCnw5dVi7AAAA4wA...
</script>
<script type="text/javascript">
 window.vm = new batavia.VirtualMachine({});
 window.vm.run('index', []);
</script>

I'm going to build my own React

with Python and Codecs

# coding: pyxl
import dom
from pyxl import html

div = dom.document.getElementById('fill-me')
div.innerHTML = <h1>Hello World!</h1>

index.html

<script src="batavia.js"></script>
<!-- Bandled PyXL library -->
<script id="batavia-pyxl">
  Fg0NCgELfFgWAAAA4w...
</script>
<script id="batavia-pyxl.html">
  Fg0NCtRLfFh6AAAA4w...
</script>
<!-- Our index.py -->
<script id="batavia-index">
  Fg0NCj8SfFiEAAAA4w...
</script>

Replacing import system with webpack

Because why not?
window.vm = new batavia.VirtualMachine({
  loader: function(name) {
    var stdlibModule = batavia.stdlib[name];
    return {
      'bytecode': stdlibModule,
      'filename': new batavia.types.Str("<input>")
    };
  }
});
window.vm.run('index', []);

Python modules as js files

module.exports = 'Fg0NCuBMo1brAwAA4wAAAAAAAAA...'

Ouroboros

Pure python implementation of the standard library

Python all the things!

pybee.org

?