-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFakeFile.py
More file actions
109 lines (87 loc) · 3.14 KB
/
FakeFile.py
File metadata and controls
109 lines (87 loc) · 3.14 KB
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
'''
This program simulates file operations using a FakeFile class and overriding the
reserved method open(). It is intended to be used on platforms where disk-
access is prohibited.
'''
from io import UnsupportedOperation
from collections import defaultdict
'''Overrides open() to return modified FakeFile object
PRECONDITION:
EXISTS global variable:
CONTENT (defaultdict{str:str}) - mapping from FakeFile name to content
'''
def open(file_name, file_mode="r"):
if file_mode == "r" and file_name not in CONTENT.keys():
raise FileNotFoundError("Errno 2] No such file or directory: '" + file_name + "'")
return FakeFile(file_name, CONTENT[file_name], file_mode)
''' FakeFile class
Stores "file" as str
'''
class FakeFile:
def __init__(self, file, content, file_mode):
self.file_name = file
self.content = "" if file_mode == "w" else content
self.file_mode = file_mode
self.file_pointer = 0
self.closed = False
def __iter__(self):
return FakeFileIterator(self)
def validate(func):
def wrapper(self, *argv):
if self.closed:
raise ValueError("I/O operation on closed file.")
return func(self, *argv)
return wrapper
@validate
def readline(self):
if "r" not in self.file_mode:
raise UnsupportedOperation("not readable")
try:
line = self.content[self.file_pointer:].splitlines(keepends=True)[0]
self.file_pointer += len(line)
except IndexError:
line = ""
return line
@validate
def readlines(self):
if "r" not in self.file_mode:
raise UnsupportedOperation("not readable")
lines = self.content[self.file_pointer:].splitlines(keepends=True)
self.file_pointer += len(self.content)
return lines
@validate
def write(self, text):
if not ("w" in self.file_mode or "a" in self.file_mode):
raise UnsupportedOperation("not writable")
self.content += text
self.file_pointer += len(text)
@validate
def writelines(self, texts):
if not ("w" in self.file_mode or "a" in self.file_mode):
raise UnsupportedOperation("not writable")
text = ''.join(texts)
self.content += text
self.file_pointer += len(text)
def close(self):
self.closed = True
def name(self):
return self.file_name
def mode(self):
return self.file_mode
''' FakeFile iterator class
Enables looping over FakeFile objects
'''
class FakeFileIterator:
def __init__(self, fakefile):
self.fakefile = fakefile
def __next__(self):
if self.fakefile.file_pointer < len(self.fakefile.content):
end = self.fakefile.content.find("\n", self.fakefile.file_pointer)
if end == -1:
nxt = self.fakefile.content[self.fakefile.file_pointer:]
else:
nxt = self.fakefile.content[self.fakefile.file_pointer : end + 1]
self.fakefile.file_pointer += len(nxt)
return nxt
raise StopIteration
CONTENT = defaultdict(lambda: "")