I'm currently learning unittesting, and I have stumbled upon a strange error:
If I run my script from inside PyCharm, everything works perfectly. If I run it from my cmd.exe (as administrator), I get the following error:
This is my code:
import unittest
class TutorialUnittest(unittest.TestCase):
def test_add(self):
self.assertEqual(23,23)
self.assertNotEqual(11,12)
# function for raising errors.
def test_raise(self):
with self.assertRaises(Exception):
raise Exception`
Just remove the .py extension.
You are running your tests using the -m command-line flag. The Python documentation will tell you more about it, just check out this link.
In a word, the -m option let you run a module, in your case the unittest module. This module expect to receive a module path or a class path following the Python format for module path (using dots). For example, if you want to run the FirstTest class in the mytests module in a mypackage folder you would use the following command line:
python -m unittest mypackage.mytests.FirstTest
Assuming that you are running the previous command line from the parent folder of mypackage. This allows you to select precisely the tests you want to run (even inside a module).
When you add the .py extension, unittest is looking for a py object (like a module or a class) inside the last element of the module path you gave but, yet this object does not exist. This is exactly what your terminal error tells:
AttributeError: ’module’ object has no attribute ’py’
you can add at the bottom of your script:
if __name__ == "__main__":
unittest.main()
Then you can run python test_my_function.py normally
Related
ran into a weird problem where there is a shared-object import error only when I run the script from command line. It succeed if i run the script in the python console using exec(...)
I have a class that needs a shared object: foo.py:
import os
cur_dir = os.curdir()
os.chdir('/tmp/dir_with_shared_object/')
import shared_object_class
os.chdir(cur_dir)
class Useful:
... # use the shared object import
Then there is a script like this:
from foo import Useful
If I enter python console and run:
exec(open('script.py').read())
Everything works fine.
If I run this on command line:
python script.py
I will get
ModuleNotFoundError: No module named 'shared_object_class'
The python is the same. It is 3.7.3, GCC 7.3.0 Anaconda. Anyone knows what is causing this discrepancy in behavior for shared object import?
A standard way of importing from a custom directory would be to include it in the PYTHONPATH environmental variable, with export PYTHONPATH=/tmp/dir_with_shared_object/.
update
It could also be done dynamically with
import sys
p = '/tmp/dir_with_shared_object/'
sys.path.insert(0, p)
PS
I think I have an explanation for why OP's original code didn't work. According to this python reference page, the import system searches, inter alia, in "[t]he directory containing the input script (or the current directory when no file is specified)." So the behavior in the REPL loop is different from how it is when running a script. Apparently the current directory is evaluated each time an import statement is encountered, while the directory containing the input script doesn't change.
The doc says
Some Python modules are also useful as scripts. These can be invoked using python -m module [arg] ..., which executes the source file for module as if you had spelled out its full name on the command line
I wrote this code to help myself understand the -m
def print_hi(n=1):
print('hi'*n)
if __name__ == "__main__":
print_hi(9)
I saved this as a file aname.py.
And then I ran this command, and get the expected result.
$ python aname.py
hihihihihihihihihi
question
When I execute the file as a module, this error shows up
$ python -m aname.py
/usr/bin/python: Error while finding module specification for 'aname.py' (AttributeError: module 'aname' has no attribute '__path__')
What causes this error? How to fix it?
You're supposed to use the m without the .py suffix, i.e.: $ python -m aname
From the man page:
-m module-name
Searches sys.path for the named module and runs the corresponding .py file as
a script.
The m parameter is a module, similar to import or from.
I am trying to run a specific test method with pytest on Python 3.6 with the following command:
pytest sanity_test.py::test_check
(as mentioned in pytest docs)
and it fails with the following error message:
ERROR: not found: <rootdir>/tests/automation/sanity/sanity_test.py::test_check
(no name '<rootdir>/tests/automation/sanity/sanity_test.py::test_check' in any of [<DoctestModule 'tests/automation/sanity/sanity_test.py'>, <Module
'tests/automation/sanity/sanity_test.py'>])
when I run the whole test file the tests are running properly with:
pytest sanity_test.py
When I tried running a specific method in isolated project it works perfectly.
Any reason why pytest can't find specifically my test methods on my project?
The file is very simple and looks like this:
def test_check():
pass
Thank to hoefling, I recognized that I had --doctest-modules option in my setup.cfg file. Removing this option fixed the problem.
hoefling opened an issue in pytest for that problem.
I have a file named main.py with the following code:
#!/usr/bin/env python3
import utils.stuff
if __name__ == "__main__":
print("hi from main.py")
utils.stuff.foo()
In the directory with main.py, I have a subdirectory named utils which has a file named stuff.py with the following code:
print("hi from stuff.py")
def foo():
print("foo")
If I run ./main.py from the command line, I get the following output:
hi from stuff.py
hi from main.py
foo
That is exactly what I expect. However, if I run pylint main.py, I get the following output:
No config file found, using default configuration
************* Module main
C: 1, 0: Missing module docstring (missing-docstring)
E: 3, 0: No name 'stuff' in module 'utils' (no-name-in-module)
E: 3, 0: Unable to import 'utils.stuff' (import-error)
E: 7, 4: Module 'utils' has no 'stuff' member (no-member)
followed by some more detailed statistics that do not seem relevant to my question. Why is this happening? What can I do to make Pylint aware of utils/stuff.py? I am running Python 3.5.2, Pylint 1.6.4 and OS X 10.11.6.
You need a create utils/__init__.py. This will make python aware of the submodule and also allows you to run any code you want to happen on import. If you don't want anything to run then just include a docstring.
I got this error when my function was named start:
from views import start
It worked when I changed the name of the function.
I sometimes got this pylint warning in PyCharm. The code works and PyCharm is able to navigate to the imported function if I Ctrl-click on the name.
From https://pycodequ.al/docs/pylint-messages/e0611-no-name-in-module.html
There can be false positive issues of the type when
pylint is run with an incompatible python version
pylint is run in an environment that misses a depedency of your code (this is more likely to lead to issues of type import-error
(E0401))
the name you are importing is in turn imported into the target module by a wildcard import
A false positive warning can be disabled with a comment:
# pylint: disable = no-name-in-module
The warning can also be disabled in pyproject.toml section of pylint:
[tool.pylint.'MESSAGES CONTROL']
disable=[
'no-name-in-module'
]
Suppose there is a module somewhere, which I can import with
from sound.effects import echo
How can I run echo directly from command line?
Command
python sound/effects/echo.py
does not work since the relative path is generally incorrect
If the module has top-level code executing on import, you can use the -m switch to run it from the command line (using Python attribute notation):
python -m sound.effect.echo
The module is then executed as a script, so a if __name__ == '__main__': guard will pass. See for example the timeit module, which executes the timeit.main() function when run from the command line like this.