Created
February 9, 2014 22:03
-
-
Save micklat/8906673 to your computer and use it in GitHub Desktop.
mostly-isolated issue 888
This file contains 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
import python except expr | |
type | |
# A non-borrowed (counted) reference. Avoid copying these around! Nimrod doesn't have | |
# the equivalent of an assignment constructor (yet?), so any copy of PyRef must be counted (use dup for that). | |
PyRef = object {.inheritable, byref.} | |
p: PPyObject | |
PPyRef* = ref PyRef | |
EPyException = object of E_Base | |
# forward declarations | |
proc getattr*(o: PPyRef, name: cstring) : PPyRef | |
proc handle_error(s : string) = | |
PyErr_Print() | |
raise newException(EPyException, s) | |
proc check(p: PPyObject) : PPyObject = | |
if p == nil: handle_error("check(nil)") | |
result = p | |
proc check(x: int) : int = | |
if x == -1: handle_error("check(-1)") | |
result = x | |
converter to_PPyRef*(p: PPyObject) : PPyRef = | |
new result | |
result.p = check(p) | |
proc new_list*(size: int): PPyRef = PyList_New(size) | |
proc new_tuple*(size: int): PPyRef = PyTuple_New(size) | |
converter to_py*(i: int) : PPyRef = PyInt_FromLong(int32(i)) | |
proc to_py*(s: cstring) : PPyRef = PyString_fromString(s) | |
proc to_tuple*(vals: openarray[PPyRef]): PPyRef = | |
result = new_tuple(len(vals)) | |
for i in 0..len(vals)-1: | |
let p = vals[i].p | |
discard check(PyTuple_SetItem(result.p, i, p)) | |
Py_INCREF(p) # PyTuple_SetItem steals refs, I don't want that | |
proc `()`*(f: PPyRef, args: varargs[PPyRef]): PPyRef {.discardable.} = | |
let args_tup = to_tuple(args) | |
PyObject_CallObject(f.p, args_tup.p) | |
proc destroy(o: var PyRef) {.destructor.} = | |
if o.p != nil: | |
echo "decrefing" | |
Py_DECREF(o.p) | |
o.p = nil | |
proc getattr*(o: PPyRef, name: cstring) : PPyRef = | |
result = to_PPyRef(PyObject_GetAttrString(o.p, name)) | |
proc py_import*(name : cstring) : PPyRef = | |
PyImport_ImportModule(name) | |
type | |
Interpreter = object {.bycopy.} | |
proc make_interpreter() : Interpreter = | |
Py_Initialize() | |
result = Interpreter() | |
proc destroy(interpreter : Interpreter) {.destructor.} = | |
Py_Finalize() | |
var py_interpreter = make_interpreter() | |
let n = 100 | |
let lx = new_list(0) | |
for i in 1..n: | |
# compilation succeeds: | |
getattr(lx, "append")(to_py(1)) | |
# compilation fails: | |
getattr(lx, "append")(1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment