diff --git a/CHANGES.txt b/CHANGES.txt index 67279884..eb3a170c 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -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) ------------------- diff --git a/fiona/ogrext.pyx b/fiona/ogrext.pyx index 604e8c6f..c18cc3d5 100644 --- a/fiona/ogrext.pyx +++ b/fiona/ogrext.pyx @@ -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 diff --git a/tests/test_datetime.py b/tests/test_datetime.py index cc2e5978..7f29f627 100644 --- a/tests/test_datetime.py +++ b/tests/test_datetime.py @@ -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"