-
Notifications
You must be signed in to change notification settings - Fork 2
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
formatting(docstrings): fix common errors #5
Closed
Closed
Changes from all commits
Commits
Show all changes
91 commits
Select commit
Hold shift + click to select a range
f8837b2
initial commit
NripeshN f49f98c
small fix
NripeshN c7f30a5
ignore FunctionOrderingFormatter for now
NripeshN ad5d9b8
example section
NripeshN a3aba96
print docstring
NripeshN df24707
print test
NripeshN c12980b
revert print statements
NripeshN 05c73cd
extract docstrings fix
NripeshN 9858545
small fix
NripeshN 3403a29
small fix
NripeshN e01eca7
small fix
NripeshN bfc11a7
small fix
NripeshN 15635eb
small fix
NripeshN 009fa64
big change
NripeshN be7fc1a
big fix
NripeshN 647f6a7
Revert "big fix"
NripeshN 112ed4a
small fix
NripeshN bb185b0
big changes
NripeshN b66bb44
small fix
NripeshN 140d9c3
import fix
NripeshN beb2a4d
small changes
NripeshN cac6277
big changes
NripeshN ba5d03d
small fix
NripeshN 14593aa
small fix
NripeshN a322eb0
small fix
NripeshN 4c5dd3d
indentation fix
NripeshN 0d2e1a3
redundant underline fix
NripeshN 8c48996
small fix
NripeshN d38f2a4
small fix
NripeshN d1ad169
indentation issue
NripeshN b0d961a
small fix
NripeshN 13e85ea
small fix
NripeshN 05cec2d
uncomment functional ordering formatting
NripeshN 0a51a24
Update docs_formatter.py
he11owthere 1757b15
Update docs_formatter.py
he11owthere 27d479e
Update docs_formatter.py
he11owthere 9b7f3cb
Update docs_formatter.py
he11owthere bffe3ff
Update docs_formatter.py
he11owthere 1588d06
original
he11owthere f0f4d77
Update docs_formatter.py
he11owthere f4fec9f
small fix
he11owthere a4fea43
Update docs_formatter.py
he11owthere 90ec9b8
testing
he11owthere 86e2ef8
testing formatter
he11owthere 5c58a21
Update docs_formatter.py
he11owthere 56b8f3c
Update docs_formatter.py
he11owthere e50c8a8
Update docs_formatter.py
he11owthere bb654eb
Update docs_formatter.py
he11owthere 737d15e
Update docs_formatter.py
he11owthere 2e05c73
Update docs_formatter.py
he11owthere 263b162
Update docs_formatter.py
he11owthere 5044d97
tokenization approach
he11owthere 05e173d
Update docs_formatter.py
he11owthere 5b99d49
Update docs_formatter.py
he11owthere 820bb96
Update docs_formatter.py
he11owthere 8be213c
Update docs_formatter.py
he11owthere 6f3b35e
Update docs_formatter.py
he11owthere 5fc13a6
Update docs_formatter.py
he11owthere 70a84c1
Update docs_formatter.py
he11owthere c65ef35
Update docs_formatter.py
he11owthere 4984ee2
Update docs_formatter.py
he11owthere 4006d33
Update docs_formatter.py
he11owthere 069bdbd
Update docs_formatter.py
he11owthere 2a707fb
Update docs_formatter.py
he11owthere 25bed81
Update docs_formatter.py
he11owthere e66555a
append "..."
he11owthere 532f1c8
Update docs_formatter.py
he11owthere 0f69d5b
Update docs_formatter.py
he11owthere 7027ec0
Update docs_formatter.py
he11owthere 219dc38
Update docs_formatter.py
he11owthere 8a28533
Update docs_formatter.py
he11owthere 38f1ffc
Update docs_formatter.py
he11owthere a5a6acd
Update docs_formatter.py
he11owthere e2c659b
Update docs_formatter.py
he11owthere 168ba13
Update docs_formatter.py
he11owthere dfe0243
small fix
he11owthere c211afd
Update docs_formatter.py
he11owthere 002f70b
Update docs_formatter.py
he11owthere 1f582a5
Update docs_formatter.py
he11owthere ff10e0e
Update docs_formatter.py
he11owthere 0f98a43
Update docs_formatter.py
he11owthere ce0b255
small fix
he11owthere 48ed776
Update docs_formatter.py
he11owthere a68e93b
Update docs_formatter.py
he11owthere 33cd752
Update docs_formatter.py
he11owthere 60cd1c8
section name checker
he11owthere 287b257
Update docs_formatter.py
he11owthere 306b148
small test
he11owthere 8ecec4c
Update docs_formatter.py
he11owthere a81dda1
Update docs_formatter.py
he11owthere da35495
working code
he11owthere File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import tokenize | ||
from io import BytesIO | ||
import re | ||
import ast | ||
|
||
from ivy_lint.formatters import BaseFormatter, BaseDocstringFormatter | ||
|
||
class DocstringFormatter(BaseDocstringFormatter): | ||
def validate_section_name(self, section_name, VALID_SECTION_NAMES): | ||
if section_name not in VALID_SECTION_NAMES: | ||
print(f"Invalid section name: {section_name}. Valid section names are {VALID_SECTION_NAMES}") | ||
return False | ||
return True | ||
|
||
def format_docstring(self, doc): | ||
"""Formats a single docstring.""" | ||
# Rename "Functional Examples" to "Examples" and format it without the extra newline | ||
doc = re.sub(r'(\s*)Functional Examples\n\1-*\n?', r'\1Examples\n\1--------\n', doc) | ||
|
||
# Ensure newline and correct indentation after "Examples" when it's already there | ||
doc = re.sub(r'(\s*)Examples\n\1--------\s*\n+([^\n])', r'\1Examples\n\1--------\n\2', doc) | ||
|
||
VALID_SECTION_NAMES = ["Args", "Arguments", "Attention", "Attributes", "Caution", "Danger", "Error", "Example", "Examples", "Hint", "Important", | ||
"Keyword Args", "Keyword Arguments", "Methods", "Note", "Notes", "Other Parameters", "Parameters", "Return", "Returns", | ||
"Raise", "Raises", "References", "See Also", "Tip", "Todo", "Warning", "Warnings", "Warn", "Warns", "Yield", "Yields"] | ||
|
||
# Identify code blocks | ||
lines = doc.split('\n') | ||
is_codeblock = False | ||
codeblock_start_lines = set() # This will store indices of lines which start a code block | ||
lines_to_modify = set() # This will store the indices of indented lines not containing "..." | ||
incorrect_sections = set() # This will store the indices of all the incorrect sections | ||
prev_line = "" | ||
is_codeblock_cont = False | ||
lb = 0 | ||
rb = 0 | ||
|
||
for idx, line in enumerate(lines): | ||
stripped_line = line.strip() | ||
|
||
if stripped_line.startswith('-') and stripped_line.endswith('-'): | ||
section_title = prev_line | ||
if not self.validate_section_name(section_title, VALID_SECTION_NAMES): | ||
incorrect_sections.add(idx) | ||
|
||
if not is_codeblock and stripped_line.startswith('>>>'): | ||
is_codeblock = True | ||
codeblock_start_lines.add(idx) | ||
elif is_codeblock and not is_codeblock_cont and (not stripped_line or (not stripped_line.startswith(('>>>', '...')))): | ||
is_codeblock = False | ||
|
||
if is_codeblock: | ||
if stripped_line.startswith(('>>>')): | ||
lb = rb = 0 | ||
lb += line.count('(') | ||
rb += line.count(')') | ||
if rb >= lb: | ||
rb = 0 | ||
lb = 0 | ||
is_codeblock_cont = False | ||
else: | ||
lb = lb - rb | ||
rb = 0 | ||
is_codeblock_cont = True | ||
if not stripped_line.startswith(('>>>', '...')): | ||
lines_to_modify.add(idx) | ||
prev_line = stripped_line | ||
|
||
# Add blank lines before code blocks | ||
formatted_lines = [] | ||
skip = True | ||
indentation = 0 | ||
for idx, line in enumerate(lines): | ||
if idx in codeblock_start_lines and formatted_lines and formatted_lines[-1].strip(): # Insert blank line before code block | ||
if not formatted_lines[-1].strip().startswith("-"): | ||
skip = False | ||
elif skip: | ||
skip = False | ||
formatted_lines.append(line) | ||
continue | ||
formatted_lines.append('') | ||
if idx in lines_to_modify: | ||
formatted_lines.append(line) | ||
indentation = len(formatted_lines[-2]) - len(formatted_lines[-2].lstrip()) | ||
formatted_lines[-1] = (indentation * ' ') + '...' + line[indentation:] | ||
continue | ||
if idx in incorrect_sections: #for future purposes | ||
pass | ||
formatted_lines.append(line) | ||
|
||
return '\n'.join(formatted_lines) | ||
|
||
def format_all_docstrings(self, python_code): | ||
"""Extracts all docstrings from the given Python code, formats them, and replaces the original ones with the formatted versions.""" | ||
replacements = {} | ||
# Tokenize the code | ||
tokens = tokenize.tokenize(BytesIO(python_code.encode('utf-8')).readline) | ||
for token in tokens: | ||
if token.type == tokenize.STRING: | ||
original_docstring = token.string | ||
modified_docstring = self.format_docstring(original_docstring) | ||
formatted_docstring = self._do_format_docstring(modified_docstring) | ||
if original_docstring != formatted_docstring: # Only add if there are changes | ||
replacements[original_docstring] = formatted_docstring | ||
|
||
for original, formatted in replacements.items(): | ||
python_code = python_code.replace(original, formatted, 1) # Only replace once to be safe | ||
|
||
return python_code | ||
|
||
def _format_file(self, filename: str) -> bool: | ||
with open(filename, 'r') as file: | ||
original_content = file.read() | ||
|
||
formatted_content = self.format_all_docstrings(original_content) | ||
|
||
if original_content != formatted_content: | ||
with open(filename, 'w') as file: | ||
file.write(formatted_content) | ||
return True | ||
|
||
return False |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
If I'm remembering correctly, we have the infrastructure for section manipulation already in place , you may use those.
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.
I'm still not convinced why didn't we use the base class instead and extended it?