diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5fdf4a1a3..951ac5515 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,7 @@ Unreleased - feat: :doc:`/scripts/csvclean` adds a :code:`--remove-empty-columns` option to remove empty columns from standard output. - feat: :doc:`/scripts/in2csv` guesses the ``ndjson`` format for files with :code:`.ndjson`, :code:`.jsonl` and :code:`.jl` extensions. - fix: :code:`-C/--not-columns` now excludes the last column of an open-ended range (e.g. :code:`2-`). +- fix: :doc:`/scripts/in2csv` with :code:`--format geojson` serializes array-valued properties as JSON, like object-valued properties, instead of as a Python ``repr``. 2.2.0 - December 15, 2025 ------------------------- diff --git a/csvkit/convert/geojs.py b/csvkit/convert/geojs.py index 28d2583a5..60e55b161 100644 --- a/csvkit/convert/geojs.py +++ b/csvkit/convert/geojs.py @@ -64,7 +64,7 @@ def geojson2csv(f, key=None, **kwargs): for field in property_fields: value = properties.get(field) - if isinstance(value, OrderedDict): + if isinstance(value, (OrderedDict, list)): value = json.dumps(value) row.append(value) diff --git a/tests/test_utilities/test_in2csv.py b/tests/test_utilities/test_in2csv.py index 6c9e60fd4..894291c2b 100644 --- a/tests/test_utilities/test_in2csv.py +++ b/tests/test_utilities/test_in2csv.py @@ -229,6 +229,19 @@ def test_geojson_no_inference(self): input_file.close() + def test_geojson_array_property(self): + input_file = io.BytesIO( + b'{"type": "FeatureCollection", "features": [{"geometry": null, "properties": ' + b'{"tags": ["a", "b"], "obj": {"k": "v"}}}]}') + + with stdin_as_string(input_file): + self.assertLines(['-f', 'geojson'], [ + 'id,tags,obj,geojson,type,longitude,latitude', + ',"[""a"", ""b""]","{""k"": ""v""}",null,,,', + ]) + + input_file.close() + def test_json_no_inference(self): input_file = io.BytesIO(b'[{"a": 1, "b": 2, "c": 3}]')