summaryrefslogtreecommitdiff
path: root/gpspacket.c
diff options
context:
space:
mode:
authorFred Wright <fw@fwright.net>2016-04-08 10:07:42 -0700
committerEric S. Raymond <esr@thyrsus.com>2016-04-09 04:39:15 -0400
commit97be9754e1eb6fb83e114af1b2286e287793f693 (patch)
treeddf288e79d4208498b7aaa039b230bdbfe292be9 /gpspacket.c
parent90413f5f16d66b69da2f8d5cd8d989aabb12514b (diff)
downloadgpsd-97be9754e1eb6fb83e114af1b2286e287793f693.tar.gz
Fixes Python C extensions for Python 3 compatibility.
These are necessary, but not sufficient, changes to make the C extensions work "polyglot". These are believed to be complete as far as the C code is concerned, and don't break Python 2 compatibility. This puts all the stuff that needs to differ between Python 2 and Python 3 into conditionally-defined macros in a new header file python_compatibility.h. The definitions assume Python 2.6 or later. In addition to the things requiring conditionals, the Lexer object was using the deprecated tp_getattr entry, with a function based on Py_FindMethod, which is gone in Python 3. However, the newer tp_getattro entry can be pointed directly to PyObject_GenericGetAttr, which works in Python 2 and 3. Packet data returned by the Lexer is now 'bytes' in Python 3, which is appropriate given that it may contain binary data. However, it means that packet data can't be passed directly to anything expecting a 'str'. In Python 2, the data is just a 'str' as usual. TESTED: Ran "scons build-all check" and xgps (using Python 2.7). Also ran the daemon and maidenhead-locator tests with Python 2.6.
Diffstat (limited to 'gpspacket.c')
-rw-r--r--gpspacket.c31
1 files changed, 13 insertions, 18 deletions
diff --git a/gpspacket.c b/gpspacket.c
index 06a41d36..0c9ade28 100644
--- a/gpspacket.c
+++ b/gpspacket.c
@@ -9,6 +9,7 @@
#include <stdio.h>
#include "gpsd.h"
+#include "python_compatibility.h"
static PyObject *ErrorObject = NULL;
@@ -94,7 +95,7 @@ Lexer_get(LexerObject *self, PyObject *args)
if (PyErr_Occurred())
return NULL;
- return Py_BuildValue("(i, i, s#, i)",
+ return Py_BuildValue("(i, i, " GPSD_PY_BYTE_FORMAT ", i)",
len,
self->lexer.type,
self->lexer.outbuffer,
@@ -125,12 +126,6 @@ static PyMethodDef Lexer_methods[] = {
{NULL, NULL} /* sentinel */
};
-static PyObject *
-Lexer_getattr(LexerObject *self, char *name)
-{
- return Py_FindMethod(Lexer_methods, (PyObject *)self, name);
-}
-
PyDoc_STRVAR(Lexer__doc__,
"GPS packet lexer object\n\
\n\
@@ -139,15 +134,14 @@ Fetch a single packet from file descriptor");
static PyTypeObject Lexer_Type = {
/* The ob_type field must be initialized in the module init function
* to be portable to Windows without using C++. */
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
+ PyVarObject_HEAD_INIT(NULL, 0)
"gps.packet.lexer", /*tp_name*/
sizeof(LexerObject), /*tp_basicsize*/
0, /*tp_itemsize*/
/* methods */
(destructor)Lexer_dealloc, /*tp_dealloc*/
0, /*tp_print*/
- (getattrfunc)Lexer_getattr, /*tp_getattr*/
+ 0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
@@ -157,11 +151,11 @@ static PyTypeObject Lexer_Type = {
0, /*tp_hash*/
0, /*tp_call*/
0, /*tp_str*/
- 0, /*tp_getattro*/
+ PyObject_GenericGetAttr, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
- Lexer__doc__, /*tp_doc*/
+ Lexer__doc__, /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
0, /*tp_richcompare*/
@@ -255,17 +249,16 @@ level of the message and the message itself.\n\
/* banishes a pointless compiler warning */
extern PyMODINIT_FUNC initpacket(void);
-PyMODINIT_FUNC
// cppcheck-suppress unusedFunction
-initpacket(void)
+GPSD_PY_MODULE_INIT(packet)
{
PyObject *m;
- if (PyType_Ready(&Lexer_Type) < 0)
- return;
-
/* Create the module and add the functions */
- m = Py_InitModule3("packet", packet_methods, module_doc);
+ GPSD_PY_MODULE_DEF(m, "packet", module_doc, packet_methods)
+
+ if (m == NULL || PyType_Ready(&Lexer_Type) < 0)
+ return GPSD_PY_MODULE_ERROR_VAL;
PyModule_AddIntConstant(m, "BAD_PACKET", BAD_PACKET);
PyModule_AddIntConstant(m, "COMMENT_PACKET", COMMENT_PACKET);
@@ -298,4 +291,6 @@ initpacket(void)
PyModule_AddIntConstant(m, "LOG_DATA", LOG_DATA);
PyModule_AddIntConstant(m, "LOG_SPIN", LOG_SPIN);
PyModule_AddIntConstant(m, "LOG_RAW", LOG_RAW);
+
+ return GPSD_PY_MODULE_SUCCESS_VAL(m);
}