[Thuban-commits] r2884 - branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Sat Aug 15 18:09:35 CEST 2009
Author: bramz
Date: 2009-08-15 18:09:34 +0200 (Sat, 15 Aug 2009)
New Revision: 2884
Modified:
branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/ChangeLog
branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/dbflibmodule.c
branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/setup.py
branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/testdbf.py
Log:
* setup.py: add compiler flags to suppress a spurious warning
* dbflibmodule.c: out of index reads raise IndexError
* testdbf.py: moving dbflib test to here in unittest format (with unicode test)
Modified: branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/ChangeLog
===================================================================
--- branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/ChangeLog 2009-08-12 23:21:12 UTC (rev 2883)
+++ branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/ChangeLog 2009-08-15 16:09:34 UTC (rev 2884)
@@ -1,3 +1,11 @@
+2009-08-15 Bram de Greve <bram.degreve at bramz.net>
+
+ * setup.py: add compiler flags to suppress a spurious warning
+
+ * dbflibmodule.c: out of index reads raise IndexError
+
+ * testdbf.py: moving dbflib test to here in unittest format (with unicode test)
+
2008-01-17 Bram de Greve <bram.degreve at bramz.net>
* pyshapelib_common.h, shapelibmodule.c, dbflibmodule.c, shptreemodule.c:
Modified: branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/dbflibmodule.c
===================================================================
--- branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/dbflibmodule.c 2009-08-12 23:21:12 UTC (rev 2883)
+++ branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/dbflibmodule.c 2009-08-15 16:09:34 UTC (rev 2884)
@@ -251,7 +251,7 @@
if (field < 0)
{
- PyErr_SetString(PyExc_ValueError, "Failed to add field due to inappropriate field definition");
+ PyErr_SetString(PyExc_ValueError, "Failed to add field");
return NULL;
}
return PyInt_FromLong((long)field);
@@ -342,11 +342,11 @@
{
int record, field;
- if (!PyArg_ParseTuple(args, "ii:read_field", &record, &field)) return NULL;
+ if (!PyArg_ParseTuple(args, "ii:read_attribute", &record, &field)) return NULL;
if (record < 0 || record >= DBFGetRecordCount(self->handle))
{
- PyErr_Format(PyExc_ValueError,
+ PyErr_Format(PyExc_IndexError,
"record index %d out of bounds (record count: %d)",
record, DBFGetRecordCount(self->handle));
return NULL;
@@ -354,7 +354,7 @@
if (field < 0 || field >= DBFGetFieldCount(self->handle))
{
- PyErr_Format(PyExc_ValueError,
+ PyErr_Format(PyExc_IndexError,
"field index %d out of bounds (field count: %d)",
field, DBFGetFieldCount(self->handle));
return NULL;
@@ -382,7 +382,7 @@
if (record < 0 || record >= DBFGetRecordCount(self->handle))
{
- PyErr_Format(PyExc_ValueError,
+ PyErr_Format(PyExc_IndexError,
"record index %d out of bounds (record count: %d)",
record, DBFGetRecordCount(self->handle));
return NULL;
Modified: branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/setup.py
===================================================================
--- branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/setup.py 2009-08-12 23:21:12 UTC (rev 2883)
+++ branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/setup.py 2009-08-15 16:09:34 UTC (rev 2884)
@@ -5,34 +5,52 @@
from distutils.core import setup, Extension
from distutils.util import convert_path
-# try to determine the directory where the shapelib source files are.
-# There are currently two supported situations.
-#
-# 1. "Standalone" build: the parent directory is the shapelib source
-# directory
-# 2. Built in the Thuban source tree where ../shapelib/ relative to the
-# directory containing this setup.py contains (the relevant parts of)
-# shapelib
-#
-# 3. Binary build with e.g. bdist_rpm. This takes place deep in the
-# build directory.
-
-# os.path expects filenames in OS-specific form so we have to construct
-# the files with os.path functions. distutils, OTOH, uses posix-style
-# filenames exclusively, so we use posix conventions when making
-# filenames for distutils.
-for shp_dir in ["..", "../shapelib", "../../../../../../shapelib"]:
- if (os.path.isdir(convert_path(shp_dir))
- and os.path.exists(os.path.join(convert_path(shp_dir), "shpopen.c"))):
- # shp_dir contains shpopen.c, so assume it's the directory with
- # the shapefile library to use
- break
-else:
+def find_shapelib():
+ '''
+ try to determine the directory where the shapelib source files are.
+ There are currently two supported situations.
+
+ 1. "Standalone" build: the parent directory is the shapelib source
+ directory
+ 2. Built in the Thuban source tree where ../shapelib/ relative to the
+ directory containing this setup.py contains (the relevant parts of)
+ shapelib
+
+ 3. Binary build with e.g. bdist_rpm. This takes place deep in the
+ build directory.
+
+ os.path expects filenames in OS-specific form so we have to construct
+ the files with os.path functions. distutils, OTOH, uses posix-style
+ filenames exclusively, so we use posix conventions when making
+ filenames for distutils.
+ '''
+ for shp_dir in ["..", "../shapelib", "../../../../../../shapelib"]:
+ if (os.path.isdir(convert_path(shp_dir))
+ and os.path.exists(os.path.join(convert_path(shp_dir), "shpopen.c"))):
+ # shp_dir contains shpopen.c, so assume it's the directory with
+ # the shapefile library to use
+ return shp_dir
print >>sys.stderr, "no shapelib directory found"
sys.exit(1)
+shp_dir = find_shapelib()
+
+
+
+def find_sahooks_files():
+ '''
+ Return a filelist of additional files implementing the SA hooks.
+ '''
+ candidates = [shp_dir + "/safileio.c"]
+ return filter(os.path.exists, candidates)
+
+sahooks_files = find_sahooks_files()
+
+
+
def determine_macros():
- """Return the macros to define when compiling the dbflib wrapper.
+ '''
+ Return the macros to define when compiling the dbflib wrapper.
The returned list specifies following macros:
- HAVE_UPDATE_HEADER, which is
@@ -43,7 +61,7 @@
- HAVE_CODE_PAGE, which is '1' if the dbflib version we will
compiling with has the DBFGetCodePage function and '0' otherwise.
Again, shapefil.h is scanned to check this.
- """
+ '''
f = open(convert_path(shp_dir + "/shapefil.h"))
contents = f.read()
f.close()
@@ -58,38 +76,37 @@
("HAVE_CODE_PAGE", have("DBFGetCodePage")),
("DISABLE_CVSID", "1")]
+macros = determine_macros()
-def search_sahooks_files():
- """
- Return a filelist of additional files implementing the SA hooks.
- """
-
- candidates = [shp_dir + "/safileio.c"]
- return filter(os.path.exists, candidates)
+def determine_cflags():
+ if "win32" in sys.platform:
+ # assume we're going to use MSVC.
+ return [
+ "/wd4996" # disable warning on "potential unsafe" strncpy
+ ]
+ return []
-macros = determine_macros()
-sahooks_files = search_sahooks_files()
-extensions = [Extension("shapelib",
- ["shapelibmodule.c",
- shp_dir + "/shpopen.c",
- shp_dir + "/shptree.c"]
- + sahooks_files,
- include_dirs = [shp_dir],
- define_macros = macros),
- Extension("shptree",
- ["shptreemodule.c"],
- include_dirs = [shp_dir],
- define_macros = macros),
- Extension("dbflib",
- ["dbflibmodule.c",
- shp_dir + "/dbfopen.c"]
- + sahooks_files,
- include_dirs = [shp_dir],
- define_macros = macros)]
+cflags = determine_cflags()
+
+
+def make_extension(name, *sources):
+ return Extension(name, list(sources), include_dirs=[shp_dir], define_macros=macros, extra_compile_args=cflags)
+
+
+
+
+extensions = [
+ make_extension("shapelib", "shapelibmodule.c", shp_dir + "/shpopen.c", shp_dir + "/shptree.c", *sahooks_files),
+ make_extension("shptree", "shptreemodule.c"),
+ make_extension("dbflib", "dbflibmodule.c", shp_dir + "/dbfopen.c", *sahooks_files)
+ ]
+
+
+
setup(name = "pyshapelib",
version = "0.4",
description = "Python bindings for shapelib",
Modified: branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/testdbf.py
===================================================================
--- branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/testdbf.py 2009-08-12 23:21:12 UTC (rev 2883)
+++ branches/WIP-pyshapelib-Unicode/thuban/libraries/pyshapelib/testdbf.py 2009-08-15 16:09:34 UTC (rev 2884)
@@ -12,17 +12,99 @@
# $Id$
import unittest
-import dbflib
+import os
+import shutil
class TestDBF(unittest.TestCase):
- def test_add_field(self):
- """Test whethe add_field reports exceptions"""
- dbf = dbflib.create("test.dbf")
- # For strings the precision parameter must be 0
- self.assertRaises(RuntimeError,
- dbf.add_field, "str", dbflib.FTString, 10, 5)
+ def setUp(self):
+ self.testdir = "testdbf-dir"
+ if os.path.exists(self.testdir):
+ shutil.rmtree(self.testdir)
+ os.mkdir(self.testdir)
+ self.testpath = os.path.join(self.testdir, "test")
+
+ import dbflib
+ self.fields = [
+ ("NAME", dbflib.FTString, 20, 0),
+ ("INT", dbflib.FTInteger, 10, 0),
+ ("FLOAT", dbflib.FTDouble, 10, 4),
+ ("BOOL", dbflib.FTLogical, 1, 0)
+ ]
+ self.records = [
+ ('Weatherwax', 1, 3.1415926535, True),
+ ('Ogg', 2, -1000.1234, False),
+ (u'x\u03C0\u03C1\u03C2', 10, 0, 1),
+ ]
+ def test_add_field(self):
+ '''Test whethe add_field reports exceptions'''
+ import dbflib
+ dbf = dbflib.create(self.testpath)
+ # For strings the precision parameter must be 0
+ #self.assertRaises(RuntimeError, dbf.add_field, "str", dbflib.FTString, 10, 5)
+ def test_dbflib_flow(self):
+ self.__make_dbf()
+ self.__read_dbf()
+
+ def __make_dbf(self):
+ import dbflib
+ # create a new dbf file and add three fields.
+ dbf = dbflib.create(self.testpath, code_page=dbflib.CPG_UTF_8, return_unicode=True)
+ for name, type, width, decimals in self.fields:
+ dbf.add_field(name, type, width, decimals)
+
+ # Records can be added as a dictionary...
+ keys = [field[0] for field in self.fields]
+ dbf.write_record(0, dict(zip(keys, self.records[0])))
+
+ # ... or as a sequence
+ dbf.write_record(1, self.records[1])
+
+ # ... or as individual attributes
+ for i, value in enumerate(self.records[2]):
+ dbf.write_attribute(2, i, value)
+
+ dbf.close()
+
+ def __read_dbf(self):
+ import dbflib
+ dbf = dbflib.DBFFile(self.testpath, return_unicode=True)
+ # test the fields
+ self.assertEqual(dbf.field_count(), len(self.fields))
+ for i in range(dbf.field_count()):
+ type, name, width, decimals = dbf.field_info(i)
+ self.assertEqual((name, type, width, decimals), self.fields[i])
+
+ # try to read individual attributes (one field within a record)
+ self.assertEqual(dbf.record_count(), len(self.records))
+ for i in range(dbf.record_count()):
+ for k in range(dbf.field_count()):
+ self.__assertEqual(dbf.read_attribute(i, k), self.records[i][k])
+
+ # try to read complete records (they are returned as dictionaries)
+ keys = zip(*self.fields)[0]
+ for i in range(dbf.record_count()):
+ rec = dbf.read_record(i)
+ self.assert_(isinstance(rec, dict))
+ for k, key in enumerate(keys):
+ self.__assertEqual(rec[key], self.records[i][k])
+
+ # try to read past bounds
+ self.assertRaises(IndexError, dbf.read_record, -1)
+ self.assertRaises(IndexError, dbf.read_record, dbf.record_count())
+ self.assertRaises(IndexError, dbf.read_attribute, 0, -1)
+ self.assertRaises(IndexError, dbf.read_attribute, -1, 0)
+ self.assertRaises(IndexError, dbf.read_attribute, dbf.record_count(), 0)
+ self.assertRaises(IndexError, dbf.read_attribute, 0, dbf.field_count())
+
+ def __assertEqual(self, a, b, msg=None):
+ if isinstance(a, float):
+ self.assertAlmostEqual(a, b, 4, msg)
+ else:
+ self.assertEqual(a, b, msg)
+
+
if __name__ == "__main__":
unittest.main()
More information about the Thuban-commits
mailing list