How to define instance methods from wrap - python

I am working on a django site and want to define some instance methods like below.
Class Auth(models.Model):
def wrap_has_perm(self, perm):
def wrap():
if self.is_staff and self.has_perm(perm):
return True
else:
return False
can_add_order = wrap_has_perm('finance.normal')
can_review_order = wrap_has_perm('finance.review')
is_leader = wrap_has_perm('finance.leader')
is_finance = wrap_has_perm('finance.finance')
I want to use can_add_order, can_review_order, is_leader, is_finance as django admin site's list_display element. But now these instance methods is illegal.(TypeError: wrap_has_perm() takes exactly 2 arguments (1 given))
How can I achieve these methods?
If I use partial:
def staff_has_perm(self, perm):
return self.is_staff and self.has_perm(perm)
can_add_order = partial(staff_has_perm, perm='finance.normal')
can_review_order = partial(staff_has_perm, perm='finance.review')
is_leader = partial(staff_has_perm, perm='finance.leader')
is_finance = partial(staff_has_perm, perm='finance.finance')
It raises (* TypeError: staff_has_perm() takes exactly 2 arguments (1 given));
Should I pass self to and how to ?

Move the self to wrap()'s definition:
def wrap_has_perm(perm):
def wrap(self):
However, a more Pythonic way to do this might be to use functools.partial:
from functools import partial
class Auth(models.Model):
def has_perm(self, perm):
# ...
can_add_order = partial(has_perm, perm='finance.normal')
can_review_order = partial(has_perm, perm='finance.review')
is_leader = partial(has_perm, perm='finance.leader')
is_finance = partial(has_perm, perm='finance.finance')

Related

How can I mock an attribute of a class using the mock decorator?

#these classes live inside exchanges/impl/tse/mixins.py
class PacketContext:
capture_tstamp = None
def __init__(self, capture_tstamp=None):
self.capture_tstamp = capture_tstamp
class SubParserMixin():
def __init__(self):
self.context = PacketContext()
def on_packet(self, packet):
self.context.capture_tstamp = packet.capture_timestamp
self.parse_er_data(packet.payload)
#this mock test lives in another python file
from exchanges.impl.tse.mixins import PacketContext
#patch.object(PacketContext, 'capture_tstamp', 1655417400314635000)
def test_receive_timestamp(self):
"""
test receive_timestamp is passed down correctly from PacketContext to on_packet()
"""
assert self.context.capture_tstamp == 1655417400314635000
I am trying to mock the self.capture_tstamp attribute in the PacketContext() class.
But in the above, I am getting an error that says
AssertionError: assert None == 1655417400314635000
E + where None = <exchanges.impl.tse.mixins.PacketContext object at 0x7fb324ac04c0>.capture_tstamp
E + where <exchanges.impl.tse.mixins.PacketContext object at 0x7fb324ac04c0> = <tests.unit.exchanges.tse.test_quote_write.TestTSE testMethod=test_receive_timestamp>.context
It seems very strange that the program is not recognising PacketContext().
You can make use of the patch.object decorator as below
class PacketContext:
capture_tstamp = None
def __init__(self, capture_tstamp=None):
self.capture_tstamp = capture_tstamp
<import_PacketContext_here>
#patch.object(PacketContext, 'capture_tstamp', 1655417400314635000)
def test_receive_timestamp():
test_instance = PacketContext()
assert test_instance.capture_tstamp == 1655417400314635000

Mock function to return different value based on argument passed

In my test function, my mocks are not behaving properly because when I mock my get_config function, I only know how to mock it to return one value. How can I add some logic to my mock in order for the mock to return a different value only when get_config is passed the argument of "restricted"
def func():
conf1 = get_config("conf1")
conf2 = get_config("conf2")
conf3 = get_config("conf3")
restricted_datasets = get_config("restricted")
dataset = get_config("dataset")
if dataset not in restricted_datas:
return run_code()
You can assign a function to side_effect as described in official doc
from unittest.mock import Mock
def side_effect(value):
return value
m = Mock(side_effect=side_effect)
m('restricted')
'restricted'
class Ctx():
def get_config(confName):
return confName
def mock_get_config(value):
if value == "conf1":
return "confA"
elif value == "conf2":
return "confB"
else:
return "UnknownValue"
class CtxSourceFileTrial(unittest.TestCase):
def test(self):
mockCtx = Mock()
mockCtx.get_config.side_effect = mock_get_config
self.assertEqual("confA", mockCtx.get_config("conf1"))
self.assertEqual("confB", mockCtx.get_config("conf2"))
#
# By the way I think Python is EXTREMELY screwy, Adligo
#

Render template based on the name of the endpoint in Flask?

