Coverage for cogapp/utils.py: 76.74%

37 statements  

« prev     ^ index     » next       coverage.py v7.9.2, created at 2025-07-03 06:03 -0400

1"""Utilities for cog.""" 

2 

3import contextlib 

4import functools 

5import hashlib 

6import os 

7import sys 

8 

9 

10# Support FIPS mode. We don't use MD5 for security. 

11md5 = functools.partial(hashlib.md5, usedforsecurity=False) 

12 

13 

14class Redirectable: 

15 """An object with its own stdout and stderr files.""" 

16 

17 def __init__(self): 

18 self.stdout = sys.stdout 

19 self.stderr = sys.stderr 

20 

21 def set_output(self, stdout=None, stderr=None): 

22 """Assign new files for standard out and/or standard error.""" 

23 if stdout: 23 ↛ 25line 23 didn't jump to line 25 because the condition on line 23 was always true

24 self.stdout = stdout 

25 if stderr: 25 ↛ 26line 25 didn't jump to line 26 because the condition on line 25 was never true

26 self.stderr = stderr 

27 

28 def prout(self, s, end="\n"): 

29 print(s, file=self.stdout, end=end) 

30 

31 def prerr(self, s, end="\n"): 

32 print(s, file=self.stderr, end=end) 

33 

34 

35class NumberedFileReader: 

36 """A decorator for files that counts the readline()'s called.""" 

37 

38 def __init__(self, f): 

39 self.f = f 

40 self.n = 0 

41 

42 def readline(self): 

43 line = self.f.readline() 

44 if line: 

45 self.n += 1 

46 return line 

47 

48 def linenumber(self): 

49 return self.n 

50 

51 

52@contextlib.contextmanager 

53def change_dir(new_dir): 

54 """Change directory, and then change back. 

55 

56 Use as a context manager, it will return to the original 

57 directory at the end of the block. 

58 

59 """ 

60 old_dir = os.getcwd() 

61 os.chdir(str(new_dir)) 

62 try: 

63 yield 

64 finally: 

65 os.chdir(old_dir)