Matt,

That seems good to me. I would, however, very much like to keep the
optional dependence on simplejson for dumps/loads. BTW, simplejson is in
the 2.6/3.0 standard library:

http://bugs.python.org/issue2750

Sean


Matthew Russell wrote:
> Sean, Eric, those interested,
> 
> Another option is to abandon my abstracton idea, and just get ride of
> dumps/dump/load/loads/encode/decode in favour of:
> 
> # 'feature' in this example, could be geojson.GeoJSON.to_instance({"type":
> ..., ...})
> feature  = geojsonlib.Feature(geometry=geojsonlib.Point(coordinates=[x, y]))
> d = dict(feature)
> myjsonlib.[encode|write|dumps](d, ...)
> 
> (Where myjsonlib is simplejson, json.py, jsonlib, cjson etc)
> 
> since this is all that needs to happen, and is exactly what each 'codec' in
> my hooks idea would accomplish, except we gain the advantage of not having
> to track each JSON library api, give the user (us too) one less level of
> indirection to follow.
> 
> We'd also not have dependancy on simplejson, and have no other dependancies.
> 
> The GeoJSON spec declares that geojson can have arbitrary members, this is
> still possible,
> just less convienient syntax:
> 
> d = {"blog":
>           {"placename": "California",
>             "location": feature}
> }
> json1 = cjson.write(d)
> json 2 = simplejson.dumps(d, encoding="utf-8")
> 
> So, now I think this is (probably) the right way to go... what do you think?
> 
> 
> 
> 2008/6/19 Matthew Russell <[EMAIL PROTECTED]>:
> 
>> Sean,
>>
>> I've done a bit of digging, an unfortunatly, writing a cjson codec would be
>> non-trivial, or impossible; unless the author(s) of that package provided a
>> hook (like JSONEcoder.default is)
>>
>> jsonlib's write (equivilent of dumps/encode)  has an 'on_unknown' hook, so
>> that'd work,
>> as would all other pure-python json libraries.
>>
>> A jsonlib codec might look like:
>>
>> class JsonlibCodec(object):
>>     def encode(self, obj, **kwargs):
>>          def on_unknown(value):
>>              d = dict(gejsonlib.GeoJSON.to_instance(value))
>>              return jsonlib.write(d)
>>          kwargs["on_unknown"] = on_unknown
>>          return jsonlib.write(obj, **kwargs)
>>
>>     def decode(self, json, **kwargs):
>>         obj_hooj = kwargs.get("object_hook", hoo)
>>         o = jsonlib.read(json)
>>         if obj_hook:
>>             o = obj_hook(o)
>>         return o
>>
>> A json-py codec might look like:
>>
>>
>> import json
>> class JsonPyCodec(object):
>>     def encode(self, obj, *args, **kwargs):
>>          json_writer = json.JsonWriter()
>>          try:
>>              return json_writer.write(obj)
>>          except json.WriteException: # not a python object corrospondng to
>> 'primative' json type
>>              return
>> json_writer.write(dict(geojsonlib.GeoJSON.to_instance(obj)))
>>
>>      def decode(obj, *args, **kwargs):
>>           obj_hook = kwargs.pop("object_hook", lambda x: obj)
>>           return json.JsonReader().read(obj_hooj(obj))
>>
>>
>> Matt
>>
>>
>>
>> 2008/6/18 Matthew Russell <[EMAIL PROTECTED]>:
>>
>>> Sean,
>>>
>>>
>>> I'd be ok with keeping loads/dumps as functions in geojsonlib/__init__.py
>>> They could even raise DepricationWaring.
>>>
>>> I've seen r1113's encoding.py, and it's similar to what I had in mind, but
>>> not quite.
>>>
>>> There's an extra level of indirection, geojsonlib/__init__ would define:
>>>
>>> # nb. in the following, geojsonlib.encoding is renamed to codecs
>>>
>>> def encode(obj, codec=None, *args, **kwargs):
>>>      codec = codec or geojsonlib.codecs.default
>>>      return codec.encode(obj, *args, **kwargs)
>>>
>>> decode would be much the same.
>>> Then I can write a CJson() codec (which defines encode and decode), and
>>> have that used instead.
>>>
>>> in geojsonlib.codecs, my hacked up version of the module goes something
>>> like:
>>>
>>> class JSONCodec(objet):
>>>     def encode(self, obj, **kwargs): raise NotImplemented
>>>     def decode(self, obj, **kwargs): raise NotImplemented
>>>
>>> try:
>>>    import simplejson
>>> except ImportError:
>>>    default = Codec()
>>> else:
>>>    class SimpleJSONCodec(JSONCodec):
>>>
>>>        def encode(self obj, **kwargs):
>>>             return simplejson.dumps(obj, **kwargs)
>>>
>>>        def decode(self, obj, **kwargs):
>>>             return simplejson.loads(obj, **kwargs)
>>>
>>>    default = SimepJSONCodec
>>>
>>>
>>> Cheers,
>>> Matt
>>>
>>> 2008/6/18 Sean Gillies <[EMAIL PROTECTED]>:
>>>
>>> Matt,
>>>> What would you think about keeping geojsonlib.dumps/loads as is for
>>>> convenience and just raise exceptions if simplejson can't be imported?
>>>> See rev 1113 -- I marked the dump/load feature as an "extra" in setup.py.
>>>>
>>>> Sean
>>>>
>>>> Matthew Russell wrote:
>>>>> Hi,
>>>>>
>>>>> this is a proposal which Sean already +1'd in the recent "[Community]
>>>> [Fwd:
>>>>> [Geojson] GeoJSON 1.0 Released]" thread.
>>>>>
>>>>> The proposal is to remove the reliance on simplejson from geojsonlib
>>>> (but
>>>>> keeping simplejson as the default).
>>>>>
>>>>> I'n slight alteration to my previous api suggestion for the interface
>>>> for
>>>>> simplejson's peers,
>>>>> I'd like to change the api from:
>>>>>
>>>>> geojsonlib.{dumps, dump, loads, load}
>>>>>
>>>>> to:
>>>>>
>>>>> json = geojsonlib.encode(obj, codec="geojsonlib.defaultcodec",
>>>> *codec_args,
>>>>> **codec_kwargs)
>>>>>   - where obj is any python object supporting the geointerface, or a
>>>> mapping
>>>>>   - returns unicode or str
>>>>>
>>>>> obj = geojsonlib.decode(json, codec="geojsonlib.defaultcodec",
>>>> *codec_args,
>>>>> **codec_kwargs)
>>>>>
>>>>>   - where 'json' is a unicode or str instance.
>>>>>   - reutrns a geojsonlib.GeoJSON instance or subclass thereof.
>>>>>
>>>>> The primary motivation for this is file encoding.
>>>>> I'd like to keep the serialisation to file-like objects within the
>>>> control
>>>>> of the user at the I/O boundaries.
>>>>> Removing the dump and load functions from geojsonlib would acheive
>>>> this.
>>>>> I also think the names encode and decode are better, since load and
>>>> dumps
>>>>> indicate serialization to disk.
>>>>>
>>>>> So, does anyone object if the api changes from:
>>>>> geojsonlib.dumps -> geojson.encode
>>>>> geojsonlib.loads -> geojson.decode
>>>>> geojsonlib.dump -> file_like.write(geojsonlib.encode(obj))
>>>>> geojsonlib.load -> geojsonlib.decode(file_like.read())
>>>>>
>>>>> ?
>>>>>
>>>>> Once this is implemented, simplejson will only be required in the
>>>> default
>>>>> case:
>>>>>
>>>>> .encode(obj), .decode(obj)
>>>>>
>>>>> and not if you want to use another JSON library, and have an adapter:
>>>>>
>>>>> e.g
>>>>>
>>>>> class CjsonEncoder:
>>>>>      def encode(self, obj):
>>>>>            ...
>>>>>
>>>>> .encode(obj, codec=CjsonEncoder)
>>>>>
>>>>> N.B:
>>>>>
>>>>> 'codec' can be a dotted path, or any namespace with a .encode or
>>>> .decode
>>>>> callable attribute as releveant.
>>>>>
>>>>> --
>>>>> Cheers,
>>>>> Matt

_______________________________________________
Community mailing list
[email protected]
http://lists.gispython.org/mailman/listinfo/community

Reply via email to