Repository navigation
encoding parameter to json.loads has been deprecated and removed in Python 3.9 #150
Copy link
Copy link
Closed
Description
encoding parameter has been deprecated and removed in Python 3.9. geojson.loads internally uses json.loads. This will cause test failure.
geojson/tests/test_features.py
Line 85 in 3cef47c
| feature = geojson.loads(json, object_hook=factory, encoding="utf-8") |
Ref : python/cpython#18075
Sample fa
pytest -v tests/test_features.py
=============================== test session starts ===============================
platform linux -- Python 3.10.0a0, pytest-6.0.1, py-1.9.0, pluggy-0.13.1 -- /root/pydev-venv/bin/python
cachedir: .pytest_cache
rootdir: /root/checked_repos/geojson
collected 4 items
tests/test_features.py::FeaturesTest::test_feature_class FAILED [ 25%]
tests/test_features.py::FeaturesTest::test_geo_interface PASSED [ 50%]
tests/test_features.py::FeaturesTest::test_protocol PASSED [ 75%]
tests/test_features.py::FeaturesTest::test_unicode_properties PASSED [100%]
==================================== FAILURES =====================================
_________________________ FeaturesTest.test_feature_class _________________________
self = <tests.test_features.FeaturesTest testMethod=test_feature_class>
def test_feature_class(self):
"""
Test the Feature class
"""
from geojson.examples import SimpleWebFeature
feature = SimpleWebFeature(
id='1',
geometry={'type': 'Point', 'coordinates': [53.0, -4.0]},
title='Feature 1', summary='The first feature',
link='http://example.org/features/1'
)
# It satisfies the feature protocol
self.assertEqual(feature.id, '1')
self.assertEqual(feature.properties['title'], 'Feature 1')
self.assertEqual(feature.properties['summary'], 'The first feature')
self.assertEqual(feature.properties['link'],
'http://example.org/features/1')
self.assertEqual(geojson.dumps(feature.geometry, sort_keys=True),
'{"coordinates": [53.0, -4.0], "type": "Point"}')
# Encoding
json = ('{"geometry": {"coordinates": [53.0, -4.0],'
' "type": "Point"},'
' "id": "1",'
' "properties":'
' {"link": "http://example.org/features/1",'
' "summary": "The first feature",'
' "title": "Feature 1"},'
' "type": "Feature"}')
self.assertEqual(geojson.dumps(feature, sort_keys=True), json)
# Decoding
factory = geojson.examples.create_simple_web_feature
json = ('{"geometry": {"type": "Point",'
' "coordinates": [53.0, -4.0]},'
' "id": "1",'
' "properties": {"summary": "The first feature",'
' "link": "http://example.org/features/1",'
' "title": "Feature 1"}}')
> feature = geojson.loads(json, object_hook=factory, encoding="utf-8")
tests/test_features.py:85:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
geojson/codec.py:51: in loads
return json.loads(s,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
s = '{"geometry": {"type": "Point", "coordinates": [53.0, -4.0]}, "id": "1", "properties": {"summary": "The first feature", "link": "http://example.org/features/1", "title": "Feature 1"}}'
cls = <class 'json.decoder.JSONDecoder'>
object_hook = <function create_simple_web_feature at 0x7f711ac7dd30>
parse_float = None, parse_int = None
parse_constant = <function _enforce_strict_numbers at 0x7f711acff1f0>
object_pairs_hook = None
kw = {'encoding': 'utf-8', 'object_hook': <function create_simple_web_feature at 0x7f711ac7dd30>, 'parse_constant': <function _enforce_strict_numbers at 0x7f711acff1f0>}
def loads(s, *, cls=None, object_hook=None, parse_float=None,
parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
"""Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray`` instance
containing a JSON document) to a Python object.
``object_hook`` is an optional function that will be called with the
result of any object literal decode (a ``dict``). The return value of
``object_hook`` will be used instead of the ``dict``. This feature
can be used to implement custom decoders (e.g. JSON-RPC class hinting).
``object_pairs_hook`` is an optional function that will be called with the
result of any object literal decoded with an ordered list of pairs. The
return value of ``object_pairs_hook`` will be used instead of the ``dict``.
This feature can be used to implement custom decoders. If ``object_hook``
is also defined, the ``object_pairs_hook`` takes priority.
``parse_float``, if specified, will be called with the string
of every JSON float to be decoded. By default this is equivalent to
float(num_str). This can be used to use another datatype or parser
for JSON floats (e.g. decimal.Decimal).
``parse_int``, if specified, will be called with the string
of every JSON int to be decoded. By default this is equivalent to
int(num_str). This can be used to use another datatype or parser
for JSON integers (e.g. float).
``parse_constant``, if specified, will be called with one of the
following strings: -Infinity, Infinity, NaN.
This can be used to raise an exception if invalid JSON numbers
are encountered.
To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
kwarg; otherwise ``JSONDecoder`` is used.
"""
if isinstance(s, str):
if s.startswith('\ufeff'):
raise JSONDecodeError("Unexpected UTF-8 BOM (decode using utf-8-sig)",
s, 0)
else:
if not isinstance(s, (bytes, bytearray)):
raise TypeError(f'the JSON object must be str, bytes or bytearray, '
f'not {s.__class__.__name__}')
s = s.decode(detect_encoding(s), 'surrogatepass')
if (cls is None and object_hook is None and
parse_int is None and parse_float is None and
parse_constant is None and object_pairs_hook is None and not kw):
return _default_decoder.decode(s)
if cls is None:
cls = JSONDecoder
if object_hook is not None:
kw['object_hook'] = object_hook
if object_pairs_hook is not None:
kw['object_pairs_hook'] = object_pairs_hook
if parse_float is not None:
kw['parse_float'] = parse_float
if parse_int is not None:
kw['parse_int'] = parse_int
if parse_constant is not None:
kw['parse_constant'] = parse_constant
> return cls(**kw).decode(s)
E TypeError: JSONDecoder.__init__() got an unexpected keyword argument 'encoding'
/root/cpython/Lib/json/__init__.py:359: TypeError
============================= short test summary info =============================
FAILED tests/test_features.py::FeaturesTest::test_feature_class - TypeError: JSO...
=========================== 1 failed, 3 passed in 0.09s ===========================
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
rayrrr commentedon Aug 8, 2020
@tirkarthi thank you for submitting this issue and PR. I think it should be fine but I am going to take a bit of time this weekend to consider "Chesterton's Fence" and make sure removing the utf-8 encoding thing is all good and then will merge or circle back.