-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
get rid of "ImportMismatchError" #2042
get rid of "ImportMismatchError" #2042
Comments
@hpk42 proposal: ignoring the error altogether if the contents of the wanted and the imported file are the same (and adding a mention of install/reinstall/develop maybe) |
ignoring the error seems dangerous to me as the module under question might import or depend on other modules which are not the same at source versus install location. So i can change files at the source location, run tests and they all appear to be running fine while in fact they are just running against the last installed version. |
thats why i made content equality a condition! |
But with what @hpk42 brought up, the condition would need to be module equality, plus equality for all modules that module imports - right? |
sure, i was referring to that case where a module source under test is equal to the imported version of it. It might still import something that isn't. Imagine e.g. a typical inline test layout with |
well, from my pov we can either stop supporting broken folder layouts or we have to introduce broken hacks ^^ my proposal was such a hack i mean this is one of the cases where we literally loose because there is no clean and backward compatible way to support this, so we pick the cost and pay it ^^ |
I hold that the automatic redirection from source to install location is worth trying and could resolve this problem by default with pytest-4.0 (if not earlier -- nobody can really have relied on an ImportMismatchError appearing). |
In pypa/setuptools#250, I'm working to resolve issues with namespace packages, and the leading solution will require all namespace package distributions to follow this model, even at the development source. And currently, any namespace packages installed by pip (or with setuptools |
Is there a way to find out if a directory is the root of a package if there is no |
I thought you might ask that, and the answer is essentially no. Or rather, on Python 3.3+, any directory on sys.path is always the root of a package:
Probably the packaging infrastructure should expose the "namespace packages" declared for a given distribution, such that you could enumerate all installed packages and determine the namespace packages they declare (and from there resolve the paths pertinent to those packages), but in my initial investigation, I don't see that metadata exposed for installed packages. |
@hpk42: Is it viable to actually perform the import and then inspect |
we need to figure the module name from the filesystem so its a bit tricky to guess the root |
@jaraco i guess it's possible. Directories are not themselves represented in the collection tree. So as soon as we collect a python module and would throw an ImportMismatchError we can instead deliver a message "redirecting collection of source location X to installed location Y" and accept the import instead of throwing. We probably want to only report this once for the root, though, not for each module. |
for correct redirection we should compare a complete module tree before accepting it (imagine a installed package missing a module |
maybe this works: when importing a collected source python module which turns out to come from some other install-location we memorize a source-rootdir -> install-rootdir mapping and issue a report about the redirection. When we subsequently try to import another module based on a mapped root, we don't report it again but verify that the import will come from the install location and if not throw an ImportMismatchError (this should be very rare). We might also check at first redirection time that no module was imported already and was not mapped. Altogether requires a bit of state keeping but should be doable. |
I'm still mid-way digesting the discussion, so sorry if I'm asking something which is obvious to everyone involved. I'm used to run tests in 3 scenarios, which is:
Of those, only when using In which situations an |
regarding tox installing packages, it's possible that due to MANIFEST or other issues not all files are installed. Import-Mismatch can happen out side tox e.g.: if you "pip install ." and then run tests with |
@nicoddemus when people do pip install instead of pip install -e that can happen as well |
@hpk42 and @RonnyPfannschmidt thanks! How about we add some way to force While of course that's not the most elegant solution and does not address the underlying issue, it has some advantages to it:
This is not meant to solve the other user cases you described, but at least would solve the issue for a lot of Just throwing this idea here to see what you guys think, don't mean to disrupt/stop the current discussion on how to treat the problem properly. |
a accessible workaround for tox/env var use seems really sensible as a first step to enable users to test at all and leaves us time for working on a more detailed "propper" fix im in favour, good idea :) |
I am also having this issue when using the Windows Subsystem for Linux and trying to run my tests there. Apparently the linux/windows paths get mixed up. I am not sure if this is a separate issue as I am somewhat surprised how the windows path even gets in there in the first place. Here is the traceback (with shortened paths):
|
That sounds reasonable to me. In my experience, it's only the tox-created environments that are experiencing the false positives. |
Another case where this happens when running tests in a Docker container, where the source gets bind-mounted as an image (into something like |
due to a devpi bug, we always get a sdist install which in turn triggers the pytest issue pytest-dev#2042 / pytest-dev#726 going for pyargs and a changed folder, it should no longer happen (and will be tested firther after rebasing the release branch)
@RonnyPfannschmidt |
im all for fixing problems, but it sounds a lot like all we will be doing is hiding/ignoring |
Yeah, I see. While you can (and should) fix the problem when run with Docker ( |
thanks very much for the MR @blueyed . I'll report the symlink issue with py project. |
|
Thanks! We just used the latest py and it works very well in our context :) |
I think it would be worth to add a note about using the env to https://github.com/blueyed/pytest/blob/6bf4692c7d8100b19dc0178764398edbd7803701/src/_pytest/python.py#L487-L496 (if py >= 1.7). |
…idth on windows Bruno Oliveira (5): Merge pull request #197 from nicoddemus/release-1.6.0 Fix test and add CHANGELOG for #174 Merge pull request #199 from blueyed/PY_IGNORE_IMPORTMISMATCH Merge pull request #201 from Victorious3/issue174 Update CHANGELOG for 1.7.0 Daniel Hahler (1): pyimport: add support for PY_IGNORE_IMPORTMISMATCH Victorious3 (1): Use shutil.get_terminal_size for correct terminal width on windows 1.7.0 (2018-10-11) ================== - fix #174: use ``shutil.get_terminal_size()`` in Python 3.3+ to determine the size of the terminal, which produces more accurate results than the previous method. - fix pytest-dev/pytest#2042: introduce new ``PY_IGNORE_IMPORTMISMATCH`` environment variable that suppresses ``ImportMismatchError`` exceptions when set to ``1``.
I am facing these issues here, any way to supress it? https://circleci.com/gh/einsteinpy/einsteinpy/75?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link |
@shreyasbapat |
Over on the tox issue tracker, there was a discussion about the irritating "ImportMismatchError" that pytest throws if one collects from the source tree but the imports actually come from some installed location (e.g. some virtualenv). This happens more often with tox i guess because the default way of testing with tox is creating and installing a package and then collecting from the source tree.
@jaraco and me agreed that it's probably best to try improve pytest so that it, say with pytest-4.0, will automatically redirect from source to install location. Initially and up until the next major release we could introduce a
--collect-redirect-to-installed=yes
option or so which works like this: if during collection we find a python package (a directory with an__init__.py
for now) we check if importing it will actually get it from another location. If so, we redirect to the install location and also report this fact. Only problem is that with python3 one can have python packages without__init__.py
files so the actual logic needs to take that into account as well (how many people are really using this, btw?).The text was updated successfully, but these errors were encountered: