16
16
from .utility import normal_relative , ensure_parent
17
17
18
18
19
+ def hexdigest (s : str ) -> str :
20
+ """Creates a MD5 hash digest from a string. Before hashing, the string has
21
+ linefeed `\\ r` characters and trailing newlines removed, and the string
22
+ is encoded as UTF-8."""
23
+ content = s .replace ("\r " , "" ).rstrip ("\n " ).encode ()
24
+ return hashlib .sha256 (content ).hexdigest ()
25
+
26
+
19
27
@dataclass
20
28
class FileStat :
21
29
path : Path
@@ -26,10 +34,10 @@ class FileStat:
26
34
@staticmethod
27
35
def from_path (path : Path , deps : Optional [list [Path ]]):
28
36
stat = os .stat (path )
29
- with open (path , "rb " ) as f :
30
- hash = hashlib . sha256 (f .read ())
37
+ with open (path , "r " ) as f :
38
+ digest = hexdigest (f .read ())
31
39
return FileStat (
32
- path , deps , datetime .fromtimestamp (stat .st_mtime ), hash . hexdigest ()
40
+ path , deps , datetime .fromtimestamp (stat .st_mtime ), digest
33
41
)
34
42
35
43
def __lt__ (self , other : FileStat ) -> bool :
@@ -136,9 +144,7 @@ def files(self) -> Iterable[Path]:
136
144
return self ._files .keys ()
137
145
138
146
def check (self , path : Path , content : str ) -> bool :
139
- return (
140
- hashlib .sha256 (content .encode ()).hexdigest () == self ._files [path ].hexdigest
141
- )
147
+ return hexdigest (content ) == self ._files [path ].hexdigest
142
148
143
149
@staticmethod
144
150
def initialize () -> FileDB :
0 commit comments