44
55import os
66import json
7+ import hashlib
78from uuid import uuid4
89from copy import deepcopy
910
@@ -112,12 +113,12 @@ def __init__(self, name=None):
112113
113114 def __getstate__ (self ):
114115 """Return the object data for state serialization with older pickle protocols."""
115- return {' __dict__' : self .__dict__ , ' dtype' : self .dtype , ' data' : self .data }
116+ return {" __dict__" : self .__dict__ , " dtype" : self .dtype , " data" : self .data }
116117
117118 def __setstate__ (self , state ):
118119 """Assign a deserialized state to the object data to support older pickle protocols."""
119- self .__dict__ .update (state [' __dict__' ])
120- self .data = state [' data' ]
120+ self .__dict__ .update (state [" __dict__" ])
121+ self .data = state [" data" ]
121122
122123 @property
123124 def DATASCHEMA (self ):
@@ -133,18 +134,22 @@ def JSONSCHEMANAME(self):
133134 def JSONSCHEMA (self ):
134135 """dict : The schema of the JSON representation of the data of this object."""
135136 if not self ._JSONSCHEMA :
136- schema_filename = '{}.json' .format (self .JSONSCHEMANAME .lower ())
137- schema_path = os .path .join (os .path .dirname (__file__ ), 'schemas' , schema_filename )
138- with open (schema_path , 'r' ) as fp :
137+ schema_filename = "{}.json" .format (self .JSONSCHEMANAME .lower ())
138+ schema_path = os .path .join (
139+ os .path .dirname (__file__ ), "schemas" , schema_filename
140+ )
141+ with open (schema_path , "r" ) as fp :
139142 self ._JSONSCHEMA = json .load (fp )
140143 return self ._JSONSCHEMA
141144
142145 @property
143146 def jsondefinitions (self ):
144147 """dict : Reusable schema definitions."""
145148 if not self ._jsondefinitions :
146- schema_path = os .path .join (os .path .dirname (__file__ ), 'schemas' , 'compas.json' )
147- with open (schema_path , 'r' ) as fp :
149+ schema_path = os .path .join (
150+ os .path .dirname (__file__ ), "schemas" , "compas.json"
151+ )
152+ with open (schema_path , "r" ) as fp :
148153 self ._jsondefinitions = json .load (fp )
149154 return self ._jsondefinitions
150155
@@ -153,13 +158,16 @@ def jsonvalidator(self):
153158 """jsonschema.Draft7Validator : JSON schema validator for draft 7."""
154159 if not self ._jsonvalidator :
155160 from jsonschema import RefResolver , Draft7Validator
161+
156162 resolver = RefResolver .from_schema (self .jsondefinitions )
157163 self ._jsonvalidator = Draft7Validator (self .JSONSCHEMA , resolver = resolver )
158164 return self ._jsonvalidator
159165
160166 @property
161167 def dtype (self ):
162- return '{}/{}' .format ('.' .join (self .__class__ .__module__ .split ('.' )[:2 ]), self .__class__ .__name__ )
168+ return "{}/{}" .format (
169+ "." .join (self .__class__ .__module__ .split ("." )[:2 ]), self .__class__ .__name__
170+ )
163171
164172 @property
165173 def data (self ):
@@ -321,6 +329,7 @@ def validate_data(self):
321329
322330 """
323331 import schema
332+
324333 try :
325334 data = self .DATASCHEMA .validate (self .data )
326335 except schema .SchemaError as e :
@@ -342,6 +351,7 @@ def validate_json(self):
342351
343352 """
344353 import jsonschema
354+
345355 jsonstring = json .dumps (self .data , cls = DataEncoder )
346356 jsondata = json .loads (jsonstring , cls = DataDecoder )
347357 try :
@@ -350,3 +360,35 @@ def validate_json(self):
350360 print ("Validation against the JSON schema of this object failed." )
351361 raise e
352362 return jsonstring
363+
364+ def sha256 (self , as_string = False ):
365+ """Compute a hash of the data for comparison during version control using the sha256 algorithm.
366+
367+ Parameters
368+ ----------
369+ as_string : bool, optional
370+ If True, return the digest in hexadecimal format rather than as bytes.
371+
372+ Returns
373+ -------
374+ bytes | str
375+
376+ Examples
377+ --------
378+ >>> from compas.datastructures import Mesh
379+ >>> mesh = Mesh.from_obj(compas.get('faces.obj'))
380+ >>> v1 = mesh.sha256()
381+ >>> v2 = mesh.sha256()
382+ >>> mesh.vertex_attribute(mesh.vertex_sample(1)[0], 'z', 1)
383+ >>> v3 = mesh.sha256()
384+ >>> v1 == v2
385+ True
386+ >>> v2 == v3
387+ False
388+
389+ """
390+ h = hashlib .sha256 ()
391+ h .update (self .jsonstring .encode ())
392+ if as_string :
393+ return h .hexdigest ()
394+ return h .digest ()
0 commit comments