[Zope-Checkins] CVS: Zope/lib/python/Missing - _Missing.c:1.2 __init__.py:1.2 setup.py:1.2 tests.py:1.2

Jim Fulton cvs-admin at zope.org
Fri Nov 28 11:45:08 EST 2003


Update of /cvs-repository/Zope/lib/python/Missing
In directory cvs.zope.org:/tmp/cvs-serv4361/lib/python/Missing

Added Files:
	_Missing.c __init__.py setup.py tests.py 
Log Message:
Reimplemented missing objects to use new-style extension classes.


=== Zope/lib/python/Missing/_Missing.c 1.1 => 1.2 ===
--- /dev/null	Fri Nov 28 11:45:08 2003
+++ Zope/lib/python/Missing/_Missing.c	Fri Nov 28 11:45:07 2003
@@ -0,0 +1,299 @@
+/*****************************************************************************
+
+  Copyright (c) 1996-2002 Zope Corporation and Contributors.
+  All Rights Reserved.
+
+  This software is subject to the provisions of the Zope Public License,
+  Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+  WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+  FOR A PARTICULAR PURPOSE
+
+ ****************************************************************************/
+
+static char Missing_module_documentation[] = 
+""
+"\n$Id$"
+;
+
+#include "ExtensionClass.h"
+
+/* Declarations for objects of type Missing */
+
+typedef struct {
+  PyObject_HEAD
+} Missing;
+
+static PyObject *vname=0, *Missing_dot_Value=0, *empty_string=0, *reduce=0;
+static PyObject *theValue, *notMissing;
+
+static void
+Missing_dealloc(Missing *self)
+{
+  Py_DECREF(self->ob_type);
+  PyMem_DEL(self);
+}
+
+static PyObject *
+Missing_repr(Missing *self)
+{
+  Py_INCREF(Missing_dot_Value);
+  return Missing_dot_Value;
+}
+
+static PyObject *
+Missing_str(Missing *self)
+{
+  Py_INCREF(empty_string);
+  return empty_string;
+}
+
+/* Code to access Missing objects as numbers.
+
+   We must guarantee that notMissing is never returned to Python code,
+   because it would violate the guarantee that all Python-accessible
+   Missing values are equal to each other.
+
+*/
+
+static PyObject *
+Missing_bin(PyObject *v, PyObject *w)
+{
+    if (v == notMissing)
+	v = w;
+    assert(v != notMissing);
+    Py_INCREF(v);
+    return v;
+}
+
+static PyObject *
+Missing_pow(PyObject *v, PyObject *w, PyObject *z)
+{
+    if (v == notMissing)
+	v = w;
+    assert(v != notMissing);
+    Py_INCREF(v);
+    return v;
+}				
+
+static PyObject *
+Missing_un(PyObject *v)
+{
+  Py_INCREF(v);
+  return v;
+}
+
+static int
+Missing_nonzero(PyObject *v)
+{
+  return 0;
+}
+
+/* Always return the distinguished notMissing object as the result
+   of the coercion.  The notMissing object does not compare equal
+   to other Missing objects.
+*/
+
+static int
+Missing_coerce(PyObject **pv, PyObject **pw)
+{
+    Py_INCREF(*pv);
+    Py_INCREF(notMissing);
+    *pw = notMissing;
+    return 0;
+}
+
+static PyNumberMethods Missing_as_number = {
+	(binaryfunc)Missing_bin,	/*nb_add*/
+	(binaryfunc)Missing_bin,	/*nb_subtract*/
+	(binaryfunc)Missing_bin,	/*nb_multiply*/
+	(binaryfunc)Missing_bin,	/*nb_divide*/
+	(binaryfunc)Missing_bin,	/*nb_remainder*/
+	(binaryfunc)Missing_bin,	/*nb_divmod*/
+	(ternaryfunc)Missing_pow,	/*nb_power*/
+	(unaryfunc)Missing_un,		/*nb_negative*/
+	(unaryfunc)Missing_un,		/*nb_positive*/
+	(unaryfunc)Missing_un,		/*nb_absolute*/
+	(inquiry)Missing_nonzero,	/*nb_nonzero*/
+	(unaryfunc)Missing_un,		/*nb_invert*/
+	(binaryfunc)Missing_bin,	/*nb_lshift*/
+	(binaryfunc)Missing_bin,	/*nb_rshift*/
+	(binaryfunc)Missing_bin,	/*nb_and*/
+	(binaryfunc)Missing_bin,	/*nb_xor*/
+	(binaryfunc)Missing_bin,	/*nb_or*/
+	(coercion)Missing_coerce,	/*nb_coerce*/
+	0,		/*nb_int*/
+	0,		/*nb_long*/
+	0,		/*nb_float*/
+	0,		/*nb_oct*/
+	0,		/*nb_hex*/
+#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION != 1
+	0,		/* nb_inplace_add */
+	0,		/* nb_inplace_subtract */
+	0,		/* nb_inplace_multiply */
+	0,		/* nb_inplace_divide */
+	0,		/* nb_inplace_remainder */
+	0, 		/* nb_inplace_power */
+	0,		/* nb_inplace_lshift */
+	0,		/* nb_inplace_rshift */
+	0,		/* nb_inplace_and */
+	0,		/* nb_inplace_xor */
+	0,		/* nb_inplace_or */
+	Missing_bin, /* nb_floor_divide */
+	Missing_bin,	/* nb_true_divide */
+	0,		/* nb_inplace_floor_divide */
+	0,		/* nb_inplace_true_divide */
+#endif
+};
+
+/* ------------------------------------------------------- */
+
+static PyObject *
+Missing_reduce(PyObject *self, PyObject *args, PyObject *kw)
+{
+  if(self==theValue)
+    {
+      Py_INCREF(vname);
+      return vname;
+    }
+  return Py_BuildValue("O()",self->ob_type);
+}
+
+static struct PyMethodDef reduce_ml[] = {  
+  {"__reduce__", (PyCFunction)Missing_reduce, 1,
+   "Return a missing value reduced to standard python objects"
+  }
+};
+
+static PyObject *
+Missing_getattr(PyObject *self, PyObject *name)
+{
+  char *c, *legal;
+
+  if(!(c=PyString_AsString(name))) return NULL;
+
+  legal=c;
+  if (strchr("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 
+	     *legal) != NULL)
+    {
+      for (legal++; *legal; legal++)
+	if (strchr("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_", 
+		   *legal) == NULL) 
+	  {
+	    legal=NULL;
+	    break;
+	  }
+    }
+  else legal=NULL;
+
+  if(! legal)
+    {
+      if(strcmp(c,"__reduce__")==0)
+	{
+	  if(self==theValue)
+	    {
+	      Py_INCREF(reduce);
+	      return reduce;
+	    }
+	  return PyCFunction_New(reduce_ml, self);
+	}
+      PyErr_SetObject(PyExc_AttributeError, name);
+      return NULL;
+    }
+
+  Py_INCREF(self);
+  return self;
+}
+
+static PyObject *
+Missing_call(PyObject *self, PyObject *args, PyObject *kw)
+{
+  Py_INCREF(self);
+  return self;
+}
+
+/* All Missing objects are equal to each other, except for the
+   special notMissing object.  It is returned by coerce to 
+   indicate that Missing is being compare to something else.
+*/
+
+static int
+Missing_cmp(PyObject *m1, PyObject *m2)
+{
+    if (m1 == notMissing)
+	return -1;
+    return (m2 == notMissing);
+}
+
+static PyExtensionClass MissingType = {
+  PyObject_HEAD_INIT(NULL)
+  0,					/*ob_size*/
+  "Missing",				/*tp_name*/
+  sizeof(Missing),			/*tp_basicsize*/
+  0,					/*tp_itemsize*/
+  /* methods */
+  (destructor)Missing_dealloc,		/*tp_dealloc*/
+  (printfunc)0,				/*tp_print*/
+  (getattrfunc)0,			/*obsolete tp_getattr*/
+  (setattrfunc)0,			/*obsolete tp_setattr*/
+  Missing_cmp,				/*tp_compare*/
+  (reprfunc)Missing_repr,		/*tp_repr*/
+  &Missing_as_number,			/*tp_as_number*/
+  0,					/*tp_as_sequence*/
+  0,					/*tp_as_mapping*/
+  (hashfunc)0,				/*tp_hash*/
+  (ternaryfunc)Missing_call,		/*tp_call*/
+  (reprfunc)Missing_str,		/*tp_str*/
+  (getattrofunc)Missing_getattr,	/*tp_getattro*/
+  (setattrofunc)0,			/*tp_setattro*/
+  
+  /* Space for future expansion */
+  0L,0L,
+  "Represent totally unknown quantities\n"
+  "\n"
+  "Missing values are used to represent numeric quantities that are\n"
+  "unknown.  They support all mathematical operations except\n"
+  "conversions by returning themselves.\n",
+  METHOD_CHAIN(NULL)
+};
+
+/* End of code for Missing objects */
+/* -------------------------------------------------------- */
+
+
+/* List of methods defined in the module */
+
+static struct PyMethodDef Module_Level__methods[] = {  
+  {NULL, (PyCFunction)NULL, 0, NULL}		/* sentinel */
+};
+
+void
+init_Missing(void)
+{
+  PyObject *m, *d;
+
+  if(! ((vname=PyString_FromString("V"))
+	&& (Missing_dot_Value=PyString_FromString("Missing.Value"))
+	&& (empty_string=PyString_FromString(""))
+	)) return;
+
+  /* Create the module and add the functions */
+  m = Py_InitModule4("_Missing", Module_Level__methods,
+		     Missing_module_documentation,
+		     (PyObject*)NULL,PYTHON_API_VERSION);
+
+  /* Add some symbolic constants to the module */
+  d = PyModule_GetDict(m);
+
+  PyExtensionClass_Export(d,"Missing",MissingType);
+
+  theValue = PyObject_CallObject((PyObject*)&MissingType, NULL);
+  notMissing = PyObject_CallObject((PyObject*)&MissingType, NULL);
+  reduce=PyCFunction_New(reduce_ml, theValue);
+
+  PyDict_SetItemString(d, "Value", theValue);
+  PyDict_SetItemString(d, "V", theValue); 
+  PyDict_SetItemString(d, "MV", theValue); 
+}
+ 


