This repository was archived by the owner on Jul 24, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 140
Reorganize package to support both py2 and py3 runtimes #66
Open
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
471 changes: 471 additions & 0 deletions
.legacy/object.go
Oops, something went wrong.
File renamed without changes.
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
104 changes: 104 additions & 0 deletions
.legacy/python.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| // simplistic wrapper around the python C-API | ||
| package python | ||
|
|
||
| //#include "go-python.h" | ||
| import "C" | ||
|
|
||
| import ( | ||
| "fmt" | ||
| ) | ||
|
|
||
| // PyGILState is the Go alias for the PyGILState_STATE enum | ||
| type PyGILState C.PyGILState_STATE | ||
|
|
||
| // PyThreadState layer | ||
| type PyThreadState struct { | ||
| ptr *C.PyThreadState | ||
| } | ||
|
|
||
| // Initialize initializes the python interpreter and its GIL | ||
| func Initialize() error { | ||
| // make sure the python interpreter has been initialized | ||
| if C.Py_IsInitialized() == 0 { | ||
| C.Py_Initialize() | ||
| } | ||
| if C.Py_IsInitialized() == 0 { | ||
| return fmt.Errorf("python: could not initialize the python interpreter") | ||
| } | ||
|
|
||
| // make sure the GIL is correctly initialized | ||
| if C.PyEval_ThreadsInitialized() == 0 { | ||
| C.PyEval_InitThreads() | ||
| } | ||
| if C.PyEval_ThreadsInitialized() == 0 { | ||
| return fmt.Errorf("python: could not initialize the GIL") | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| // Finalize shutdowns the python interpreter | ||
| func Finalize() error { | ||
| C.Py_Finalize() | ||
| return nil | ||
| } | ||
|
|
||
| // PyThreadState* PyEval_SaveThread() | ||
| // Release the global interpreter lock (if it has been created and thread | ||
| // support is enabled) and reset the thread state to NULL, returning the | ||
| // previous thread state (which is not NULL). If the lock has been created, | ||
| // the current thread must have acquired it. (This function is available even | ||
| // when thread support is disabled at compile time.) | ||
| func PyEval_SaveThread() *PyThreadState { | ||
| state := C.PyEval_SaveThread() | ||
| return &PyThreadState{ptr: state} | ||
| } | ||
|
|
||
| // void PyEval_RestoreThread(PyThreadState *tstate) | ||
| // Acquire the global interpreter lock (if it has been created and thread | ||
| // support is enabled) and set the thread state to tstate, which must not be | ||
| // NULL. If the lock has been created, the current thread must not have | ||
| // acquired it, otherwise deadlock ensues. (This function is available even | ||
| // when thread support is disabled at compile time.) | ||
| func PyEval_RestoreThread(state *PyThreadState) { | ||
| C.PyEval_RestoreThread(state.ptr) | ||
| } | ||
|
|
||
| // Ensure that the current thread is ready to call the Python C API regardless | ||
| // of the current state of Python, or of the global interpreter lock. This may | ||
| // be called as many times as desired by a thread as long as each call is | ||
| // matched with a call to PyGILState_Release(). In general, other thread-related | ||
| // APIs may be used between PyGILState_Ensure() and PyGILState_Release() calls | ||
| // as long as the thread state is restored to its previous state before the | ||
| // Release(). For example, normal usage of the Py_BEGIN_ALLOW_THREADS and | ||
| // Py_END_ALLOW_THREADS macros is acceptable. | ||
| // | ||
| // The return value is an opaque "handle" to the thread state when | ||
| // PyGILState_Ensure() was called, and must be passed to PyGILState_Release() | ||
| // to ensure Python is left in the same state. Even though recursive calls are | ||
| // allowed, these handles cannot be shared - each unique call to | ||
| // PyGILState_Ensure() must save the handle for its call to PyGILState_Release(). | ||
| // | ||
| // When the function returns, the current thread will hold the GIL and be able | ||
| // to call arbitrary Python code. Failure is a fatal error. | ||
| // | ||
| // New in version 2.3. | ||
| func PyGILState_Ensure() PyGILState { | ||
| return PyGILState(C.PyGILState_Ensure()) | ||
| } | ||
|
|
||
| // void PyGILState_Release(PyGILState_STATE) | ||
| // Release any resources previously acquired. After this call, Python’s state | ||
| // will be the same as it was prior to the corresponding PyGILState_Ensure() | ||
| // call (but generally this state will be unknown to the caller, hence the use | ||
| // of the GILState API). | ||
| // | ||
| // Every call to PyGILState_Ensure() must be matched by a call to | ||
| // PyGILState_Release() on the same thread. | ||
| // | ||
| // New in version 2.3. | ||
| func PyGILState_Release(state PyGILState) { | ||
| C.PyGILState_Release(C.PyGILState_STATE(state)) | ||
| } | ||
|
|
||
| // EOF |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 0 additions & 7 deletions
cgoflags.go
Oops, something went wrong.
47 changes: 47 additions & 0 deletions
cmd/go-python/go-python.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| // a go wrapper around py-main | ||
| package main | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "os" | ||
| "plugin" | ||
|
|
||
| "github.com/sbinet/go-python" | ||
| ) | ||
|
|
||
| func loadRuntime(vers string) python.Runtime { | ||
| pl, err := plugin.Open(fmt.Sprintf("python%s.so", vers)) | ||
| if err != nil { | ||
| panic(err) | ||
| } | ||
| s, err := pl.Lookup("Runtime") | ||
| if err != nil { | ||
| panic(err) | ||
| } | ||
| r, ok := s.(*python.Runtime) | ||
| if !ok { | ||
| panic(fmt.Errorf("unexpected type: %T", s)) | ||
| } | ||
| return *r | ||
| } | ||
|
|
||
| func main() { | ||
| vers := "2" | ||
| if os.Getenv("GO_PYTHON") == "3" { | ||
| vers = "3" | ||
| } | ||
| r := loadRuntime(vers) | ||
| py := python.NewInterpreter(r) | ||
| err := py.Initialize(true) | ||
| if err != nil { | ||
| panic(err) | ||
| } | ||
| defer py.Close() | ||
|
|
||
| err = py.Main(os.Args) | ||
| if e, ok := err.(python.RunError); ok { | ||
| os.Exit(e.Code) | ||
| } else if err != nil { | ||
| panic(err) | ||
| } | ||
| } |
19 changes: 0 additions & 19 deletions
cmd/go-python/main.go
Oops, something went wrong.
27 changes: 27 additions & 0 deletions
errors.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| package python | ||
|
|
||
| import "fmt" | ||
|
|
||
| type RunError struct { | ||
| Code int | ||
| File string | ||
| } | ||
|
|
||
| func (e RunError) Error() string { | ||
| return fmt.Sprintf("python: error %d executing script %s", e.Code, e.File) | ||
| } | ||
|
|
||
| func errCode(ret int) error { | ||
| if ret == 0 { | ||
| return nil | ||
| } | ||
| return Error{Code: ret} | ||
| } | ||
|
|
||
| type Error struct { | ||
| Code int | ||
| } | ||
|
|
||
| func (e Error) Error() string { | ||
| return fmt.Sprintf("python: C-Python error code %d", e.Code) | ||
| } |
21 changes: 21 additions & 0 deletions
eval.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| package python | ||
|
|
||
| import "github.com/sbinet/go-python/runtime" | ||
|
|
||
| type TraceFunc func(frame *Frame, what runtime.TraceType, arg runtime.Object) | ||
|
|
||
| func (py *Interpreter) Trace(fnc TraceFunc) { | ||
| var obj runtime.Object // TODO: unique value | ||
| py.r.EvalSetTrace(func(_ runtime.Object, frame runtime.Frame, what runtime.TraceType, arg runtime.Object) int { | ||
| fnc(&Frame{ptr: frame}, what, arg) | ||
| return 0 | ||
| }, obj) | ||
| } | ||
|
|
||
| func (py *Interpreter) GetFrame() *Frame { | ||
| f := py.r.EvalGetFrame() | ||
| if f == nil { | ||
| return nil | ||
| } | ||
| return &Frame{ptr: f} | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.