-
Notifications
You must be signed in to change notification settings - Fork 235
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
use string buffer to store generated code #211
Changes from 4 commits
2c2b174
0fb2771
24d7c9f
955321b
c90e3ac
ffd5f0a
fe069e7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -1,4 +1,6 @@ | ||||
from io import StringIO | ||||
from string import Template | ||||
from weakref import finalize | ||||
|
||||
|
||||
class CodeTemplate: | ||||
|
@@ -29,11 +31,38 @@ class BaseCodeGenerator: | |||
|
||||
def __init__(self, indent=4): | ||||
self._indent = indent | ||||
self._code_buf = None | ||||
self.reset_state() | ||||
|
||||
def reset_state(self): | ||||
self._current_indent = 0 | ||||
self.code = "" | ||||
self._finalize_buffer() | ||||
self._code_buf = StringIO() | ||||
self._code = None | ||||
self._finalizer = finalize(self, self._finalize_buffer) | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice, yet another Python TIL for me! |
||||
|
||||
def _finalize_buffer(self): | ||||
if self._code_buf is not None and not self._code_buf.closed: | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Minor] |
||||
self._code_buf.close() | ||||
|
||||
def _write_to_code_buffer(self, text, prepend=False): | ||||
if self._code_buf.closed: | ||||
raise BufferError( | ||||
"Cannot modify code after getting generated code and " | ||||
"closing the underlying buffer!\n" | ||||
"Call reset_state() to allocate new buffer.") | ||||
if prepend: | ||||
self._code_buf.seek(0) | ||||
old_content = self._code_buf.read() | ||||
self._code_buf.seek(0) | ||||
text += old_content | ||||
self._code_buf.write(text) | ||||
|
||||
def finalize_and_get_generated_code(self): | ||||
if not self._code_buf.closed: | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shall we do the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nope. We call |
||||
self._code = self._code_buf.getvalue() | ||||
self._finalize_buffer() | ||||
return self._code if self._code is not None else "" | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Minor] There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I always prefer to check for
|
||||
|
||||
def increase_indent(self): | ||||
self._current_indent += self._indent | ||||
|
@@ -48,22 +77,24 @@ def decrease_indent(self): | |||
def add_code_line(self, line): | ||||
if not line: | ||||
return | ||||
indent = " " * self._current_indent | ||||
self.code += indent + line + "\n" | ||||
self.add_code_lines([line.strip()]) | ||||
|
||||
def add_code_lines(self, lines): | ||||
if isinstance(lines, str): | ||||
lines = lines.strip().split("\n") | ||||
indent = " " * self._current_indent | ||||
self.code += indent + "\n{}".format(indent).join(lines) + "\n" | ||||
self._write_to_code_buffer( | ||||
indent + "\n{}".format(indent).join(lines) + "\n") | ||||
|
||||
def prepend_code_line(self, line): | ||||
self.code = line + "\n" + self.code | ||||
if not line: | ||||
return | ||||
self.prepend_code_lines([line.strip()]) | ||||
|
||||
def prepend_code_lines(self, lines): | ||||
if isinstance(lines, str): | ||||
lines = lines.strip().split("\n") | ||||
self.code = "\n".join(lines) + "\n" + self.code | ||||
self._write_to_code_buffer("\n".join(lines) + "\n", prepend=True) | ||||
|
||||
# Following methods simply compute expressions using templates without | ||||
# changing result. | ||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://docs.python.org/3/library/weakref.html#comparing-finalizers-with-del-methods