Skip to content

Instantly share code, notes, and snippets.

@charmander
Last active May 19, 2018 11:50
Show Gist options
  • Save charmander/243039826551f36f13bd5b6a80b8b4d2 to your computer and use it in GitHub Desktop.
Save charmander/243039826551f36f13bd5b6a80b8b4d2 to your computer and use it in GitHub Desktop.
today’s hacked-together but task-appropriate refactoring aid
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import ast
import codeop
def try_get_context(source_lines, lineno, limit=10):
# does not try very hard
line = source_lines[node.lineno - 1]
extend = 0
source = 'def _():\n ' + line.lstrip()
while extend < limit:
try:
code = codeop.compile_command(source + '\n\n') is not None
except (SyntaxError, OverflowError, ValueError):
return 0, False
source += '\n' + source_lines[node.lineno + extend]
extend += 1
if code:
return extend, False
return limit, True
if __name__ == '__main__':
import io
import sys
for path in sys.argv[1:]:
with io.open(path, "rb") as f:
source = f.read()
module = ast.parse(source, filename=path)
for node in ast.walk(module):
if isinstance(node, ast.Call):
if isinstance(node.func, ast.Name):
match = node.func.id == 'webpage'
elif isinstance(node.func, ast.Attribute):
match = node.func.attr == 'webpage'
else:
raise Exception("Unexpected")
if match:
if (
len(node.args) >= 4 or
'options' in (kw.arg for kw in node.keywords) or
node.starargs is not None or
node.kwargs is not None
):
source_lines = source.decode('utf-8').splitlines()
line = source_lines[node.lineno - 1]
location = '%s:%i:%i' % (path, node.lineno, node.col_offset)
align = ' ' * (len(location) - 2)
print '%s %s' % (location, line)
extend, continues = try_get_context(source_lines, node.lineno)
for i in range(extend):
print '%s | %s' % (align, source_lines[node.lineno + i])
if continues:
print align + ' ...'
print
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment