Skip to content

Commit 341a7b3

Browse files
committed
Reformat with isort & black
1 parent b1b811a commit 341a7b3

File tree

11 files changed

+892
-450
lines changed

11 files changed

+892
-450
lines changed

lchelper/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
from . import utils
12
from .codegen import *
23
from .common import *
34
from .crawler import *
45
from .logging import *
56
from .parser import *
6-
from . import utils

lchelper/codegen/base.py

+98-48
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"CodeGen",
1616
]
1717

18-
T = TypeVar('T')
18+
T = TypeVar("T")
1919
Signature = Union[ProblemSignature, InteractiveProblemSignature]
2020
Code = List[str]
2121

@@ -24,32 +24,34 @@ class CodeGen(abc.ABC):
2424
@property
2525
@abc.abstractmethod
2626
def language(self) -> str:
27-
r"""Name of the language to generate."""
27+
"""Name of the language to generate."""
2828
raise NotImplementedError
2929

3030
@property
3131
def extra_files(self) -> Dict[str, str]:
32-
r"""Extra files that will be written verbatim under the project folder. The returned dictionary maps file names
33-
to raw code.
32+
"""
33+
Extra files that will be written verbatim under the project folder. The returned
34+
dictionary maps file names to raw code.
3435
"""
3536
return {}
3637

3738
@property
3839
@abc.abstractmethod
3940
def code_extension(self) -> str:
40-
r"""The file extension for code files."""
41+
"""The file extension for code files."""
4142
raise NotImplementedError
4243

4344
@property
4445
@abc.abstractmethod
4546
def line_comment_symbol(self) -> str:
46-
r"""The symbol for starting a line comment."""
47+
"""The symbol for starting a line comment."""
4748
raise NotImplementedError
4849

4950
@property
5051
@abc.abstractmethod
5152
def template_code(self) -> str:
52-
r"""The template code for each problem. Should include section markers for:
53+
"""
54+
The template code for each problem. Should include section markers for:
5355
5456
- ``SOLUTION CLASS``: the section to insert the solution class.
5557
- ``SUBMIT``: the section to submit to LeetCode.
@@ -64,48 +66,68 @@ def template_code(self) -> str:
6466

6567
@property
6668
def user_template_code(self) -> str:
67-
r"""User-defined templates for convenience. These will be included in the submission."""
69+
"""
70+
User-defined templates for convenience. These will be included in the
71+
submission.
72+
"""
6873
return ""
6974

7075
@classmethod
7176
def write_and_backup(cls, path: str, contents: str) -> None:
72-
r"""Check if there is already a file at the given path, create a backup if there is, and then write contents to
73-
the file.
77+
"""
78+
Check if there is already a file at the given path, create a backup if there is,
79+
and then write contents to the file.
7480
"""
7581
if os.path.exists(path):
7682
with open(path, "r") as f:
7783
original_contents = f.read()
7884
if original_contents != contents:
7985
# Only create backup if contents differ.
8086
creation_time = os.path.getctime(path)
81-
timestamp = datetime.fromtimestamp(creation_time).strftime("%Y%m%d_%H%M%S")
87+
timestamp = datetime.fromtimestamp(creation_time).strftime(
88+
"%Y%m%d_%H%M%S"
89+
)
8290

8391
file_name, file_ext = os.path.splitext(path)
8492
dest_path = f"{file_name}_{timestamp}{file_ext}"
8593
shutil.move(path, dest_path)
86-
log(f"File '{path}' is modified, backup created at '{dest_path}'", "warning")
94+
log(
95+
f"File '{path}' is modified, backup created at '{dest_path}'",
96+
level="warning",
97+
)
8798
with open(path, "w") as f:
8899
f.write(contents)
89100

