changeset 8:6647870380cc

Added support for undefined.
author Atul Varma <varmaa@toolness.com>
date Sun, 28 Jun 2009 13:32:46 -0700
parents 0d0ce6415b66
children 032cfc448079
files pymonkey.c test_pymonkey.py
diffstat 2 files changed, 54 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/pymonkey.c	Sun Jun 28 13:09:39 2009 -0700
+++ b/pymonkey.c	Sun Jun 28 13:32:46 2009 -0700
@@ -1,6 +1,44 @@
 #include "jsapi.h"
 #include <Python/Python.h>
 
+#define Py_RETURN_UNDEFINED  { Py_INCREF(PYM_undefined);        \
+                               return PYM_undefined; }
+
+typedef struct {
+  PyObject_HEAD
+} PYM_undefinedObject;
+
+// TODO: We should make this behave as much like JavaScript's
+// "undefined" value as possible; e.g., its string value should
+// be "undefined", the singleton should be falsy, etc.
+static PyTypeObject PYM_undefinedType = {
+  PyObject_HEAD_INIT(NULL)
+  0,                           /*ob_size*/
+  "pymonkey.undefined",        /*tp_name*/
+  sizeof(PYM_undefinedObject), /*tp_basicsize*/
+  0,                           /*tp_itemsize*/
+  0,                           /*tp_dealloc*/
+  0,                           /*tp_print*/
+  0,                           /*tp_getattr*/
+  0,                           /*tp_setattr*/
+  0,                           /*tp_compare*/
+  0,                           /*tp_repr*/
+  0,                           /*tp_as_number*/
+  0,                           /*tp_as_sequence*/
+  0,                           /*tp_as_mapping*/
+  0,                           /*tp_hash */
+  0,                           /*tp_call*/
+  0,                           /*tp_str*/
+  0,                           /*tp_getattro*/
+  0,                           /*tp_setattro*/
+  0,                           /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT,          /*tp_flags*/
+  /* tp_doc */
+  "Pythonic equivalent of JavaScript's 'undefined' value",
+};
+
+static PyObject *PYM_undefined = (PyObject *) &PYM_undefinedType;
+
 static JSClass PYM_jsGlobalClass = {
   "PymonkeyGlobal", JSCLASS_GLOBAL_FLAGS,
   JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
@@ -29,6 +67,9 @@
   if (JSVAL_IS_NULL(value))
     Py_RETURN_NONE;
 
+  if (JSVAL_IS_VOID(value))
+    Py_RETURN_UNDEFINED;
+
   if (JSVAL_IS_STRING(value) && JS_CStringsAreUTF8()) {
     // TODO: What to do if C strings aren't UTF-8?  The jschar *
     // type isn't actually UTF-16, it's just "UTF-16-ish", so
@@ -132,6 +173,12 @@
   if (module == NULL)
     return;
 
+  if (PyType_Ready(&PYM_undefinedType) < 0)
+    return;
+
+  Py_INCREF(PYM_undefined);
+  PyModule_AddObject(module, "undefined", PYM_undefined);
+
   PYM_error = PyErr_NewException("pymonkey.error", NULL, NULL);
   Py_INCREF(PYM_error);
   PyModule_AddObject(module, "error", PYM_error);
--- a/test_pymonkey.py	Sun Jun 28 13:09:39 2009 -0700
+++ b/test_pymonkey.py	Sun Jun 28 13:32:46 2009 -0700
@@ -2,6 +2,13 @@
 import pymonkey
 
 class PymonkeyTests(unittest.TestCase):
+    def testUndefinedCannotBeInstantiated(self):
+        self.assertRaises(TypeError, pymonkey.undefined)
+
+    def testEvaluateReturnsUndefined(self):
+        retval = pymonkey.evaluate("", '<string>', 1)
+        self.assertTrue(retval is pymonkey.undefined)
+
     def testEvaluateReturnsUnicode(self):
         retval = pymonkey.evaluate("'o hai\u2026'", '<string>', 1)
         self.assertTrue(type(retval) == unicode)