@@ -80,9 +80,19 @@ async def read_text_file(file_path: str) -> str:
8080 return safe_decode (await f .read ())
8181
8282 @staticmethod
83- def compute_file_hash (content : str ) -> str :
84- """SHA-256 hex digest of UTF-8 file content (not a Git blob SHA)."""
85- return hashlib .sha256 (content .encode ("utf-8" )).hexdigest ()
83+ async def compute_file_hash_from_path (
84+ file_path : str , * , retain_content : bool = False
85+ ) -> tuple [bytes | None , str ]:
86+ """SHA-256 of raw file bytes. Set retain_content to decode and parse under the size limit."""
87+ hasher = hashlib .sha256 ()
88+ chunks : list [bytes ] = []
89+ async with aiofiles .open (file_path , "rb" ) as affiliation_file :
90+ while file_chunk := await affiliation_file .read (1024 * 1024 ):
91+ hasher .update (file_chunk )
92+ if retain_content :
93+ chunks .append (file_chunk )
94+ file_bytes = b"" .join (chunks ) if retain_content else None
95+ return file_bytes , hasher .hexdigest ()
8696
8797 @classmethod
8898 def is_text_file_path (cls , relative_path : str ) -> bool :
@@ -972,11 +982,7 @@ async def process_affiliations(
972982 parse_cost = 0.0
973983 else :
974984 # First hit: hash it so the registry can mark it as unusable.
975- hasher = hashlib .sha256 ()
976- async with aiofiles .open (file_path_on_disk , "rb" ) as affiliation_file :
977- while file_chunk := await affiliation_file .read (1024 * 1024 ):
978- hasher .update (file_chunk )
979- file_hash = hasher .hexdigest ()
985+ _ , file_hash = await self .compute_file_hash_from_path (file_path_on_disk )
980986 latest_file_hash = file_hash
981987 raise AffiliationAnalysisError (
982988 retain_file_hash = True ,
@@ -986,8 +992,10 @@ async def process_affiliations(
986992 ),
987993 )
988994 else :
989- content = await self .read_text_file (file_path_on_disk )
990- file_hash = self .compute_file_hash (content )
995+ file_bytes , file_hash = await self .compute_file_hash_from_path (
996+ file_path_on_disk , retain_content = True
997+ )
998+ content = safe_decode (file_bytes )
991999 latest_file_hash = file_hash
9921000 affiliations , parse_cost = await self .resolve_snapshot (
9931001 registry ,
0 commit comments