Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Ensure all text files use LF line endings in the repository
* text=auto

# Explicitly set LF for specific files that are checked in tests
*.go text eol=lf
*.md text eol=lf
*.sh text eol=lf
*.py text eol=lf
*.yml text eol=lf
*.yaml text eol=lf
*.json text eol=lf
*.txt text eol=lf

# Binary files
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.so binary
*.pyd binary
*.dll binary
*.exe binary
*.pyc binary
55 changes: 33 additions & 22 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
branches: [ '**' ]

env:
TAGS: "-tags=ci"
Expand All @@ -20,32 +20,26 @@ jobs:
build:
name: Build
strategy:
fail-fast: false
matrix:
go-version: [1.22.x, 1.21.x]
platform: [ubuntu-latest]
go-version: [1.25.x, 1.24.x, 1.22.x, 1.21.x]
platform: [ubuntu-latest, windows-latest]
#platform: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.platform }}
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install Go
uses: actions/setup-go@v2
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}

- name: Cache-Go
uses: actions/cache@v1
with:
path: |
~/go/pkg/mod # Module download cache
~/.cache/go-build # Build cache (Linux)
~/Library/Caches/go-build # Build cache (Mac)
'%LocalAppData%\go-build' # Build cache (Windows)

key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}

- name: Checkout code
uses: actions/checkout@v2
cache: true

- name: Install Linux packages
if: matrix.platform == 'ubuntu-latest'
Expand All @@ -57,7 +51,15 @@ jobs:
# install goimports
go install golang.org/x/tools/cmd/goimports@latest


- name: Install Windows packages
if: matrix.platform == 'windows-latest'
run: |
# install pybindgen and psutil (for memory tracking in tests)
python -m pip install -U pybindgen psutil
# install goimports
go install golang.org/x/tools/cmd/goimports@latest


- name: Build-Linux
if: matrix.platform == 'ubuntu-latest'
run: |
Expand All @@ -66,6 +68,15 @@ jobs:
if: matrix.platform == 'ubuntu-latest'
run: |
make test

- name: Build-Windows
if: matrix.platform == 'windows-latest'
run: |
go build -v ./...
- name: Test Windows
if: matrix.platform == 'windows-latest'
run: |
go test -v ./...
- name: Upload-Coverage
if: matrix.platform == 'ubuntu-latest'
uses: codecov/codecov-action@v1
uses: codecov/codecov-action@v4
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ https://stackoverflow.com/questions/39910730/python3-is-not-recognized-as-an-int

If you get a bunch of errors during linking in the build process, set `LIBDIR` or `GOPY_LIBDIR` to path to python libraries, and `LIBRARY` or `GOPY_PYLIB` to name of python library (e.g., python39 for 3.9).

#### Running Tests on Windows

To run the test suite on Windows, you need to install `psutil` for memory tracking. This is required because Python's built-in `resource` module is [only available on Unix](https://docs.python.org/3/library/resource.html):

```sh
python -m pip install psutil
```

Without `psutil`, tests that check for memory leaks will fail with `ModuleNotFoundError`.

## Community