I'm looking to make the code more maintainable. Right now "thing1" is repeated three times. Is there a way to make this
#app.route("/thing1")
def thing1():
return render_template("thing1.ejs")
#app.route("/thing2")
def thing2():
return render_template("thing2.ejs")
#app.route("/thing3")
def thing3():
return render_template("thing3.ejs")
More like...
#app.route("/thing1")
def thing1():
return render_template_name_of_function() # should render thing1
#app.route("/thing2")
def thing2():
return render_template_name_of_function() # should render thing2
#app.route("/thing3")
def thing3():
return render_template_name_of_function() # should render thing3
This is how it would be done.
#app.route("/thing1")
def thing1():
return render()
#app.route("/another_thing1")
def another_thing1():
return render()
#app.route("/yet_anther_thing1")
def yet_antoher_thing1():
return render()
def render():
return render_template("thing1.ejs")
Although, unless you think it is absolutely necessary, I would argue it should be done by using redirect("thing1").
You can try to read function infos by using inspect module, to get the currently function name:
import inspect
#app.route("/thing1")
def thing1():
return render_template(inspect.stack()[0][3])
#app.route("/thing2")
def thing2():
return render_template(inspect.stack()[0][3])
#app.route("/thing3")
def thing3():
return render_template(inspect.stack()[0][3])
Then, you can specify a extension to template file, after the inspect.stack() call, such as inspect.stack()[0][3] + '.html'

how to do argument matching, capturing in python

I am trying to understand how to mock in python external dependencies while doing mock methods argument matching and argument capture.
1) Argument matching:
class ExternalDep(object):
def do_heavy_calc(self, anInput):
return 3
class Client(object):
def __init__(self, aDep):
self._dep = aDep
def invokeMe(self, aStrVal):
sum = self._dep.do_heavy_calc(aStrVal)
aNewStrVal = 'new_' + aStrVal
sum += self._dep.do_heavy_calc(aNewStrVal)
class ClientTest(unittest.TestCase):
self.mockDep = MagicMock(name='mockExternalDep', spec_set=ExternalDep)
###
self.mockDep.do_heavy_calc.return_value = 5
### this will be called twice regardless of what parameters are used
### in mockito-python, it is possible to create two diff mocks (by param),like
###
### when(self.mockDep).do_heavy_calc('A').thenReturn(7)
### when(self.mockDep).do_heavy_calc('new_A').thenReturn(11)
###
### QUESTION: how could I archive the same result in MagicMock?
def setUp(self):
self.cut = Client(self.mockDep)
def test_invokeMe(self):
capturedResult = self.cut.invokeMe('A')
self.assertEqual(capturedResult, 10, 'Unexpected sum')
# self.assertEqual(capturedResult, 18, 'Two Stubs did not execute')
2) Argument Capturing
I cannot find good docs or examples on neither MagicMock or mockito-python able to accommodate the following mocking scenario:
class ExternalDep(object):
def save_out(self, anInput):
return 17
class Client(object):
def __init__(self, aDep):
self._dep = aDep
def create(self, aStrVal):
aNewStrVal = 'new_' + aStrVal if aStrVal.startswith('a')
self._dep.save_out(aNewStrVal)
class ClientTest(unittest.TestCase):
self.mockDep = MagicMock(name='mockExternalDep', spec_set=ExternalDep)
###
self.mockDep.save_out.return_value = 5
### this will be called with SOME value BUT how can I capture it?
### mockito-python does not seem to provide an answer to this situation either
### (unline its Java counterpart with ArgumentCaptor capability)
###
### Looking for something conceptually like this (using MagicMock):
### self.mockDep.save_out.argCapture(basestring).return_value = 11
###
### QUESTION: how could I capture value of parameters with which
### 'save_out' is invoked in MagicMock?
def setUp(self):
self.cut = Client(self.mockDep)
def test_create(self):
capturedResult = self.cut.create('Z')
self.assertEqual(capturedResult, 5, 'Unexpected sum')
### now argument will be of different value but we cannot assert on what it is
capturedResult = self.cut.create('a')
self.assertEqual(capturedResult, 5, 'Unexpected sum')
If anyone could show me how to accomplish these two mocking scenarios (using MagicMock), I would be very grateful! (Please ask if something is unclear.)
Something that might help you is to use assert_called_with with a Matcher.
This will allow you to have a finer grain access to the arguments on your calls. i.e.:
>>> def compare(self, other):
... if not type(self) == type(other):
... return False
... if self.a != other.a:
... return False
... if self.b != other.b:
... return False
... return True
>>> class Matcher(object):
def __init__(self, compare, some_obj):
self.compare = compare
self.some_obj = some_obj
def __eq__(self, other):
return self.compare(self.some_obj, other)
>>> match_foo = Matcher(compare, Foo(1, 2))
>>> mock.assert_called_with(match_foo)

Python Strategy Pattern: using class wrapper not function + simple_vs_easy_logic

I am trying to build a Strategy Pattern using S.Lott's response.
Problem is function returns None.
Am using Hickey's Simple vs Easy {what, how, who}-logic.
-[WHAT] I/O
class base_fnc(object):
def fncExc(self,data1,data2):
return
-[HOW] DATA <> queue[where,when] (direct injection)
class stump( base_fnc ):
def fncExc(self, d1, aContext):
return d1
class MAB(base_fnc ):
def fncExc(self, d, aContext ):
return d+10
-[WHO] API
class context( object ):
def __init__(self, alt_how_class ):
self.how = alt_how_class
def exc(self, d ):
return self.how.fncExc(d, self)
if __name__ == "__main__":
c1 = context(MAB())
ss=c1.exc(10)
print ss
ss prints None
You're not returning in exc. You need to do return self.how.fncExc(d, self).

Categories