Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve symlinks in the import path #1253

Merged
merged 4 commits into from
Dec 15, 2021

Conversation

keichi
Copy link
Contributor

@keichi keichi commented Nov 18, 2021

Currently, module import fails when the import path contains a symlink.

An example is Python installed on macOS using Homebrew where /opt/homebrew/opt/python is a symlink to /opt/homebrew/Cellar/python@3.9/3.9.8 (exact version varies). As a result, get_python_lib(standard_lib=True) returns /opt/homebrew/opt/python@3.9/Frameworks/Python.framework/Versions/3.9/lib/python3.9 while sys.path is [..., '/opt/homebrew/Cellar/python@3.9/3.9.8/Frameworks/Python.framework/Versions/3.9/lib/python3.9', ...]. The following tests fail due to this inconsistency:

FAILED tests/unittest_brain.py::MultiprocessingBrainTest::test_multiprocessing_manager - AssertionError: Uninferable != 'array.array'
FAILED tests/unittest_brain_ctypes.py::test_cdata_member_access - astroid.exceptions.InferenceError: StopIteration raised without ...
FAILED tests/unittest_builder.py::BuilderTest::test_socket_build - AssertionError: 'connect' not found in <ClassDef.socket l.214 a...
FAILED tests/unittest_modutils.py::StandardLibModuleTest::test_4 - AssertionError: False is not true
FAILED tests/unittest_modutils.py::StandardLibModuleTest::test_datetime - AssertionError: False is not true
FAILED tests/unittest_regrtest.py::NonRegressionTests::test_ssl_protocol - AssertionError: Uninferable is not an instance of <clas...

Description

Type of Changes

Type
🐛 Bug fix
✨ New feature
🔨 Refactoring
📜 Docs

Related Issue

Fixes #823

@Pierre-Sassoulas
Copy link
Member

I wonder if this also fix pylint-dev/pylint#4798. (We could ping DudeNr33 if no one can test this on Mac)

@Pierre-Sassoulas Pierre-Sassoulas added this to the 2.8.6 milestone Nov 18, 2021
@keichi
Copy link
Contributor Author

keichi commented Nov 18, 2021

@Pierre-Sassoulas Just checked, it does!

pylint 2.11 w/ astroid 2.8.5

keichi@isa3-dhcp-190-228 tmp2 % pylint socket_test.py
************* Module socket_test
socket_test.py:14:13: E1101: Module 'socket' has no 'gethostbyname_ex' member (no-member)
socket_test.py:15:7: E1101: Module 'socket' has no 'gaierror' member (no-member)

------------------------------------
Your code has been rated at -2.50/10

pylint 2.11 w/ astroid (this branch)

keichi@isa3-dhcp-190-228 tmp2 % pylint socket_test.py

---------------------------------------------------------------------
Your code has been rated at 10.00/10 (previous run: -2.50/10, +12.50)

Would you like me to update the change log?

@DanielNoord
Copy link
Collaborator

Do we think pylint-dev/pylint#4798 is indeed similar to pylint-dev/pylint#4759? We could then also close that issue!

@Pierre-Sassoulas
Copy link
Member

I think #4759 would be valuable to do even if we fixed this particular issue thanks to @keichi

@Pierre-Sassoulas
Copy link
Member

Would you like me to update the change log?

Yes please :) And thank you for fixing this issue in the first place, it's really hard to investigate without access to a Mac !

@keichi
Copy link
Contributor Author

keichi commented Nov 18, 2021

Yep, the problems reported in pylint-dev/pylint#4759 are fixed 🎉 Maybe we can run macOS CI jobs in this repository too?

@keichi keichi force-pushed the fix-errors-on-macos branch 2 times, most recently from 8d4ea3a to 7f213b6 Compare November 18, 2021 10:09
@keichi
Copy link
Contributor Author

keichi commented Nov 18, 2021

Turns out this fixes pylint-dev/pylint#4302 and pylint-dev/pylint#5081 as well.

@keichi
Copy link
Contributor Author

keichi commented Nov 19, 2021

pylint-dev/pylint#3499 is also fixed. To summarize, here are the pylint issues resolved with this PR:

Copy link
Member

@Pierre-Sassoulas Pierre-Sassoulas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, so many fixes at once, this is 🔥

astroid/modutils.py Outdated Show resolved Hide resolved
@Pierre-Sassoulas Pierre-Sassoulas modified the milestones: 2.8.6, 2.9.1 Nov 21, 2021
Copy link
Member

@Pierre-Sassoulas Pierre-Sassoulas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I missed that this was not merged yet with the release of pylint 2.12. Thanks a lot for the numerous fixes !

Copy link
Collaborator

@DanielNoord DanielNoord left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't leave this opportunity to add the typing already.

Should we add tests to this?

astroid/modutils.py Outdated Show resolved Hide resolved
astroid/modutils.py Outdated Show resolved Hide resolved
@Pierre-Sassoulas
Copy link
Member

Should we add tests to this?

I think pylint-dev/pylint#4759 would be part of the solution ? But there might be a trick to test if on any platform ?

Co-authored-by: Daniël van Noord <13665637+DanielNoord@users.noreply.github.com>
@DanielNoord
Copy link
Collaborator

I think we should add a test specific to this. I'm not sure: can we create a temporary symlink with pytest, sys or os or something? This seems to warrant an actual test.

@Pierre-Sassoulas
Copy link
Member

Unit testing is not really hard, maybe a mix of os.symlink() on a tmp_path fixture ? But the integration testing means we need to create a new job to launch pylint from a symlinked environment ?

@DanielNoord
Copy link
Collaborator

Unit testing is not really hard, maybe a mix of os.symlink() on a tmp_path fixture ? But the integration testing means we need to create a new job to launch pylint from a symlinked environment ?

I don't really follow you here 😅

What do you mean with integration testing (I'm not that experienced with testing frameworks so forgive me if this is obvious)?

@Pierre-Sassoulas
Copy link
Member

By integration testing I mean the generic computer science term, i.e. testing that modules using this new _normalize_path work properly. As opposed to unit tests that would just test the _normalize_path function output directly (not very useful). I was thinking more of "system testing" than integration testing now that I had to read the definition (testing that pylint work with the new _normalize_path).

@DanielNoord
Copy link
Collaborator

I have a Mac so I'll work on creating a test for this. I played around for a bit already and noticed that one test is actually breaking because of this change on Mac, so this can't be merged in its current state.

@DanielNoord
Copy link
Collaborator

DanielNoord commented Dec 15, 2021

I looked into this but I'm not sure we can create a test. The problem is not that what we import contains a symlink but that the python path is a symlink. This means that sysconfig.get_python_lib will return that symlink instead of the actual python directory.

I don't think we can add a symlink to the python executable/directory while we are already running a python instance.. Setting up a completely new action with a symlinked install of python just to test this does not seem worth it. I think we should go ahead and merge this without tests (sadly..)

@Pierre-Sassoulas
Copy link
Member

I think we should go ahead and merge this without tests (sadly..)

I came to the same conclusion. I think the lack of tests is the reason why we did not merge this earlier. Some things are really hard to test. So really useful MR are rotting in astroid because of that. Same problem with #1207, it's not impossible to test, but it's hard.

@Pierre-Sassoulas Pierre-Sassoulas merged commit 2ee20cc into pylint-dev:main Dec 15, 2021
@DanielNoord
Copy link
Collaborator

Can we auto-close the pylint issues? Or do you want to add something to the pylint changelog and do it then?

@Pierre-Sassoulas
Copy link
Member

Generally I add a regression test in pylint before closing but right now testing is just as hard. I added them to the 2.13.0 milestone but we could close it when upgrading pylint to astroid 2.9.1 ?

@DanielNoord
Copy link
Collaborator

Fine with me!

@Pierre-Sassoulas
Copy link
Member

pylint-dev/pylint#5529

Pierre-Sassoulas added a commit to pylint-dev/pylint that referenced this pull request Dec 19, 2021
tushar-deepsource pushed a commit to tushar-deepsource/astroid that referenced this pull request Dec 20, 2021
* Resolve symlinks in the import path

* Drop expanduser() from _normalize_path() and add note

Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
Co-authored-by: Daniël van Noord <13665637+DanielNoord@users.noreply.github.com>
Pierre-Sassoulas added a commit to pylint-dev/pylint that referenced this pull request Dec 31, 2021
Pierre-Sassoulas added a commit to pylint-dev/pylint that referenced this pull request Dec 31, 2021
Pierre-Sassoulas added a commit to Pierre-Sassoulas/pylint that referenced this pull request Jan 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

modutils.is_standard_module mistakenly returns False for 'os'
3 participants