Coverage for cogapp/utils.py: 76.74%
37 statements
« prev ^ index » next coverage.py v7.5.0a1.dev1, created at 2024-04-15 15:50 -0400
« prev ^ index » next coverage.py v7.5.0a1.dev1, created at 2024-04-15 15:50 -0400
1""" Utilities for cog.
2"""
4import contextlib
5import functools
6import hashlib
7import os
8import sys
11# Support FIPS mode where possible (Python >= 3.9). We don't use MD5 for security.
12md5 = (
13 functools.partial(hashlib.md5, usedforsecurity=False)
14 if sys.version_info >= (3, 9)
15 else hashlib.md5
16)
19class Redirectable:
20 """ An object with its own stdout and stderr files.
21 """
22 def __init__(self):
23 self.stdout = sys.stdout
24 self.stderr = sys.stderr
26 def setOutput(self, stdout=None, stderr=None):
27 """ Assign new files for standard out and/or standard error.
28 """
29 if stdout: 29 ↛ 31line 29 didn't jump to line 31, because the condition on line 29 was never false
30 self.stdout = stdout
31 if stderr: 31 ↛ 32line 31 didn't jump to line 32, because the condition on line 31 was never true
32 self.stderr = stderr
34 def prout(self, s, end="\n"):
35 print(s, file=self.stdout, end=end)
37 def prerr(self, s, end="\n"):
38 print(s, file=self.stderr, end=end)
41class NumberedFileReader:
42 """ A decorator for files that counts the readline()'s called.
43 """
44 def __init__(self, f):
45 self.f = f
46 self.n = 0
48 def readline(self):
49 l = self.f.readline()
50 if l:
51 self.n += 1
52 return l
54 def linenumber(self):
55 return self.n
58@contextlib.contextmanager
59def change_dir(new_dir):
60 """Change directory, and then change back.
62 Use as a context manager, it will return to the original
63 directory at the end of the block.
65 """
66 old_dir = os.getcwd()
67 os.chdir(str(new_dir))
68 try:
69 yield
70 finally:
71 os.chdir(old_dir)