py-astroid: add new versions and update dependencies (#23687)

Change-Id: I2c07e75b404ec289feebdbfb09f6b0e733404911
This commit is contained in:
Andreas Baumbach 2021-05-17 19:31:34 +02:00 committed by GitHub
parent dd350e83d3
commit b2bc0241eb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 140 additions and 2 deletions

View file

@ -0,0 +1,129 @@
From beb8c1add0facf57d70d986812ffb45336b6b261 Mon Sep 17 00:00:00 2001
From: Mario Corchero <mcorcherojim@bloomberg.net>
Date: Mon, 14 May 2018 11:20:45 -0400
Subject: [PATCH 1/2] Fix import of symlinks outside of path
Makes load_module_from_file able to import files within the path that
are just a symlink to a file outside of the path.
modutils is using realpath at the moment which will resolve the symlink
and don't allow the import as the file is detected outside of the
available paths. By checking both abspath and realpath this patches add
support for such scenarios.
---
astroid/modutils.py | 64 ++++++++++++++++++++++++------
astroid/tests/unittest_modutils.py | 11 +++++
2 files changed, 63 insertions(+), 12 deletions(-)
diff --git a/astroid/modutils.py b/astroid/modutils.py
index 83d0ba74..78a55575 100644
--- a/astroid/modutils.py
+++ b/astroid/modutils.py
@@ -285,26 +285,66 @@ def check_modpath_has_init(path, mod_path):
return True
+def _get_relative_base_path(filename, path_to_check):
+ """Extracts the relative mod path of the file to import from
+
+ Check if a file is within the passed in path and if so, returns the
+ relative mod path from the one passed in.
+
+ If the filename is no in path_to_check, returns None
+
+ Note this function will look for both abs and realpath of the file,
+ this allows to find the relative base path even if the file is a
+ symlink of a file in the passed in path
+
+ Examples:
+ _get_relative_base_path("/a/b/c/d.py", "/a/b") -> ["c","d"]
+ _get_relative_base_path("/a/b/c/d.py", "/dev") -> None
+
+ Given "/myfile.py" is a symlink of "/a/b/c/d.py":
+ _get_relative_base_path("/myfile.py", "/dev") -> ["c","d"]
+ """
+ importable_path = None
+ path_to_check = os.path.normcase(path_to_check)
+ abs_filename = os.path.abspath(filename)
+ if os.path.normcase(abs_filename).startswith(path_to_check):
+ importable_path = abs_filename
+
+ real_filename = os.path.realpath(filename)
+ if os.path.normcase(real_filename).startswith(path_to_check):
+ importable_path = real_filename
+
+ if importable_path:
+ base_path = os.path.splitext(importable_path)[0]
+ relative_base_path = base_path[len(path_to_check):]
+ return [pkg for pkg in relative_base_path.split(os.sep) if pkg]
+
+ return None
+
+
def modpath_from_file_with_callback(filename, extrapath=None, is_package_cb=None):
- filename = _path_from_filename(filename)
- filename = os.path.realpath(os.path.expanduser(filename))
- base = os.path.splitext(filename)[0]
+ filename = os.path.expanduser(_path_from_filename(filename))
if extrapath is not None:
for path_ in six.moves.map(_canonicalize_path, extrapath):
path = os.path.abspath(path_)
- if path and os.path.normcase(base[:len(path)]) == os.path.normcase(path):
- submodpath = [pkg for pkg in base[len(path):].split(os.sep)
- if pkg]
- if is_package_cb(path, submodpath[:-1]):
- return extrapath[path_].split('.') + submodpath
+ if not path:
+ continue
+ submodpath = _get_relative_base_path(filename, path)
+ if not submodpath:
+ continue
+ if is_package_cb(path, submodpath[:-1]):
+ return extrapath[path_].split('.') + submodpath
for path in six.moves.map(_canonicalize_path, sys.path):
path = _cache_normalize_path(path)
- if path and os.path.normcase(base).startswith(path):
- modpath = [pkg for pkg in base[len(path):].split(os.sep) if pkg]
- if is_package_cb(path, modpath[:-1]):
- return modpath
+ if not path:
+ continue
+ modpath = _get_relative_base_path(filename, path)
+ if not modpath:
+ continue
+ if is_package_cb(path, modpath[:-1]):
+ return modpath
raise ImportError('Unable to find module for %s in %s' % (
filename, ', \n'.join(sys.path)))
diff --git a/astroid/tests/unittest_modutils.py b/astroid/tests/unittest_modutils.py
index ef3c460c..76c04eb1 100644
--- a/astroid/tests/unittest_modutils.py
+++ b/astroid/tests/unittest_modutils.py
@@ -15,6 +15,7 @@
import sys
import unittest
from xml import etree
+import tempfile
import astroid
from astroid.interpreter._import import spec
@@ -110,6 +111,16 @@ def test_knownValues_modpath_from_file_2(self):
def test_raise_modpath_from_file_Exception(self):
self.assertRaises(Exception, modutils.modpath_from_file, '/turlututu')
+ def test_import_symlink_with_source_outside_of_path(self):
+ with tempfile.NamedTemporaryFile() as tmpfile:
+ linked_file_name = 'symlinked_file.py'
+ try:
+ os.symlink(tmpfile.name, linked_file_name)
+ self.assertEqual(modutils.modpath_from_file(linked_file_name),
+ ['symlinked_file'])
+ finally:
+ os.remove(linked_file_name)
+
class LoadModuleFromPathTest(resources.SysPathSetup, unittest.TestCase):

View file

@ -13,8 +13,11 @@ class PyAstroid(PythonPackage):
homepage = "https://github.com/PyCQA/astroid"
url = "https://github.com/PyCQA/astroid/archive/astroid-1.4.5.tar.gz"
version('2.4.2', sha256='34d480d364dcf3e176bc302da56c5ef585ab45d4460f5a2761f960d2fd7b624c')
version('2.3.3', sha256='3a82983cf34dcbfe42ebcffeb98739e8a7bb868f03c1d9e298c530179b5075e7')
version('2.2.5', sha256='232c2cfc72bae18a28de6541bbd560a1a3f42e08c52e41bd3f1f00ed74b0a4a6')
version('2.2.0', sha256='7e289d0aa4a537b4aa798bd609fdf745de0f3c37e6b67642ed328e1482421a6d')
version('2.0.4', sha256='e2161452b7a07a4663dba61bfb2191a7b61b792fb8239427581dad43773e071e')
version('1.6.6', sha256='3fbcc144457ba598fb48e0ddce5eacee62610ab11e6fe374b6eef5f7df2a3fbb')
# version('1.5.3', sha256='6f65e4ea8290ec032320460905afb828') # has broken unit tests
version('1.4.5', sha256='28d8f5b898087ecf86fd66ca0934e5c0e51fc0beb5972cfc4e0c11080e0cb6ab')
@ -23,12 +26,17 @@ class PyAstroid(PythonPackage):
version('1.4.2', sha256='f9007d651f4b3514ea5812127677a4bb681ff194164290cea358987920f24ee6')
version('1.4.1', sha256='f1ab3ee6f17f9d30981399a52b56a7a7d2747ba24f0aa504e411ee6205a01fc0')
# fixes symlink resolution, already included in 2: but not in 1.6.6
patch('PR546.patch', when='@1.6.6')
# Dependencies taken from astroid/__pkginfo__.py
depends_on('python@2.7:2.8,3.4:', when='@:1.999', type=('build', 'run'))
depends_on('python@3.4:', when='@2.0.0:', type=('build', 'run'))
depends_on('python@3.5:', when='@2.3.3:', type=('build', 'run'))
depends_on('py-lazy-object-proxy', type=('build', 'run'))
depends_on('py-lazy-object-proxy@1.4:1.4.999', when='@2.3.3:', type=('build', 'run'))
# Starting with astroid 2.3.1, astroid's dependencies were restricted
# to a given minor version, c.f. commit e1b4e11.
depends_on('py-lazy-object-proxy@1.4:1.4.999', when='@2.3.1:', type=('build', 'run'))
depends_on('py-six', type=('build', 'run'))
depends_on('py-six@1.12:1.999', when='@2.3.3:', type=('build', 'run'))
depends_on('py-wrapt', when='@:2.2.999', type=('build', 'run'))
@ -36,5 +44,6 @@ class PyAstroid(PythonPackage):
depends_on('py-enum34@1.1.3:', when='^python@:3.3.99', type=('build', 'run'))
depends_on('py-singledispatch', when='^python@:3.3.99', type=('build', 'run'))
depends_on('py-backports-functools-lru-cache', when='^python@:3.2.99', type=('build', 'run'))
depends_on('py-typed-ast@1.4.0:1.4.999', when='@2.3.3: ^python@:3.7.999', type=('build', 'run'))
depends_on('py-typed-ast@1.3.0:1.3.999', when='@2.2.5:2.3.0 ^python@3.7.0:3.7.999')
depends_on('py-typed-ast@1.4.0:1.4.999', when='@2.3.1: ^python@:3.7.999', type=('build', 'run'))
depends_on('py-setuptools@17.1:', type='build')