| 220 | |
| 221 | def flake8(file_path: str) -> str: |
| 222 | """Run flake8 on a given file and return the output as a string""" |
| 223 | if Path(file_path).suffix != ".py": |
| 224 | return "" |
| 225 | cmd = "flake8 --isolated --select=F821,F822,F831,E111,E112,E113,E999,E902 {file_path}" |
| 226 | out = subprocess.run( |
| 227 | cmd.format(file_path=file_path), shell=True, check=False, capture_output=True |
| 228 | ) |
| 229 | # Use errors="replace" so non-UTF-8 bytes (e.g. GBK-encoded paths on Windows) don't crash decoding. |
| 230 | return out.stdout.decode("utf-8", errors="replace") |
| 231 | |
| 232 | |
| 233 | class Filemap: |
| 234 | def show_filemap(self, file_contents: str, encoding: str = "utf8"): |
| 235 | import warnings |
| 236 | |
| 237 | from tree_sitter_languages import get_language, get_parser |
| 238 | |
| 239 | warnings.simplefilter("ignore", category=FutureWarning) |
| 240 | |
| 241 | parser = get_parser("python") |
| 242 | language = get_language("python") |
| 243 | |
| 244 | tree = parser.parse(bytes(file_contents.encode(encoding, errors="replace"))) |
| 245 | |
| 246 | # See https://tree-sitter.github.io/tree-sitter/using-parsers#pattern-matching-with-queries. |
| 247 | query = language.query(""" |
| 248 | (function_definition |
| 249 | body: (_) @body) |
| 250 | """) |
| 251 | |
| 252 | # TODO: consider special casing docstrings such that they are not elided. This |
| 253 | # could be accomplished by checking whether `body.text.decode('utf8')` starts |
| 254 | # with `"""` or `'''`. |
| 255 | elide_line_ranges = [ |
| 256 | (node.start_point[0], node.end_point[0]) |
| 257 | for node, _ in query.captures(tree.root_node) |
| 258 | # Only elide if it's sufficiently long |
| 259 | if node.end_point[0] - node.start_point[0] >= 5 |
| 260 | ] |