@@ -1047,7 +1047,6 @@ def to_rdf(self, input_, options):
10471047 issuer = IdentifierIssuer ('_:b' )
10481048 node_map = {'@default' : {}}
10491049 self ._create_node_map (expanded , node_map , '@default' , issuer )
1050-
10511050 # output RDF dataset
10521051 dataset = {}
10531052 for graph_name , graph in sorted (node_map .items ()):
@@ -1148,15 +1147,21 @@ def has_value(subject, property, value):
11481147 """
11491148 if JsonLdProcessor .has_property (subject , property ):
11501149 val = subject [property ]
1151- is_list = _is_list (val )
1152- if _is_array (val ) or is_list :
1153- if is_list :
1154- val = val ['@list' ]
1150+ # Avoid double checking if val is a list.
1151+ # If val is a list, then we treat is as an array (i.e. if value occurs in the list, has_value returns true)
1152+ # TODO: is this desirable behavior?
1153+ if _is_list (val ):
1154+ val = val ['@list' ]
1155+
1156+ if _is_array (val ):
11551157 for v in val :
1156- if JsonLdProcessor .compare_values (value , v ):
1157- return True
1158+ # Avoid in depth comparison if the types are not the same
1159+ if type (v ) == type (value ):
1160+ return JsonLdProcessor .compare_values (value , v )
11581161 # avoid matching the set of values with an array value parameter
1159- elif not _is_array (value ):
1162+ # TODO: this means that if `value` is an array, there will be no comparison at all and we default to False
1163+ # is this desirable behavior?
1164+ elif not _is_array (value ) and type (val ) == type (value ):
11601165 return JsonLdProcessor .compare_values (value , val )
11611166 return False
11621167
@@ -1275,28 +1280,33 @@ def compare_values(v1, v2):
12751280
12761281 :return: True if v1 and v2 are considered equal, False if not.
12771282 """
1278- # 1. equal primitives
1279- if not _is_object (v1 ) and not _is_object (v2 ) and v1 == v2 :
1280- if isinstance (v1 , bool ) or isinstance (v2 , bool ):
1281- return type (v1 ) is type (v2 )
1282- return True
1283-
1284- # 2. equal @values
1285- if (_is_value (v1 ) and _is_value (v2 ) and
1286- v1 ['@value' ] == v2 ['@value' ] and
1287- v1 .get ('@type' ) == v2 .get ('@type' ) and
1288- v1 .get ('@language' ) == v2 .get ('@language' ) and
1289- v1 .get ('@index' ) == v2 .get ('@index' )):
12901283
1291- if isinstance (v1 ['@value' ], bool ) or isinstance (v2 ['@value' ], bool ):
1292- return type (v1 ['@value' ]) is type (v2 ['@value' ])
1284+ # 1. equal primitives (= equal anything)
1285+ # This should just be equality...
1286+ # The previous version also returned true if one of the value types was bool and they were equal
1287+ # but they should only be equal if the types correspond as well.
1288+ # If they are both objects and they are equal in all respects, then they *are* equal (even if they are not primitives)
1289+ if v1 == v2 :
12931290 return True
12941291
12951292 # 3. equal @ids
1296- if (_is_object (v1 ) and '@id' in v1 and
1297- _is_object (v2 ) and '@id' in v2 ):
1298- return v1 ['@id' ] == v2 ['@id' ]
1293+ # equal @ids only compares on one key, and is therefore preferred to do
1294+ # so let's do that first, and then only if there's a key error (i.e. no '@id'), we assume it's a value comparison.
1295+ try :
1296+ # If v1 and v2 have the same @id, they are the same
1297+ v1 ['@id' ] == v2 ['@id' ]
1298+ except KeyError :
1299+ # if key error, then it is indeed a dict, but a literal value, not an object.
1300+ try :
1301+ return v1 ['@value' ] == v2 ['@value' ] and v1 .get ('@type' ) == v2 .get ('@type' ) and v1 .get ('@language' ) == v2 .get ('@language' ) and v1 .get ('@index' ) == v2 .get ('@index' )
1302+ except :
1303+ # It is a dictionary, but a regular JSON one, not a JSON-LD dictionary
1304+ return False
1305+ except :
1306+ # one of v1 and v2 is not a dictionary
1307+ return False
12991308
1309+ # The two values are not the same.
13001310 return False
13011311
13021312 @staticmethod
0 commit comments