90-
def replace_section(self, code: Code, replacements: Dict[str, Code], *, ignore_errors: bool = False) -> Code:
91-
r"""Replace a section of template with actual code. Sections are often marked with line comments.
101+
def replace_section(
102+
self, code: Code, replacements: Dict[str, Code], *, ignore_errors: bool = False
103+
) -> Code:
104+
"""
105+
Replace a section of template with actual code. Sections are often marked with
106+
line comments.
92107
93108
:param code: The code as a list of strings, one per line.
94109
:param replacements: A dictionary mapping section names to replacement code.
95-
:param ignore_errors: A :exc:`ValueError` will be thrown for sections that are not found, unless this argument
96-
is ``True``. Defaults to ``False``.
110+
:param ignore_errors: A :exc:`ValueError` will be thrown for sections that are
111+
not found, unless this argument is ``True``. Defaults to
112+
``False``.
97113
:return: The updated code.
98114
"""
99115
for section_name, section_code in replacements.items():
100116
try:
101-
start_line = code.index(f"{self.line_comment_symbol} BEGIN {section_name}")
102-
end_line = code.index(f"{self.line_comment_symbol} END {section_name}", start_line + 1)
117+
start_line = code.index(
118+
f"{self.line_comment_symbol} BEGIN {section_name}"
119+
)
120+
end_line = code.index(
121+
f"{self.line_comment_symbol} END {section_name}", start_line + 1
122+
)
103123
# exclude the line comments
104-
code = code[:start_line] + section_code + code[(end_line + 1):]
124+
code = code[:start_line] + section_code + code[(end_line + 1) :]
105125
except ValueError:
106126
if not ignore_errors:
107-
raise ValueError(f"Section '{section_name}' not found in template code for {self.language} "
108-
f"({self.__class__!r})")
127+
raise ValueError(
128+
f"Section {section_name!r} not found in template code for"
129+
f" {self.language} ({self.__class__!r})"
130+
)
109131
return code
110132

111133
@classmethod
@@ -118,23 +140,30 @@ def list_join(cls, list_xs: Iterable[List[T]], sep: List[T]) -> List[T]:
118140
return ret
119141

120142
@abc.abstractmethod
121-
def generate_code(self, problem: Problem, signature: Signature) -> Tuple[Code, Code]:
122-
r"""Generate code given the signature. Code consists of two parts:
143+
def generate_code(
144+
self, problem: Problem, signature: Signature
145+
) -> Tuple[Code, Code]:
146+
"""
147+
Generate code given the signature. Code consists of two parts:
123148
124149
- Code for the solution class. This is basically the template as-is.
125-
- Code for testing the solution. This includes test functions for each example, and also the main function where
126-
the test functions are called and results are compared.
150+
- Code for testing the solution. This includes test functions for each example,
151+
and also the main function where the test functions are called and results are
152+
compared.
127153
128154
:param problem: The crawled raw description of the problem.
129155
:param signature: The parsed signature of the problem.
130-
:return: A tuple of two lists of strings, corresponding to code for the solution class, and code for testing.
156+
:return: A tuple of two lists of strings, corresponding to code for the solution
157+
class, and code for testing.
131158
"""
132159
raise NotImplementedError
133160

