grumpy README

The project's README from github.com/google/grumpy. As one markdown file: README.md.

Grumpy: Go running Python

Build Status Join the chat at https://gitter.im/grumpy-devel/Lobby

Overview

Grumpy is a Python to Go source code transcompiler and runtime that is intended to be a near drop-in replacement for CPython 2.7. The key difference is that it compiles Python source code to Go source code which is then compiled to native code, rather than to bytecode. This means that Grumpy has no VM. The compiled Go source code is a series of calls to the Grumpy runtime, a Go library serving a similar purpose to the Python C API (although the API is incompatible with CPython's).

Limitations

Things that will probably never be supported by Grumpy

  1. exec, eval and compile: These dynamic features of CPython are not supported by Grumpy because Grumpy modules consist of statically-compiled Go code. Supporting dynamic execution would require bundling Grumpy programs with the compilation toolchain, which would be unwieldy and impractically slow.

  2. C extension modules: Grumpy has a different API and object layout than CPython and so supporting C extensions would be difficult. In principle it's possible to support them via an API bridge layer like the one that JyNI provides for Jython, but it would be hard to maintain and would add significant overhead when calling into and out of extension modules.

Things that Grumpy will support but doesn't yet

There are three basic categories of incomplete functionality:

  1. Language features: Most language features are implemented with the notable exception of old-style classes. There are also a handful of operators that aren't yet supported.

  2. Builtin functions and types: There are a number of missing functions and types in __builtins__ that have not yet been implemented. There are also a lot of methods on builtin types that are missing.

  3. Standard library: The Python standard library is very large and much of it is pure Python, so as the language features and builtins get filled out, many modules will just work. But there are also a number of libraries in CPython that are C extension modules which will need to be rewritten.

  4. C locale support: Go doesn't support locales in the same way that C does. As such, some functionality that is locale-dependent may not currently work the same as in CPython.

Running Grumpy Programs

Method 1: make run:

The simplest way to execute a Grumpy program is to use make run, which wraps a shell script called grumprun that takes Python code on stdin and builds and runs the code under Grumpy. All of the commands below are assumed to be run from the root directory of the Grumpy source code distribution:

echo "print 'hello, world'" | make run

Method 2: grumpc and grumprun:

For more complicated programs, you'll want to compile your Python source code to Go using grumpc (the Grumpy compiler) and then build the Go code using go build. Since Grumpy programs are statically linked, all the modules in a program must be findable by the Grumpy toolchain on the GOPATH. Grumpy looks for Go packages corresponding to Python modules in the __python__ subdirectory of the GOPATH. By convention, this subdirectory is also used for staging Python source code, making it similar to the PYTHONPATH.

The first step is to set up the shell so that the Grumpy toolchain and libraries can be found. From the root directory of the Grumpy source distribution run:

make
export PATH=$PWD/build/bin:$PATH
export GOPATH=$PWD/build
export PYTHONPATH=$PWD/build/lib/python2.7/site-packages

You will know things are working if you see the expected output from this command:

echo 'import sys; print sys.version' | grumprun

Next, we will write our simple Python module into the __python__ directory:

echo 'def hello(): print "hello, world"' > $GOPATH/src/__python__/hello.py

To build a Go package from our Python script, run the following:

mkdir -p $GOPATH/src/__python__/hello
grumpc -modname=hello $GOPATH/src/__python__/hello.py > \
    $GOPATH/src/__python__/hello/module.go

You should now be able to build a Go program that imports the package "__python__/hello". We can also import this module into Python programs that are built using grumprun:

echo 'from hello import hello; hello()' | grumprun

grumprun is doing a few things under the hood here:

  1. Compiles the given Python code to a dummy Go package, the same way we produced __python__/hello/module.go above
  2. Produces a main Go package that imports the Go package from step 1. and executes it as our __main__ Python package
  3. Executes go run on the main package generated in step 2.

Developing Grumpy

There are three main components and depending on what kind of feature you're writing, you may need to change one or more of these.

grumpc

Grumpy converts Python programs into Go programs and grumpc is the tool responsible for parsing Python code and generating Go code from it. grumpc is written in Python and uses the pythonparser module to accomplish parsing.

The grumpc script itself lives at tools/grumpc. It is supported by a number of Python modules in the compiler subdir.

Grumpy Runtime

The Go code generated by grumpc performs operations on data structures that represent Python objects in running Grumpy programs. These data structures and operations are defined in the grumpy Go library (source is in the runtime subdir of the source distribution). This runtime is analogous to the Python C API and many of the structures and operations defined by grumpy have counterparts in CPython.

Grumpy Standard Library

Much of the Python standard library is written in Python and thus "just works" in Grumpy. These parts of the standard library are copied from CPython 2.7 (possibly with light modifications). For licensing reasons, these files are kept in the third_party subdir.

The parts of the standard library that cannot be written in pure Python, e.g. file and directory operations, are kept in the lib subdir. In CPython these kinds of modules are written as C extensions. In Grumpy they are written in Python but they use native Go extensions to access facilities not otherwise available in Python.

Source Code Overview

Contact

Questions? Comments? Drop us a line at [email protected] or join our Gitter channel

grumpy (google/grumpy)

Searching Database…

10.5K ·GitHub
archived
这是什么?Grumpy 是 Google 出品的 Python 到 Go 的转编译器和运行时——它把 Python 程序通过生成的 Go 源代码变成原生可执行文件,几乎是 CPython 2.7 的直接替代品。
它和直接用普通的 Python 运行有什么不同?没有虚拟机:你的代码不会变成字节码,而是被静态编译成 Go 代码,调用 Grumpy 运行时。这个运行时是一个 Go 库,作用类似 Python 的 C API,不过它的 API 和 CPython 的并不兼容。
我怎么用它运行 Python 脚本?在 Grumpy 源代码目录的根下运行 make run —— 它会把 Python 代码从标准输入传给 grumprun 脚本,由它在 Grumpy 下构建并执行。
用之前我需要先装好什么?需要 Go 工具链和 Grumpy 源代码本身:除了简单测试之外,你要用 grumpc 把 Python 编译成 Go,再用 go build 构建。而 grumpc 本身是用 Python 写的,所以还需要一个 Python 解释器。
哪些 Python 功能缺失或不支持?它只面向 CPython 2.7。exec、eval 和 compile 永远不会支持,也无法加载 C 扩展模块;许多内置函数、方法和标准库模块仍然缺失。
生成的 Go 代码是什么样的?它是一系列对 Grumpy 运行时库的调用——生成的 Go 源代码操作代表 Python 对象的数据结构,和 CPython 的 C API 的工作方式如出一辙。
没有虚拟机的话,Python 标准库是怎么运作的?从 CPython 2.7、PyPy 和 Ouroboros 项目复制来的纯 Python 模块开箱即用。需要原生能力的模块,比如文件和目录操作,则用 Python 编写、底层由 Go 扩展支撑。
我能编译自己的模块并在多个程序间复用吗?可以——grumpc 会把 Go 包生成到你 GOPATH 的 python 子目录下,而且由于 Grumpy 程序是静态链接的,程序用到的每个模块在构建时都必须能在那里找到。
Grumpy 还在开发吗?不。GitHub 仓库已经归档为只读,开发已经停止——在为这套工具链投入时间之前请先掂量这一点。
What are similar projects?cython, tsx, zig, gopherjs, scriptc, closure-compiler, wire, porffor
Creator
google
Size
1.4 MB
Stars
10.5K
Updated
CommitNov 22
Age
9y
Commits · 90 Days