Skip to content
This repository has been archived by the owner on Mar 23, 2023. It is now read-only.

Native integration

Dylan Trotter edited this page Aug 22, 2017 · 4 revisions

Grumpy allows you to access Go functions, variables and types directly from Python by importing Go packages similar to normal Python modules. The symbols accessed via "native imports" are normal Python objects that have methods and can be passed around just like any other object.

Python module names are more restrictive than Go package names, so the usual Python import syntax is not sufficient to import all Go packages. To make it possible to import any Go package, Grumpy introduces string literal imports. Here we import the standard Python sys module:

import "sys"

Go packages can be imported using this syntax, as subpackages of the __go__ package. Here we import the standard Go strconv package in a Python program:

import "__go__/strconv"

Python import rules would suggest that the local namespace would contain the name __go__ corresponding to that package, but string literal imports follow the Go rules for imports meaning that the last name is the one introduced into the local namespace. In this case, the name strconv is locally available and can be used to access the functions and types in that package so that this code:

print repr(strconv.Itoa(-42))

Outputs the string '-42'.

Conversions between primitive Python types and Go types (for the most part) happen implicitly. For example:

import "__go__/encoding/hex"
print hex.Dump('foobar')

the Dump() function called above takes []byte, but since it is convertible from string, the call works as you'd expect.

The following snippet demonstrates two capabilities of Grumpy native integration. First, Go methods are available on wrapped types as Python methods. Second, multiple return values from Go functions are converted to tuples in Python:

from __go__.time import Now
print Now().Date()

The code above will print a tuple containing (year, month, day), like: (2017, 6, 2).

Limitations

Python objects implement no Go interfaces

Python types are defined dynamically at runtime and do not have corresponding Go static types. Therefore, they cannot implement Go interfaces.

It may be technically possible to support this by generating a stub type in Go for each interface that wraps an arbitrary Python object and forwards Go method calls to Python methods of the same name, there would still be edge cases that wouldn't work well. For example, passing a Python object through to a function taking interface{}, which in turn passes the object through to a function taking a non-empty interface would not work correctly.