aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/past/translation
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/past/translation
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are hereHEADmaster
Diffstat (limited to '.venv/lib/python3.12/site-packages/past/translation')
-rw-r--r--.venv/lib/python3.12/site-packages/past/translation/__init__.py453
1 files changed, 453 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/past/translation/__init__.py b/.venv/lib/python3.12/site-packages/past/translation/__init__.py
new file mode 100644
index 00000000..ae6c0d90
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/past/translation/__init__.py
@@ -0,0 +1,453 @@
+# -*- coding: utf-8 -*-
+"""
+past.translation
+==================
+
+The ``past.translation`` package provides an import hook for Python 3 which
+transparently runs ``futurize`` fixers over Python 2 code on import to convert
+print statements into functions, etc.
+
+It is intended to assist users in migrating to Python 3.x even if some
+dependencies still only support Python 2.x.
+
+Usage
+-----
+
+Once your Py2 package is installed in the usual module search path, the import
+hook is invoked as follows:
+
+ >>> from past.translation import autotranslate
+ >>> autotranslate('mypackagename')
+
+Or:
+
+ >>> autotranslate(['mypackage1', 'mypackage2'])
+
+You can unregister the hook using::
+
+ >>> from past.translation import remove_hooks
+ >>> remove_hooks()
+
+Author: Ed Schofield.
+Inspired by and based on ``uprefix`` by Vinay M. Sajip.
+"""
+
+import sys
+# imp was deprecated in python 3.6
+if sys.version_info >= (3, 6):
+ import importlib as imp
+else:
+ import imp
+import logging
+import os
+import copy
+from lib2to3.pgen2.parse import ParseError
+from lib2to3.refactor import RefactoringTool
+
+from libfuturize import fixes
+
+try:
+ from importlib.machinery import (
+ PathFinder,
+ SourceFileLoader,
+ )
+except ImportError:
+ PathFinder = None
+ SourceFileLoader = object
+
+if sys.version_info[:2] < (3, 4):
+ import imp
+
+logger = logging.getLogger(__name__)
+logger.setLevel(logging.DEBUG)
+
+myfixes = (list(fixes.libfuturize_fix_names_stage1) +
+ list(fixes.lib2to3_fix_names_stage1) +
+ list(fixes.libfuturize_fix_names_stage2) +
+ list(fixes.lib2to3_fix_names_stage2))
+
+
+# We detect whether the code is Py2 or Py3 by applying certain lib2to3 fixers
+# to it. If the diff is empty, it's Python 3 code.
+
+py2_detect_fixers = [
+# From stage 1:
+ 'lib2to3.fixes.fix_apply',
+ # 'lib2to3.fixes.fix_dict', # TODO: add support for utils.viewitems() etc. and move to stage2
+ 'lib2to3.fixes.fix_except',
+ 'lib2to3.fixes.fix_execfile',
+ 'lib2to3.fixes.fix_exitfunc',
+ 'lib2to3.fixes.fix_funcattrs',
+ 'lib2to3.fixes.fix_filter',
+ 'lib2to3.fixes.fix_has_key',
+ 'lib2to3.fixes.fix_idioms',
+ 'lib2to3.fixes.fix_import', # makes any implicit relative imports explicit. (Use with ``from __future__ import absolute_import)
+ 'lib2to3.fixes.fix_intern',
+ 'lib2to3.fixes.fix_isinstance',
+ 'lib2to3.fixes.fix_methodattrs',
+ 'lib2to3.fixes.fix_ne',
+ 'lib2to3.fixes.fix_numliterals', # turns 1L into 1, 0755 into 0o755
+ 'lib2to3.fixes.fix_paren',
+ 'lib2to3.fixes.fix_print',
+ 'lib2to3.fixes.fix_raise', # uses incompatible with_traceback() method on exceptions
+ 'lib2to3.fixes.fix_renames',
+ 'lib2to3.fixes.fix_reduce',
+ # 'lib2to3.fixes.fix_set_literal', # this is unnecessary and breaks Py2.6 support
+ 'lib2to3.fixes.fix_repr',
+ 'lib2to3.fixes.fix_standarderror',
+ 'lib2to3.fixes.fix_sys_exc',
+ 'lib2to3.fixes.fix_throw',
+ 'lib2to3.fixes.fix_tuple_params',
+ 'lib2to3.fixes.fix_types',
+ 'lib2to3.fixes.fix_ws_comma',
+ 'lib2to3.fixes.fix_xreadlines',
+
+# From stage 2:
+ 'lib2to3.fixes.fix_basestring',
+ # 'lib2to3.fixes.fix_buffer', # perhaps not safe. Test this.
+ # 'lib2to3.fixes.fix_callable', # not needed in Py3.2+
+ # 'lib2to3.fixes.fix_dict', # TODO: add support for utils.viewitems() etc.
+ 'lib2to3.fixes.fix_exec',
+ # 'lib2to3.fixes.fix_future', # we don't want to remove __future__ imports
+ 'lib2to3.fixes.fix_getcwdu',
+ # 'lib2to3.fixes.fix_imports', # called by libfuturize.fixes.fix_future_standard_library
+ # 'lib2to3.fixes.fix_imports2', # we don't handle this yet (dbm)
+ # 'lib2to3.fixes.fix_input',
+ # 'lib2to3.fixes.fix_itertools',
+ # 'lib2to3.fixes.fix_itertools_imports',
+ 'lib2to3.fixes.fix_long',
+ # 'lib2to3.fixes.fix_map',
+ # 'lib2to3.fixes.fix_metaclass', # causes SyntaxError in Py2! Use the one from ``six`` instead
+ 'lib2to3.fixes.fix_next',
+ 'lib2to3.fixes.fix_nonzero', # TODO: add a decorator for mapping __bool__ to __nonzero__
+ # 'lib2to3.fixes.fix_operator', # we will need support for this by e.g. extending the Py2 operator module to provide those functions in Py3
+ 'lib2to3.fixes.fix_raw_input',
+ # 'lib2to3.fixes.fix_unicode', # strips off the u'' prefix, which removes a potentially helpful source of information for disambiguating unicode/byte strings
+ # 'lib2to3.fixes.fix_urllib',
+ 'lib2to3.fixes.fix_xrange',
+ # 'lib2to3.fixes.fix_zip',
+]
+
+
+class RTs:
+ """
+ A namespace for the refactoring tools. This avoids creating these at
+ the module level, which slows down the module import. (See issue #117).
+
+ There are two possible grammars: with or without the print statement.
+ Hence we have two possible refactoring tool implementations.
+ """
+ _rt = None
+ _rtp = None
+ _rt_py2_detect = None
+ _rtp_py2_detect = None
+
+ @staticmethod
+ def setup():
+ """
+ Call this before using the refactoring tools to create them on demand
+ if needed.
+ """
+ if None in [RTs._rt, RTs._rtp]:
+ RTs._rt = RefactoringTool(myfixes)
+ RTs._rtp = RefactoringTool(myfixes, {'print_function': True})
+
+
+ @staticmethod
+ def setup_detect_python2():
+ """
+ Call this before using the refactoring tools to create them on demand
+ if needed.
+ """
+ if None in [RTs._rt_py2_detect, RTs._rtp_py2_detect]:
+ RTs._rt_py2_detect = RefactoringTool(py2_detect_fixers)
+ RTs._rtp_py2_detect = RefactoringTool(py2_detect_fixers,
+ {'print_function': True})
+
+
+# We need to find a prefix for the standard library, as we don't want to
+# process any files there (they will already be Python 3).
+#
+# The following method is used by Sanjay Vinip in uprefix. This fails for
+# ``conda`` environments:
+# # In a non-pythonv virtualenv, sys.real_prefix points to the installed Python.
+# # In a pythonv venv, sys.base_prefix points to the installed Python.
+# # Outside a virtual environment, sys.prefix points to the installed Python.
+
+# if hasattr(sys, 'real_prefix'):
+# _syslibprefix = sys.real_prefix
+# else:
+# _syslibprefix = getattr(sys, 'base_prefix', sys.prefix)
+
+# Instead, we use the portion of the path common to both the stdlib modules
+# ``math`` and ``urllib``.
+
+def splitall(path):
+ """
+ Split a path into all components. From Python Cookbook.
+ """
+ allparts = []
+ while True:
+ parts = os.path.split(path)
+ if parts[0] == path: # sentinel for absolute paths
+ allparts.insert(0, parts[0])
+ break
+ elif parts[1] == path: # sentinel for relative paths
+ allparts.insert(0, parts[1])
+ break
+ else:
+ path = parts[0]
+ allparts.insert(0, parts[1])
+ return allparts
+
+
+def common_substring(s1, s2):
+ """
+ Returns the longest common substring to the two strings, starting from the
+ left.
+ """
+ chunks = []
+ path1 = splitall(s1)
+ path2 = splitall(s2)
+ for (dir1, dir2) in zip(path1, path2):
+ if dir1 != dir2:
+ break
+ chunks.append(dir1)
+ return os.path.join(*chunks)
+
+# _stdlibprefix = common_substring(math.__file__, urllib.__file__)
+
+
+def detect_python2(source, pathname):
+ """
+ Returns a bool indicating whether we think the code is Py2
+ """
+ RTs.setup_detect_python2()
+ try:
+ tree = RTs._rt_py2_detect.refactor_string(source, pathname)
+ except ParseError as e:
+ if e.msg != 'bad input' or e.value != '=':
+ raise
+ tree = RTs._rtp.refactor_string(source, pathname)
+
+ if source != str(tree)[:-1]: # remove added newline
+ # The above fixers made changes, so we conclude it's Python 2 code
+ logger.debug('Detected Python 2 code: {0}'.format(pathname))
+ return True
+ else:
+ logger.debug('Detected Python 3 code: {0}'.format(pathname))
+ return False
+
+
+def transform(source, pathname):
+ # This implementation uses lib2to3,
+ # you can override and use something else
+ # if that's better for you
+
+ # lib2to3 likes a newline at the end
+ RTs.setup()
+ source += '\n'
+ try:
+ tree = RTs._rt.refactor_string(source, pathname)
+ except ParseError as e:
+ if e.msg != 'bad input' or e.value != '=':
+ raise
+ tree = RTs._rtp.refactor_string(source, pathname)
+ # could optimise a bit for only doing str(tree) if
+ # getattr(tree, 'was_changed', False) returns True
+ return str(tree)[:-1] # remove added newline
+
+
+class PastSourceFileLoader(SourceFileLoader):
+ exclude_paths = []
+ include_paths = []
+
+ def _convert_needed(self):
+ fullname = self.name
+ if any(fullname.startswith(path) for path in self.exclude_paths):
+ convert = False
+ elif any(fullname.startswith(path) for path in self.include_paths):
+ convert = True
+ else:
+ convert = False
+ return convert
+
+ def _exec_transformed_module(self, module):
+ source = self.get_source(self.name)
+ pathname = self.path
+ if detect_python2(source, pathname):
+ source = transform(source, pathname)
+ code = compile(source, pathname, "exec")
+ exec(code, module.__dict__)
+
+ # For Python 3.3
+ def load_module(self, fullname):
+ logger.debug("Running load_module for %s", fullname)
+ if fullname in sys.modules:
+ mod = sys.modules[fullname]
+ else:
+ if self._convert_needed():
+ logger.debug("Autoconverting %s", fullname)
+ mod = imp.new_module(fullname)
+ sys.modules[fullname] = mod
+
+ # required by PEP 302
+ mod.__file__ = self.path
+ mod.__loader__ = self
+ if self.is_package(fullname):
+ mod.__path__ = []
+ mod.__package__ = fullname
+ else:
+ mod.__package__ = fullname.rpartition('.')[0]
+ self._exec_transformed_module(mod)
+ else:
+ mod = super().load_module(fullname)
+ return mod
+
+ # For Python >=3.4
+ def exec_module(self, module):
+ logger.debug("Running exec_module for %s", module)
+ if self._convert_needed():
+ logger.debug("Autoconverting %s", self.name)
+ self._exec_transformed_module(module)
+ else:
+ super().exec_module(module)
+
+
+class Py2Fixer(object):
+ """
+ An import hook class that uses lib2to3 for source-to-source translation of
+ Py2 code to Py3.
+ """
+
+ # See the comments on :class:future.standard_library.RenameImport.
+ # We add this attribute here so remove_hooks() and install_hooks() can
+ # unambiguously detect whether the import hook is installed:
+ PY2FIXER = True
+
+ def __init__(self):
+ self.found = None
+ self.base_exclude_paths = ['future', 'past']
+ self.exclude_paths = copy.copy(self.base_exclude_paths)
+ self.include_paths = []
+
+ def include(self, paths):
+ """
+ Pass in a sequence of module names such as 'plotrique.plotting' that,
+ if present at the leftmost side of the full package name, would
+ specify the module to be transformed from Py2 to Py3.
+ """
+ self.include_paths += paths
+
+ def exclude(self, paths):
+ """
+ Pass in a sequence of strings such as 'mymodule' that, if
+ present at the leftmost side of the full package name, would cause
+ the module not to undergo any source transformation.
+ """
+ self.exclude_paths += paths
+
+ # For Python 3.3
+ def find_module(self, fullname, path=None):
+ logger.debug("Running find_module: (%s, %s)", fullname, path)
+ loader = PathFinder.find_module(fullname, path)
+ if not loader:
+ logger.debug("Py2Fixer could not find %s", fullname)
+ return None
+ loader.__class__ = PastSourceFileLoader
+ loader.exclude_paths = self.exclude_paths
+ loader.include_paths = self.include_paths
+ return loader
+
+ # For Python >=3.4
+ def find_spec(self, fullname, path=None, target=None):
+ logger.debug("Running find_spec: (%s, %s, %s)", fullname, path, target)
+ spec = PathFinder.find_spec(fullname, path, target)
+ if not spec:
+ logger.debug("Py2Fixer could not find %s", fullname)
+ return None
+ spec.loader.__class__ = PastSourceFileLoader
+ spec.loader.exclude_paths = self.exclude_paths
+ spec.loader.include_paths = self.include_paths
+ return spec
+
+
+_hook = Py2Fixer()
+
+
+def install_hooks(include_paths=(), exclude_paths=()):
+ if isinstance(include_paths, str):
+ include_paths = (include_paths,)
+ if isinstance(exclude_paths, str):
+ exclude_paths = (exclude_paths,)
+ assert len(include_paths) + len(exclude_paths) > 0, 'Pass at least one argument'
+ _hook.include(include_paths)
+ _hook.exclude(exclude_paths)
+ # _hook.debug = debug
+ enable = sys.version_info[0] >= 3 # enabled for all 3.x+
+ if enable and _hook not in sys.meta_path:
+ sys.meta_path.insert(0, _hook) # insert at beginning. This could be made a parameter
+
+ # We could return the hook when there are ways of configuring it
+ #return _hook
+
+
+def remove_hooks():
+ if _hook in sys.meta_path:
+ sys.meta_path.remove(_hook)
+
+
+def detect_hooks():
+ """
+ Returns True if the import hooks are installed, False if not.
+ """
+ return _hook in sys.meta_path
+ # present = any([hasattr(hook, 'PY2FIXER') for hook in sys.meta_path])
+ # return present
+
+
+class hooks(object):
+ """
+ Acts as a context manager. Use like this:
+
+ >>> from past import translation
+ >>> with translation.hooks():
+ ... import mypy2module
+ >>> import requests # py2/3 compatible anyway
+ >>> # etc.
+ """
+ def __enter__(self):
+ self.hooks_were_installed = detect_hooks()
+ install_hooks()
+ return self
+
+ def __exit__(self, *args):
+ if not self.hooks_were_installed:
+ remove_hooks()
+
+
+class suspend_hooks(object):
+ """
+ Acts as a context manager. Use like this:
+
+ >>> from past import translation
+ >>> translation.install_hooks()
+ >>> import http.client
+ >>> # ...
+ >>> with translation.suspend_hooks():
+ >>> import requests # or others that support Py2/3
+
+ If the hooks were disabled before the context, they are not installed when
+ the context is left.
+ """
+ def __enter__(self):
+ self.hooks_were_installed = detect_hooks()
+ remove_hooks()
+ return self
+ def __exit__(self, *args):
+ if self.hooks_were_installed:
+ install_hooks()
+
+
+# alias
+autotranslate = install_hooks