Running unit tests on nested functions
I come from the Java world, where you can hide variables and functions and then run unit tests against them using reflection. I have used nested functions to hide implementation details of my classes so that only the public API is visible. I am trying to write unit tests against these nested functions to make sure that I don't break them as I develop. I have tried calling one of the nested functions like:
def outer():
def inner():
pass
outer.inner()
which results in the error message:
AttributeError: 'function' object has no attribute 'inner'
Is there a way for me to write unit tests against these nested functions? If not, is there a way to trigger the name munging for function names like you can for class variables by prefixing them with __?
Asked by: Maddie843 | Posted: 28-01-2022
Answer 1
inner doesn't exist until outer makes it. You should either move inner up to a toplevel function for testability, or have the outer test test all the possible execution paths of itself and inner.
Do note that the inner function isn't a simple function, it's a closure. Consider this case:
def outer(a):
b = compute_something_from(a)
def inner():
do_something_with(a, b)
That's the standard testability trade-off. If your cyclomatic complexity is too high, your tests will be too numerous.
Answered by: Catherine810 | Posted: 01-03-2022Answer 2
I have written a small helper module which allows exactly this:
Examples of nested functions:
def f(v1):
v2 = 1
def g(v3=2):
return v1 + v2 + v3 + 4
def h():
return 16
return g() + h() + 32
class C(object):
def foo(self):
def k(x):
return [ self, x ]
return k(3)
def m():
vm = 1
def n(an=2):
vn = 4
def o(ao=8):
vo = 16
return vm + an + vn + ao + vo
return o()
return n()
These can be unit tested using this kind of code:
import unittest
from nested import nested
class TestNested(unittest.TestCase):
def runTest(self):
nestedG = nested(f, 'g', v1=8, v2=1)
self.assertEqual(nestedG(2), 15)
nestedH = nested(f, 'h')
self.assertEqual(nestedH(), 16)
nestedK = nested(C.foo, 'k', self='mock')
self.assertEqual(nestedK(5), [ 'mock', 5 ])
nestedN = nested(m, 'n', vm=1)
nestedO = nested(nestedN, 'o', vm=1, an=2, vn=4)
self.assertEqual(nestedO(8), 31)
def main(argv):
unittest.main()
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))
The small helper module nested
looks like this:
import types
def freeVar(val):
def nested():
return val
return nested.__closure__[0]
def nested(outer, innerName, **freeVars):
if isinstance(outer, (types.FunctionType, types.MethodType)):
outer = outer.func_code
for const in outer.co_consts:
if isinstance(const, types.CodeType) and const.co_name == innerName:
return types.FunctionType(const, globals(), None, None, tuple(
freeVar(freeVars[name]) for name in const.co_freevars))
Answered by: Sydney314 | Posted: 01-03-2022
Answer 3
The Python convention is to name "private" functions and methods with a leading underscore. When you see a leading underscore, you know not to try and use it.
Remember, Python is not Java.
Answered by: Ted660 | Posted: 01-03-2022Answer 4
I don't think that there is any chance to access inner() from the extern namespace.
However, in my opinion the fact that you keep inner() nested implies that the only "contract" that really matters is outer()'s one. inner() is part of the implementation, and you shouldn't want to test the implementation. If you really want to test inner(), do extensive tests on outer() with data that will involve all the functionalities of inner().
Answered by: Joyce332 | Posted: 01-03-2022Answer 5
I had the same doubt and found a way to get tests going for inner functions.
def outer():
def inner():
pass
if __debug__:
test_inner(inner)
# return
def test_inner(f):
f() # this calls the inner function
outer()
Basically you can send the inner function as a parameter to the outside and test it as you wish. When calling outer(), your test will run, and since it's a closure, it will preserve any extra property from the outer function (like variables). Using a list, you can send as many functions as you wish. To ignore the if, an option is to run the code like that:
python -O code.py
Answered by: Chloe541 | Posted: 01-03-2022
Answer 6
No way to get inner function from outer function object (see the other replies!). Yet both unit tests and closures have made (for me at least) amazing developer performance improvements. Can we have both? Can we test nested functions in isolation?
Not easily.
However, such could seemingly be achieved with use of python modules parser, ast, or tokenizer to dice up the code itself, extracting inner functions (by some path through the nesting), and allowing tests to run them with state from enclosing functions (values for closed-over names) and stubs/mocks for more-nested functions (defined within the test target).
Anybody know of anything like this? Googling failed to find anything.
Answered by: Blake800 | Posted: 01-03-2022Answer 7
I ran into an interesting case where I was able to run a unit test on a nested function using MagicMock. The key was that the nested function was being sent as an argument to another function that I had access to. To keep with the OP's example:
# my_app.py
def util(func):
# run some logic using func
def outer():
def inner():
pass
util(inner)
Being able to mock the util
function allowed access to the call arguments, which in this case happens to be the inner
function:
def test_inner
# Arrange
mock_util = MagicMock()
with patch.object(my_app, 'util', mock_util):
outer() # run the outer function to capture the util call with MagicMock
inner_function = mock_util.call_args[0][0]
# Act
inner_function() # run the inner function for testing
# Assert
# make whatever assertions you would like
I got lucky this time, in that I did not need to alter the code that I was asked to test. @Victor-Barroso's answer features an intentional way to do something similar, for those who are looking for options. Although, if you are going to alter the code, you may as well follow @Dustin's advice or any of the other good answers on this question.
Answered by: Marcus351 | Posted: 01-03-2022Similar questions
python - Running functions from a list issue
I am wondering how to run functions from a list, and calling them using the random module, but I can't seem to get it to work can anyone help? Here is an example below.
import random
def word1():
print "Hello"
def word2():
print "Hello again"
wordFunctList = [word1, word2]
def run():
printWord = random.randint(1, len(wordFunctList))-1
wordFunctList[printWord]
run()
run()...
python - Thread for each item in list, running two functions for each item in list
I'll preface this with I'm new to threading. I have tried a couple different ways, and come sort of close to success, but not really.
I have a list that is created from a file as such:
with open(server_file, 'rU') as fi:
servers = fi.read().split('\n')
I have two functions grabdata() and runcheck() that I need to be run for each item in the list, each pair (grabdata and then ru...
python - Functions running when not being called
This question already has answers here:
python - Call functions that are inside a running thread
I have this code:
def Spawn(nick,password):
Active=True
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('asdasd',asdasdasd))
s.send('PASS '+password+'\r\n')
s.send('NICK '+nick+'\r\n')
s.send('JOIN '+channel+'\r\n')
while True:
buf=s.recv(1024)
if('PRIVMSG' in buf):
sender=buf.split('!',1)[0].split(':')
message=buf.split(':'...
python - What is the running time of these functions?
What is the running time?
def a(n):
if n % 2 == 0:
return n
else:
return a(n/2)
My guess T(n) = T(n/2) + 1, then use master theorem.
How about this function:
def b(n):
for i in range(n):
print(a(i))
This is my guess.
T(n) = nT(n/2) + 1
Python functions running too fast?
I'm writing a script (Python 2.7.10) to log in to networking devices and gather diagnostics information that the vendor can potentially ask for. It's fairly straightforward, but I've run into an interesting problem (at least for me).
I've exhausted my limited knowledge on this.
This is the piece of the code that calls the functions to run:
elif args.hostname and args.username and args.jtac ...
python - Why is one of my functions running twice?
The function search_for_song(pbody) is running twice, i can't figure out why.
would like some help, just started learning python a few days ago.
Here's the full code:
#a bot that replies with youtube songs that were mentioned in the comments
import traceback
import praw
import time
import sqlite3
import requests
from lxml import html
import socket
import errno
import re
import urllib
from bs4 import...
python - Functions aren't running
My functions in Python aren't returning values that I expect them to. Here is a MWE:
a = 6
b = 18
c = 0
def random_function(c):
c = b/a
return c
random_function(c)
print(c)
I expect this function to print 3, but instead it prints 0. I have just updated from 2.7 to 3.6 and this would have worked in 2.7 - what am I doing wrong?
python - Running nested functions using numba
I am trying to use numba recently to speedup parts of my code in python. I was trying to run function 1 from inside function 2 while they are both compiled with numba but it is not working. Here is my code:
import numba as nb
from math import acos
from time import time
@nb.jit("void()")
def myfunc():
s = 0
for i in range(10000000):
s += acos(0.5)
print('The sum is: ', s)
@nb.jit("void...
python - Running unit tests with pytest on functions
I am trying to run a unit test on a set of functions. The functions return multiple pandas dataframes.
How would I approach asserting equality between multiple dataframes using pytest?
Appreciate your help!
@pytest.fixture
def function_to_test():
df1 = pd.DataFrame({'random': ['1'],'columns': ['One']})
df2 = pd.DataFrame({'random': ['1'],'columns': ['One']})
df3 = pd.DataFrame({'...
python - Running different functions based on the user's input
I am new to Pycharm, and Python as a whole, and for my first project I decided to do a random name/object selector which chooses a name from a pre-made variable of letters and prints that result.
I wanted to expand on this and have the user either use the default names in the code or add their own names to be used.
I gave it my best effort but when it came to the script running 1 of two functions I was unable to figure ou...
python - 2 functions in scrapy spider and the second one not running
I am using scrapy to get the content inside some urls on a page, similar to this question here:
Use scrapy to get list of urls, and then scrape content inside those urls
I am able to get the subURLs from my start urls(first def), However, my second def doesn't seem to be passing throu...
functions in list loop not running one by one in python
i have 5+ functions, so i want to run all functions one by one in series. like if i put loop range = 10 and i have 5 functions on list, so func1() should run once and func2() on 2nd and func3() on 3rd range and it should be in loop until range = 10 reaches.
loop = 10
funcs = [func1(), func2(), func3(), func4(), func5()]
for i in range(funcs,loop):
print(i)
i have trie...
python - Issue running functions in pygame
import pygame
import random
import time
pygame.init()
backX = 1000
backY = 600
screen = pygame.display.set_mode((backX, backY))
score = 0
white = (255, 255, 255)
green = (0, 255, 0)
blue = (0, 0, 128)
timespent = 0
pygame.display.set_caption('Monkey Simulator') # game name
pygame.font.init() # you have to call this at the start,
# if you want to use this module.
myfont = pygame.font.SysFont('Comic Sans MS', 30)...
python - Running two functions at the same time?
from turtle import *
a = Screen()
b = Turtle()
c = Turtle()
def one():
b.forward(100)
def two():
c.forward(-100)
I want b and c moving away from each other at the same time, tried lots of stuff but I cant figure it out. Help me out please.
Why does running java functions from a python script crash
I am trying to use java classes in a python script by importing jpype, however, every time I do so, the execution crashes.
I am running the script using python3 on macOS, and JVM is zulu-8.jdk.
Here is the script
import jpype as jp
jp.startJVM(jp.getDefaultJVMPath(), "-ea")
jp.java.lang.System.out.println("hello world")
jp.shutdownJVM()
Crash mess...
.net - Running CPython functions from C#
I'm working on a project where I need to be able to run a python function that depends on SciPy/NumPy. Due to this being an add-on to a project already in progress, using IronPython would not be an option.
Additional info:
Python.NET seemed to be a good fit, but I was unable to get the return value from RunString() (it would only return NULL).
Passing arguments and ...
Running python functions in Eclipse command line
I would like to run a python function using the command line in Eclipse (if it exists), just like the normal Python Shell (IDLE) or programs such as MATLAB. How would I do that.
python - running different classes and functions
Im a threading noob. I'm trying to run a function as a thread that weighs something, and another that checks that the weight is sensible -- and shuts down both threads if the weights are not. This is running on a beagleboneblack -- but that is probably not relevant. For the purposes of simplicity, I include here code that produces the same sort of undesired behaviour -- but is simplified.
from time import ...
python - Running functions from a list issue
I am wondering how to run functions from a list, and calling them using the random module, but I can't seem to get it to work can anyone help? Here is an example below.
import random
def word1():
print "Hello"
def word2():
print "Hello again"
wordFunctList = [word1, word2]
def run():
printWord = random.randint(1, len(wordFunctList))-1
wordFunctList[printWord]
run()
run()...
python - Thread for each item in list, running two functions for each item in list
I'll preface this with I'm new to threading. I have tried a couple different ways, and come sort of close to success, but not really.
I have a list that is created from a file as such:
with open(server_file, 'rU') as fi:
servers = fi.read().split('\n')
I have two functions grabdata() and runcheck() that I need to be run for each item in the list, each pair (grabdata and then ru...
python - Running functions defined within classes
I have a python class which houses some info. I have another file which some of these functions refer to. My get_date , is working fine however, none of my other functions seem to be working. I am getting the error AttributeError: PVData instance has no attribute 'time' when calling the time function.
class PVData:
def __init__(self):
self.date = yesterday()
se...
python - Functions running when not being called
This question already has answers here:
python - Call functions that are inside a running thread
I have this code:
def Spawn(nick,password):
Active=True
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('asdasd',asdasdasd))
s.send('PASS '+password+'\r\n')
s.send('NICK '+nick+'\r\n')
s.send('JOIN '+channel+'\r\n')
while True:
buf=s.recv(1024)
if('PRIVMSG' in buf):
sender=buf.split('!',1)[0].split(':')
message=buf.split(':'...
python - What is the running time of these functions?
What is the running time?
def a(n):
if n % 2 == 0:
return n
else:
return a(n/2)
My guess T(n) = T(n/2) + 1, then use master theorem.
How about this function:
def b(n):
for i in range(n):
print(a(i))
This is my guess.
T(n) = nT(n/2) + 1
Python functions running too fast?
I'm writing a script (Python 2.7.10) to log in to networking devices and gather diagnostics information that the vendor can potentially ask for. It's fairly straightforward, but I've run into an interesting problem (at least for me).
I've exhausted my limited knowledge on this.
This is the piece of the code that calls the functions to run:
elif args.hostname and args.username and args.jtac ...
variadic functions - Passing on named variable arguments in python
Say I have the following methods:
def methodA(arg, **kwargs):
pass
def methodB(arg, *args, **kwargs):
pass
In methodA I wish to call methodB, passing on the kwargs. However, it seems that if I define methodA as follows, the second argument will be passed on as positional rather than named variable arguments.
def methodA(arg, **kwargs):
methodB("arg...
storing unbound python functions in a class object
I'm trying to do the following in python:
In a file called foo.py:
# simple function that does something:
def myFunction(a,b,c):
print "call to myFunction:",a,b,c
# class used to store some data:
class data:
fn = None
# assign function to the class for storage.
data.fn = myFunction
And then in a file called bar.py:
import foo
d = foo.data
d.fn(1,2,3)
python - Porting MATLAB functions to Scilab. How do I use symbolic?
I'm porting some MATLAB functions to Scilab. The cool thing is that there is a conversion toolbox that make things very easy.
The problem is I did not find the counterpart to...
python - Parsing Functions
I'm making a script parser in python and I'm a little stuck. I am not quite sure how to parse a line for all its functions (or even just one function at a time) and then search for a function with that name, and if it exists, execute that function short of writing a massive list if elif else block....
EDIT
This is for my own scripting language that i'm making. its nothing very complex, but i have a...
python - How to call java objects and functions from CPython?
I have a python program, which runs on the CPython implementation, and inside it I must call a function defined in a java program. How can I do this?
It would be nice to be able to use some java objects too.
Jython is not an option. I must run the python part in CPython.
Passing functions which have multiple return values as arguments in Python
So, Python functions can return multiple values. It struck me that it would be convenient (though a bit less readable) if the following were possible.
a = [[1,2],[3,4]]
def cord():
return 1, 1
def printa(y,x):
print a[y][x]
printa(cord())
...but it's not. I'm aware that you can do the same thing by dumping both return values into temporary variables, but it doesn't seem as elega...
Passing self to class functions in Python
This question already has answers here:
c# - Import python functions into a .NET language?
I am a C# .NET programmer and am learning Python. I have downloaded IronPython, and know that it can call into .NET libraries.
I'm wondering whether there is a way to do the reverse, that is to call into some existing "classic" Python libraries in my C# code, maybe using .NET Interop.
I'd like to be able to access functions in libraries such as pygame.
Python Hash Functions
What is a good way of hashing a hierarchy (similar to a file structure) in python?
I could convert the whole hierarchy into a dotted string and then hash that, but is there a better (or more efficient) way of doing this without going back and forth all the time?
An example of a structure I might want to hash is:
a -> b1 -> c -> 1 -> d
a -> b2 -> c -> 2 -> d
a -> c ...
Passing functions with arguments to another function in Python?
This question already has answers here:
Still can't find your answer? Check out these communities...
PySlackers | Full Stack Python | NHS Python | Pythonist Cafe | Hacker Earth | Discord Python