@@ -19,8 +19,11 @@ class JsonObj(ExtendedNamespace):
1919 identifier is represented as a first-class member of the objects. JSON identifiers that begin with "_" are
2020 disallowed in this implementation.
2121 """
22- def __new__ (cls , list_or_dict : Optional [Union [List , Dict ]] = None , * ,
23- _if_missing : Callable [["JsonObj" , str ], Tuple [bool , Any ]] = None , ** kwargs ):
22+ # Set this class variable to False if recursive construction is absolutely necessare (see: test_issue13.py for
23+ # details
24+ _idempotent = True
25+
26+ def __new__ (cls , * args , _if_missing : Callable [["JsonObj" , str ], Tuple [bool , Any ]] = None , ** kwargs ):
2427 """ Construct a JsonObj from set of keyword/value pairs
2528
2629 :param list_or_dict: A list or dictionary that can be used to construct the object
@@ -30,18 +33,15 @@ def __new__(cls, list_or_dict: Optional[Union[List, Dict]] = None, *,
3033 :param kwargs: A dictionary as an alternative constructor.
3134 """
3235 # This makes JsonObj idempotent
33- if isinstance (list_or_dict , JsonObj ):
34- if not kwargs and (not _if_missing or _if_missing == list_or_dict ._if_missing ):
35- return list_or_dict
36- else :
37- obj = super (ExtendedNamespace , cls ).__new__ (cls )
38- obj .__init__ (as_json_obj (list_or_dict ), _if_missing = _if_missing , ** kwargs )
39- else :
40- obj = super (ExtendedNamespace , cls ).__new__ (cls )
36+ if cls ._idempotent and args and isinstance (args [0 ], JsonObj ):
37+ # If we're being called with a single argument
38+ if not kwargs and not args [1 :] and \
39+ (not _if_missing or _if_missing == args [0 ]._if_missing ) and cls == type (args [0 ]):
40+ return args [0 ]
41+ obj = super (ExtendedNamespace , cls ).__new__ (cls )
4142 return obj
4243
43- def __init__ (self , list_or_dict : Optional [Union [List , Dict ]] = None , * ,
44- _if_missing : Callable [["JsonObj" , str ], Tuple [bool , Any ]] = None , ** kwargs ):
44+ def __init__ (self , * args , _if_missing : Callable [["JsonObj" , str ], Tuple [bool , Any ]] = None , ** kwargs ):
4545 """ Construct a JsonObj from set of keyword/value pairs
4646
4747 :param list_or_dict: A list or dictionary that can be used to construct the object
@@ -50,22 +50,23 @@ def __init__(self, list_or_dict: Optional[Union[List, Dict]] = None, *,
5050 processing proceeds.
5151 :param kwargs: A dictionary as an alternative constructor.
5252 """
53- if isinstance (list_or_dict , JsonObj ):
53+ if args and isinstance (args [0 ], JsonObj ) and not kwargs and not args [1 :] and type (self )._idempotent and \
54+ (not _if_missing or _if_missing == args [0 ]._if_missing ) and type (self ) == type (args [0 ]):
5455 return
5556
5657 if _if_missing and _if_missing != self ._if_missing :
5758 self ._if_missing = _if_missing
58- if list_or_dict is not None :
59+ if args :
5960 if kwargs :
6061 raise TypeError ("Constructor can't have both a single item and a dict" )
61- if isinstance (list_or_dict , JsonObj ):
62+ if isinstance (args [ 0 ] , JsonObj ):
6263 pass
63- elif isinstance (list_or_dict , dict ):
64- self ._init_from_dict (list_or_dict )
65- elif isinstance (list_or_dict , list ):
64+ elif isinstance (args [ 0 ] , dict ):
65+ self ._init_from_dict (args [ 0 ] )
66+ elif isinstance (args [ 0 ] , list ):
6667 ExtendedNamespace .__init__ (self ,
6768 _root = [JsonObj (e ) if isinstance (e , (dict , list )) else
68- e for e in list_or_dict ])
69+ e for e in args [ 0 ] ])
6970 else :
7071 raise TypeError ("JSON Object can only be a list or dictionary" )
7172 else :
0 commit comments