134-
def generate_additional_files(self, project_path: str, problems: List[Problem],
135-
signatures: List[Signature]) -> None:
136-
r"""Generate additional files that the project requires, besides those in :attr:`EXTRA_FILES` that are written
137-
verbatim.
161+
def generate_additional_files(
162+
self, project_path: str, problems: List[Problem], signatures: List[Signature]
163+
) -> None:
164+
"""
165+
Generate additional files that the project requires, besides those in
166+
:attr:`EXTRA_FILES` that are written verbatim.
138167
139168
:param project_path: Path to the project folder.
140169
:param problems: List of problem descriptions to generate code for.
@@ -143,7 +172,9 @@ def generate_additional_files(self, project_path: str, problems: List[Problem],
143172
pass
144173

145174
def get_problem_file_name(self, idx: int, problem: Problem) -> str:
146-
r"""Generate the code file name for a problem. By default, names are uppercase letters starting from "A".
175+
"""
176+
Generate the code file name for a problem. By default, names are uppercase
177+
letters starting from "A".
147178
148179
:param idx: Zero-based index of the problem.
149180
:param problem: The description of the problem.
@@ -152,28 +183,35 @@ def get_problem_file_name(self, idx: int, problem: Problem) -> str:
152183
return f"{chr(ord('A') + idx)}{self.code_extension}"
153184

154185
def format_statement(self, problem: Problem) -> List[str]:
155-
r"""Convert the problem statement into code (as comments).
186+
"""
187+
Convert the problem statement into code (as comments).
156188
157189
:param problem: The problem description.
158190
:return: Code for the problem statement.
159191
"""
160192
statement = []
161193
max_length = 80 - (len(self.line_comment_symbol) + 1)
162194
for line in problem.statement.strip().split("\n"):
163-
comments = [f"{self.line_comment_symbol} {line[i:(i + max_length)]}"
164-
for i in range(0, len(line), max_length)]
195+
comments = [
196+
f"{self.line_comment_symbol} {line[i:(i + max_length)]}"
197+
for i in range(0, len(line), max_length)
198+
]
165199
statement.extend(comments)
166200
return statement
167201

168-
def create_project(self, project_path: str, problems: List[Problem], site: str, debug: bool = False) -> None:
169-
r"""Create the folder for the project and generate code and supporting files.
202+
def create_project(
203+
self, project_path: str, problems: List[Problem], site: str, debug: bool = False
204+
) -> None:
205+
"""
206+
Create the folder for the project and generate code and supporting files.
170207
171208
:param project_path: Path to the project folder.
172209
:param problems: List of problem descriptions to generate code for.
173-
:param site: The LeetCode site where problems are crawled. Different sites may have slightly different syntax
174-
(or language-dependent markings).
175-
:param debug: If ``True``, exceptions will not be caught. This is probably only useful when the ``--debug``
176-
flag is set, in which case the Python debugger is hooked to handle exceptions.
210+
:param site: The LeetCode site where problems are crawled. Different sites may
211+
have slightly different syntax (or language-dependent markings).
212+
:param debug: If ``True``, exceptions will not be caught. This is probably only
213+
useful when the ``--debug`` flag is set, in which case the Python
214+
debugger is hooked to handle exceptions.
177215
"""
178216
if not os.path.exists(project_path):
179217
os.makedirs(project_path)
@@ -186,21 +224,33 @@ def create_project(self, project_path: str, problems: List[Problem], site: str,
186224
try:
187225
problem_signature = parse_problem(problem, site)
188226
signatures.append(problem_signature)
189-
solution_code, test_code = self.generate_code(problem, problem_signature)
190-
problem_code = self.replace_section(template, {
191-
"SOLUTION CLASS": solution_code,
192-
"TEST": test_code,
193-
})
227+
solution_code, test_code = self.generate_code(
228+
problem, problem_signature
229+
)
230+
problem_code = self.replace_section(
231+
template,
232+
{
233+
"SOLUTION CLASS": solution_code,
234+
"TEST": test_code,
235+
},
236+
)
194237
if problem.statement != "":
195238
statement = self.format_statement(problem)
196-
problem_code = self.replace_section(problem_code, {"STATEMENT": statement}, ignore_errors=True)
197-
code_path = os.path.join(project_path, self.get_problem_file_name(idx, problem))
239+
problem_code = self.replace_section(
240+
problem_code, {"STATEMENT": statement}, ignore_errors=True
241+
)
242+
code_path = os.path.join(
243+
project_path, self.get_problem_file_name(idx, problem)
244+
)
198245
self.write_and_backup(code_path, "\n".join(problem_code) + "\n")
199246
except Exception:
200247
if debug:
201248
raise
202249
traceback.print_exc()
203-
log(f"Exception occurred while processing \"{problem.name}\"", "error")
250+
log(
251+
f"Exception occurred while processing {problem.name!r}",
252+
level="error",
253+
)
204254

205255
for tmpl_name, tmpl_code in self.extra_files.items():
206256
with open(os.path.join(project_path, tmpl_name), "w") as f:

0 commit comments

Comments
 (0)