1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
"""Utilities for cog."""
import contextlib
import functools
import hashlib
import os
import sys
# Support FIPS mode. We don't use MD5 for security.
md5 = functools.partial(hashlib.md5, usedforsecurity=False)
class Redirectable:
"""An object with its own stdout and stderr files."""
def __init__(self):
self.stdout = sys.stdout
self.stderr = sys.stderr
def set_output(self, stdout=None, stderr=None):
"""Assign new files for standard out and/or standard error."""
if stdout:
self.stdout = stdout
if stderr:
self.stderr = stderr
def prout(self, s, end="\n"):
print(s, file=self.stdout, end=end)
def prerr(self, s, end="\n"):
print(s, file=self.stderr, end=end)
class NumberedFileReader:
"""A decorator for files that counts the readline()'s called."""
def __init__(self, f):
self.f = f
self.n = 0
def readline(self):
line = self.f.readline()
if line:
self.n += 1
return line
def linenumber(self):
return self.n
@contextlib.contextmanager
def change_dir(new_dir):
"""Change directory, and then change back.
Use as a context manager, it will return to the original
directory at the end of the block.
"""
old_dir = os.getcwd()
os.chdir(str(new_dir))
try:
yield
finally:
os.chdir(old_dir)
|