From ce425df78ce5da50005635cb270ba0e5e74ef814 Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Tue, 9 Aug 2011 16:52:15 -0700 Subject: [PATCH] More Python upb.FieldDef functionality and tests. --- lang_ext/python/test.py | 31 +++++++++++++++++++++++++++--- lang_ext/python/upb.c | 42 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 66 insertions(+), 7 deletions(-) diff --git a/lang_ext/python/test.py b/lang_ext/python/test.py index df152da9e3..d278cab4cf 100644 --- a/lang_ext/python/test.py +++ b/lang_ext/python/test.py @@ -5,10 +5,35 @@ import unittest class TestFieldDef(unittest.TestCase): def test_construction(self): fielddef1 = upb.FieldDef() - self.assertTrue(fielddef1 is not None) - fielddef2 = upb.FieldDef(number=1, name="field1", label=2, type=3) - self.assertTrue(fielddef2 is not None) + self.assertTrue(fielddef1.number is None) + self.assertTrue(fielddef1.name is None) + self.assertTrue(fielddef1.type is None) + self.assertEqual(fielddef1.label, upb.LABEL_OPTIONAL) + + fielddef2 = upb.FieldDef(number=5, name="field2", + label=upb.LABEL_REQUIRED, type=upb.TYPE_INT32, + type_name="MyType") + self.assertTrue(id(fielddef1) != id(fielddef2)) + self.assertEqual(fielddef2.number, 5) + self.assertEqual(fielddef2.name, "field2") + self.assertEqual(fielddef2.label, upb.LABEL_REQUIRED) + self.assertEqual(fielddef2.type, upb.TYPE_INT32) + self.assertEqual(fielddef2.type_name, "MyType") + + fielddef2.number = 8 + self.assertEqual(fielddef2.number, 8) + + fielddef2.name = "xxx" + self.assertEqual(fielddef2.name, "xxx") + + fielddef2.label = upb.LABEL_REPEATED + self.assertEqual(fielddef2.label, upb.LABEL_REPEATED) + + fielddef2.type = upb.TYPE_FLOAT + self.assertEqual(fielddef2.type, upb.TYPE_FLOAT) + + # TODO: test that assigning invalid values is properly prevented. if __name__ == '__main__': unittest.main() diff --git a/lang_ext/python/upb.c b/lang_ext/python/upb.c index 9a4840189e..0b892114d8 100644 --- a/lang_ext/python/upb.c +++ b/lang_ext/python/upb.c @@ -60,15 +60,25 @@ static void PyUpb_FieldDef_dealloc(PyObject *obj) { static PyObject* PyUpb_FieldDef_getattro(PyObject *obj, PyObject *attr_name) { PyUpb_FieldDef *f = Check_FieldDef(obj, NULL); + if (!upb_fielddef_ismutable(f->field)) { + PyErr_SetString(PyExc_TypeError, "fielddef is not mutable."); + return NULL; + } const char *name = PyString_AsString(attr_name); if (streql(name, "name")) { - return PyString_FromString(upb_fielddef_name(f->field)); + const char *name = upb_fielddef_name(f->field); + return name == NULL ? Py_None : PyString_FromString(name); } else if (streql(name, "number")) { - return PyInt_FromLong(upb_fielddef_number(f->field)); + uint32_t num = upb_fielddef_number(f->field); + return num == 0 ? Py_None : PyInt_FromLong(num); } else if (streql(name, "type")) { - return PyInt_FromLong(upb_fielddef_type(f->field)); + uint8_t type = upb_fielddef_type(f->field); + return type == 0 ? Py_None : PyInt_FromLong(type); } else if (streql(name, "label")) { return PyInt_FromLong(upb_fielddef_label(f->field)); + } else if (streql(name, "type_name")) { + const char *name = upb_fielddef_typename(f->field); + return name == NULL ? Py_None : PyString_FromString(name); } else if (streql(name, "subdef")) { // NYI; return NULL; @@ -150,7 +160,7 @@ static PyTypeObject PyUpb_FieldDefType = { 0, /* tp_call */ 0, /* tp_str */ &PyUpb_FieldDef_getattro, /* tp_getattro */ - 0, /* tp_setattro */ + &PyUpb_FieldDef_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ 0, /* tp_doc */ @@ -187,4 +197,28 @@ PyMODINIT_FUNC initupb(void) { Py_INCREF(&PyUpb_FieldDefType); PyModule_AddObject(mod, "FieldDef", (PyObject*)&PyUpb_FieldDefType); + + // Register constants. + PyModule_AddIntConstant(mod, "LABEL_OPTIONAL", UPB_LABEL(OPTIONAL)); + PyModule_AddIntConstant(mod, "LABEL_REQUIRED", UPB_LABEL(REQUIRED)); + PyModule_AddIntConstant(mod, "LABEL_REPEATED", UPB_LABEL(REPEATED)); + + PyModule_AddIntConstant(mod, "TYPE_DOUBLE", UPB_TYPE(DOUBLE)); + PyModule_AddIntConstant(mod, "TYPE_FLOAT", UPB_TYPE(FLOAT)); + PyModule_AddIntConstant(mod, "TYPE_INT64", UPB_TYPE(INT64)); + PyModule_AddIntConstant(mod, "TYPE_UINT64", UPB_TYPE(UINT64)); + PyModule_AddIntConstant(mod, "TYPE_INT32", UPB_TYPE(INT32)); + PyModule_AddIntConstant(mod, "TYPE_FIXED64", UPB_TYPE(FIXED64)); + PyModule_AddIntConstant(mod, "TYPE_FIXED32", UPB_TYPE(FIXED32)); + PyModule_AddIntConstant(mod, "TYPE_BOOL", UPB_TYPE(BOOL)); + PyModule_AddIntConstant(mod, "TYPE_STRING", UPB_TYPE(STRING)); + PyModule_AddIntConstant(mod, "TYPE_GROUP", UPB_TYPE(GROUP)); + PyModule_AddIntConstant(mod, "TYPE_MESSAGE", UPB_TYPE(MESSAGE)); + PyModule_AddIntConstant(mod, "TYPE_BYTES", UPB_TYPE(BYTES)); + PyModule_AddIntConstant(mod, "TYPE_UINT32", UPB_TYPE(UINT32)); + PyModule_AddIntConstant(mod, "TYPE_ENUM", UPB_TYPE(ENUM)); + PyModule_AddIntConstant(mod, "TYPE_SFIXED32", UPB_TYPE(SFIXED32)); + PyModule_AddIntConstant(mod, "TYPE_SFIXED64", UPB_TYPE(SFIXED64)); + PyModule_AddIntConstant(mod, "TYPE_SINT32", UPB_TYPE(SINT32)); + PyModule_AddIntConstant(mod, "TYPE_SINT64", UPB_TYPE(SINT64)); }