Python's mock throwing AttributeError: 'module' object has no attribute 'patch' - python

I am trying to create some tests for a Python program. I am using Python version 2.7.12 so I had to install mock using sudo pip install mock.
According to the documentation and several other sites, I should be able to use the following code to use patch:
import mock # Also could use from mock import patch
import unittest
class TestCases(unittest.TestCase):
#mock.patch('MyClass.ImportedClass') # If using from mock import patch should just be #patch
def test_patches(self, mock_ImportedClass):
# Test code...
However, the above code throws the following error:
AttributeError: 'module' object has no attribute 'patch'
After some experimenting in the terminal, it seems quite a few things don't work. For example
>>> import mock
>>> mock.MagicMock
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'MagicMock'
>>> mock.patch
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'patch'
>>> mock.Mock
<class mock.Mock at 0x7fdff56b0600>
Interestingly, I can access something called patch using mock.Mock(), but I don't know if this works in the same way and cannot find anything about it in the documentation.
My experience with Python is fairly limited so I'm not sure what might be wrong. I'm fairly certain the right package was installed. Any help on how I can get this working?

Just for the sake of completeness, I wanted to add the answer, but the credit goes to #user2357112.
If you run into this issue check to make sure you don't have another file named mock.py (or whatever file you're trying to import) either in the same directory or in the search path for python. To confirm you've loaded the correct file, you can check mock.__file_, which is an attribute added automatically by python to your imported files. If you're using the terminal, you can just do something like:
>>> import mock
>>> mock.__file__
'/usr/lib/python2.7/...'
If the file path doesn't match what you expect, you should remove the file being imported from your search path or modify your search path so that the file you want is found first. If neither of those are an option, you need to change the name of the file you're importing (if it's one you define and not a library like mock).

Related

object has no attribute 'loads' in UnitTest class

Im trying to run some tests in python. Im using Unittest framework.
The test "test_processJson" uses a test Json, dictTestString, and then checks if it has one or more elements. This is my script "testing.py"
import json
import starter#The code Im trying to test
import unittest
class MyTests(unittest.TestCase):
def test_processJson(json):
dictTestString = '{"city":"Barcelona"}'
jTest = json.loads(dictTestString)
dictProcess = starter.processJson(dictTest)
self.assertEquals(dictProcess["city"], "Barcelona")
if __name__ == '__main__':
unittest.main()
The problem comes when I run the test I get this error:
Traceback (most recent call last):
File "testing.py", line 16, in test_processJson
jTest = json.loads(dictTestString)
AttributeError: 'MyTests' object has no attribute 'loads'
I'm new to python, so I've been looking for an answer but any of the mistakes I've seen Im not doing.
Any help will be appreciated.
Thanks.
Your function's argument is named json, which shadow's the global json module. Actually since this is the first argument of a method, it get bound to the current MyTest instance, and since unittest test methods only expect the current instance as argument AND you don't have any need for a json argument here, you just have to rename it to self (which is the convention for the first argument of instance methods) and you problem will be solved.
NB : There are a couple other typos / issues with your code but I leave it up to you to find and solve them - that's part of the fun isn't it ?

Serializing custom modules together with object in python

Problem
Let's say I have this module named custom_module:
class CustomClass:
pass
And I use this class in a script that serializes an object of the class I defined in custom_module:
import cloudpickle
import custom_module as cm
custom_object = cm.CustomClass()
with open('filename.pkl', 'wb') as file:
cloudpickle.dump(custom_object, file)
I copy this pickle file to another environment and load it with another script:
import cloudpickle
with open('filename.pkl', 'rb') as file:
custom_object = cloudpickle.load(file)
That would yield this error:
Traceback (most recent call last):
File "loader.py", line 4, in <module>
custom_object = cloudpickle.load(file)
ModuleNotFoundError: No module named 'custom_module'
Awkward solution
As a workaround it is possible to read and execute everything that is in custom_module in my script:
exec(open(path.join('custom_module.py')).read())
but that looks really weird and I can't use CustomClass as cm.CustomClass. Is there any other solution that doesn't involve copying all the code in the first environment to the second?
You can solve the problem by reimplement CustomClass in custom_module the following way:
def __CustomClass():
class CustomeClass:
... # Your implementaion here
return CustomeClass
CustomClass = __CustomClass()
The error will gone if you are lucky enough. If not, you need to dive into CustomClass to find out other functions or classes that are defined in other local modules, and reimplement them using the same method.
You can find more detail in this question. You may also use cloudpickle.register_pickle_by_value to solve the issue, but it is labeled as an experimental feature.

I'm getting AttributeError when I call a method in other class

I'm very new to Python and I have a code like this:
class Configuration:
#staticmethod
def test():
return "Hello World"
When I call the method test from other python code like this:
import test
test.Configuration.test()
I get an error like this:
Traceback (most recent call last):
File "example.py", line 3, in <module>
test.Configuration.test()
AttributeError: 'module' object has no attribute 'test'
where I'm making the mistake?
Edit:
My directory structure:
root
--example.py
--test
----__init.py__
----Configuration.py
Python module names and the classes they contain are separate. You need use the full path:
import test
print test.Configuration.Configuration.test()
Your test package has a module named Configuration, and inside that module is your Configuration class.
Note that Python, unlike Java, lets you define methods outside classes too, no need to make this a static method. Nor do you need to use a separate file per class.
Try to rename your module to something other than 'test', since this is the name of a standard library module (http://docs.python.org/2/library/test.html) and probably you're importing that module instead of your own. Another option is to add the directory containing your test module into the PYTHONPATH environment variable, so that python may find it instead of the standard library module (but this is not advised as it shadows the standard module and you won't be able to import it later).
To check which file you're importing from, do:
import test
print test

In python, what is contained in the info property of a module object?

I'm looking into creating a Plugin structure for a program and making it so even the core library is treated as plugins. in my research I came across this code that is dynamically importing modules.
def __initialize_def(self, module):
"""Attempt to load the definition"""
# Import works the same for py files and package modules so strip!
if module.endswith(".py"):
name = module [:-3]
else:
name = module
# Do the actual import
__import__(name)
definition = sys.modules[name]
# Add the definition only if the class is available
if hasattr(definition, definition.info["class"]):
self.definitions[definition.info["name"]] = definition
logging.info("Loaded %s" % name)
I have tried to understand what this code is doing and I've succeeded to a point. However, I simply can't understand the latter part of the code, specifically these two lines:
if hasattr(definition, definition.info["class"]):
self.definitions[definition.info["name"]] = definition
I can't figure out what definition.info["<key>"] is referring to.
What is this .info[] dictionary and what does it hold? Is it common to all Python objects or only module objects? What is it useful for?
py> import sys,os
py> sys.modules["os"].info["class"]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'info'
So this info attribute must be specific to modules that can be used as plugins in this program.
Reserved names in Python generally begin with two underscores. You just stumbled on some piece of a larger codebase, that gives info module-scope values a special meaning. I don't think its authors chose a particularly good name for these, anyway; $FRAMEWORK_MODULE_INFO would be more explicit.

I can't instantiate a simple class in Python

I want to generate a Python class via a file.
This is a very simple file, named testy.py:
def __init__(self,var):
print (var)
When I try to instantiate it I get:
>>> import testy
>>> testy('1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'module' object is not callable
Then , I try something else:
class testy_rev1:
def __init__(self,var):
print (var)
I try to instanicate it and I get:
>>> import testy_rev1
>>> a=testy_rev1('1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'module' object is not callable
>>> a=testy_rev1.testy_rev1('1')
1
What I am looking for is a way to import it from a file w/o resorting to:
import <module name>.<module name>
With a file called testy.py with this:
class testy_rev1:
def __init__(self, var):
print (var)
You will have to do either:
>>> import testy
>>> testy.testy_rev1('1')
Or:
>>> from testy import testy_rev1
>>> testy_rev1('1')
Or (not recommended, since you will not see where the definition came from in the source):
>>> from testy import *
>>> testy_rev1('1')
Other than that I do not know how you could do it.
Attempt 1 failed because you were not defining a class, just a function (which you fixed with attempt 2).
Attempt 2 is failing because you looking at the import statement like it is a Java import statement. In Python, an import makes a module object that can be used to access items inside it. If you want use a class with in a module without first specifying the module you want to use the following:
from my_module import MyClass
a = MyClass()
As a side note, your print method in the 2nd attempt in not indented after the __init__ method. This might just me a formatting error when you posted here, but it will not run the code how you expect.
import x imports a module called x. import y.x imports the module d from the module/package y. Anything in this module is refered to as x.stuff or y.x.stuff. That's how it works and they won't change the language for your convenience ;)
You can always do from module import thingy. But consider that importing the whole module is usually preferred over this... for a reason (to make clearer where it came from, to avoid namespace clashes, because "explicit is better than mplicit")!

Categories