pytest cannot find module on import but code runs just fine - python-3.x

The goal is to use the pytest unit test framework for a Python3 project that uses Cython. This is not a plug-and-play thing, because pytest by default is not able to import the Cython modules. Namely, I get the following error when importing from a Cython .pyx module, in my case named 'calculateScore':
package/mainmodule.py:5: in <module>
from calculateScore import some_functions
E ImportError: No module named 'calculateScore'
This problem occurs both when using the pytest-runner as well as the pytest-cython approach. Strangely enough, the code runs just fine as a python application when you're not trying to test it using pytest.
Changing the import style to import calculateScore or import package.calculateScore does not help.

I have no idea why this is happening, but for me the easiest solution was to use the pytest-cython approach and change one or multiple things listed below in the package's setup.py file:
when defining your Extension for the ext_modules to include the Cython .pyx files, do not use distutils.extension.Extension but rather use setuptools.Extension
The reason why I manually create an Extension instead of using the Cython.Build.cythonize function, is not important here. But please note that for the pytest-runner approach:
do not use the cythonize function, but create the Extension manually
After writing this post I cannot even seem to reproduce the problem using pytest-cython anymore, which suggests that maybe something else is the cause of the problem. An additional thing you could try is to make sure that:
when manually creating an Extension for your .pyx module, make sure the name of the Extension is identical to the name of the module (so name it 'calculateScore' and not for instance 'package.calculateScore').
delete the compiled .so file corresponding to your .pyx file and then re-run.

Related

The file is in the same directory but cannot be imported

The python version I am using is 3.8.2
I searched a lot and most of the solutions are to use sys.path.append()
But it didn't solve the problem for me, if I use from . import players
it will say
ImportError: attempted relative import with no known parent package
if i use import players it will say
ModuleNotFoundError: No module named 'players'
The code I used to fix this:
sys.path.append(".")
sys.path.append(os.getcwd() + "\\players.py")
sys.path.append(os.getcwd())
still can't fix this,It's worth mentioning that at some point sys.path.append(os.getcwd() + "\\players.py") can run
Make sure that the name of the file is actually players.py.
And not for example players.py, players .py (note the spaces).
Also check for all other "invisible" Unicode characters that would not necessarily show up.
And make sure that there is no directory players as well.
I deleted the file completely so I couldn't test it, but I ran into this problem again, it's an import order problem, I tried to import attributes.py first and then content.py, there was a problem Check, can't find attributes.py , the problem is solved when their import order is swapped, I can't understand why, but if you encounter such problems please try once (other files are not imported)
I've had similar issues and I've created a new, experimental import library for Python to solve this kind of import error: ultraimport
Instead of from . import players it allows you to write
import ultraimport
players = ultraimport('__dir__/players.py')
This will always work, no matter how you run your code, no matter what is your current working directory and no matter if there's another directory somewhere called 'players'.

ImportError: No module named functions

Image
I don't know what am I doing wrong here. I am importing the module from the functions package in the tests package. I tried every method but couldn't solve this problem while I tried to run valid_test.py
You need to use one dot before the functions so the python will know it is in the folder "above" the current location (import statement).
This look like this issue.
When specifying what module to import you do not have to specify the
absolute name of the module. When a module or package is contained
within another package it is possible to make a relative import within
the same top package without having to mention the package name. By
using leading dots in the specified module or package after from you
can specify how high to traverse up the current package hierarchy
without specifying exact names. One leading dot means the current
package where the module making the import exists. Two dots means up
one package level. Three dots is up two levels, etc. So if you execute
from . import mod from a module in the pkg package then you will end
up importing pkg.mod. If you execute from ..subpkg2 import mod from
within pkg.subpkg1 you will import pkg.subpkg2.mod. The specification
for relative imports is contained within PEP 328.
There is another way to solve this issue by adding the "father" folder to the sys.path
by:
import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__, '..')))
I have been getting the same problem again and again while using SPYDER with anaconda.
I make my own function in other file and import those functions. The code was still not running giving me the error "ModuleNotFoundError: No module named 'my_functions".
I am sure you are selecting lines and executing only selected line only\
Solution to problem is here below
To execute your code as whole/line by line Follow the steps.
Change the working directory of spyder to the folder of current file as here https://pasteboard.co/ee79y0dLqzu4.png .
select lines and execute or you can also execute the whole code.

