name not defined in python module - python

I see python throwing the below error
"errorMessage": "name 'get_client' is not defined",
Below is my code
get_client()
def get_client():
# optional fields
level = 'INFO'
verify = True

You are trying to call or execute the function before it was defined.
Try to alter the order of the 2 parts:
def get_client():
# optional fields
level = 'INFO'
verify = True
get_client()
Does that work for you?
Code is read from top to bottom by the python internpreter; at this point the functions that are defined are registered in the global namespace, but the content of those functions does not get executed yet (just syntax checking is done) unless they are specifically invoked.
For example:
def f1():
print('1')
print('A')
f1()
print('B')
def f2():
print('2')
Here f1() is registered and then it is executed even before f2() has been registered in the namespace. The output of running the example would be:
A
1
B
f2() never gets called in this code, so its print statement never writes anything to the output.

You are calling on a function before you have defined it.
Try:
def get_client():
# optional fields
level = 'INFO'
verify = True
get_client()

Python interpreter reads from top to bottom. Thus, you need to call your function AFTER you have defined it:
def get_client():
# optional fields
level = 'INFO'
verify = True
get_client()

Related

How can I mock out this python function properly?

I have the following function in a file called my_file.py:
import logging
log = logging.getLogger(__name__)
class MyClass:
def my_func(self):
print("Entered my_func()")
print("log.error = {}".format(log.error))
log.error("Hello World")
When my_func() is run, I see this output:
Entered my_func()
log.error = <bound method ProcessAwareLogger.error of <celery.utils.log.ProcessAwareLogger object at 0x7fd52d4f0d50>>
I want to write a unit-test case to check that whenever my_func() is called, log.error() is called with the argument "Hello World".
So my test case looks like this:
import mock
from my_file import MyClass
#mock.patch("my_file.logging.error")
def test_parse_response_with_error(self, mock_log_error):
m = MyClass()
m.my_func()
mock_log_error.assert_called_once_with("Hello World")
When I run this test case, I get the error: AssertionError: Expected to be called once. Called 0 times. So my patch apparently didn't work. Did I specify the path my_file.logging.error wrong? How can I make this work properly so that the unit-test case passes?
You mocked the wrong thing. log.error creates a bound method that is distinct from logging.error, and that method already has a reference to the "real" logging.error saved before your patch was created.
Instead, mock the error attribute of the Logger instance directly.
#mock.patch.object(my_file.log, 'error'):
def test_it(self, mock_log_error):
m = MyClass()
m.my_func()
mock_log_error.assert_called_once_with("Hello World")
(It's possible that patching logging.error before importing my_file might work.)

Print statement executing but function call directly after failing assert_called

tl;dr: I know a code block I am testing with unittest is being executed because of a print statement, but a function directly after the print statement is failing an assert_called check. When running the code, the function is being called and exectued as expected. Unclear why test is failing.
Code in function being tested:
from path.to import deliver_error
def handle_error(ARGS):
if HANDLE_ERROR_BOOL:
print('calling deliver_error')
deliver_error(ARGS)
else:
# do something else
Test code:
class TestSampleRegistration(unittest.TestCase):
def setUp():
# mock deliver_error
mock_deliver_error_patch = patch("path.to.deliver_error", autospec=True)
self.mock_deliver_error = mock_deliver_error_patch.start()
self.addCleanup(mock_deliver_error_patch.stop)
def test_handle_error(self):
main.HANDLE_ERROR_BOOL = True
handle_error(ARGS)
self.mock_deliver_error.assert_called() # point of failure
Assertion failure:
AssertionError: Expected 'deliver_error' to have been called.
Captured stdout:
Captured stdout for test_main.MyTestClass.test_handle_error
calling deliver_error
I KNOW:
HANDLE_ERROR_BOOL is correctly set (print statement executed and showing up in stdout)
deliver_error should be getting called since there is nothing between the print statement and the deliver_error call, and the print statement is being executed
when running the actual code the function is being executed as expected
So why is the assert_called test failing? Help very much appreciated, thank you!
Answering for the sake of others who might see this post:
As per MrBean Bremen's comment, the resolution was to update the mock from
class TestSampleRegistration(unittest.TestCase):
def setUp():
# mock deliver_error
mock_deliver_error_patch = patch("path.to.deliver_error", autospec=True)
to
class TestSampleRegistration(unittest.TestCase):
def setUp():
# mock deliver_error
mock_deliver_error_patch = patch("mymodule.deliver_error", autospec=True)

Call a Function by alias in a Decorator

The current code I have, allows the function to call the wrapper decorator, and uses the function name in its code. However, I'm looking for a way to give the function a 'alias' in a way as an argument. Here's the current code:
import os, sys
# Take user input
message = input('type command: ')
# Command wrapper
ALLCOMMANDS = {}
def command(function):
ALLCOMMANDS[function.__name__] = function
return function
# Commands
#command
def foo():
print("bar")
#command
def goo():
print('ber')
# Run appropriate command
if message in ALLCOMMANDS:
ALLCOMMANDS[message]()
For example I would want to be able to call the function by a name such as '!foo' from the user input, so maybe the argument would look like #command(name='!foo'), I just don't know where to go from there to use that argument in the decorator since it already has an argument.
I attempted
# Command wrapper
ALLCOMMANDS = {}
def command(name):
ALLCOMMANDS[name] = name
return name
but keep getting errors and I assume I am missing something
You should read up a bit more on python decorators. You're getting an error with:
def command(name):
ALLCOMMANDS[name] = name
return name
Because of the return name.
Decorators are just syntactic sugar. This:
#command
def foo():
print('bar')
Is equivalent to:
def foo():
print('bar')
foo = command(foo)
From this you can see why your original decorator works. At the end you return function.
Things get a little tricker when you have a decorator that takes arguments. Desugared the following:
#command('nickname')
def foo():
print('bar')
Looks like this:
def foo():
print('bar')
foo = command('nickname')(foo)
So, to write a decorator that takes arguments, the decorator needs to return a function that takes the function to decorate as an argument:
def command(nickname):
def wrapped(f):
ALLCOMMANDS[nickname] = f
return f
return wrapped
Also consider making ALLCOMMANDS an attribute on your command instead of a global (UPPER_SNAKE is usually reserved for constants):
def command(nickname):
def wrapped(f):
command._functions[nickname] = f
return f
return wrapped
command._functions = {}

declarations within python class equivalent to _init_?

I was wondering if the declarations put at the top of the python class are equivalent to statements in __init__? For example
import sys
class bla():
print 'not init'
def __init__(self):
print 'init'
def whatever(self):
print 'whatever'
def main():
b=bla()
b.whatever()
return 0
if __name__ == '__main__':
sys.exit( main() )
The output is:
not init
init
whatever
As a sidenote, right now I also get:
Fatal Python error: PyImport_GetModuleDict: no module dictionary!
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Any ideas on why this is? Thank you in advance!
No, it's not equivalent. The statement print 'not init' is run while the class bla is being defined, even before you instantiate an object of type bla.
>>> class bla():
... print 'not init'
... def __init__(self):
... print 'init'
not init
>>> b = bla()
init
They aren't exactly the same, because if you do c=bla() afterwards it will only print init
Also, if you reduce your main() to just return 0 it still prints the not init.
Declarations such as that are for the whole class. If print was a variable assignment rather a print statement then the variable would be a class variable. This means that rather than each object of the class having its own, there is only one of the variable for the whole class.
They are not equivalent. Your print statement outside the init method is only called once, when he class is defined. For example, if I were to modify your main() routine to be the following:
def main():
b=bla()
b.whatever()
c = bla()
c.whatever()
return 0
I get the following output:
not init
init
whatever
init
whatever
The not init print statement executes once, when the class is being defined.

UnboundLocalError from imported class

I have some code that is structured as follows
from my.modules import MyClass
Class AnotherClass(object):
def __init__(a): #line 5
if a:
setup_a()
else:
setup_b()
def setup_a():
# Do some stuff to get local_x
# ..
self.a = MyClass(local_x)
def setup_b():
# Do some stuff to get local_y
# ..
self.b = MyClass(local_y)
However I run with a = True in line 5 it runs fine, but when I run with a = False I get an UnboundedLocalError. I understand what causes this normally (modifying a global variable) and if I change setup_b() to:
def setup_b():
global MyClass
# Do some stuff to get local_y
# ..
self.b = MyClass(local_y)
It works correctly. I just don't understand why I am getting this error as I am not modifying the MyClass by instantiating it.
Note: The above example is a basic version of the code not the actual code producing the error.
Does anyone know what is causing this error?
Somewhere in the code you're not showing you're assigning to MyClass, making the compiler think that it's a local variable when it's not.

Categories

Resources