How to getattr() of a function defined inside another function? Python - python

I have this file with unit tests:
#file tests.py
class TestResults(TestBase): ...
class TestRegisteredFunctions(TestBase):
"""Tests functions registered dynamically."""
def testNewFunction(self):
"""Server must register new functions."""
# Register new function
def square(num):
return num * num
self.server.register('square', square)
res = self.jsonrpc_req(1, 'square', [2])
self.assertEqual(res['result'], 4)
Most of the code is omitted because will not be relevant.
My problem is I need to grab that "square" function.
For example doing getattr(tests, 'square') in another module would correctly get me that square function. How can I achieve such result?

Related

Pytest mocking: pass kwargs through side_effect function

I want to test a file called ninja.py wrote in Python3.6.
# File ninja.py
def what_to_do_result(result):
# Send a mail, write something in a file, play a song or whatever
def my_function(a, b):
# Step 1
result = a + b
# Step 2
if result == 3:
what_to_do_result(result)
elif result == 5:
what_to_do_result(result + 1)
else:
return True
I have started writing a test file called test_ninjapy and wrote some unittest. I do use Pytest.
import pytest
class MyTestException(Exception):
pass
def run_side_effect(*args, **kwargs):
raise MyTestException(kwargs["result"])
#pytest.fixture(name="resource")
def setup_fixture():
# Some code here
class TestNinja:
#staticmethod
def setup_method():
# Function called before each test
#staticmethod
def teardown_method():
# Function called after each test
#staticmethod
def test_my_function(mocker, resource):
# How to do this ???
mocker.patch("ninja.what_to_do_result", return_value=None, side_effect=run_side_effect)
# Then the test
assert 1 == 1 # -> This works
with pytest.raises(MyTestException):
ninja_function(a=1, b=2)
assert ninja_function(a=5, b=10)
The point is that I want to mock the function ninja.what_to_do_result and apply a side effect (= run a function).
I want the side effect to use the parameter (kwargs) or the function what_to_do_result.
But I don't know how to do this.
For example:
Because there are multiple possibilities (in the step 2, the call of what_to_do_result could be with 3 & 5, which are linked with 2 differents use cases I wxant to test.
Can you help me?
I did not found the related section in the documentation below.
Link to the documentation: https://github.com/pytest-dev/pytest-mock

Mocking local function from another file

I need to patch a function imported from the same file containing another function I want to test, but it's not working =/.
# funcs.py
def func_one():
return 1
def func_two():
return func_one() + 2
from .funcs import func_two
class TestFunc(TestCase):
def test_func_two(self):
with patch('func_one', 0):
result = func_two()
The result should be two but I got an error with the test:
TypeError: Need a valid target to patch. You supplied: 'func_one'
I need to import the absolute path of the function:
from .funcs import func_two
class TestFunc(TestCase):
def test_func_two(self):
#patch('funcs.func_one', MagicMock(return_value=0)):
result = func_two()
Where funcs.func_one is the entire module path + func name.

Propagating a variable defined under a function (under a particular Class) to some other function under the same Class

I have a code which has few Classes in it. Under SecondClass, there is a function called plot_image. Under this function, there are three variables defined called my_x, my_y, my_z. I am trying to make these variables accessible inside some other function called get_histogram in the same Class. Here is a non-working example in the form of a pseudo-snippet:
import some_modules_in_here #these are required for classes below
#===================================================================================================
# utility
#===================================================================================================
class FirstClass(something.something.SayClass):
def file1(self, some_arguments):
pros = do_something
return pros
#===================================================================================================
# visualize
#===================================================================================================
class SecondClass(something.something.SayClass):
def plot_image(self, some_parameter):
if some_parameter is not None:
my_x = some_value1
my_y = some_value2
my_z = some_value3
def get_histogram(self, some_parameter, some_other_parameter, return_info):
if '3d' in some_parameter:
do_this
else:
do_that
if some_other_parameter:
calculate_something
if return_info:
for k, l, m in zip(my_x, my_y, my_z):
do_some_stuff
print(something_in_here)
return_value = do_something_else_in_here
return return_value
.
.
.
def print_values(self):
'''
write some values of image to file.
'''
Second = SecondClass()
I tried the keyword global at the top of the function plot_image but that doesn't do the job for me giving error message:
"NameError: Name 'my_x' is not defined."
What is the solution?

How to do python meta programming to pass code blocks around (like ruby yield)

Like ruby, how to pass code block and get it executed (yield) where you pass it. I am trying to achieve same thing in python 3.5
This is what my pseudo code looks like. How to achieve what I am trying to do. What changes would I have to make?
# Calculate all
# I want this function should yield whatever method passed to it
# THIS MUST BE A CLASS
class Calculator:
def __init__(self):
self.prefix = "hello"
def calculate(self, function_name)
local_val = 10
print("executing {} function with {}".format(function_name, self.prefix))
result = function_name(local_val)
print(result)
return result
# I want to pass these functions to Calculator().calculate() method
def add_one(x):
return x+1
def minus_one(x):
return x-1
def divide_in_half(x):
return x/2
Calculator().calculate(add_one(?))
# expect this to print:
# executing add_one function with hello
# 11
Calculator().calculate(minus_one(?))
# expect this to print:
# executing minus_one function with hello
# 9
Calculator().calculate(divide_in_half(?))
# expect this to print:
# executing divide_in_half function with hello
# 5
Functions are objects in Python, so you can just do this:
Calculator().calculate(add_one)
Calculator().calculate(minus_one)
Calculator().calculate(divide_in_half)
Note that this passes the function itself and not the name of the function. (In your code, you would have to access function_name.func_name to obtain the function's name, so I would suggest renaming function_name to fn, which is short for "function.")
You don't even need to declare predefined functions. You can use the lambda syntax to pass an anonymous callable on the fly:
# Instead of add_one, for example:
Calculator().calculate(lambda x: x + 1)
Initially, fix your __init__ so it doesn't complain when called with no args:
def __init__(self, prefix="hello")
use the function __name__ in the call to format done in calculate:
msg = "executing {} function with {}"
print(msg.format(function_name.__name__, self.prefix))
then pass the function objects along:
Calculator().calculate(add_one)
# expect this to print:
# executing add_one function with hello
# 11
Calculator().calculate(minus_one)
# expect this to print:
# executing minus_one function with hello
# 9
Calculator().calculate(divide_in_half)
# expect this to print:
# executing divide_in_half function with hello
# 5

Create dictionary dinamically and automatically assign the attributes from evaluations of functions

I'm working with a code that have this appearence:
module.py:
def attribute3():
return "something3"
def attribute2():
return "something2"
def attribute1():
return "something1"
main.py:
from module import attribute1, attribute2, attribute3
def main():
return {
"attribute1": attribute1(),
"attribute2": attribute2(),
"attribute3": attribute3()
}
print main()
And i would like to know if there is any better way to create the dictionary in the main function, without the necessaty of doing "attribute: function()". I'm feeling like i'm repeating my self.
I don't have access to the module.py code, so i can't change to a Class.
I'm using Python 2.5 because this is a legacy software.
Thanks.
You could use getattr and call the arbitrary functions returned.
import some_module
def create_dict(module, names):
resp = {}
for name in names: # Iterate over an arbitrary number of arguments
# Get the function with the name provided and call it,
# setting the response as the value for the name
resp[name] = getattr(module, name)()
return resp
print create_dict(some_module, ['attribute1', 'attribute2', 'attribute3'])
I didn't test this on Python 2.5 but I don't see any reason why it wouldn't work.

Categories