=== Zope/lib/python/Missing/__init__.py 1.1 => 1.2 ===
--- /dev/null	Fri Nov 28 11:45:08 2003
+++ Zope/lib/python/Missing/__init__.py	Fri Nov 28 11:45:07 2003
@@ -0,0 +1 @@
+from _Missing import *


=== Zope/lib/python/Missing/setup.py 1.1 => 1.2 ===
--- /dev/null	Fri Nov 28 11:45:08 2003
+++ Zope/lib/python/Missing/setup.py	Fri Nov 28 11:45:07 2003
@@ -0,0 +1,22 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+
+from distutils.core import setup, Extension
+setup(name="_Missing", version="2.0",
+      ext_modules=[
+         Extension("_Missing", ["_Missing.c"],
+                   include_dirs = ['.', '../ExtensionClass'],
+                   depends = ['../ExtensionClass/ExtensionClass.h']),
+         ])
+


=== Zope/lib/python/Missing/tests.py 1.1 => 1.2 ===
--- /dev/null	Fri Nov 28 11:45:08 2003
+++ Zope/lib/python/Missing/tests.py	Fri Nov 28 11:45:07 2003
@@ -0,0 +1,46 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Test for missing values.
+
+>>> from Missing import Value
+
+>>> Value != 12
+1
+>>> 12 != Value
+1
+>>> u"abc" != Value
+1
+>>> Value != u"abc"
+1
+
+>>> 1 + Value == Value
+1
+>>> Value + 1 == Value
+1
+>>> Value == 1 + Value
+1
+>>> Value == Value + 1
+1
+
+$Id$
+"""
+import unittest
+from doctest import DocTestSuite
+
+def test_suite():
+    return unittest.TestSuite((
+        DocTestSuite(),
+        ))
+
+if __name__ == '__main__': unittest.main()




More information about the Zope-Checkins mailing list