github.com/grumpyhome/grumpy@v0.3.1-0.20201208125205-7b775405bdf1/README.md (about) 1 # Grumpy: Go running Python 2 3 [![Build Status](https://travis-ci.org/grumpyhome/grumpy.svg?branch=master)](https://travis-ci.org/grumpyhome/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 [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) 6 7 ## Overview 8 9 Grumpy is a Python to Go source code transcompiler and runtime that is intended 10 to be a near drop-in replacement for CPython 2.7. Grumpy has no VM, because it 11 compiles Python source code to Go source code which is then compiled to native 12 code (rather than to bytecode). The compiled Go source code uses Go library 13 called Grumpy runtime, which replaces Python C API for system calls (although 14 the API is incompatible with 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 58 59 ### Pre-requisites 60 Python 2.7 61 pip 62 Go 1.10+ 63 64 ##### Mac Python 2.7 65 OSX users can go to https://www.python.org/downloads/release/python-2718/ 66 67 Once you've succesfull installed Python2.7 please ensure that pip is also 68 installed on your system by running the command "python -m pip --version". 69 If pip is not installed please follow the instructions found here 70 https://pip.pypa.io/en/stable/installing/# 71 72 Once pip has succesfully been installed please run the following command 73 74 python -m pip install --upgrade pip setuptools 75 76 ##### Linux Python 2.7 77 For Debian based distos you can install Python 2 with. 78 79 sudo apt install python2 80 81 Next ensure that pip is installed by running "python -m pip --version" 82 or, "python2 -m pip version". If it returns pip [version number] then 83 pip is already installed. If it doesn't run the command "sudo apt install python-pip". 84 Note: Again, replace apt with the appropriate package tool. 85 86 ##### Go Compiler 87 88 Go can be downloaded here: https://golang.org/dl/ 89 90 Please see the official go installation documentation to install Go: https://golang.org/doc/install 91 92 If you wish to build Go from source see the documentation here: https://golang.org/doc/install/source 93 94 95 ## Installing Grumpy 96 97 The commands ahead assumes that you have Golang installed and a recent 98 version of Python 2 and `pip`. 99 100 ### Method 0: binary package 101 102 For convenience, a Python package is provided from the PyPI. During install, 103 many Grumpy will be compiled and stored inside your Python installation. 104 105 You need Golang preinstalled anyway for the installation to be successful. 106 107 ```sh 108 pip2 install -U grumpy-runtime -I --no-cache 109 (wait about 5 minutes) 110 echo "print 'hello, world'" | grumpy run 111 ``` 112 113 ### Method 1: make run: 114 115 The simplest way to execute a Grumpy program is to use `make run`, which wraps a 116 shell script called grumprun that takes Python code on stdin and builds and runs 117 the code under Grumpy: 118 119 ```sh 120 cd grumpy-tools-src 121 python2 setup.py develop 122 cd ../grumpy-runtime-src 123 echo "print 'hello, world'" | make run 124 ``` 125 126 ### Method 2: grumpc and grumprun: 127 128 For more complicated programs, you'll want to compile your Python source code to 129 Go using grumpc (the Grumpy compiler) and then build the Go code using `go 130 build`. Since Grumpy programs are statically linked, all the modules in a 131 program must be findable by the Grumpy toolchain on the GOPATH. Grumpy looks for 132 Go packages corresponding to Python modules in the \_\_python\_\_ subdirectory 133 of the GOPATH. By convention, this subdirectory is also used for staging Python 134 source code, making it similar to the PYTHONPATH. 135 136 The first step is to set up the shell so that the Grumpy toolchain and libraries 137 can be found. From the root directory of the Grumpy source distribution run: 138 139 ```sh 140 cd grumpy-tools-src 141 python2 setup.py develop 142 cd ../grumpy-runtime-src 143 make 144 export PATH=$PWD/build/bin:$PATH 145 export GOPATH=$PWD/build 146 export PYTHONPATH=$PWD/build/lib/python2.7/site-packages 147 ``` 148 149 You will know things are working if you see the expected output from this 150 command: 151 152 ```sh 153 cd grumpy-runtime-src 154 echo 'import sys; print sys.version' | grumprun 155 ``` 156 157 Next, we will write our simple Python module into the \_\_python\_\_ directory: 158 159 ```sh 160 cd grumpy-runtime-src 161 echo 'def hello(): print "hello, world"' > $GOPATH/src/__python__/hello.py 162 ``` 163 164 To build a Go package from our Python script, run the following: 165 166 ```sh 167 cd grumpy-runtime-src 168 mkdir -p $GOPATH/src/__python__/hello 169 grumpc -modname=hello $GOPATH/src/__python__/hello.py > \ 170 $GOPATH/src/__python__/hello/module.go 171 ``` 172 173 You should now be able to build a Go program that imports the package 174 "\_\_python\_\_/hello". We can also import this module into Python programs 175 that are built using grumprun: 176 177 ```sh 178 cd grumpy-runtime-src 179 echo 'from hello import hello; hello()' | grumprun 180 ``` 181 182 grumprun is doing a few things under the hood here: 183 184 1. Compiles the given Python code to a dummy Go package, the same way we 185 produced \_\_python\_\_/hello/module.go above 186 2. Produces a main Go package that imports the Go package from step 1. and 187 executes it as our \_\_main\_\_ Python package 188 3. Executes `go run` on the main package generated in step 2. 189 190 ## Developing Grumpy 191 192 There are three main components and depending on what kind of feature you're 193 writing, you may need to change one or more of these. 194 195 ### Grumpy Tools 196 197 Grumpy converts Python programs into Go programs and 198 `grumpy transpile` is the CLI tool responsible for parsing Python code 199 and generating Go code from it. `grumpy transpile` is written in Python 200 and uses the [`pythonparser`](https://github.com/m-labs/pythonparser) 201 module to accomplish parsing. 202 203 The CLI main entrypoint lives at `grumpy-tools-src/grumpy_tools/cli.py`. 204 It is supported by a number of Python modules in the 205 `grumpy-tools-src/grumpy_tools/compiler` subdir. 206 207 ### Grumpy Runtime 208 209 The Go code generated by `grumpy transpile` performs operations 210 on data structures that represent Python objects in running Grumpy programs. 211 These data structures and operations are defined in the `grumpy` Go library 212 (source is in the `grumpy-runtime-src/runtime` subdir of the source 213 distribution). This runtime is analogous to the Python C API and many of the 214 structures and operations defined by `grumpy` have counterparts in CPython. 215 216 ### Grumpy Standard Library 217 218 Much of the Python standard library is written in Python and thus "just works" 219 in Grumpy. These parts of the standard library are copied from CPython 2.7 220 (possibly with light modifications). For licensing reasons, these files are kept 221 in the `grumpy-runtime-src/third_party` subdir. 222 223 The parts of the standard library that cannot be written in pure Python, e.g. 224 file and directory operations, are kept in the `grumpy-runtime-src/lib` subdir. 225 In CPython these kinds of modules are written as C extensions. In Grumpy they 226 are written in Python but they use native Go extensions to access facilities not 227 otherwise available in Python. 228 229 ### Source Code Overview 230 231 - `grumpy-tools-src/grumpy_tools/compiler`: Python package implementating Python -> Go transcompilation logic. 232 - `grumpy-runtime-src/lib`: Grumpy-specific Python standard library implementation. 233 - `grumpy-runtime-src/runtime`: Go source code for the Grumpy runtime library. 234 - `grumpy-runtime-src/third_party/ouroboros`: Pure Python standard libraries copied from the 235 [Ouroboros project](https://github.com/pybee/ouroboros). 236 - `grumpy-runtime-src/third_party/pypy`: Pure Python standard libraries copied from PyPy. 237 - `grumpy-runtime-src/third_party/stdlib`: Pure Python standard libraries copied from CPython. 238 - `grumpy-tools-src/grumpy_tools/`: Transcompilation and utility CLI. 239 240 ## Contact 241 242 Questions? Comments? Drop us a line at [grumpy-users@googlegroups.com](https://groups.google.com/forum/#!forum/grumpy-users) 243 or join our [Gitter channel](https://gitter.im/grumpy-devel/Lobby)