[Python-checkins] python/nondist/sandbox/setobj setobject.c, 1.4, 1.5 test_set.py, 1.4, 1.5

rhettinger at users.sourceforge.net rhettinger at users.sourceforge.net
Thu Nov 13 12:14:39 EST 2003


Update of /cvsroot/python/python/nondist/sandbox/setobj
In directory sc8-pr-cvs1:/tmp/cvs-serv29508

Modified Files:
	setobject.c test_set.py 
Log Message:
Split into set() and frozenset().  Add __hash__().

Index: setobject.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/setobj/setobject.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** setobject.c	13 Nov 2003 11:31:04 -0000	1.4
--- setobject.c	13 Nov 2003 17:14:37 -0000	1.5
***************
*** 27,31 ****
  
  static PyTypeObject set_type;
! 
  
  static PyObject *
--- 27,31 ----
  
  static PyTypeObject set_type;
! static PyTypeObject frozenset_type;
  
  static PyObject *
***************
*** 118,122 ****
  {
  	return DICT_CONTAINS(so->data, key);
- 	//return so->data->ob_type->tp_as_sequence->sq_contains(so->data, key);
  }
  
--- 118,121 ----
***************
*** 130,134 ****
  		return NULL;
  
! 	so = (setobject *)PyObject_GC_New(setobject, &set_type);
  	if (so == NULL) {
  		Py_DECREF(data);
--- 129,133 ----
  		return NULL;
  
! 	so = (setobject *)PyObject_GC_New(setobject, so->ob_type);
  	if (so == NULL) {
  		Py_DECREF(data);
***************
*** 178,182 ****
  	PyObject *item, *selfdata, *tgtdata, *it;
  
! 	result = (setobject *)make_new_set(&set_type, NULL);
  	if (result == NULL)
  		return NULL;
--- 177,181 ----
  	PyObject *item, *selfdata, *tgtdata, *it;
  
! 	result = (setobject *)make_new_set(so->ob_type, NULL);
  	if (result == NULL)
  		return NULL;
***************
*** 256,260 ****
  	tgtdata = result->data;
  
! 	otherset = (setobject *)make_new_set(&set_type, other);
  	if (otherset == NULL) {
  		Py_DECREF(result);
--- 255,259 ----
  	tgtdata = result->data;
  
! 	otherset = (setobject *)make_new_set(so->ob_type, other);
  	if (otherset == NULL) {
  		Py_DECREF(result);
***************
*** 294,297 ****
--- 293,321 ----
  (i.e. all elements that are in exactly one of the sets.)\n");
  
+ static long
+ set_nohash(PyObject *self)
+ {
+ 	PyErr_SetString(PyExc_TypeError, "set objects are unhashable");
+ 	return -1;
+ }
+ 
+ static long
+ frozenset_hash(PyObject *so)
+ {
+ 	PyObject *it, *item;
+ 	long hash = 0;
+ 		
+ 	it = PyObject_GetIter(((setobject *)so)->data);
+ 	if (it == NULL) 
+ 		return -1;
+ 
+ 	while ((item = PyIter_Next(it)) != NULL) {
+ 		hash ^= PyObject_Hash(item);
+ 		Py_DECREF(item);
+ 	}
+ 	Py_DECREF(it);
+ 	return hash;
+ }
+ 
  static PySequenceMethods set_as_sequence = {
  	(inquiry)set_len,		/* sq_length */
***************
*** 305,308 ****
--- 329,334 ----
  };
  
+ /* set object ********************************************************/
+ 
  static PyMethodDef set_methods[] = {
  	{"copy",	(PyCFunction)set_copy,		METH_NOARGS,
***************
*** 342,346 ****
  	&set_as_sequence,		/* tp_as_sequence */
  	0,				/* tp_as_mapping */
! 	0,				/* tp_hash */
  	0,				/* tp_call */
  	0,				/* tp_str */
--- 368,372 ----
  	&set_as_sequence,		/* tp_as_sequence */
  	0,				/* tp_as_mapping */
! 	set_nohash,			/* tp_hash */
  	0,				/* tp_call */
  	0,				/* tp_str */
***************
*** 371,374 ****
--- 397,469 ----
  };
  
+ /* frozenset object ********************************************************/
+ 
+ 
+ static PyMethodDef frozenset_methods[] = {
+ 	{"copy",	(PyCFunction)set_copy,		METH_NOARGS,
+ 	 copy_doc},
+ 	{"__copy__",	(PyCFunction)set_copy,		METH_NOARGS,
+ 	 copy_doc},
+ 	{"difference",(PyCFunction)set_difference,	METH_O,
+ 	 difference_doc},
+ 	{"intersection",(PyCFunction)set_intersection,	METH_O,
+ 	 intersection_doc},
+ 	{"symmetric_difference",(PyCFunction)set_symmetric_difference,	METH_O,
+ 	 symmetric_difference_doc},
+ 	{"union",	(PyCFunction)set_union,		METH_O,
+ 	 union_doc},
+ 	{NULL,		NULL}	/* sentinel */
+ };
+ 
+ PyDoc_STRVAR(frozenset_doc,
+ "frozenset(iterable) --> frozenset object\n\
+ \n\
+ Build an immutable unordered collection.");
+ 
+ static PyTypeObject frozenset_type = {
+ 	PyObject_HEAD_INIT(NULL)
+ 	0,				/* ob_size */
+ 	"frozenset",			/* tp_name */
+ 	sizeof(setobject),		/* tp_basicsize */
+ 	0,				/* tp_itemsize */
+ 	/* methods */
+ 	(destructor)set_dealloc,	/* tp_dealloc */
+ 	0,				/* tp_print */
+ 	0,				/* tp_getattr */
+ 	0,				/* tp_setattr */
+ 	0,				/* tp_compare */
+ 	0,				/* tp_repr */
+ 	0,				/* tp_as_number */
+ 	&set_as_sequence,		/* tp_as_sequence */
+ 	0,				/* tp_as_mapping */
+ 	frozenset_hash,			/* tp_hash */
+ 	0,				/* tp_call */
+ 	0,				/* tp_str */
+ 	PyObject_GenericGetAttr,	/* tp_getattro */
+ 	0,				/* tp_setattro */
+ 	0,				/* tp_as_buffer */
+ 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
+ 		Py_TPFLAGS_BASETYPE,	/* tp_flags */
+ 	frozenset_doc,			/* tp_doc */
+ 	(traverseproc)set_traverse,	/* tp_traverse */
+ 	0,				/* tp_clear */
+ 	0,				/* tp_richcompare */
+ 	0,				/* tp_weaklistoffset */
+ 	(getiterfunc)set_iter,		/* tp_iter */
+ 	0,				/* tp_iternext */
+ 	frozenset_methods,		/* tp_methods */
+ 	0,				/* tp_members */
+ 	0,				/* tp_getset */
+ 	0,				/* tp_base */
+ 	0,				/* tp_dict */
+ 	0,				/* tp_descr_get */
+ 	0,				/* tp_descr_set */
+ 	0,				/* tp_dictoffset */
+ 	0,				/* tp_init */
+ 	0,				/* tp_alloc */
+ 	set_new,			/* tp_new */
+ 	PyObject_GC_Del,		/* tp_free */
+ };
+ 
  
  
***************
*** 388,396 ****
  	PyObject *m;
  
- 	if (PyType_Ready(&set_type) < 0)
- 		return;
  	m = Py_InitModule3("set", NULL, module_doc);
  
  	Py_INCREF(&set_type);
  	PyModule_AddObject(m, "set", (PyObject *)&set_type);
  }
--- 483,496 ----
  	PyObject *m;
  
  	m = Py_InitModule3("set", NULL, module_doc);
  
+ 	if (PyType_Ready(&set_type) < 0)
+ 		return;
  	Py_INCREF(&set_type);
  	PyModule_AddObject(m, "set", (PyObject *)&set_type);
+ 
+ 	if (PyType_Ready(&frozenset_type) < 0)
+ 		return;
+ 	Py_INCREF(&frozenset_type);
+ 	PyModule_AddObject(m, "frozenset", (PyObject *)&frozenset_type);
  }

Index: test_set.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/setobj/test_set.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** test_set.py	13 Nov 2003 11:31:04 -0000	1.4
--- test_set.py	13 Nov 2003 17:14:37 -0000	1.5
***************
*** 1,7 ****
! from set import set
  import unittest
  from test import test_support
  
! class TestBasicOps(unittest.TestCase):
  
      def setUp(self):
--- 1,8 ----
! from set import set, frozenset
  import unittest
  from test import test_support
  
! class TestJointOps(unittest.TestCase):
!     # Tests common to both set and frozenset
  
      def setUp(self):
***************
*** 9,13 ****
          self.otherword = 'alacazam'
          self.letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
!         self.s = set(word)
          self.d = dict.fromkeys(word)
  
--- 10,14 ----
          self.otherword = 'alacazam'
          self.letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
!         self.s = self.thetype(word)
          self.d = dict.fromkeys(word)
  
***************
*** 28,31 ****
--- 29,33 ----
          for c in self.letters:
              self.assertEqual(c in u, c in self.d or c in self.otherword)
+         self.assertEqual(type(u), self.thetype)
  
      def test_intersection(self):
***************
*** 33,36 ****
--- 35,39 ----
          for c in self.letters:
              self.assertEqual(c in i, c in self.d and c in self.otherword)
+         self.assertEqual(type(i), self.thetype)
  
      def test_difference(self):
***************
*** 38,41 ****
--- 41,45 ----
          for c in self.letters:
              self.assertEqual(c in i, c in self.d and c not in self.otherword)
+         self.assertEqual(type(i), self.thetype)
  
      def test_symmetric_difference(self):
***************
*** 43,50 ****
          for c in self.letters:
              self.assertEqual(c in i, (c in self.d) ^ (c in self.otherword))
  
  def test_main(verbose=None):
      from test import test_sets
!     test_support.run_unittest(TestBasicOps)
  
  if __name__ == "__main__":
--- 47,70 ----
          for c in self.letters:
              self.assertEqual(c in i, (c in self.d) ^ (c in self.otherword))
+         self.assertEqual(type(i), self.thetype)
+ 
+ class TestSet(TestJointOps):
+     thetype = set
+ 
+     def test_hash(self):
+         self.assertRaises(TypeError, hash, self.s)
+ 
+ class TestFrozenSet(TestJointOps):
+     thetype = frozenset
+ 
+     def test_hash(self):
+         self.assertEqual(hash(frozenset('abcdeb')), hash(frozenset('ebecda')))
  
  def test_main(verbose=None):
      from test import test_sets
!     test_support.run_unittest(
!         TestSet,
!         TestFrozenSet,
!         )
  
  if __name__ == "__main__":





More information about the Python-checkins mailing list