Skip to content
Commits on Source (9)
......@@ -14,6 +14,7 @@ env:
- GDALVERSION="1.11.5"
- GDALVERSION="2.0.3"
- GDALVERSION="2.1.4"
- GDALVERSION="2.2.4"
addons:
apt:
packages:
......
......@@ -3,6 +3,14 @@ Changes
All issue numbers are relative to https://github.com/Toblerity/Fiona/issues.
1.7.13 (2018-07-17)
-------------------
In GDAL 2.2, the behavior of GDAL with respect to null fields changed (#460).
A fix in the master (1.8-to-be) branch has been back-ported so that Fiona's
results with GDAL 2.1 and 2.2 are the same. The value reported for unset
integer or string fields will be `None` and not `0` or `""`.
1.7.12 (2018-06-11)
-------------------
......
fiona (1.7.12-2) UNRELEASED; urgency=medium
fiona (1.7.13-1) unstable; urgency=medium
* Team upload.
* New upstream release.
* Use filter instead of findstring to prevent partial matches.
* Bump Standards-Version to 4.2.0, no changes.
* Drop autopkgtests to test installability & module import.
* Add lintian override for testsuite-autopkgtest-missing.
* Update watch file to use releases instead of tags.
* Refresh patches.
* Exclude test_feature from tests.
* Update watch file to limit matches to archive path.
* Fix incomplete-creative-commons-license issue.
-- Bas Couwenberg <sebastic@debian.org> Tue, 17 Jul 2018 18:27:30 +0200
-- Bas Couwenberg <sebastic@debian.org> Wed, 15 Aug 2018 18:20:14 +0200
fiona (1.7.12-1) unstable; urgency=medium
......
......@@ -84,6 +84,14 @@ License: BSD-3-Clause
License: CC-BY-3.0-US
http://creativecommons.org/licenses/by/3.0/us/legalcode
.
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL
SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT
RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS.
CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND
DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE.
.
License
.
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE
COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY
COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
......
......@@ -9,7 +9,7 @@ There is already another package providing a binary "fio" (fio).
--- a/setup.py
+++ b/setup.py
@@ -251,7 +251,7 @@ setup_args = dict(
@@ -265,7 +265,7 @@ setup_args = dict(
packages=['fiona', 'fiona.fio'],
entry_points='''
[console_scripts]
......
......@@ -6,7 +6,7 @@ Author: Bas Couwenberg <sebastic@debian.org>
--- a/setup.py
+++ b/setup.py
@@ -233,11 +233,8 @@ if sys.version_info < (3, 4):
@@ -247,11 +247,8 @@ if sys.version_info < (3, 4):
setup_args = dict(
cmdclass={'sdist': sdist_multi_gdal},
......
......@@ -21,6 +21,7 @@ export PYBUILD_TEST_ARGS=--exclude cli \
--exclude fiona \
--exclude test_bytescollection \
--exclude test_collection \
--exclude test_feature \
--exclude test_filter_vsi \
--exclude test_fio_info \
--exclude test_fio_ls \
......
......@@ -3,5 +3,5 @@ opts=\
dversionmangle=s/\+(debian|dfsg|ds|deb)\d*$//,\
uversionmangle=s/(\d)[_\.\-\+]?((RC|rc|pre|dev|b|beta|a|alpha)\d*)$/$1~$2/,\
filenamemangle=s/(?:.*?\/)?(?:rel|r|v|fiona)?[\-\_]?(\d\S+)\.(tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz)))/fiona-$1.$2/ \
https://github.com/Toblerity/Fiona/tags \
(?:.*/)?(?:rel|r|v|fiona)?[\-\_]?(\d\S+)\.(?:tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz)))
https://github.com/Toblerity/Fiona/releases \
(?:.*/archive/)?(?:rel|r|v|fiona)?[\-\_]?(\d\S+)\.(?:tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz)))
......@@ -81,7 +81,7 @@ import uuid
__all__ = ['bounds', 'listlayers', 'open', 'prop_type', 'prop_width']
__version__ = "1.7.12"
__version__ = "1.7.13"
__gdal_version__ = get_gdal_release_name().decode('utf-8')
log = logging.getLogger(__name__)
......
cdef extern from "ogr_api.h":
int OGR_F_IsFieldSet (void *feature, int n)
cdef bint is_field_null(void *feature, int n):
if not OGR_F_IsFieldSet(feature, n):
return True
else:
return False
cdef extern from "ogr_api.h":
int OGR_F_IsFieldSet (void *feature, int n)
int OGR_F_IsFieldNull(void *feature, int n)
cdef bint is_field_null(void *feature, int n):
if OGR_F_IsFieldNull(feature, n):
return True
elif not OGR_F_IsFieldSet(feature, n):
return True
else:
return False
......@@ -34,6 +34,10 @@ from libc.string cimport strcmp
log = logging.getLogger("Fiona")
class NullHandler(logging.Handler):
def emit(self, record):
pass
log.addHandler(NullHandler())
# Mapping of OGR integer field types to Fiona field type names.
#
......@@ -122,19 +126,25 @@ def _bounds(geometry):
except (KeyError, TypeError):
return None
def calc_gdal_version_num(maj, min, rev):
"""Calculates the internal gdal version number based on major, minor and revision"""
return int(maj * 1000000 + min * 10000 + rev*100)
def get_gdal_version_num():
"""Return current internal version number of gdal"""
return int(ogrext2.GDALVersionInfo("VERSION_NUM"))
def get_gdal_release_name():
"""Return release name of gdal"""
return ogrext2.GDALVersionInfo("RELEASE_NAME")
include "isfieldnull.pxi"
# Feature extension classes and functions follow.
cdef class FeatureBuilder:
......@@ -157,6 +167,7 @@ cdef class FeatureBuilder:
cdef int tz = 0
cdef int retval
cdef const char *key_c = NULL
cdef bint is_null
props = OrderedDict()
for i in range(ogrext2.OGR_F_GetFieldCount(feature)):
fdefn = ogrext2.OGR_F_GetFieldDefnRef(feature, i)
......@@ -177,8 +188,10 @@ cdef class FeatureBuilder:
# TODO: other types
fieldtype = FIELD_TYPES_MAP[fieldtypename]
if not ogrext2.OGR_F_IsFieldSet(feature, i):
if is_field_null(feature, i):
props[key] = None
elif fieldtype is int:
props[key] = ogrext2.OGR_F_GetFieldAsInteger64(feature, i)
elif fieldtype is float:
......
-r requirements.txt
coverage
cython>=0.21.2
cython==0.28.4
nose
pytest
pytest-cov
......
from distutils.command.sdist import sdist
from distutils import log
import logging
import os
import shutil
import subprocess
......@@ -168,11 +167,19 @@ if 'clean' not in sys.argv:
log.info("Copying proj data from %s" % projdatadir)
copy_data_tree(projdatadir, 'fiona/proj_data')
def calc_gdal_version_num(maj=1, min=0, rev=0):
return int(maj * 1000000 + min * 10000 + rev*100)
GDAL_VERSION_NUM = calc_gdal_version_num(*[int(i) for i in gdalversion.split(".")])
ext_options = dict(
include_dirs=include_dirs,
library_dirs=library_dirs,
libraries=libraries,
extra_link_args=extra_link_args)
extra_link_args=extra_link_args,
)
# Define the extension modules.
ext_modules = []
......@@ -192,13 +199,20 @@ if source_is_repo and "clean" not in sys.argv:
log.info("Building Fiona for gdal 2.x: {0}".format(gdalversion))
shutil.copy('fiona/ogrext2.pyx', 'fiona/ogrext.pyx')
# Add shim for OGR_IsFieldNull.
if gdalversion.startswith("2.2"):
shutil.copy("fiona/isfieldnull22.pxi", "fiona/isfieldnull.pxi")
else:
shutil.copy("fiona/isfieldnull1.pxi", "fiona/isfieldnull.pxi")
ext_modules = cythonize([
Extension('fiona._geometry', ['fiona/_geometry.pyx'], **ext_options),
Extension('fiona._transform', ['fiona/_transform.pyx'], **ext_options),
Extension('fiona._crs', ['fiona/_crs.pyx'], **ext_options),
Extension('fiona._drivers', ['fiona/_drivers.pyx'], **ext_options),
Extension('fiona._err', ['fiona/_err.pyx'], **ext_options),
Extension('fiona.ogrext', ['fiona/ogrext.pyx'], **ext_options)])
Extension('fiona.ogrext', ['fiona/ogrext.pyx'], **ext_options)],
compile_time_env={"GDAL_VERSION_NUM": GDAL_VERSION_NUM},)
# If there's no manifest template, as in an sdist, we just specify .c files.
elif "clean" not in sys.argv:
......
# testing features, to be called by nosetests
import logging
import os
import shutil
import sys
import tempfile
import unittest
from fiona import collection
import fiona
from fiona.collection import Collection
from fiona.ogrext import featureRT
#logging.basicConfig(stream=sys.stderr, level=logging.INFO)
class PointRoundTripTest(unittest.TestCase):
def setUp(self):
......@@ -110,3 +107,27 @@ class PolygonRoundTripTest(unittest.TestCase):
g = featureRT(f, self.c)
self.assertEqual(g['properties']['title'], 'foo')
class NullFieldTest(unittest.TestCase):
"""See issue #460."""
def setUp(self):
self.tempdir = tempfile.mkdtemp()
def tearDown(self):
shutil.rmtree(self.tempdir)
def test_feature_null_field(self):
"""Undefined int feature properties are None, not 0"""
meta = {"driver": "ESRI Shapefile", "schema": {"geometry": "Point", "properties": {"RETURN_P": "int"}}}
filename = os.path.join(self.tempdir, "test_null.shp")
with fiona.open(filename, "w", **meta) as dst:
g = {"coordinates": [1.0, 2.0], "type": "Point"}
feature = {"geometry": g, "properties": {"RETURN_P": None}}
dst.write(feature)
with fiona.open(filename, "r") as src:
feature = next(iter(src))
self.assertEqual(feature["properties"]["RETURN_P"], None)