gopy

repository·master·Indexed 25 days ago

https://github.com/go-python/gopy

A tool that generates and compiles CPython extension modules from Go packages, enabling the integration of Go code into Python applications. It supports multi-package modules, Python callbacks from Go, and class inheritance via embedded structs. gopy provides several commands including 'pkg' for creating distributable modules, 'exe' for standalone Python executables, and 'gen' and 'build' for raw binding generation.

Tokens
5.8K
Snippets
17
Records
33
Agent score
81%

What's inside gopy

  1. What is gopy

    master

    gopy is a tool that generates and compiles a CPython extension module from a Go package. It allows you to use Go code within Python by creating bindings.

    Key features include:

    • Safety: Uses unique int64 handles to interface with Python instead of raw pointers, making it safe for Go's moving garbage collector.
    • Multi-package support: Supports Python modules containing multiple Go packages. It generates a separate .py module file for each package, which link into a single common binding library.
    • Callbacks: Supports calling Python functions from Go. You can pass a Python function as an argument to a Go function.
    • Inheritance: Uses the first embedded struct field in Go to establish corresponding class inheritance in the Python wrappers, allowing efficient inheritance of methods and properties.
  2. Understand code review terminology

    master

    Reviewers in this project use specific shorthand. Familiarize yourself with these terms:

    • LGTM: Looks good to me (required for merge).
    • SGTM: Sounds good to me.
    • PTAL: Please take another look.
    • CL: Change list (a single commit).
    • s/foo/bar/: Replace foo with bar (sed syntax).
    • s/foo/bar/g: Replace foo with bar throughout the entire change.

    If you need more eyes on a PR, you can comment PTAL @username or PTAL @go-python/developers to request additional review.

  3. Quickstart: Build and use Go bindings in Python

    master

    To build bindings for a Go package and use them in Python, follow these steps:

    1. Initialize a Go module and fetch the package.
    2. Run gopy build specifying the output directory and the Python interpreter version.
    3. Import the generated module in Python.

    Note: Always use the -vm flag to specify your Python interpreter (e.g., -vm=python3) to avoid version mismatches.

    $ go mod init dummy.com/dum
    $ go get github.com/go-python/gopy/_examples/hi
    $ gopy build -output=out -vm=python3 github.com/go-python/gopy/_examples/hi
    
    # Use in Python
    $ cd out
    $ python3
    >>> from out import hi
    >>> hi.Hello("you")
    hello you from go
  4. Report a bug in gopy

    master

    When you encounter a bug, open an issue on the corresponding repository. To help maintainers, follow these guidelines:

    1. Title Format: Start the issue title with the repository/sub-repository name (e.g., bind: issue name).
    2. Environment Details: Be specific about your environment, including the operating system and Go compiler version.
    3. Reproducer: If possible, include a minimal code example that reproduces the bug.
    4. Testing: The project aims to keep all tests passing and increase code coverage; providing a test case is highly encouraged.
  5. Guidelines for code contributions

    master

    When submitting code to go-python or gopy, follow these requirements:

    • Pull Requests: Split large PRs into smaller ones. PRs must include tests for new code before merging. It is acceptable to open a PR for partially implemented code to seek early feedback.
    • Licensing: All code follows the BSD license. New contributions should not introduce additional licensing; if exceptions are made, the added code must also follow a BSD license.
    • Formatting: Always format code with goimports. It is recommended to use it as a save hook.
    • Copyright: New files must use the standard copyright header. Do not update the copyright year on existing files you modify.
    • Benchmarks: If a PR is intended for performance improvements, you must include a report using benchcmp or benchstat to measure the impact.
    • Magic Numbers: If tests use magic numbers, include a comment explaining their source.
    // Copyright 20xx The go-python Authors.  All rights reserved.
    // Use of this source code is governed by a BSD-style
    // license that can be found in the LICENSE file.
  6. Configure gopy for Linux

    master

    On Linux, you may need to ensure the linker ld can find library files in your current directory. Add the following to your .bashrc file (and source it) or run it in your current session:

    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
  7. Configure gopy for Windows

    master

    When using Windows, follow these requirements and configuration steps:

    Python Installation

    • Do not install Python from the Microsoft Store, as its symbolic links are incompatible with go exec.Command.
    • Use the standard Python distribution from python.org.
    • Since the standard install may not provide a python3.exe, you may need to manually copy python.exe to python3.exe in your Python installation directory.

    Environment Variables

    If you encounter linking errors during the build process, configure the following environment variables:

    • LIBDIR or GOPY_LIBDIR: Path to Python libraries.
    • LIBRARY or GOPY_PYLIB: Name of the Python library (e.g., python39 for Python 3.9).

    Running Tests

    To run the test suite on Windows, you must install psutil to enable memory tracking, as Python's resource module is unavailable on Windows:

    python -m pip install psutil
  8. Build bindings using Docker

    master

    For cross-platform builds, you can use the gopy/gopy Docker image. This allows you to generate bindings in a controlled environment.

    To run a bind command via Docker:

    1. Navigate to the Go package directory.
    2. Run the docker run command, mounting your current directory to /go/src/in and an output directory to /out.
    $ cd github.com/go-python/gopy/_examples/hi
    $ docker run --rm -v `pwd`:/go/src/in -v `pwd`:/out gopy/gopy app bind -output=/out in
  9. Format commit messages for go-python

    master

    Commit messages should follow Go's official guidelines. For gopy or go-python sub-packages, prefix the message with the relevant package name. If a change affects multiple packages, include all of them in the prefix.

    Example for a single package:

    bind: add support for cffi
    
    This CL adds support for the cffi python backend.
    ...
    Fixes go-python/gopy#42.

    Example for multiple packages:

    py,bind: implement wrapping of Go interfaces
    
    bla-bla
    
    Fixes go-python/gopy#40.
    bind: add support for cffi
    
    This CL adds support for the cffi python backend.
    The existing implementation, cpython, only generates code for the
    CPython-2 C API.
    Now, with cffi, we support generation of python modules for Python-2,
    Python-3 and PyPy VMs.
    
    Fixes go-python/gopy#42.
  10. Install gopy

    master

    To use gopy, you must have Go (version 1.15 or above) installed and ~/go/bin added to your PATH. gopy requires a valid go.mod file (module-based builds).

    Install the necessary dependencies using the following commands:

    $ python3 -m pip install pybindgen
    $ go install golang.org/x/tools/cmd/goimports@latest
    $ go install github.com/go-python/gopy@latest

    If you intend to install the resulting bindings as Python modules, ensure you have the following installed:

    python3 -m pip install --upgrade setuptools wheel

    Tip: To avoid common errors where gopy defaults to Python 2, use the -vm option to specify the Python 3 executable (e.g., -vm=python3).

  11. Generate a Python package with the `pkg` command

    master

    The pkg command generates and compiles (C)Python language bindings for a Go package (including subdirectories) and creates a Python module structure suitable for distribution.

    If a setup.py file does not already exist in the target output directory, gopy will create one along with other default packaging files using the provided metadata arguments. Once the initial files are created, you can edit them and subsequently use gopy to only regenerate the Go binding files.

    When including multiple Go packages, list them in order of increasing dependency. Use the -name flag to specify the appropriate name for the output package.

    Usage

    $ gopy pkg [options] <go-package-name> [other-go-package...]
    
    # Example: generating bindings for a specific package
    $ gopy pkg github.com/go-python/gopy/_examples/hi
    $ gopy pkg [options] <go-package-name> [other-go-package...]