Skip to content

Commit

Permalink
Restore behavior of setting fields to values derived from date, time (#…
Browse files Browse the repository at this point in the history
…1377)

* Restore behavior of setting fields to values derived from date, time

Resolves #1376

* 1.10a2 release (#1368)

* This is 1.10a2

* Rename VSI plugin prefix

Resolves #1369

* This is 1.10b1.dev0

* Restore behavior of setting fields to values derived from date, time

Resolves #1376
  • Loading branch information
sgillies committed Apr 16, 2024
1 parent ea24f55 commit b6e62cc
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 13 deletions.
8 changes: 8 additions & 0 deletions CHANGES.txt
Expand Up @@ -3,6 +3,14 @@ Changes

All issue numbers are relative to https://github.com/Toblerity/Fiona/issues.

1.10b1 (2024-04-16)
-------------------

Bug fixes:

- Fiona can again set fields with values that are instances of classes derived
from date, time, and datetime (#). This was broken by changes in 1.10a2.

1.10a2 (2024-04-05)
-------------------

Expand Down
30 changes: 17 additions & 13 deletions fiona/ogrext.pyx
Expand Up @@ -760,26 +760,30 @@ cdef class OGRFeatureBuilder:
OGR_F_SetFieldNull(cogr_feature, i)
else:
schema_type = session._schema_normalized_field_types[key]
fieldkey = (*FIELD_TYPES_MAP2[NAMED_FIELD_TYPES[schema_type]], type(value).__name__)
if fieldkey in self.property_setter_cache:
setter = self.property_setter_cache[fieldkey]
val_type = type(value)

if val_type in self.property_setter_cache:
setter = self.property_setter_cache[val_type]
else:
try:
setter = self.OGRPropertySetter[fieldkey](driver=self.driver)
self.property_setter_cache[fieldkey] = setter
except KeyError:
log.warning(
"Skipping field %s: invalid type %s",
key,
fieldkey
)
for cls in val_type.mro():
fieldkey = (*FIELD_TYPES_MAP2[NAMED_FIELD_TYPES[schema_type]], cls.__name__)
try:
setter = self.OGRPropertySetter[fieldkey](driver=self.driver)
except KeyError:
continue
else:
self.property_setter_cache[val_type] = setter
break
else:
log.warning("Skipping field because of invalid value: key=%r, value=%r", key, value)
continue

# Special case: serialize dicts to assist OGR.
if isinstance(value, dict):
value = json.dumps(value)

log.debug("Setting feature property: fieldkey=%r, setter=%r, i=%r, value=%r", fieldkey, setter, i, value)
log.debug("Setting feature property: key=%r, value=%r, i=%r, setter=%r", key, value, i, setter)

setter.set(cogr_feature, i, value, {"encoding": encoding})

return cogr_feature
Expand Down
27 changes: 27 additions & 0 deletions tests/test_datetime.py
Expand Up @@ -827,3 +827,30 @@ def test_read_timezone_geojson(path_test_tz_geojson):
with fiona.open(path_test_tz_geojson) as c:
items = list(c)
assert items[0]["properties"]["test"] == "2015-04-22T00:00:00+07:00"


def test_property_setter_lookup(tmp_path):
"""Demonstrate fix for #1376."""

class MyDate(datetime.date):
pass

feat = Feature.from_dict(
{
"properties": {"when": MyDate(2024, 4, 15)},
"geometry": {"type": "Point", "coordinates": [0, 0]},
}
)
with fiona.open(
tmp_path / "test.gpkg",
"w",
driver="GPKG",
crs="EPSG:4326",
schema={"geometry": "Point", "properties": {"when": "date"}},
) as colxn:
colxn.writerecords([feat])

with fiona.open(tmp_path / "test.gpkg") as colxn:
assert colxn.schema["properties"]["when"] == "date"
feat = next(colxn)
assert feat.properties["when"] == "2024-04-15"

0 comments on commit b6e62cc

Please sign in to comment.