NameError: name 'log10' is not defined in function called in script

Why log10() is failing to be recognized when called within a function definition in another script? I'm running Python3 in Anaconda (Jupyter and Spyder).
I've had success with log10() in Jupyter (oddly without even calling "import math"). I've had success with defining functions in a .py file and calling those functions within a separate script. I should be able to perform a simple log10.
I created a new function (in Spyder) and saved it in a file "test_log10.py":
def test_log10(input):
import math
return math.log10(input)
In a separate script (Jupyter notebook) I run :
import test_log10
test_log10.test_log10(10)
I get the following error:
"NameError: name 'log10' is not defined"
What am I missing?
Since I'm not using the environment of Jupyther and alike, I don't know how to correct it in these system, perhaps there is some configuration file over there,check the documentation.
But exactly on the issue, when this happens its because python has not "linked" well something at the import, so I suggest a workaround with the libs in the next way:
import numpy as np
import math
and when you are using functions from math, simply add the np. before, i.e.:
return math.log10(input)
to
return np.math.log10(input)
Exactly I don't know why the mismatch, but this worked for me.

How can I set up an alias for imports in Python?

I want my project to work in two different situations. It should work as a standalone library, but also as sub package of a larger project. The main use case is that of a standalone library, where its internal imports should be of the form
from my_library import sub_package
When using the code as sub package of a larger project, these imports don't work as there is no global name my_library. Instead, I would have to use relative or absolute imports, for example
from large_project.my_library import sub_package
Let's assume I wrote my library as shown in the first example. How can I overwrite importing behavior when running as part of a larger project to automatically adjust import paths?
Thanks to #MatrixTai's suggestion of adding the parent directory of the package to the the module path, I came up with this dynamic solution. At the top of my_library/__init__.py:
# Make package global even if used as a sub package to enable short imports.
import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(__file__)))
We have to navigate up two directories here to do from the my_library/__init__.py to my_library and from there to its parent direction, where imports will find the library.
You don't have much choice.
If you want to reference the my_library.py anywhere, there is 2 method (as I known) can do similar work.
1: add system path. Like those module you installed by pip. pip module is installed in /Python/Scripts. You can add a new path or simply put my_library.py into one of the path. For adding, that's in Computer(right-click)-> Properties -> Environment Variable -> Choose Path and Click Edit
(Though you may not want to use this.)
2: Changing __init__.py, but still at least one line you must add in my_library.py.
For example,
/Directory
/large_project
-__init__.py #call this sub_init
-my_library.py
-__init__.py #call this main_init, this fake
-main.py
In main_init,
import sys
sys.path.append('\\Directory\\large_project')
As main_init is not executed when you execute main.py (this is fake), so in main.py
import __init__
from my_library import sub_package
But as well you can take this main_init as the starter of library, like declaring __all__, etc.

Python import scheme

I am trying to write a python library, where some files depend on other files, for example:
I have folder structure:
../libname
../libname/core.py
../libname/supplementary1.py
../libname/supplementary2.py
../libname/__init__.py
where libname is where I import from.
the core.py file begins with:
import supplementary1
import supplementary2
...some code...
and this works fine, if I test it in the main of the core.py
Let's say I want to use libname as library in my project. My folder structure is then:
./libname
./main.py
where main.py calls functions from core.py, which in fact need functions from supplementary1 and supplementary2.
Currently, it throws me an error, saying there is no supplementary1, if I try (in main.py)
from core.py import function1
My question is, how do I import files from my library then? I mean one option would be to copy all the code from e.g. supplementary1 to the core.py, but I wish to maintain my code elegantly separated, if possible.
So in other words, how does one import a file, which already imports some files from a local library?
Thank you very much.
In import ... and from ... import ... you need to write not the filename, but module name. Instead of core.py you should say libname.core, meaning "module core, from package libname" (libname will be searched in all module paths, that normally includes the directory of the script you've started, i.e. where your main.py is).
tl;dr: a simple answer to your question is to write from libname.core import function1 instead.
Also, I'd suggest to use relative imports and instead of import supplementary1 write from . import supplementary1 - here, from . means "from the current package - where this file (module) resides in".
Consider reading Python documentation on modules - there are a lot of examples and explanations there.

Resources