[fiona] 01/03: New upstream version 1.7.1

Johan Van de Wauw johanvdw-guest at moszumanska.debian.org
Thu Nov 17 21:02:14 UTC 2016


This is an automated email from the git hooks/post-receive script.

johanvdw-guest pushed a commit to branch master
in repository fiona.

commit 315d5dc53b5b7dfefda417d23e5cdebf70c01cf7
Author: Johan Van de Wauw <johan at vandewauw.be>
Date:   Thu Nov 17 21:36:35 2016 +0100

    New upstream version 1.7.1
---
 .gitignore                     |   1 +
 .travis.yml                    |  11 ++--
 CHANGES.txt                    |  20 ++++++
 CREDITS.txt                    |  21 ++++---
 docs/Makefile                  |   4 +-
 docs/fiona.fio.rst             | 134 +++++++++++++++++++++++++++++++++++++++++
 docs/fiona.rst                 | 117 +++++++++++++++++++++++++++++++++++
 docs/modules.rst               |   7 +++
 fiona/__init__.py              |   4 +-
 fiona/_geometry.pxd            |   4 ++
 fiona/_geometry.pyx            |  65 ++++++++++++++++++--
 fiona/collection.py            |   6 +-
 fiona/compat.py                |  12 ++++
 fiona/errors.py                |   3 +
 fiona/fio/cat.py               |   2 +-
 fiona/fio/main.py              |   4 ++
 fiona/odict.py                 |   4 --
 fiona/ogrext1.pyx              |  35 ++++++-----
 fiona/ogrext2.pyx              |  39 ++++++------
 scripts/travis_gdal_install.sh |  35 ++++-------
 setup.py                       |  61 ++++++++++++-------
 tests/test_collection.py       |   3 +-
 tests/test_geometry.py         |   6 +-
 tests/test_integration.py      |  59 ++++++++++++++++++
 tests/test_multiconxn.py       |   2 +-
 tests/test_schema.py           |  19 ++++++
 26 files changed, 564 insertions(+), 114 deletions(-)

diff --git a/.gitignore b/.gitignore
index 60d9629..2adb45f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -64,6 +64,7 @@ venv2/
 # fiona
 VERSION.txt
 fiona/ogrext.c
+fiona/_crs.c
 fiona/_drivers.c
 fiona/_err.c
 fiona/_geometry.c
diff --git a/.travis.yml b/.travis.yml
index f2b14d0..724cf8a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -12,24 +12,22 @@ env:
     - GDALBUILD=$HOME/gdalbuild
   matrix:
     - GDALVERSION="1.9.2"
-    - GDALVERSION="1.11.4"
-    - GDALVERSION="2.0.2"
+    - GDALVERSION="1.11.5"
+    - GDALVERSION="2.0.3"
+    - GDALVERSION="2.1.1"
 addons:
   apt:
     packages:
-    - libgdal1h
     - gdal-bin
     - libproj-dev
     - libhdf5-serial-dev
-    - libpng-dev
+    - libpng12-dev
     - libgdal-dev
     - libatlas-dev
     - libatlas-base-dev
     - gfortran
 python:
   - "2.7"
-  - "3.3"
-  - "3.4"
   - "3.5"
 before_install:
   - pip install -U pip
@@ -47,7 +45,6 @@ install:
   - "fio --version"
   - "cp -r tests /tmp"
 script: 
-  - "cd /tmp && nosetests --exclude test_filter_vsi --exclude test_geopackage --exclude test_write_mismatch tests"
   - "cd /tmp && coverage run --source=fiona --omit='*.pxd,*.pyx,*/tests/*,*/docs/*,*/examples/*,*/benchmarks/*' -m nose --exclude test_filter_vsi --exclude test_geopackage --exclude test_write_mismatch tests"
 after_success:
   - coveralls || echo "!! intermittent coveralls failure"
diff --git a/CHANGES.txt b/CHANGES.txt
index 7fc5853..3ca052d 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -3,6 +3,26 @@ Changes
 
 All issue numbers are relative to https://github.com/Toblerity/Fiona/issues.
 
