Skip to content

Commit 65aa14c

Browse files
committed
port to py3
1 parent b67bee1 commit 65aa14c

File tree

2 files changed

+22
-25
lines changed

2 files changed

+22
-25
lines changed

include/wrappy/wrappy.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,14 @@ class PythonObject {
7171
PyObject* obj_;
7272
};
7373

74-
// Note that this is an input iterator, iterators cannot
74+
// Note that this is an input iterator, iterators cannot
7575
// be stored, rewound, or compared to anything but "end"
7676
struct PythonIterator {
7777
PythonIterator& operator++(); // pre-increment
7878
PythonObject operator*(); // dereference
79-
// *only* for comparison to "end", python iterators have
79+
// *only* for comparison to "end", python iterators have
8080
// no concept of position or comparability
81-
bool operator!=(const PythonIterator&);
81+
bool operator!=(const PythonIterator&);
8282

8383
private:
8484
PythonIterator(bool, PythonObject);
@@ -102,12 +102,12 @@ void addModuleSearchPath(const std::string& path);
102102

103103
// There is one quirk of call() for the case of member methods:
104104
//
105-
// call("module.A.foo")
105+
// call("module.A.foo")
106106
//
107107
// calls the unbound method "foo", so it is necessary to provide an instance
108108
// of A as the first argument, while
109109
//
110-
// auto a = call("module.A"); call(a, "foo");
110+
// auto a = call("module.A"); call(a, "foo");
111111
//
112112
// calls the method "foo" that is already bound to a, so providing an explicit
113113
// self argument in that case is an error.

wrappy.cpp

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Python header must be included first since they insist on
1+
// Python header must be included first since they insist on
22
// unconditionally defining some system macros
33
// (http://bugs.python.org/issue1045893, still broken in python3.4)
44
#include <Python.h>
@@ -40,7 +40,8 @@ void wrappyInitialize()
4040
Py_Initialize();
4141

4242
// Setting a dummy value since many libraries require sys.argv[0] to exist
43-
char* dummy_args[] = {const_cast<char*>("wrappy"), nullptr};
43+
wchar_t name[16] = L"wrappy";
44+
wchar_t* dummy_args[] = {const_cast<wchar_t*>(name), nullptr};
4445
PySys_SetArgvEx(1, dummy_args, 0);
4546

4647
wrappy::None = PythonObject(PythonObject::borrowed{}, Py_None);
@@ -179,7 +180,7 @@ double PythonObject::floating() const
179180

180181
const char* PythonObject::str() const
181182
{
182-
return PyString_AsString(obj_);
183+
return PyUnicode_AsUTF8(obj_);
183184
}
184185

185186
PythonObject::operator bool() const
@@ -200,7 +201,7 @@ PythonObject construct(long long ll)
200201

201202
PythonObject construct(int i)
202203
{
203-
return PythonObject(PythonObject::owning {}, PyInt_FromLong(i));
204+
return PythonObject(PythonObject::owning {}, PyLong_FromLong(i));
204205
}
205206

206207
PythonObject construct(double d)
@@ -210,7 +211,7 @@ PythonObject construct(double d)
210211

211212
PythonObject construct(const std::string& str)
212213
{
213-
return PythonObject(PythonObject::owning {}, PyString_FromString(str.c_str()));
214+
return PythonObject(PythonObject::owning {}, PyUnicode_FromString(str.c_str()));
214215
}
215216

216217
PythonObject construct(const std::vector<PythonObject>& v)
@@ -235,7 +236,7 @@ void addModuleSearchPath(const std::string& path)
235236
auto syspath = PySys_GetObject(&pathString[0]); // Borrowed reference
236237

237238
PythonObject pypath(PythonObject::owning {},
238-
PyString_FromString(path.c_str()));
239+
PyUnicode_FromString(path.c_str()));
239240