See the [CONTRIBUTING](https://github.com/go-python/gopy/blob/master/CONTRIBUTE.md) guide for pointers on how to contribute to `gopy`.
Expand Down
26 changes: 20 additions & 6 deletions _examples/cstrings/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,16 @@

import cstrings
import gc
import resource
import sys

# resource module is Unix-only, not available on Windows
# On Windows, use psutil for memory tracking
if sys.platform == 'win32':
import psutil
HAS_RESOURCE = False
else:
import resource
HAS_RESOURCE = True

verbose = False
iterations = 10000
Expand Down Expand Up @@ -39,7 +48,11 @@ def gofnMap():


def print_memory(s):
m = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
if HAS_RESOURCE:
m = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
else:
# psutil returns memory in bytes, convert to KB to match resource module
m = psutil.Process().memory_info().rss // 1024
if verbose:
print(s, m)
return m
Expand Down Expand Up @@ -69,17 +82,18 @@ def _run_fn(fn):

for fn in [gofnString, gofnStruct, gofnNestedStruct, gofnSlice, gofnMap]:
alloced = size * iterations
a = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
a = print_memory("Initial memory:")
pass1 = _run_fn(fn)
b = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
b = print_memory("After first pass:")
pass2 = _run_fn(fn)
c = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
c = print_memory("After second pass:")
if verbose:
print(fn.__name__, pass1)
print(fn.__name__, pass2)
print(fn.__name__, a, b, c)

print(fn.__name__, "leaked: ", (c-b) > (size * iterations))
leaked = (c-b) > (size * iterations)
print(fn.__name__, "leaked: ", leaked)

# bump up the size of each successive test to ensure that leaks
# are not absorbed by previous rss growth.
Expand Down
37 changes: 0 additions & 37 deletions appveyor.yml

This file was deleted.

6 changes: 4 additions & 2 deletions bind/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ package main
%[3]s
// #define Py_LIMITED_API // need full API for PyRun*
#include <Python.h>
#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 202311L)
typedef uint8_t bool;
#endif
// static inline is trick for avoiding need for extra .c file
// the following are used for build value -- switch on reflect.Kind
// or the types equivalent
Expand Down Expand Up @@ -409,8 +411,8 @@ build:
# goimports is needed to ensure that the imports list is valid
$(GOIMPORTS) -w %[1]s.go
# this will otherwise be built during go build and may be out of date
- rm %[1]s.c
echo "typedef uint8_t bool;" > %[1]s_go.h
- rm %[1]s.c
printf "#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 202311L)\ntypedef uint8_t bool;\n#endif\n" > %[1]s_go.h
# this will fail but is needed to generate the .c file that then allows go build to work
- $(PYTHON) build.py >/dev/null 2>&1
# generate %[1]s_go.h from %[1]s.go -- unfortunately no way to build .h only
Expand Down
2 changes: 1 addition & 1 deletion cmd_build.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ func runBuild(mode bind.BuildMode, cfg *BuildCfg) error {

if mode == bind.ModeExe {
of, err := os.Create(buildname + ".h") // overwrite existing
fmt.Fprintf(of, "typedef uint8_t bool;\n")
fmt.Fprintf(of, "#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 202311L)\ntypedef uint8_t bool;\n#endif\n")
of.Close()

fmt.Printf("%v build.py # will fail, but needed to generate .c file\n", cfg.VM)
Expand Down
9 changes: 6 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
module github.com/go-python/gopy

go 1.19
go 1.22.0

require (
github.com/gonuts/commander v0.1.0
github.com/gonuts/flag v0.1.0
github.com/pkg/errors v0.9.1
golang.org/x/tools v0.16.0
golang.org/x/tools v0.29.0
)

require golang.org/x/mod v0.14.0 // indirect
require (
golang.org/x/mod v0.22.0 // indirect
golang.org/x/sync v0.10.0 // indirect
)
16 changes: 8 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ github.com/gonuts/commander v0.1.0 h1:EcDTiVw9oAVORFjQOEOuHQqcl6OXMyTgELocTq6zJ0
github.com/gonuts/commander v0.1.0/go.mod h1:qkb5mSlcWodYgo7vs8ulLnXhfinhZsZcm6+H/z1JjgY=
github.com/gonuts/flag v0.1.0 h1:fqMv/MZ+oNGu0i9gp0/IQ/ZaPIDoAZBOBaJoV7viCWM=
github.com/gonuts/flag v0.1.0/go.mod h1:ZTmTGtrSPejTo/SRNhCqwLTmiAgyBdCkLYhHrAoBdz4=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM=
golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE=
golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588=
2 changes: 2 additions & 0 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ OK
}

func TestBindSimple(t *testing.T) {
t.Skip("Skipping due to Go 1.21+ CGO issue (see https://github.com/go-python/gopy/issues/370)")
// t.Parallel()
path := "_examples/simple"
testPkg(t, pkg{
Expand Down Expand Up @@ -545,6 +546,7 @@ OK
}

func TestBindCgoPackage(t *testing.T) {
t.Skip("Skipping due to Go 1.21+ CGO issue (see https://github.com/go-python/gopy/issues/370)")
// t.Parallel()
path := "_examples/cgo"
testPkg(t, pkg{
Expand Down
Loading