+1.7.1 (2016-11-16)
+------------------
+
+Bug Fixes:
+
+- Prevent Fiona from stumbling over '*Z', '*M', and '*ZM' geometry types
+  introduced in GDAL 2.1 (#384). Fiona 1.7.1 doesn't add explicit support for
+  these types, they are coerced to geometry types 1-7 ('Point', 'LineString',
+  etc.)
+- Raise an `UnsupportedGeometryTypeError` when a bogus or unsupported 
+  geometry type is encountered in a new collection's schema or elsewhere
+  (#340).
+- Enable `--precision 0` for fio-cat (#370).
+- Prevent datetime exceptions from unnecessarily stopping collection iteration
+  by yielding `None` (#385)
+- Replace log.warn calls with log.warning calls (#379).
+- Print an error message if neither gdal-config or `--gdalversion` indicate
+  a GDAL C API version when running `setup.py` (#364).
+- Let dict-like subclasses through CRS type checks (#367).
+
 1.7.0post2 (2016-06-15)
 -----------------------
 
diff --git a/CREDITS.txt b/CREDITS.txt
index 44e77ff..de41ed5 100644
--- a/CREDITS.txt
+++ b/CREDITS.txt
@@ -6,31 +6,32 @@ Fiona is written by:
 - Sean Gillies <sean.gillies at gmail.com>
 - Rene Buffat <buffat at gmail.com>
 - Kevin Wurster <wursterk at gmail.com>
+- Micah Cochran <micah at micahcochran.net>
 - Matthew Perry <perrygeo at gmail.com>
 - Joshua Arnott <josh at snorfalorpagus.net>
 - Kelsey Jordahl <kjordahl at enthought.com>
-- Micah Cochran <micah at micahcochran.net>
-- Simon Norris <snorris at hillcrestgeo.ca>
 - Patrick Young <patrick.mckendree.young at gmail.com>
+- Simon Norris <snorris at hillcrestgeo.ca>
 - Hannes Gräuler <graeuler at geoplex.de>
 - Johan Van de Wauw <johan.vandewauw at gmail.com>
-- Michael Weisman <mweisman at gmail.com>
-- Ryan Grout <rgrout at continuum.io>
 - Jacob Wasserman <jwasserman at gmail.com>
-- Miro Hrončok <miro at hroncok.cz>
-- Michele Citterio <michele at citterio.net>
-- Brendan Ward <bcward at consbio.org>
+- Ryan Grout <rgrout at continuum.io>
+- Michael Weisman <mweisman at gmail.com>
 - fredj <frederic.junod at camptocamp.com>
-- wilsaj <wilson.andrew.j+github at gmail.com>
 - Bas Couwenberg <sebastic at xs4all.nl>
+- Brendan Ward <bcward at consbio.org>
+- Michele Citterio <michele at citterio.net>
+- Miro Hrončok <miro at hroncok.cz>
+- qinfeng <guo.qinfeng+github at gmail.com>
+- Michael Weisman <michael at urbanmapping.com>
 - Brandon Liu <bdon at bdon.org>
-- Hannes Gräuler <hgraeule at uos.de>
 - Ludovic Delauné <ludotux at gmail.com>
 - Martijn Visser <mgvisser at gmail.com>
+- Ariel Nunez <ingenieroariel at gmail.com>
 - Oliver Tonnhofer <olt at bogosoft.com>
 - Stefano Costa <steko at iosa.it>
 - dimlev <dimlev at gmail.com>
-- Ariel Nunez <ingenieroariel at gmail.com>
+- wilsaj <wilson.andrew.j+github at gmail.com>
 
 Fiona would not be possible without the great work of Frank Warmerdam and other
 GDAL/OGR developers.
diff --git a/docs/Makefile b/docs/Makefile
index 81081c4..bf02a6f 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -41,7 +41,7 @@ help:
 clean:
 	-rm -rf $(BUILDDIR)/*
 
-html:
+html: apidocs
 	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
 	@echo
 	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
@@ -153,6 +153,6 @@ doctest:
 	      "results in $(BUILDDIR)/doctest/output.txt."
 
 apidocs:
-	sphinx-apidoc -f -o . ../src/fiona
+	sphinx-apidoc -f -o . ../fiona
 	@echo
 	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
diff --git a/docs/fiona.fio.rst b/docs/fiona.fio.rst
new file mode 100644
index 0000000..4c82475
--- /dev/null
+++ b/docs/fiona.fio.rst
@@ -0,0 +1,134 @@
+fiona.fio package
+=================
+
+Submodules
+----------
+
+fiona.fio.bounds module
+-----------------------
+
+.. automodule:: fiona.fio.bounds
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.fio.calc module
+---------------------
+
+.. automodule:: fiona.fio.calc
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.fio.cat module
+--------------------
+
+.. automodule:: fiona.fio.cat
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.fio.collect module
+------------------------
+
+.. automodule:: fiona.fio.collect
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.fio.distrib module
+------------------------
+
+.. automodule:: fiona.fio.distrib
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.fio.dump module
+---------------------
+
+.. automodule:: fiona.fio.dump
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.fio.env module
+--------------------
+
+.. automodule:: fiona.fio.env
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.fio.filter module
+-----------------------
+
+.. automodule:: fiona.fio.filter
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.fio.helpers module
+------------------------
+
+.. automodule:: fiona.fio.helpers
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.fio.info module
+---------------------
+
+.. automodule:: fiona.fio.info
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.fio.insp module
+---------------------
+
+.. automodule:: fiona.fio.insp
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.fio.load module
+---------------------
+
+.. automodule:: fiona.fio.load
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.fio.ls module
+-------------------
+
+.. automodule:: fiona.fio.ls
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.fio.main module
+---------------------
+
+.. automodule:: fiona.fio.main
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.fio.options module
+------------------------
+
+.. automodule:: fiona.fio.options
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+
+Module contents
+---------------
+
+.. automodule:: fiona.fio
+    :members:
+    :undoc-members:
+    :show-inheritance:
diff --git a/docs/fiona.rst b/docs/fiona.rst
new file mode 100644
index 0000000..c5c4eb8
--- /dev/null
+++ b/docs/fiona.rst
@@ -0,0 +1,117 @@
+fiona package
+=============
+
+Subpackages
+-----------
+
+.. toctree::
+
+    fiona.fio
+
+Submodules
+----------
+
+fiona.collection module
+-----------------------
+
+.. automodule:: fiona.collection
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.compat module
+-------------------
+
+.. automodule:: fiona.compat
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.crs module
+----------------
+
+.. automodule:: fiona.crs
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.drvsupport module
+-----------------------
+
+.. automodule:: fiona.drvsupport
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.errors module
+-------------------
+
+.. automodule:: fiona.errors
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.inspector module
+----------------------
+
+.. automodule:: fiona.inspector
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.ogrext module
+-------------------
+
+.. automodule:: fiona.ogrext
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.ogrext1 module
+--------------------
+
+.. automodule:: fiona.ogrext1
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.ogrext2 module
+--------------------
+
+.. automodule:: fiona.ogrext2
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.rfc3339 module
+--------------------
+
+.. automodule:: fiona.rfc3339
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.tool module
+-----------------
+
+.. automodule:: fiona.tool
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+fiona.transform module
+----------------------
+
+.. automodule:: fiona.transform
+    :members:
+    :undoc-members:
+    :show-inheritance:
+
+
+Module contents
+---------------
+
+.. automodule:: fiona
+    :members:
+    :undoc-members:
+    :show-inheritance:
diff --git a/docs/modules.rst b/docs/modules.rst
new file mode 100644
index 0000000..0e4e569
--- /dev/null
+++ b/docs/modules.rst
@@ -0,0 +1,7 @@
+fiona
+=====
+
+.. toctree::
+   :maxdepth: 4
+
+   fiona
diff --git a/fiona/__init__.py b/fiona/__init__.py
index 6cca09b..8904c2d 100644
--- a/fiona/__init__.py
+++ b/fiona/__init__.py
@@ -69,7 +69,7 @@ from six import string_types
 from fiona.collection import Collection, BytesCollection, vsi_path
 from fiona._drivers import driver_count, GDALEnv
 from fiona.drvsupport import supported_drivers
-from fiona.odict import OrderedDict
+from fiona.compat import OrderedDict
 from fiona.ogrext import _bounds, _listlayers, FIELD_TYPES_MAP, _remove
 from fiona.ogrext import (
     calc_gdal_version_num, get_gdal_version_num, get_gdal_release_name)
@@ -81,7 +81,7 @@ import uuid
 
 
 __all__ = ['bounds', 'listlayers', 'open', 'prop_type', 'prop_width']
-__version__ = "1.7.0.post2"
+__version__ = "1.7.1"
 __gdal_version__ = get_gdal_release_name().decode('utf-8')
 
 log = logging.getLogger('Fiona')
diff --git a/fiona/_geometry.pxd b/fiona/_geometry.pxd
index 9f3eb6e..38f5610 100644
--- a/fiona/_geometry.pxd
+++ b/fiona/_geometry.pxd
@@ -63,3 +63,7 @@ cdef class OGRGeomBuilder:
     cdef void * _buildMultiPolygon(self, object coordinates) except NULL
     cdef void * _buildGeometryCollection(self, object coordinates) except NULL
     cdef void * build(self, object geom) except NULL
+
+
+cdef unsigned int geometry_type_code(object name)
+cdef object normalize_geometry_type_code(unsigned int code)
diff --git a/fiona/_geometry.pyx b/fiona/_geometry.pyx
index 6d57895..8adda35 100644
--- a/fiona/_geometry.pyx
+++ b/fiona/_geometry.pyx
@@ -2,6 +2,8 @@
 
 import logging
 
+from fiona.errors import UnsupportedGeometryTypeError
+
 
 class NullHandler(logging.Handler):
     def emit(self, record):
@@ -20,6 +22,17 @@ GEOMETRY_TYPES = {
     5: 'MultiLineString',
     6: 'MultiPolygon',
     7: 'GeometryCollection',
+    # Unsupported types.
+    #8: 'CircularString',
+    #9: 'CompoundCurve',
+    #10: 'CurvePolygon',
+    #11: 'MultiCurve',
+    #12: 'MultiSurface',
+    #13: 'Curve',
+    #14: 'Surface',
+    #15: 'PolyhedralSurface',
+    #16: 'TIN',
+    #17: 'Triangle',
     100: 'None',
     101: 'LinearRing',
     0x80000001: '3D Point',
@@ -34,6 +47,39 @@ GEOMETRY_TYPES = {
 GEOJSON2OGR_GEOMETRY_TYPES = dict((v, k) for k, v in GEOMETRY_TYPES.iteritems())
 
 
+cdef unsigned int geometry_type_code(name):
+    """Map OGC geometry type names to integer codes."""
+    offset = 0
+    if name.endswith('ZM'):
+        offset = 3000
+    elif name.endswith('M'):
+        offset = 2000
+    elif name.endswith('Z'):
+        offset = 1000
+
+    normalized_name = name.rstrip('ZM')
+    if normalized_name not in GEOJSON2OGR_GEOMETRY_TYPES:
+        raise UnsupportedGeometryTypeError(name)
+
+    return offset + <unsigned int>GEOJSON2OGR_GEOMETRY_TYPES[normalized_name]
+
+
+cdef object normalize_geometry_type_code(unsigned int code):
+    """Normalize geometry type codes."""
+    # Remove 2.5D flag.
+    norm_code = code & (~0x80000000)
+
+    # Normalize Z, M, and ZM types. Fiona 1.x does not support M
+    # and doesn't treat OGC 'Z' variants as special types of their
+    # own.
+    norm_code = norm_code % 1000
+
+    if norm_code not in GEOMETRY_TYPES:
+        raise UnsupportedGeometryTypeError(norm_code)
+
+    return norm_code
+
+
 # Geometry related functions and classes follow.
 cdef void * _createOgrGeomFromWKB(object wkb) except NULL:
     """Make an OGR geometry from a WKB string"""
@@ -113,14 +159,25 @@ cdef class GeomBuilder:
         # The only method anyone needs to call
         if geom == NULL:
             raise ValueError("Null geom")
-        
+
         cdef unsigned int etype = OGR_G_GetGeometryType(geom)
-        self.code = etype
-        self.geomtypename = GEOMETRY_TYPES[self.code & (~0x80000000)]
+
+        # Remove 2.5D flag.
+        self.code = etype & (~0x80000000)
+
+        # Normalize Z, M, and ZM types. Fiona 1.x does not support M
+        # and doesn't treat OGC 'Z' variants as special types of their
+        # own.
+        self.code = self.code % 1000
+
+        if self.code not in GEOMETRY_TYPES:
+            raise UnsupportedGeometryTypeError(self.code)
+
+        self.geomtypename = GEOMETRY_TYPES[self.code]
         self.ndims = OGR_G_GetCoordinateDimension(geom)
         self.geom = geom
         return getattr(self, '_build' + self.geomtypename)()
-    
+
     cpdef build_wkb(self, object wkb):
         # The only other method anyone needs to call
         cdef object data = wkb
diff --git a/fiona/collection.py b/fiona/collection.py
index 5713753..d64cde7 100644
--- a/fiona/collection.py
+++ b/fiona/collection.py
@@ -1,9 +1,10 @@
 # -*- coding: utf-8 -*-
 # Collections provide file-like access to feature data
 
+
 import os
-import sys
 
+from fiona import compat
 from fiona.ogrext import Iterator, ItemsIterator, KeysIterator
 from fiona.ogrext import Session, WritingSession
 from fiona.ogrext import (
@@ -14,6 +15,7 @@ from fiona._drivers import driver_count, GDALEnv
 from fiona.drvsupport import supported_drivers
 from six import string_types, binary_type
 
+
 class Collection(object):
 
     """A file-like interface to features of a vector dataset
@@ -50,7 +52,7 @@ class Collection(object):
             raise TypeError("invalid driver: %r" % driver)
         if schema and not hasattr(schema, 'get'):
             raise TypeError("invalid schema: %r" % schema)
-        if crs and not isinstance(crs, (dict,) + string_types):
+        if crs and not isinstance(crs, compat.DICT_TYPES + string_types):
             raise TypeError("invalid crs: %r" % crs)
         if crs_wkt and not isinstance(crs_wkt, string_types):
             raise TypeError("invalid crs_wkt: %r" % crs_wkt)
diff --git a/fiona/compat.py b/fiona/compat.py
new file mode 100644
index 0000000..28d761f
--- /dev/null
+++ b/fiona/compat.py
@@ -0,0 +1,12 @@
+import collections
+from six.moves import UserDict
+try:
+    from collections import OrderedDict
+except ImportError:    
+    from ordereddict import OrderedDict
+
+
+# Users can pass in objects that subclass a few different objects
+# More specifically, rasterio has a CRS() class that subclasses UserDict()
+# In Python 2 UserDict() is in its own module and does not subclass Mapping()
+DICT_TYPES = (dict, collections.Mapping, UserDict)
diff --git a/fiona/errors.py b/fiona/errors.py
index 4ab5f2f..b868cea 100644
--- a/fiona/errors.py
+++ b/fiona/errors.py
@@ -23,3 +23,6 @@ class DataIOError(IOError):
 
 class FieldNameEncodeError(UnicodeEncodeError):
     """Failure to encode a field name."""
+
+class UnsupportedGeometryTypeError(KeyError):
+    """When a OGR geometry type isn't supported by Fiona."""
diff --git a/fiona/fio/cat.py b/fiona/fio/cat.py
index 4562d16..8d8b85c 100644
--- a/fiona/fio/cat.py
+++ b/fiona/fio/cat.py
@@ -73,7 +73,7 @@ def cat(ctx, files, precision, indent, compact, ignore_errors, dst_crs,
                             except ValueError:
                                 bbox = json.loads(bbox)
                         for i, feat in src.items(bbox=bbox):
-                            if dst_crs or precision > 0:
+                            if dst_crs or precision >= 0:
                                 g = transform_geom(
                                         src.crs, dst_crs, feat['geometry'],
                                         antimeridian_cutting=True,
diff --git a/fiona/fio/main.py b/fiona/fio/main.py
index f1670f9..4427ddc 100644
--- a/fiona/fio/main.py
+++ b/fiona/fio/main.py
@@ -12,6 +12,7 @@ import click
 from click_plugins import with_plugins
 from cligj import verbose_opt, quiet_opt
 
+import fiona
 from fiona import __version__ as fio_version
 
 
@@ -26,6 +27,9 @@ def configure_logging(verbosity):
 @verbose_opt
 @quiet_opt
 @click.version_option(fio_version)
+ at click.version_option(fiona.__gdal_version__, '--gdal-version',
+    prog_name='GDAL')
+ at click.version_option(sys.version, '--python-version', prog_name='Python')
 @click.pass_context
 def main_group(ctx, verbose, quiet):
 
diff --git a/fiona/odict.py b/fiona/odict.py
deleted file mode 100644
index f3479bb..0000000
--- a/fiona/odict.py
+++ /dev/null
@@ -1,4 +0,0 @@
-try:
-    from collections import OrderedDict
-except ImportError:    
-    from ordereddict import OrderedDict
diff --git a/fiona/ogrext1.pyx b/fiona/ogrext1.pyx
index e9b14a1..90fcd3b 100644
--- a/fiona/ogrext1.pyx
+++ b/fiona/ogrext1.pyx
@@ -1,11 +1,11 @@
 # These are extension functions and classes using the OGR C API.
 
+
 import datetime
 import json
 import locale
 import logging
 import os
-import sys
 import warnings
 import math
 import uuid
@@ -13,12 +13,15 @@ import uuid
 from six import integer_types, string_types, text_type
 
 cimport ogrext1
-from _geometry cimport GeomBuilder, OGRGeomBuilder
+from _geometry cimport (
+    GeomBuilder, OGRGeomBuilder, geometry_type_code,
+    normalize_geometry_type_code)
 from fiona._err import cpl_errs
 from fiona._geometry import GEOMETRY_TYPES
+from fiona import compat
 from fiona.errors import (
-    DriverError, SchemaError, CRSError, FionaValueError, FieldNameEncodeError)
-from fiona.odict import OrderedDict
+    DriverError, SchemaError, CRSError, FionaValueError)
+from fiona.compat import OrderedDict
 from fiona.rfc3339 import parse_date, parse_datetime, parse_time
 from fiona.rfc3339 import FionaDateType, FionaDateTimeType, FionaTimeType
 
@@ -164,7 +167,7 @@ cdef class FeatureBuilder:
             key = key_b.decode(encoding)
             fieldtypename = FIELD_TYPES[ogrext1.OGR_Fld_GetType(fdefn)]
             if not fieldtypename:
-                log.warn(
+                log.warning(
                     "Skipping field %s: invalid type %s", 
                     key,
                     ogrext1.OGR_Fld_GetType(fdefn))
@@ -194,7 +197,7 @@ cdef class FeatureBuilder:
                     try:
                         val = json.loads(val)
                     except ValueError as err:
-                        log.warn(str(err))
+                        log.warning(str(err))
 
                 # Now add to the properties object.
                 props[key] = val
@@ -503,7 +506,7 @@ cdef class Session:
             key = key_b.decode(self.get_internalencoding())
             fieldtypename = FIELD_TYPES[ogrext1.OGR_Fld_GetType(cogr_fielddefn)]
             if not fieldtypename:
-                log.warn(
+                log.warning(
                     "Skipping field %s: invalid type %s", 
                     key,
                     ogrext1.OGR_Fld_GetType(cogr_fielddefn))
@@ -533,11 +536,12 @@ cdef class Session:
 
             props.append((key, val))
 
-        cdef unsigned int geom_type = ogrext1.OGR_FD_GetGeomType(
-            cogr_featuredefn)
+        code = normalize_geometry_type_code(
+            ogrext1.OGR_FD_GetGeomType(cogr_featuredefn))
+
         return {
-            'properties': OrderedDict(props), 
-            'geometry': GEOMETRY_TYPES[geom_type]}
+            'properties': OrderedDict(props),
+            'geometry': GEOMETRY_TYPES[code]}
 
     def get_crs(self):
         cdef char *proj_c = NULL
@@ -795,7 +799,7 @@ cdef class WritingSession(Session):
                     proj_b = col_crs.encode('utf-8')
                     proj_c = proj_b
                     ogrext1.OSRSetFromUserInput(cogr_srs, proj_c)
-                elif isinstance(col_crs, dict):
+                elif isinstance(col_crs, compat.DICT_TYPES):
                     # EPSG is a special case.
                     init = col_crs.get('init')
                     if init:
@@ -866,10 +870,9 @@ cdef class WritingSession(Session):
                 self.cogr_ds,
                 name_c,
                 cogr_srs,
-                <unsigned int>[k for k,v in GEOMETRY_TYPES.items() if 
-                    v == collection.schema.get('geometry', 'Unknown')][0],
-                options
-                )
+                geometry_type_code(
+                    collection.schema.get('geometry', 'Unknown')),
+                options)
 
             if cogr_srs != NULL:
                 ogrext1.OSRDestroySpatialReference(cogr_srs)
diff --git a/fiona/ogrext2.pyx b/fiona/ogrext2.pyx
index 3eecd31..ff0db11 100644
--- a/fiona/ogrext2.pyx
+++ b/fiona/ogrext2.pyx
@@ -1,11 +1,11 @@
 # These are extension functions and classes using the OGR C API.
 
+
 import datetime
 import json
 import locale
 import logging
 import os
-import sys
 import warnings
 import math
 import uuid
@@ -13,11 +13,14 @@ import uuid
 from six import integer_types, string_types, text_type
 
 cimport ogrext2
-from _geometry cimport GeomBuilder, OGRGeomBuilder
+from _geometry cimport (
+    GeomBuilder, OGRGeomBuilder, geometry_type_code,
+    normalize_geometry_type_code)
 from fiona._err import cpl_errs
 from fiona._geometry import GEOMETRY_TYPES
+from fiona import compat
 from fiona.errors import DriverError, SchemaError, CRSError, FionaValueError
-from fiona.odict import OrderedDict
+from fiona.compat import OrderedDict
 from fiona.rfc3339 import parse_date, parse_datetime, parse_time
 from fiona.rfc3339 import FionaDateType, FionaDateTimeType, FionaTimeType
 
@@ -179,7 +182,7 @@ cdef class FeatureBuilder:
             key = key_b.decode(encoding)
             fieldtypename = FIELD_TYPES[ogrext2.OGR_Fld_GetType(fdefn)]
             if not fieldtypename:
-                log.warn(
+                log.warning(
                     "Skipping field %s: invalid type %s", 
                     key,
                     ogrext2.OGR_Fld_GetType(fdefn))
@@ -199,7 +202,7 @@ cdef class FeatureBuilder:
                     val = ogrext2.OGR_F_GetFieldAsString(feature, i)
                     val = val.decode(encoding)
                 except UnicodeDecodeError:
-                    log.warn(
+                    log.warning(
                         "Failed to decode %s using %s codec", val, encoding)
 
                 # Does the text contain a JSON object? Let's check.
@@ -208,7 +211,7 @@ cdef class FeatureBuilder:
                     try:
                         val = json.loads(val)
                     except ValueError as err:
-                        log.warn(str(err))
+                        log.warning(str(err))
 
                 # Now add to the properties object.
                 props[key] = val
@@ -279,7 +282,7 @@ cdef class OGRFeatureBuilder:
             try:
                 key_bytes = ogr_key.encode(encoding)
             except UnicodeDecodeError:
-                log.warn("Failed to encode %s using %s codec", key, encoding)
+                log.warning("Failed to encode %s using %s codec", key, encoding)
                 key_bytes = ogr_key
             key_c = key_bytes
             i = ogrext2.OGR_F_GetFieldIndex(cogr_feature, key_c)
@@ -325,7 +328,7 @@ cdef class OGRFeatureBuilder:
                 try:
                     value_bytes = value.encode(encoding)
                 except UnicodeDecodeError:
-                    log.warn(
+                    log.warning(
                         "Failed to encode %s using %s codec", value, encoding)
                     value_bytes = value
                 string_c = value_bytes
@@ -529,7 +532,7 @@ cdef class Session:
             key = key_b.decode(self.get_internalencoding())
             fieldtypename = FIELD_TYPES[ogrext2.OGR_Fld_GetType(cogr_fielddefn)]
             if not fieldtypename:
-                log.warn(
+                log.warning(
                     "Skipping field %s: invalid type %s", 
                     key,
                     ogrext2.OGR_Fld_GetType(cogr_fielddefn))
@@ -559,11 +562,12 @@ cdef class Session:
 
             props.append((key, val))
 
-        cdef unsigned int geom_type = ogrext2.OGR_FD_GetGeomType(
-            cogr_featuredefn)
+        code = normalize_geometry_type_code(
+            ogrext2.OGR_FD_GetGeomType(cogr_featuredefn))
+
         return {
-            'properties': OrderedDict(props), 
-            'geometry': GEOMETRY_TYPES[geom_type]}
+            'properties': OrderedDict(props),
+            'geometry': GEOMETRY_TYPES[code]}
 
     def get_crs(self):
         cdef char *proj_c = NULL
@@ -855,7 +859,7 @@ cdef class WritingSession(Session):
                     proj_b = col_crs.encode('utf-8')
                     proj_c = proj_b
                     ogrext2.OSRSetFromUserInput(cogr_srs, proj_c)
-                elif isinstance(col_crs, dict):
+                elif isinstance(col_crs, compat.DICT_TYPES):
                     # EPSG is a special case.
                     init = col_crs.get('init')
                     if init:
@@ -925,10 +929,9 @@ cdef class WritingSession(Session):
                 self.cogr_ds, 
                 name_c,
                 cogr_srs,
-                <unsigned int>[k for k,v in GEOMETRY_TYPES.items() if 
-                    v == collection.schema.get('geometry', 'Unknown')][0],
-                options
-                )
+                geometry_type_code(
+                    collection.schema.get('geometry', 'Unknown')),
+                options)
 
             if cogr_srs != NULL:
                 ogrext2.OSRDestroySpatialReference(cogr_srs)
diff --git a/scripts/travis_gdal_install.sh b/scripts/travis_gdal_install.sh
index ea94072..86472fc 100755
--- a/scripts/travis_gdal_install.sh
+++ b/scripts/travis_gdal_install.sh
@@ -1,5 +1,5 @@
 #!/bin/sh
-set -ex
+set -e
 
 GDALOPTS="  --with-ogr \
             --with-geos \
@@ -15,7 +15,7 @@ GDALOPTS="  --with-ogr \
             --without-cfitsio \
             --without-pcraster \
             --without-netcdf \
-            --without-png \
+            --with-png=/usr \
             --with-jpeg=internal \
             --without-gif \
             --without-ogdi \
@@ -54,33 +54,24 @@ fi
 
 ls -l $GDALINST
 
-# download and compile gdal version
-if [ ! -d $GDALINST/gdal-1.9.2 ]; then
+if [ "$GDALVERSION" = "1.9.2" -a ! -d "$GDALINST/gdal-$GDALVERSION" ]; then
   cd $GDALBUILD
-  wget http://download.osgeo.org/gdal/gdal-1.9.2.tar.gz
-  tar -xzf gdal-1.9.2.tar.gz
-  cd gdal-1.9.2
-  ./configure --prefix=$GDALINST/gdal-1.9.2 $GDALOPTS
+  wget http://download.osgeo.org/gdal/gdal-$GDALVERSION.tar.gz
+  tar -xzf gdal-$GDALVERSION.tar.gz
+  cd gdal-$GDALVERSION
+  ./configure --prefix=$GDALINST/gdal-$GDALVERSION $GDALOPTS
   make -s -j 2
   make install
 fi
 
-if [ ! -d $GDALINST/gdal-1.11.4 ]; then
-  cd $GDALBUILD
-  wget http://download.osgeo.org/gdal/1.11.4/gdal-1.11.4.tar.gz
-  tar -xzf gdal-1.11.4.tar.gz
-  cd gdal-1.11.4
-  ./configure --prefix=$GDALINST/gdal-1.11.4 $GDALOPTS
-  make -s -j 2
-  make install
-fi
 
-if [ ! -d $GDALINST/gdal-2.0.2 ]; then
+# download and compile gdal version
+if [ "$GDALVERSION" != "1.9.2" -a ! -d "$GDALINST/gdal-$GDALVERSION" ]; then
   cd $GDALBUILD
-  wget http://download.osgeo.org/gdal/2.0.2/gdal-2.0.2.tar.gz
-  tar -xzf gdal-2.0.2.tar.gz
-  cd gdal-2.0.2
-  ./configure --prefix=$GDALINST/gdal-2.0.2 $GDALOPTS
+  wget http://download.osgeo.org/gdal/$GDALVERSION/gdal-$GDALVERSION.tar.gz
+  tar -xzf gdal-$GDALVERSION.tar.gz
+  cd gdal-$GDALVERSION
+  ./configure --prefix=$GDALINST/gdal-$GDALVERSION $GDALOPTS
   make -s -j 2
   make install
 fi
diff --git a/setup.py b/setup.py
index 731797b..e3fac13 100644
--- a/setup.py
+++ b/setup.py
@@ -1,4 +1,5 @@
 from distutils.command.sdist import sdist
+from distutils import log
 import logging
 import os
 import shutil
@@ -8,6 +9,7 @@ import sys
 from setuptools import setup
 from setuptools.extension import Extension
 
+
 # Use Cython if available.
 try:
     from Cython.Build import cythonize
@@ -15,14 +17,6 @@ except ImportError:
     cythonize = None
 
 
-logging.basicConfig()
-log = logging.getLogger()
-
-# python -W all setup.py ...
-if 'all' in sys.warnoptions:
-    log.level = logging.DEBUG
-
-
 def check_output(cmd):
     # since subprocess.check_output doesn't exist in 2.6
     # we wrap it here.
@@ -74,11 +68,6 @@ with open('CHANGES.txt', **open_kwds) as f:
 # Set a flag for builds where the source directory is a repo checkout.
 source_is_repo = os.path.exists("MANIFEST.in")
 
-# Get GDAL API version from the command line if specified there.
-if '--gdalversion' in sys.argv and 'clean' not in sys.argv:
-    index = sys.argv.index('--gdalversion')
-    sys.argv.pop(index)
-    gdalversion = sys.argv.pop(index)
 
 # Extend distutil's sdist command to generate C extension sources from
 # both `ogrext`.pyx` and `ogrext2.pyx` for GDAL 1.x and 2.x.
@@ -94,13 +83,23 @@ class sdist_multi_gdal(sdist):
         print(_)
         sdist.run(self)
 
-# By default we'll try to get options via gdal-config. On systems without,
-# options will need to be set in setup.cfg or on the setup command line.
+# Building Fiona requires options that can be obtained from GDAL's gdal-config
+# program or can be specified using setup arguments. The latter override the
+# former.
+#
+# A GDAL API version is strictly required. Without this the setup script
+# cannot know whether to use the GDAL version 1 or 2 source files. The GDAL
+# API version can be specified in 2 ways.
+#
+# 1. By the gdal-config program, optionally pointed to by GDAL_CONFIG
+# 2. By a GDAL_VERSION environment variable. This overrides number 1.
+
 include_dirs = []
 library_dirs = []
 libraries = []
 extra_link_args = []
-gdal_output = [None] * 4
+gdal_output = [None for i in range(4)]
+gdalversion = '2'
 
 if 'clean' not in sys.argv:
     try:
@@ -108,7 +107,6 @@ if 'clean' not in sys.argv:
         for i, flag in enumerate(
                 ["--cflags", "--libs", "--datadir", "--version"]):
             gdal_output[i] = check_output([gdal_config, flag]).strip()
-
         for item in gdal_output[0].split():
             if item.startswith("-I"):
                 include_dirs.extend(item[2:].split(":"))
@@ -121,6 +119,9 @@ if 'clean' not in sys.argv:
                 # e.g. -framework GDAL
                 extra_link_args.append(item)
         gdalversion = gdal_output[3]
+        if gdalversion:
+            log.info("GDAL API version obtained from gdal-config: %s",
+                     gdalversion)
 
     except Exception as e:
         if os.name == "nt":
@@ -128,7 +129,26 @@ if 'clean' not in sys.argv:
                      "to locate needed GDAL files.\nMore information is "
                      "available in the README.")
         else:
-            log.warning("Failed to get options via gdal-config: %s", str(e))
+            log.warn("Failed to get options via gdal-config: %s", str(e))
+
+    # Get GDAL API version from environment variable.
+    if 'GDAL_VERSION' in os.environ:
+        gdalversion = os.environ['GDAL_VERSION']
+        log.info("GDAL API version obtained from environment: %s", gdalversion)
+
+    # Get GDAL API version from the command line if specified there.
+    if '--gdalversion' in sys.argv:
+        index = sys.argv.index('--gdalversion')
+        sys.argv.pop(index)
+        gdalversion = sys.argv.pop(index)
+        log.info("GDAL API version obtained from command line option: %s",
+                 gdalversion)
+
+    if not gdalversion:
+        log.fatal("A GDAL API version must be specified. Provide a path "
+                  "to gdal-config using a GDAL_CONFIG environment variable "
+                  "or use a GDAL_VERSION environment variable.")
+        sys.exit(1)
 
     if os.environ.get('PACKAGE_DATA'):
         destdir = 'fiona/gdal_data'
@@ -161,9 +181,8 @@ if source_is_repo and "clean" not in sys.argv:
     # When building from a repo, Cython is required.
     log.info("MANIFEST.in found, presume a repo, cythonizing...")
     if not cythonize:
-        log.critical(
-            "Cython.Build.cythonize not found. "
-            "Cython is required to build from a repo.")
+        log.fatal("Cython.Build.cythonize not found. "
+                  "Cython is required to build from a repo.")
         sys.exit(1)
 
     if gdalversion.startswith("1"):
diff --git a/tests/test_collection.py b/tests/test_collection.py
index d4da794..2be8911 100644
--- a/tests/test_collection.py
+++ b/tests/test_collection.py
@@ -460,7 +460,6 @@ class LineWritingTest(unittest.TestCase):
 
 
 class PointAppendTest(unittest.TestCase):
-    # Tests 3D shapefiles too
     def setUp(self):
         self.tempdir = tempfile.mkdtemp()
         with fiona.open(WILDSHP, "r") as input:
@@ -481,7 +480,7 @@ class PointAppendTest(unittest.TestCase):
 
     def test_append_point(self):
         with fiona.open(os.path.join(self.tempdir, "test_append_point.shp"), "a") as c:
-            self.assertEqual(c.schema['geometry'], '3D Point')
+            self.assertEqual(c.schema['geometry'], 'Point')
             c.write({'geometry': {'type': 'Point', 'coordinates': (0.0, 45.0)},
                      'properties': {'PERIMETER': 1.0,
                                     'FEATURE2': None,
diff --git a/tests/test_geometry.py b/tests/test_geometry.py
index 58a7c39..fba95b5 100644
--- a/tests/test_geometry.py
+++ b/tests/test_geometry.py
@@ -4,10 +4,13 @@ import logging
 import sys
 import unittest
 
-from fiona._geometry import GeomBuilder, geometryRT
+from fiona._geometry import (GeomBuilder, geometryRT)
+from fiona.errors import UnsupportedGeometryTypeError
+
 
 logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
 
+
 def geometry_wkb(wkb):
     return GeomBuilder().build_wkb(wkb)
 
@@ -188,4 +191,3 @@ class MultiPolygonTest(unittest.TestCase):
         self.assertEqual(min(y), 0.0)
         self.assertEqual(max(x), 1.0)
         self.assertEqual(max(y), 1.0)
-
diff --git a/tests/test_integration.py b/tests/test_integration.py
new file mode 100644
index 0000000..06dde12
--- /dev/null
+++ b/tests/test_integration.py
@@ -0,0 +1,59 @@
+"""Unittests to verify Fiona is functioning properly with other software."""
+
+
+import collections
+import os
+import shutil
+import tempfile
+import unittest
+
+import six
+
+import fiona
+
+
+class TestCRSNonDict(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(self):
+        self.tempdir = tempfile.mkdtemp()
+
+    @classmethod
+    def tearDownClass(self):
+        shutil.rmtree(self.tempdir)
+
+    def test_dict_subclass(self):
+        """Rasterio now has a `CRS()` class that subclasses
+        `collections.UserDict()`.  Make sure we can receive it.
+
+        `UserDict()` is a good class to test against because in Python 2 it is
+        not a subclass of `collections.Mapping()`, so it provides an edge case.
+        """
+
+        class CRS(six.moves.UserDict):
+            pass
+
+        outfile = os.path.join(self.tempdir, 'test_UserDict.geojson')
+
+        profile = {
+            'crs': CRS(init='EPSG:4326'),
+            'driver': 'GeoJSON',
+            'schema': {
+                'geometry': 'Point',
+                'properties': {}
+            }
+        }
+
+        with fiona.open(outfile, 'w', **profile) as dst:
+            dst.write({
+                'type': 'Feature',
+                'properties': {},
+                'geometry': {
+                    'type': 'Point',
+                    'coordinates': (10, -10)
+                }
+            })
+
+        with fiona.open(outfile) as src:
+            assert len(src) == 1
+            assert src.crs == {'init': 'epsg:4326'}
diff --git a/tests/test_multiconxn.py b/tests/test_multiconxn.py
index 485800c..4405014 100644
--- a/tests/test_multiconxn.py
+++ b/tests/test_multiconxn.py
@@ -6,7 +6,7 @@ import tempfile
 import unittest
 
 import fiona
-from fiona.odict import OrderedDict
+from fiona.compat import OrderedDict
 
 logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
 
diff --git a/tests/test_schema.py b/tests/test_schema.py
index 63c5e5a..f8e90e3 100644
--- a/tests/test_schema.py
+++ b/tests/test_schema.py
@@ -2,7 +2,10 @@ import os
 import shutil
 import tempfile
 import unittest
+
 import fiona
+from fiona.errors import UnsupportedGeometryTypeError
+
 
 class SchemaOrder(unittest.TestCase):
 
@@ -153,3 +156,19 @@ class FieldTruncationTestCase(unittest.TestCase):
             first = next(src)
             assert first['geometry'] == {'type': 'Point', 'coordinates': (0, 0)}
             assert first['properties']['a_fieldnam'] == 3.0
+
+
+def test_unsupported_geometry_type():
+    tmpdir = tempfile.mkdtemp()
+    tmpfile = os.path.join(tmpdir, 'test-test-geom.shp')
+
+    profile = {
+        'driver': 'ESRI Shapefile',
+        'schema': {
+            'geometry': 'BOGUS',
+            'properties': {}}}
+
+    try:
+        fiona.open(tmpfile, 'w', **profile)
+    except UnsupportedGeometryTypeError:
+        assert True

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/fiona.git



More information about the Pkg-grass-devel mailing list