From 2fd1e6d056c712d31de6967e986ea6a88ef5a366 Mon Sep 17 00:00:00 2001 From: Siu Kwan Lam Date: Fri, 10 Aug 2012 19:22:30 -0700 Subject: [PATCH 1/6] Add & use capsulethunk for Py2.6 --- llvm/capsulethunk.h | 134 ++++++++++++++++++++++++++++++++++++++++++++ llvm/wrap.h | 2 +- 2 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 llvm/capsulethunk.h diff --git a/llvm/capsulethunk.h b/llvm/capsulethunk.h new file mode 100644 index 0000000..6b20564 --- /dev/null +++ b/llvm/capsulethunk.h @@ -0,0 +1,134 @@ +#ifndef __CAPSULETHUNK_H +#define __CAPSULETHUNK_H + +#if ( (PY_VERSION_HEX < 0x02070000) \ + || ((PY_VERSION_HEX >= 0x03000000) \ + && (PY_VERSION_HEX < 0x03010000)) ) + +#define __PyCapsule_GetField(capsule, field, default_value) \ + ( PyCapsule_CheckExact(capsule) \ + ? (((PyCObject *)capsule)->field) \ + : (default_value) \ + ) \ + +#define __PyCapsule_SetField(capsule, field, value) \ + ( PyCapsule_CheckExact(capsule) \ + ? (((PyCObject *)capsule)->field = value), 1 \ + : 0 \ + ) \ + + +#define PyCapsule_Type PyCObject_Type + +#define PyCapsule_CheckExact(capsule) (PyCObject_Check(capsule)) +#define PyCapsule_IsValid(capsule, name) (PyCObject_Check(capsule)) + + +#define PyCapsule_New(pointer, name, destructor) \ + (PyCObject_FromVoidPtr(pointer, destructor)) + + +#define PyCapsule_GetPointer(capsule, name) \ + (PyCObject_AsVoidPtr(capsule)) + +/* Don't call PyCObject_SetPointer here, it fails if there's a destructor */ +#define PyCapsule_SetPointer(capsule, pointer) \ + __PyCapsule_SetField(capsule, cobject, pointer) + + +#define PyCapsule_GetDestructor(capsule) \ + __PyCapsule_GetField(capsule, destructor) + +#define PyCapsule_SetDestructor(capsule, dtor) \ + __PyCapsule_SetField(capsule, destructor, dtor) + + +/* + * Sorry, there's simply no place + * to store a Capsule "name" in a CObject. + */ +#define PyCapsule_GetName(capsule) NULL + +static int +PyCapsule_SetName(PyObject *capsule, const char *unused) +{ + unused = unused; + PyErr_SetString(PyExc_NotImplementedError, + "can't use PyCapsule_SetName with CObjects"); + return 1; +} + + + +#define PyCapsule_GetContext(capsule) \ + __PyCapsule_GetField(capsule, descr) + +#define PyCapsule_SetContext(capsule, context) \ + __PyCapsule_SetField(capsule, descr, context) + + +static void * +PyCapsule_Import(const char *name, int no_block) +{ + PyObject *object = NULL; + void *return_value = NULL; + char *trace; + size_t name_length = (strlen(name) + 1) * sizeof(char); + char *name_dup = (char *)PyMem_MALLOC(name_length); + + if (!name_dup) { + return NULL; + } + + memcpy(name_dup, name, name_length); + + trace = name_dup; + while (trace) { + char *dot = strchr(trace, '.'); + if (dot) { + *dot++ = '\0'; + } + + if (object == NULL) { + if (no_block) { + object = PyImport_ImportModuleNoBlock(trace); + } else { + object = PyImport_ImportModule(trace); + if (!object) { + PyErr_Format(PyExc_ImportError, + "PyCapsule_Import could not " + "import module \"%s\"", trace); + } + } + } else { + PyObject *object2 = PyObject_GetAttrString(object, trace); + Py_DECREF(object); + object = object2; + } + if (!object) { + goto EXIT; + } + + trace = dot; + } + + if (PyCObject_Check(object)) { + PyCObject *cobject = (PyCObject *)object; + return_value = cobject->cobject; + } else { + PyErr_Format(PyExc_AttributeError, + "PyCapsule_Import \"%s\" is not valid", + name); + } + +EXIT: + Py_XDECREF(object); + if (name_dup) { + PyMem_FREE(name_dup); + } + return return_value; +} + +#endif /* #if PY_VERSION_HEX < 0x02070000 */ + +#endif /* __CAPSULETHUNK_H */ diff --git a/llvm/wrap.h b/llvm/wrap.h index bceca87..44cca92 100644 --- a/llvm/wrap.h +++ b/llvm/wrap.h @@ -43,7 +43,7 @@ //// For pre-2.7 compatbility, use the following include, which provides //// alias for PyCapsule. //// See http://docs.python.org/py3k/howto/cporting.html -// #include // pre-2.7 compatibility for PyCapsule +#include "capsulethunk.h" // pre-2.7 compatibility for PyCapsule /* llvm includes */ From 2c25966dd6f93493bb881f7e42ac7ec770a588ba Mon Sep 17 00:00:00 2001 From: Ilan Schnell Date: Sun, 12 Aug 2012 23:05:53 -0500 Subject: [PATCH 2/6] backporting assertIs and assertIsNot to objcache.py --- test/objcache.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/test/objcache.py b/test/objcache.py index 7342439..996ba47 100755 --- a/test/objcache.py +++ b/test/objcache.py @@ -2,9 +2,23 @@ from llvm.core import * -import logging, unittest +import logging, sys, unittest class TestObjCache(unittest.TestCase): + + if sys.version_info[:2] < (2, 7): + def assertIs(self, expr1, expr2, msg=None): + if expr1 is not expr2: + standardMsg = '%s is not %s' % (safe_repr(expr1), + safe_repr(expr2)) + self.fail(self._formatMessage(msg, standardMsg)) + + def assertIsNot(self, expr1, expr2, msg=None): + if expr1 is expr2: + standardMsg = 'unexpectedly identical: %s' % (safe_repr( + expr1),) + self.fail(self._formatMessage(msg, standardMsg)) + def test_objcache(self): logging.debug("Testing module aliasing ..") m1 = Module.new('a') From 7f3550f93df0e9b520dad3de5dc577090616369a Mon Sep 17 00:00:00 2001 From: Ilan Schnell Date: Sun, 12 Aug 2012 23:12:55 -0500 Subject: [PATCH 3/6] fix more tests for Python 2.6 --- test/intrinsic.py | 2 +- test/operands.py | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/test/intrinsic.py b/test/intrinsic.py index 34c70c8..bd3bb98 100755 --- a/test/intrinsic.py +++ b/test/intrinsic.py @@ -102,7 +102,7 @@ class TestIntrinsic(unittest.TestCase): golden = math.sin(1.234) answer = retval.as_real(Type.float()) - self.assertLess(abs(answer-golden)/golden, 1e-5) + self.assertTrue(abs(answer-golden)/golden < 1e-5) if __name__ == '__main__': diff --git a/test/operands.py b/test/operands.py index d7f8132..9d8a560 100755 --- a/test/operands.py +++ b/test/operands.py @@ -1,6 +1,9 @@ #!/usr/bin/env python # Tests accessing of instruction operands. +import sys +import logging +import unittest from llvm.core import * try: @@ -8,8 +11,6 @@ try: except ImportError: from io import StringIO -import logging, unittest - m = None #===----------------------------------------------------------------------=== @@ -32,6 +33,14 @@ entry: """ class TestOperands(unittest.TestCase): + + if sys.version_info[:2] < (2, 7): + def assertIs(self, expr1, expr2, msg=None): + if expr1 is not expr2: + standardMsg = '%s is not %s' % (safe_repr(expr1), + safe_repr(expr2)) + self.fail(self._formatMessage(msg, standardMsg)) + def test_operands(self): m = Module.from_assembly(StringIO(test_module)) logging.debug("-"*60) From f54e1951212fb25c30a871b01fdaccddd827bd08 Mon Sep 17 00:00:00 2001 From: Ilan Schnell Date: Sun, 12 Aug 2012 23:21:45 -0500 Subject: [PATCH 4/6] more Python 2.6 test fixes --- test/constants.py | 8 ++++---- test/opaque.py | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/test/constants.py b/test/constants.py index c8e4000..afe1020 100755 --- a/test/constants.py +++ b/test/constants.py @@ -1,14 +1,14 @@ #! /usr/bin/env python - ''' Test and stress Constants. ''' +import unittest +import logging from llvm.core import * from llvm.ee import * from ctypes import * -import unittest, logging # logging.basicConfig(level=logging.DEBUG) @@ -135,7 +135,7 @@ class TestConstants(unittest.TestCase): if golden == 0: self.assertEqual(result, golden) else: - self.assertLess(abs(result-golden)/golden, 1e-7) + self.assert_(abs(result-golden)/golden < 1e-7) def test_const_double(self): from random import random @@ -250,7 +250,7 @@ class TestConstants(unittest.TestCase): if golden[1] == 0: self.assertEqual(result[1], golden[1]) else: - self.assertLess(abs(result[1]-golden[1])/golden[1], 1e-7) + self.assert_(abs(result[1]-golden[1])/golden[1] < 1e-7) self.assertEqual(result[2], golden[2]) def test_const_vector(self): diff --git a/test/opaque.py b/test/opaque.py index 329a673..f89334d 100755 --- a/test/opaque.py +++ b/test/opaque.py @@ -6,10 +6,11 @@ from llvm import LLVMException import logging, unittest class TestOpaque(unittest.TestCase): + def test_opaque(self): # Create an opaque type ts = Type.opaque('mystruct') - self.assertIn('type opaque', str(ts)) + self.assertTrue('type opaque' in str(ts)) self.assertTrue(ts.is_opaque) self.assertTrue(ts.is_identified) self.assertFalse(ts.is_literal) From e0f18ae9de962e60aab4e7aeeb6a686c05c3c49c Mon Sep 17 00:00:00 2001 From: Ilan Schnell Date: Sun, 12 Aug 2012 23:24:12 -0500 Subject: [PATCH 5/6] fixed uses.py for Python 2.6 --- test/uses.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/uses.py b/test/uses.py index 1b13aa6..d95dc90 100755 --- a/test/uses.py +++ b/test/uses.py @@ -30,11 +30,11 @@ class TestUses(unittest.TestCase): self.assertEqual(tmp3.use_count, 1) logging.debug("Testing uses ..") - self.assertIs(f.args[0].uses[0], tmp1) + self.assert_(f.args[0].uses[0] is tmp1) self.assertEqual(len(f.args[0].uses), 1) - self.assertIs(f.args[1].uses[0], tmp2) + self.assert_(f.args[1].uses[0] is tmp2) self.assertEqual(len(f.args[1].uses), 1) - self.assertIs(f.args[2].uses[0], tmp3) + self.assert_(f.args[2].uses[0] is tmp3) self.assertEqual(len(f.args[2].uses), 1) self.assertEqual(len(tmp1.uses), 2) self.assertEqual(len(tmp2.uses), 0) From 72f7fc4a99f905bedc74185c410ca00240e0f32d Mon Sep 17 00:00:00 2001 From: Ilan Schnell Date: Sun, 12 Aug 2012 23:31:47 -0500 Subject: [PATCH 6/6] more Py26 test fixes --- test/atomic.py | 10 ++++------ test/objcache.py | 8 +------- test/operands.py | 22 +++++++--------------- 3 files changed, 12 insertions(+), 28 deletions(-) diff --git a/test/atomic.py b/test/atomic.py index fd565cc..f2dda0a 100644 --- a/test/atomic.py +++ b/test/atomic.py @@ -88,21 +88,19 @@ class TestAtomic(unittest.TestCase): for ordering in test_these_orderings: loaded = bldr.atomic_load(ptr, ordering) - self.assertIn('load atomic', str(loaded)) + self.assert_('load atomic' in str(loaded)) self.assertEqual(ordering, str(loaded).strip().split(' ')[-3].rstrip(',')) - self.assertIn('align 1', str(loaded)) + self.assert_('align 1' in str(loaded)) stored = bldr.atomic_store(loaded, ptr, ordering) - self.assertIn('store atomic', str(stored)) + self.assert_('store atomic' in str(stored)) self.assertEqual(ordering, str(stored).strip().split(' ')[-3].rstrip(',')) - self.assertIn('align 1', str(stored)) + self.assert_('align 1' in str(stored)) fenced = bldr.fence(ordering) self.assertEqual(['fence', ordering], str(fenced).strip().split(' ')) if __name__ == '__main__': unittest.main() - - diff --git a/test/objcache.py b/test/objcache.py index 996ba47..c8bc7e4 100755 --- a/test/objcache.py +++ b/test/objcache.py @@ -13,12 +13,6 @@ class TestObjCache(unittest.TestCase): safe_repr(expr2)) self.fail(self._formatMessage(msg, standardMsg)) - def assertIsNot(self, expr1, expr2, msg=None): - if expr1 is expr2: - standardMsg = 'unexpectedly identical: %s' % (safe_repr( - expr1),) - self.fail(self._formatMessage(msg, standardMsg)) - def test_objcache(self): logging.debug("Testing module aliasing ..") m1 = Module.new('a') @@ -45,7 +39,7 @@ class TestObjCache(unittest.TestCase): gv1.delete() gv4 = GlobalVariable.new(m1, t, "gv") - self.assertIsNot(gv1, gv4) + self.assert_(gv1 is not gv4) logging.debug("Testing function aliasing 1 ..") b1 = f1.append_basic_block('entry') diff --git a/test/operands.py b/test/operands.py index 9d8a560..674bc9e 100755 --- a/test/operands.py +++ b/test/operands.py @@ -34,13 +34,6 @@ entry: class TestOperands(unittest.TestCase): - if sys.version_info[:2] < (2, 7): - def assertIs(self, expr1, expr2, msg=None): - if expr1 is not expr2: - standardMsg = '%s is not %s' % (safe_repr(expr1), - safe_repr(expr2)) - self.fail(self._formatMessage(msg, standardMsg)) - def test_operands(self): m = Module.from_assembly(StringIO(test_module)) logging.debug("-"*60) @@ -50,7 +43,7 @@ class TestOperands(unittest.TestCase): test_func = m.get_function_named("test_func") prod = m.get_function_named("prod") - #===----------------------------------------------------------------------=== + #===-----------------------------------------------------------=== # test operands @@ -63,15 +56,15 @@ class TestOperands(unittest.TestCase): logging.debug("Testing User.operands ..") - self.assertIs(i1.operands[-1], prod) - self.assertIs(i1.operands[0], test_func.args[0]) - self.assertIs(i1.operands[1], test_func.args[1]) - self.assertIs(i2.operands[0], i1) - self.assertIs(i2.operands[1], test_func.args[2]) + self.assert_(i1.operands[-1] is prod) + self.assert_(i1.operands[0] is test_func.args[0]) + self.assert_(i1.operands[1] is test_func.args[1]) + self.assert_(i2.operands[0] is i1) + self.assert_(i2.operands[1] is test_func.args[2]) self.assertEqual(len(i1.operands), 3) self.assertEqual(len(i2.operands), 2) - #===----------------------------------------------------------------------=== + #===-----------------------------------------------------------=== # show test_function logging.debug("Examining test_function `test_test_func':") @@ -89,4 +82,3 @@ class TestOperands(unittest.TestCase): if __name__ == '__main__': unittest.main() -