88

When I am running tests locally its working fine, but after creating the docker and running inside the container I am getting below error.

    /usr/local/lib/python3.5/site-packages/_pytest/config.py:325: in _getconftestmodules
    return self._path2confmods[path]
E   KeyError: local('/apis/db/tests')

During handling of the above exception, another exception occurred:
/usr/local/lib/python3.5/site-packages/_pytest/config.py:356: in _importconftest
    return self._conftestpath2mod[conftestpath]
E   KeyError: local('/apis/db/tests/conftest.py')

During handling of the above exception, another exception occurred:
/usr/local/lib/python3.5/site-packages/_pytest/config.py:362: in _importconftest
    mod = conftestpath.pyimport()
/usr/local/lib/python3.5/site-packages/py/_path/local.py:680: in pyimport
    raise self.ImportMismatchError(modname, modfile, self)

_pytest.config.ConftestImportFailure: ImportMismatchError('conftest', '/projects/my_project/db/tests/conftest.py', local('/apis/db/tests/conftest.py'))

/apis - its the WORKDIR in Dockerfile.

A J
  • 3,684
  • 2
  • 19
  • 24
  • You probably have some problems with python import paths or with symlinks or whatever. What is `/projects/my_project` and what is `/apis`? Are they directories or symlinks? How are they related to each other? – MarSoft May 21 '17 at 22:22
  • @MarSoft /projects is in home directory, and /apis is in docker's home directory, btw I have solved the issue. Thanks! – A J May 22 '17 at 04:54

7 Answers7

150

I have fixed it by removing all __pycache__ pkg under test/ directory, the issue was when I was creating docker image its picking all my __pycache__ and *.pyc files too, at the time when test are running its using my local machine path instead of the path in docker container.

Conclusion: Clear your *.pyc and __pycache__ files before creating a docker image.

Azat Ibrakov
  • 9,998
  • 9
  • 38
  • 50
A J
  • 3,684
  • 2
  • 19
  • 24
  • 16
    You can put these entries in your `.dockerignore` file so that they are ignored during the build phase. Though they would still be picked up if you bind mount your source folders inside the container, in order to run tests while including local modifications. – giorgiosironi Feb 19 '18 at 14:44
  • To remove this issue, I had to locate `__pycache__` inside directory of the file, which was reporting this error. Thanks. – Jitendra Dec 18 '18 at 11:17
  • 9
    Unix command: `find . \( -name '__pycache__' -or -name '*.pyc' \) -delete` – bitoffdev Jun 05 '19 at 14:40
  • 1
    For my use-case I also had to add the `build` folder to the `.dockerignore` – CNugteren Sep 27 '19 at 09:50
39

You can use the .dockerignore file to exclude all __pycache__ folders from being sent to the docker image context:

.dockerignore file, excludes __pycache__ folders and *.pyc files from all sub/folders:

**/__pycache__
**/*.pyc
Datageek
  • 25,977
  • 6
  • 66
  • 70
25

I am using Python 3.6. In my case, I was getting ImportMismatchError in modules with the same name under different packages, e.g., A/B/main.py and C/D/main.py. Python 3 does not require __init__.py file in source folders, but adding __init__.py under A/B and C/D solved the issue.

amit kumar
  • 20,438
  • 23
  • 90
  • 126
  • I have the same issue and your answer solved it for me as well. I wonder why did adding `__init__.py` fix it though? I am trying to understand... – Newskooler Mar 24 '20 at 17:48
  • 2
    @Newskooler adding an `__init__` file lets python know about the absolute path towards every file in the tree. Without those, if you have 2 different files named the same way under different folders, it will not know which one you're referring to. – avazula Jul 20 '20 at 10:06
  • 1
    Okay, so essentially even though "Python 3 does not require __init__.py" it kind of does require it if you want it to run properly? – Newskooler Jul 20 '20 at 13:32
  • I had an `ImportPathMismatchError` with python 3.8 and this solved the problem. – iron9 Jan 29 '21 at 14:42
  • I had an `ImportPathMismatchError` with python 3.7 and this solved the problem. – Alex Fortin Sep 10 '21 at 01:17
  • I also needed to add `__init__.py` in `A/__init__.py` and `C/__init__.py`. – Alex Fortin Sep 10 '21 at 01:18
18

You can set environment variable PY_IGNORE_IMPORTMISMATCH=1 to skip this errros. It should be fine in simple cases like running tests inside and outside docker container.

monitorius
  • 3,566
  • 1
  • 20
  • 17
  • I had a similar problem when running pytest via tox via GitHub actions. This is the only solution that worked for me. – Erel Segal-Halevi Nov 07 '21 at 15:56
  • Seems like you'll make your life a hell with this trying to figure out why something isn't working and then realizing it's using a module with same name from a different path. – Kashyap Jun 14 '23 at 14:54
  • You're right, and that's why I'm talking about "simple cases" =) – monitorius Jun 28 '23 at 07:38
17

Delete all the .pyc files. You can do this by find . -name \*.pyc -delete

Abhilash
  • 261
  • 3
  • 2
  • 2
    This is essentially a re-write of @AJ's answer. How dies this add value to the OP question? – Tedinoz Jan 28 '19 at 22:46
  • 4
    @Tedinoz It's a no-brainer you can copy-paste to fix the problem. Like it or not, many people are just happy with a solution and don't want to understand the background. – poroszd May 17 '19 at 13:12
3

Found __pycache__ files in coverage/fullcoverage/ which are hidden in jupyter notebook etc.

simply navigate to the folder and use rm -r __pyache__/ . This will take care of your pytest.

Hari_pb
  • 7,088
  • 3
  • 45
  • 53
0

In my case I was setting PYTHONPATH manually to the root of my repo. Inside of this I have a worktrees/ folder, which contains worktrees, each of which contain a python package. Since I told python to look for packages at the root of my repo, it would consider all packages under worktrees/ as well, thus leading to the import error. I resolved by flattening this nested structure.

jlhasson
  • 1,516
  • 1
  • 15
  • 23