|
|
|
# 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 in range(len(from_imports)):
|
|
|
|
values = from_imports[x].value
|
|
|
|
if (values[0].value == 'flask') and (values[1].value == 'ext'):
|
|
|
|
# Case 1
|
|
|
|
if len(from_imports[x].value) == 3:
|
|
|
|
package = values[2].value
|
|
|
|
modules = from_imports[x].modules()
|
|
|
|
r = "{}," * len(modules)
|
|
|
|
from_imports[x].replace("from flask_%s import %s"
|
|
|
|
% (package, r.format(*modules)[:-1]))
|
|
|
|
# Case 2
|
|
|
|
else:
|
|
|
|
module = from_imports[x].modules()[0]
|
|
|
|
from_imports[x].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 in range(len(imports)):
|
|
|
|
values = imports[x].value
|
|
|
|
try:
|
|
|
|
if (values[x].value[0].value == 'flask' and
|
|
|
|
values[x].value[1].value == 'ext'):
|
|
|
|
package = values[x].value[2].value
|
|
|
|
imports[x].replace("import flask_%s" % package)
|
|
|
|
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__":
|
|
|
|
input_file = sys.argv[1]
|
|
|
|
fix(input_file)
|