You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
3.2 KiB

# Script which modifies source code away from the deprecated "flask.ext"
# format. Does not yet fully support imports in the style:
#
# "import flask.ext.foo"
#
# these are converted to "import flask_foo" in the
# main import statement, but does not handle function calls in the source.
#
# Run in the terminal by typing: `python flaskext_migrate.py <source_file.py>`
#
# Author: Keyan Pishdadian 2015
from redbaron import RedBaron
import sys
def read_source(input_file):
"""Parses the input_file into a RedBaron FST."""
with open(input_file, "r") as source_code:
red = RedBaron(source_code.read())
return red
def write_source(red, input_file):
"""Overwrites the input_file once the FST has been modified."""
with open(input_file, "w") as source_code:
source_code.write(red.dumps())
def fix_imports(red):
"""Wrapper which fixes "from" style imports and then "import" style."""
red = fix_standard_imports(red)
red = fix_from_imports(red)
return red
def fix_from_imports(red):
"""
Converts "from" style imports to not use "flask.ext".
Handles:
Case 1: from flask.ext.foo import bam --> from flask_foo import bam
Case 2: from flask.ext import foo --> import flask_foo as foo
"""
from_imports = red.find_all("FromImport")
for x, node in enumerate(from_imports):
values = node.value
if (values[0].value == 'flask') and (values[1].value == 'ext'):
# Case 1
if len(node.value) == 3:
package = values[2].value
modules = node.modules()
if len(modules) > 1:
r = "{}," * len(modules)
node.replace("from flask_%s import %s"
% (package, r.format(*modules)[:-1]))
else:
name = node.names()[0]
node.replace("from flask_%s import %s as %s"
% (package, modules.pop(), name))
# Case 2
else:
module = node.modules()[0]
node.replace("import flask_%s as %s"
% (module, module))
return red
def fix_standard_imports(red):
"""
Handles import modification in the form:
import flask.ext.foo" --> import flask_foo
Does not modify function calls elsewhere in the source outside of the
original import statement.
"""
imports = red.find_all("ImportNode")
for x, node in enumerate(imports):
try:
if (node.value[0].value == 'flask' and
node.value[1].value == 'ext'):
package = node.value[2].value
name = node.names()[0]
imports[x].replace("import flask_%s as %s" % (package, name))
except IndexError:
pass
return red
def fix(ast):
"""Wrapper which allows for testing when not running from shell"""
return fix_imports(ast).dumps()
if __name__ == "__main__":
if len(sys.argv) < 2:
sys.exit("No filename was included, please try again.")
input_file = sys.argv[1]
ast = read_source(input_file)
ast = fix_imports(ast)
write_source(ast, input_file)