Rune Halvorsen avatar Rune Halvorsen committed 7db3bf8

Rewritten to not use nested imports
Added exception unification
Added force_implementation method and implementation attribute

Comments (0)

Files changed (1)

 Get the best JSON encoder/decoder available on this system.
 """
 
-__version__ = "0.1.1"
+__version__ = "0.2.0"
 __author__ = "Rune Halvorsen <runefh@gmail.com>"
 __homepage__ = "http://bitbucket.org/runeh/anyjson/"
 __docformat__ = "restructuredtext"
 
     Deserialize JSON-encoded object to a Python object.
 
+.. function:: force_implementation(obj)
+
+    Load a specific json module. This is useful for testing and not much else
+
+.. attribute:: implementation
+
+    Name of the json implementation that is being used
 """
 
-# Try to import a module that provides json parsing and emitting, starting
-# with the fastest alternative and falling back to the slower ones.
-try:
-    # cjson is the fastest
-    import cjson
-    serialize = cjson.encode
-    deserialize = cjson.decode
-except ImportError:
+import sys
+from inspect import isclass
+
+implementation = None
+
+_serialize = None
+_deserialize = None
+_ser_error = None
+_des_error = None
+
+_modules = [("cjson", "encode", "EncodeError", "decode", "DecodeError"),
+            ("jsonlib2", "write", "WriteError", "read", "ReadError"),
+            ("jsonlib", "write", "WriteError", "read", "ReadError"),
+            ("simplejson", "dumps", TypeError, "loads", ValueError),
+            ("json", "dumps", TypeError, "loads", ValueError),
+            ("django.utils.simplejson", "dumps", TypeError, "loads", ValueError)
+            ]
+
+
+def _attempt_load(modname, encname, encerror, decname, decerror):
     try:
-        import jsonlib2
-        serialize = jsonlib2.read
-        deserialize = jsonlib2.write
-    except:
-        try:
-            import jsonlib
-            serialize = jsonlib.read
-            deserialize = jsonlib.write
-        except:
-            try:
-                # Then try to find simplejson. Later versions has C speedups
-                # which makes it pretty fast.
-                import simplejson
-                serialize = simplejson.dumps
-                deserialize = simplejson.loads
-            except ImportError:
-                try:
-                    import jsonpickle
-                    serialize = jsonpickle.encode
-                    deserialize = jsonpickle.decode
-                except:
-                    try:
-                        # Then try to find the python 2.6 stdlib json module.
-                        import json
-                        serialize = json.dumps
-                        deserialize = json.loads
-                    except ImportError:
-                        try:
-                            # If all of the above fails, try to fallback to
-                            # the simplejson embedded in Django.
-                            from django.utils import simplejson
-                            serialize = simplejson.dumps
-                            deserialize = simplejson.loads
-                        except:
-                            raise ImportError("No json module found")
+        global _serialize, _deserialize, _ser_error, _des_error
+        global implementation
+        __import__(modname)
+        mod = sys.modules[modname]
+        _serialize = getattr(mod, encname)
+        _deserialize = getattr(mod, decname)
+
+        if  isclass(encerror) and issubclass(encerror, Exception):
+            _ser_error = encerror
+        else:
+            _ser_error = getattr(mod, encerror)
+
+        if isclass(decerror) and issubclass(decerror, Exception):
+            _des_error = decerror
+        else:
+            _des_error = getattr(mod, decerror)
+
+        implementation = modname
+        return True
+    except ImportError:
+        return False
+
+def force_implementation(modname):
+    for name, spec in [(e[0], e) for e in _modules]:
+        print "spce:", spec
+        if name == modname and _attempt_load(*spec):
+            return
+
+    raise ImportError(modname)
+
+
+class JsonValueError(ValueError):
+    pass
+
+class JsonTypeError(TypeError):
+    pass
+
+def serialize(s):
+    try:
+        return _serialize(s)
+    except _ser_error:
+        raise JsonTypeError()
+
+def deserialize(s):
+    try:
+        return _deserialize(s)
+    except _des_error:
+        raise JsonValueError()
+
+for modspec in _modules:
+    if _attempt_load(*modspec):
+        break
+else:
+    raise ImportError("No json module found")
+
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.