github.com/google/grumpy@v0.0.0-20171122020858-3ec87959189c/README.md (about) 1 # Grumpy: Go running Python 2 3 [![Build Status](https://travis-ci.org/google/grumpy.svg?branch=master)](https://travis-ci.org/google/grumpy) 4 [![Join the chat at https://gitter.im/grumpy-devel/Lobby](https://badges.gitter.im/grumpy-devel/Lobby.svg)](https://gitter.im/grumpy-devel/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 5 6 ## Overview 7 8 Grumpy is a Python to Go source code transcompiler and runtime that is intended 9 to be a near drop-in replacement for CPython 2.7. The key difference is that it 10 compiles Python source code to Go source code which is then compiled to native 11 code, rather than to bytecode. This means that Grumpy has no VM. The compiled Go 12 source code is a series of calls to the Grumpy runtime, a Go library serving a 13 similar purpose to the Python C API (although the API is incompatible with 14 CPython's). 15 16 ## Limitations 17 18 ### Things that will probably never be supported by Grumpy 19 20 1. `exec`, `eval` and `compile`: These dynamic features of CPython are not 21 supported by Grumpy because Grumpy modules consist of statically-compiled Go 22 code. Supporting dynamic execution would require bundling Grumpy programs 23 with the compilation toolchain, which would be unwieldy and impractically 24 slow. 25 26 2. C extension modules: Grumpy has a different API and object layout than 27 CPython and so supporting C extensions would be difficult. In principle it's 28 possible to support them via an API bridge layer like the one that 29 [JyNI](http://jyni.org) provides for Jython, but it would be hard to maintain and 30 would add significant overhead when calling into and out of extension 31 modules. 32 33 ### Things that Grumpy will support but doesn't yet 34 35 There are three basic categories of incomplete functionality: 36 37 1. [Language features](https://github.com/google/grumpy/wiki/Missing-features#language-features): 38 Most language features are implemented with the notable exception of 39 [old-style classes](http://stackoverflow.com/questions/54867/what-is-the-difference-between-old-style-and-new-style-classes-in-python). 40 There are also a handful of operators that aren't yet supported. 41 42 2. [Builtin functions and types](https://github.com/google/grumpy/wiki/Missing-features#builtins): 43 There are a number of missing functions and types in `__builtins__` that have 44 not yet been implemented. There are also a lot of methods on builtin types 45 that are missing. 46 47 3. [Standard library](https://github.com/google/grumpy/wiki/Missing-features#standard-libraries): 48 The Python standard library is very large and much of it is pure Python, so 49 as the language features and builtins get filled out, many modules will 50 just work. But there are also a number of libraries in CPython that are C 51 extension modules which will need to be rewritten. 52 53 4. C locale support: Go doesn't support locales in the same way that C does. As such, 54 some functionality that is locale-dependent may not currently work the same as in 55 CPython. 56 57 ## Running Grumpy Programs 58 59 ### Method 1: make run: 60 61 The simplest way to execute a Grumpy program is to use `make run`, which wraps a 62 shell script called grumprun that takes Python code on stdin and builds and runs 63 the code under Grumpy. All of the commands below are assumed to be run from the 64 root directory of the Grumpy source code distribution: 65 66 ``` 67 echo "print 'hello, world'" | make run 68 ``` 69 70 ### Method 2: grumpc and grumprun: 71 72 For more complicated programs, you'll want to compile your Python source code to 73 Go using grumpc (the Grumpy compiler) and then build the Go code using `go 74 build`. Since Grumpy programs are statically linked, all the modules in a 75 program must be findable by the Grumpy toolchain on the GOPATH. Grumpy looks for 76 Go packages corresponding to Python modules in the \_\_python\_\_ subdirectory 77 of the GOPATH. By convention, this subdirectory is also used for staging Python 78 source code, making it similar to the PYTHONPATH. 79 80 The first step is to set up the shell so that the Grumpy toolchain and libraries 81 can be found. From the root directory of the Grumpy source distribution run: 82 83 ``` 84 make 85 export PATH=$PWD/build/bin:$PATH 86 export GOPATH=$PWD/build 87 export PYTHONPATH=$PWD/build/lib/python2.7/site-packages 88 ``` 89 90 You will know things are working if you see the expected output from this 91 command: 92 93 ``` 94 echo 'import sys; print sys.version' | grumprun 95 ``` 96 97 Next, we will write our simple Python module into the \_\_python\_\_ directory: 98 99 ``` 100 echo 'def hello(): print "hello, world"' > $GOPATH/src/__python__/hello.py 101 ``` 102 103 To build a Go package from our Python script, run the following: 104 105 ``` 106 mkdir -p $GOPATH/src/__python__/hello 107 grumpc -modname=hello $GOPATH/src/__python__/hello.py > \ 108 $GOPATH/src/__python__/hello/module.go 109 ``` 110 111 You should now be able to build a Go program that imports the package 112 "\_\_python\_\_/hello". We can also import this module into Python programs 113 that are built using grumprun: 114 115 ``` 116 echo 'from hello import hello; hello()' | grumprun 117 ``` 118 119 grumprun is doing a few things under the hood here: 120 121 1. Compiles the given Python code to a dummy Go package, the same way we 122 produced \_\_python\_\_/hello/module.go above 123 2. Produces a main Go package that imports the Go package from step 1. and 124 executes it as our \_\_main\_\_ Python package 125 3. Executes `go run` on the main package generated in step 2. 126 127 ## Developing Grumpy 128 129 There are three main components and depending on what kind of feature you're 130 writing, you may need to change one or more of these. 131 132 ### grumpc 133 134 Grumpy converts Python programs into Go programs and `grumpc` is the tool 135 responsible for parsing Python code and generating Go code from it. `grumpc` is 136 written in Python and uses the [`pythonparser`](https://github.com/m-labs/pythonparser) 137 module to accomplish parsing. 138 139 The grumpc script itself lives at `tools/grumpc`. It is supported by a number of 140 Python modules in the `compiler` subdir. 141 142 ### Grumpy Runtime 143 144 The Go code generated by `grumpc` performs operations on data structures that 145 represent Python objects in running Grumpy programs. These data structures and 146 operations are defined in the `grumpy` Go library (source is in the runtime 147 subdir of the source distribution). This runtime is analogous to the Python C 148 API and many of the structures and operations defined by `grumpy` have 149 counterparts in CPython. 150 151 ### Grumpy Standard Library 152 153 Much of the Python standard library is written in Python and thus "just works" 154 in Grumpy. These parts of the standard library are copied from CPython 2.7 155 (possibly with light modifications). For licensing reasons, these files are kept 156 in the `third_party` subdir. 157 158 The parts of the standard library that cannot be written in pure Python, e.g. 159 file and directory operations, are kept in the `lib` subdir. In CPython these 160 kinds of modules are written as C extensions. In Grumpy they are written in 161 Python but they use native Go extensions to access facilities not otherwise 162 available in Python. 163 164 ### Source Code Overview 165 166 - `compiler`: Python package implementating Python -> Go transcompilation logic. 167 - `lib`: Grumpy-specific Python standard library implementation. 168 - `runtime`: Go source code for the Grumpy runtime library. 169 - `third_party/ouroboros`: Pure Python standard libraries copied from the 170 [Ouroboros project](https://github.com/pybee/ouroboros). 171 - `third_party/pypy`: Pure Python standard libraries copied from PyPy. 172 - `third_party/stdlib`: Pure Python standard libraries copied from CPython. 173 - `tools`: Transcompilation and utility binaries. 174 175 ## Contact 176 177 Questions? Comments? Drop us a line at [grumpy-users@googlegroups.com](https://groups.google.com/forum/#!forum/grumpy-users) 178 or join our [Gitter channel](https://gitter.im/grumpy-devel/Lobby)