Index: third_party/google-endpoints/libfuturize/fixes/fix_absolute_import.py |
diff --git a/third_party/google-endpoints/libfuturize/fixes/fix_absolute_import.py b/third_party/google-endpoints/libfuturize/fixes/fix_absolute_import.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ab6a7647cb90982722d9042585892cf46e9379ab |
--- /dev/null |
+++ b/third_party/google-endpoints/libfuturize/fixes/fix_absolute_import.py |
@@ -0,0 +1,92 @@ |
+""" |
+Fixer for import statements, with a __future__ import line. |
+ |
+Based on lib2to3/fixes/fix_import.py, but extended slightly so it also |
+supports Cython modules. |
+ |
+If spam is being imported from the local directory, this import: |
+ from spam import eggs |
+becomes: |
+ from __future__ import absolute_import |
+ from .spam import eggs |
+ |
+and this import: |
+ import spam |
+becomes: |
+ from __future__ import absolute_import |
+ from . import spam |
+""" |
+ |
+from os.path import dirname, join, exists, sep |
+from lib2to3.fixes.fix_import import FixImport |
+from lib2to3.fixer_util import FromImport, syms |
+from lib2to3.fixes.fix_import import traverse_imports |
+ |
+from libfuturize.fixer_util import future_import |
+ |
+ |
+class FixAbsoluteImport(FixImport): |
+ run_order = 9 |
+ |
+ def transform(self, node, results): |
+ """ |
+ Copied from FixImport.transform(), but with this line added in |
+ any modules that had implicit relative imports changed: |
+ |
+ from __future__ import absolute_import" |
+ """ |
+ if self.skip: |
+ return |
+ imp = results['imp'] |
+ |
+ if node.type == syms.import_from: |
+ # Some imps are top-level (eg: 'import ham') |
+ # some are first level (eg: 'import ham.eggs') |
+ # some are third level (eg: 'import ham.eggs as spam') |
+ # Hence, the loop |
+ while not hasattr(imp, 'value'): |
+ imp = imp.children[0] |
+ if self.probably_a_local_import(imp.value): |
+ imp.value = u"." + imp.value |
+ imp.changed() |
+ future_import(u"absolute_import", node) |
+ else: |
+ have_local = False |
+ have_absolute = False |
+ for mod_name in traverse_imports(imp): |
+ if self.probably_a_local_import(mod_name): |
+ have_local = True |
+ else: |
+ have_absolute = True |
+ if have_absolute: |
+ if have_local: |
+ # We won't handle both sibling and absolute imports in the |
+ # same statement at the moment. |
+ self.warning(node, "absolute and local imports together") |
+ return |
+ |
+ new = FromImport(u".", [imp]) |
+ new.prefix = node.prefix |
+ future_import(u"absolute_import", node) |
+ return new |
+ |
+ def probably_a_local_import(self, imp_name): |
+ """ |
+ Like the corresponding method in the base class, but this also |
+ supports Cython modules. |
+ """ |
+ if imp_name.startswith(u"."): |
+ # Relative imports are certainly not local imports. |
+ return False |
+ imp_name = imp_name.split(u".", 1)[0] |
+ base_path = dirname(self.filename) |
+ base_path = join(base_path, imp_name) |
+ # If there is no __init__.py next to the file its not in a package |
+ # so can't be a relative import. |
+ if not exists(join(dirname(base_path), "__init__.py")): |
+ return False |
+ for ext in [".py", sep, ".pyc", ".so", ".sl", ".pyd", ".pyx"]: |
+ if exists(base_path + ext): |
+ return True |
+ return False |
+ |