aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/libfuturize/fixes/fix_absolute_import.py
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/libfuturize/fixes/fix_absolute_import.py')
-rw-r--r--.venv/lib/python3.12/site-packages/libfuturize/fixes/fix_absolute_import.py91
1 files changed, 91 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/libfuturize/fixes/fix_absolute_import.py b/.venv/lib/python3.12/site-packages/libfuturize/fixes/fix_absolute_import.py
new file mode 100644
index 00000000..eab9c527
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/libfuturize/fixes/fix_absolute_import.py
@@ -0,0 +1,91 @@
+"""
+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