240241
if (!pypath) {
241242
throw WrappyError("Wrappy: Can't allocate memory for string.");
@@ -354,7 +355,7 @@ PythonObject callWithArgs(
354355
PythonObject function = loadObject(from, name);
355356

356357
if (!function) {
357-
throw WrappyError("Wrappy: "
358+
throw WrappyError("Wrappy: "
358359
"Lookup of function " + functionName + " failed.");
359360
}
360361

@@ -444,7 +445,7 @@ std::map<const char*, PythonObject> to_map(PyObject* pykwargs)
444445
PyObject *key, *value;
445446
Py_ssize_t pos = 0;
446447
while (PyDict_Next(pykwargs, &pos, &key, &value)) {
447-
const char* str = PyString_AsString(key);
448+
const char* str = PyUnicode_AsUTF8(key);
448449
PythonObject obj(PythonObject::borrowed{}, value);
449450
kwargs.emplace(str, obj);
450451
}
@@ -453,12 +454,12 @@ std::map<const char*, PythonObject> to_map(PyObject* pykwargs)
453454
}
454455

455456
PyObject* trampolineWithData(PyObject* data, PyObject* pyargs, PyObject* pykwargs) {
456-
if (!PyCObject_Check(data)) {
457+
if (!PyCapsule_CheckExact(data)) {
457458
throw WrappyError("Trampoline data corrupted");
458459
}
459460

460-
LambdaWithData fun = reinterpret_cast<LambdaWithData>(PyCObject_AsVoidPtr(data));
461-
void* userdata = PyCObject_GetDesc(data);
461+
LambdaWithData fun = reinterpret_cast<LambdaWithData>(PyCapsule_GetPointer(data, "lambda"));
462+
void* userdata = PyCapsule_GetContext(data);
462463
auto args = to_vector(pyargs);
463464
auto kwargs = to_map(pykwargs);
464465

@@ -467,11 +468,11 @@ PyObject* trampolineWithData(PyObject* data, PyObject* pyargs, PyObject* pykwarg
467468

468469
PyObject* trampolineNoData(PyObject* data, PyObject* pyargs, PyObject* pykwargs)
469470
{
470-
if (!PyCObject_Check(data)) {
471+
if (!PyCapsule_CheckExact(data)) {
471472
throw WrappyError("Trampoline data corrupted");
472473
}
473474

474-
Lambda fun = reinterpret_cast<Lambda>(PyCObject_AsVoidPtr(data));
475+
Lambda fun = reinterpret_cast<Lambda>(PyCapsule_GetPointer(data, "lambda"));
475476
auto args = to_vector(pyargs);
476477
auto kwargs = to_map(pykwargs);
477478

@@ -487,18 +488,14 @@ PyMethodDef trampolineWithDataMethod {"trampoline2", reinterpret_cast<PyCFunctio
487488

488489
PythonObject construct(Lambda lambda)
489490
{
490-
PyObject* pydata = PyCObject_FromVoidPtr(reinterpret_cast<void*>(lambda), nullptr);
491+
PyObject * pydata = PyCapsule_New(reinterpret_cast<void*>(lambda), "lambda", nullptr);
491492
return PythonObject(PythonObject::owning{}, PyCFunction_New(&trampolineNoDataMethod, pydata));
492493
}
493494

494495
PythonObject construct(LambdaWithData lambda, void* userdata)
495496
{
496-
PyObject* pydata;
497-
if (!userdata) {
498-
pydata = PyCObject_FromVoidPtr(reinterpret_cast<void*>(lambda), nullptr);
499-
} else { // python returns an error if FromVoidPtrAndDesc is called with desc being null
500-
pydata = PyCObject_FromVoidPtrAndDesc(reinterpret_cast<void*>(lambda), userdata, nullptr);
501-
}
497+
PyObject * pydata = PyCapsule_New(reinterpret_cast<void*>(lambda), "lambda", nullptr);
498+
if (userdata) PyCapsule_SetContext(pydata, userdata);
502499
return PythonObject(PythonObject::owning{}, PyCFunction_New(&trampolineWithDataMethod, pydata));
503500
}
504501

0 commit comments

Comments
 (0)