How to avoid running argument function before the main function - python

I want to create a function that will react according to the success of the argument function and get the argument function's name.
Something like
def foo(argument_function):
try:
argument_function
print(f"{somehow name of the argument_function} executed successfully.")
except:
print(f"{somehow name of the argument_function} failed.")
argument_function should be executed only under the try statement. Otherwise, it will give an error and stop the script which I am trying to avoid.
{somehow name of the argument_function} should return the name of the argument_function.
for successful attempt:
foo(print("Hello world!"))
should return
>>Hello world!
>>print("Hello world!") executed successfully.
for unsuccessful attempt:
foo(prnt("Hello world!"))
should return
>>prnt("Hello world!") failed.

import typing
def foo(argument_function:typing.Callable):
try:
argument_function()
print(f"{argument_function.__name__} executed successfully.")
except:
print(f"{argument_function.__name__} failed.")
print(foo.__name__) # returns foo
Or use:
def foo(argument_function:callable):
__name__ returns function name and if you ensure the function is an object then adding () should run the function

Related

Access to contextvars in asyncio add_done_callback callback

In Python async function I'am creating ContextVar, task and attaching callback to it:
bbb = contextvars.ContextVar('aaa')
bbb.set(3)
task = self.loop.create_task(self.someFunc())
task.add_done_callback(self.commonCallback)
bbb.set(4)
In callback I first start debugger:
def commonCallback(self, result):
pdb.set_trace()
try:
r = result.result()
print(r)
except:
self.log.exception('commonCallback')
And in debugger:
-> try:
(Pdb) bbb.get()
*** NameError: name 'bbb' is not defined
(Pdb) ctx = contextvars.copy_context()
(Pdb) print(list(ctx.items()))
[(<ContextVar name='aaa' at 0xa8245df0>, 3)]
(Pdb)
ContextVar is there, but I can't access it. So, I am missing something, but can't find what?
The bbb local variable is defined in one place, so it won't be automatically accessible in another, such as the commonCallback function defined elsewhere in the code. The documentation states that "Context Variables should be created at the top module level", so you should try that first.
You can get a value from context without importing top level module.
contextvars.Context has __iter__ method. And you can use a for loop to get the value:
def get_ctx_var_value(ctx, var_name, default_value=None):
for var in ctx:
if var.name == var_name:
return ctx[var]
return default_value
ctx = contextvars.copy_context()
var_value = get_ctx_var_value(ctx, 'aaa')

How to call a variable from other file in python?

I have created 2 files.
a.py has a class foo() and b.py has a class fun(). fun() is a child class of foo().
foo() has a function given below:
def get_random_password(self):
" func to generate random password "
try:
password_characters = string.ascii_letters + string.digits + string.punctuation
nw_password = ''.join(random.choice(password_characters) for i in range(30))
return nw_password
now i want to use this nw_password variable in some other function of fun() ( given below function is used for user login)
username = self.driver.find_element_by_id("username")
time.sleep(3)
username.send_keys(self.vm_spec_dic['name'])
time.sleep(5)
password = self.driver.find_element_by_id("password")
time.sleep(5)
password.send_keys(nw_password)
time.sleep(10)
login = self.driver.find_element_by_id("loginBtn")
login.click()
I am using selenium to automate. I want to call variable nw_password from a.py to b.py. but getting error? I am getting errors like module 'lib.b' has no attribute 'nw_password' ????
from a import nw_password
Importing is not working
The scope of the variable is only inside the function definition, you could probably use a variable and store the return of the get_random_password(self) method
var = yourObjectFromfoo.get_random_password()
then try to import that var
To import your function try this:
from a import get_random_password
If you want to save it to a variable called nw_password you can do this in you main file:
nw_password = get_random_password()
nw_password is just the name of your returned value you're not storing it anywhere. So to get the random password you have to actually run the function you created. And as others have said the variable would be inside the function scope anyway so you would have to make it a global variable (not recommended).

How to mock PythonOperator's python_callable and on_failure_callback?

What and where do I mock, with an Airflow PythonOperator, such that:
the python_callback raises a exception, triggering the call of the on_failure_callback, and
I can test whether that callback is called, and with what arguments?
I have tried mocking both the {python_callable} and PythonOperator.execute, in a number of places, without success.
The code files look something like this:
dags/my_code.py
class CustomException(Exception): pass
def a_callable():
if OurSqlAlchemyTable.count() == 0:
raise CustomException("{} is empty".format(OurSqlAlchemyTable.name))
return True
def a_failure_callable(context):
SlackWebhookHook(
http_conn_id=slack_conn_id,
message= context['exception'].msg,
channel='#alert-channel'
).execute()
dags/a_dag.py
from my_code import a_callable, a_failure_callable
new_task = PythonOperator(
task_id='new-task', dag=dag-named-sue, conn_id='a_conn_id', timeout=30,
python_callable=a_callable,
on_failure_callback=a_failure_callable)
dags/test_a_dag.py
class TestCallback(unittest.TestCase):
def test_on_failure_callback(self):
tested_task = DagBag().get_dag('dag-named-sue').get_task('new-task')
with patch('airflow.operators.python_operator.PythonOperator.execute') as mock_execute:
with patch('dags.a_dag.a_failure_callable') as mock_callback:
mock_execute.side_effect = CustomException
tested_task.execute(context={})
# does failure of the python_callable trigger the failure callback?
mock_callback.assert_called()
# did the exception message make it to the failure callback?
failure_context = mock_callback.call_args[0]
self.assertEqual(failure_context['exception'].msg,
'OurSqlAlchemyTable is empty')O
The test does raise CustomException at the line self.task.execute(context={}) -- but, in the test code itself. What I want is for that error to be
raised in the Airflow code such that the PythonOperator fails and calls on_failure_callback.
I have tried any number of permutations, all either raising in test without
triggering, calling the python_callable, or not finding an object to patch:
patch('dags.a_dag.a_callable') as mock_callable
'a_dag.a_callable'
'dags.my_code.a_callable'
'my_code.a_callable'
'airflow.models.Task.execute'
(Python3, pytest, and mock.)
What am I missing / doing wrong?
(Better still, I would like to verify the arguments passed to SlackWebhookHook. Something like:
with patch('???.SlackWebhookHook.execute') as mock_webhook:
... as above ...
kw_dict = mock_webhook.call_args[-1]
assert kw_dict['http_conn_id'] == slack_conn_id
assert kw_dict['message'] == 'OurSqlAlchemyTable is empty'
assert kw_dict['channel'] == '#alert-channel'
(But I am first focussing on testing the failure callback.)
Thank you in advance.

Pass instance name as argument from several UI controls to a single function in Python-Maya

I'm developing a UI in python for maya, and I'm trying to do a function that performs an action when a frameLayout expands, in this case I have several "frameLayout" objects and I would like to use a single function "fl_expand", instead of one for each object
def fl_expand(*args):
print args
with frameLayout("layout1", collapsable=True, expandCommand=fl_expand):
...
with frameLayout("layout2", collapsable=True, expandCommand=fl_expand):
...
but I don't know how to pass the instance name as argument to the function, I tried:
with frameLayout("layout1", collapsable=True, expandCommand=fl_expand("layout1")):
...
But of course I get this error:
# Error: TypeError: file /usr/autodesk/maya2018/lib/python2.7/site-packages/pymel/internal/pmcmds.py line 134: Invalid arguments for flag 'ec'. Expected string or function, got NoneType #
Currently, you have something like that:
def fl_expand(*args):
print(args)
def frameLayout(name, collapsable, expandCommand):
print("frameLayout: " + name)
expandCommand('foo')
frameLayout("layout1", collapsable=True, expandCommand=fl_expand)
What you want is to call the fl_expand function with the first argument already filled with the name of the layout. To do that, you can use a partiel function. See the documentation for functools.partial.
You can try:
import functools
frameLayout("layout1", collapsable=True, expandCommand=functools.partial(fl_expand, "layout1"))
Of course, it could be laborious if you have a lot of calls like that. You can also define your own frameLayout function:
def myFrameLayout(name, collapsable, expandCommand):
cmd = functools.partial(fl_expand, name)
return frameLayout(name, collapsable, cmd)
myFrameLayout("layout2", collapsable=True, expandCommand=fl_expand)

Function which take as input variable result from other function

As I'm new in python coding, I stuck on defining a function which take as input variable from other function. Generally my code is :
#!/usr/bin/python
import configparser
import re
var="abc"
class Config:
def getSources(var):
config = configparser.ConfigParser()
config.read("C\\configFile.ini")
connection=config.get(connectinfo,'connectStr')
if source in connection_source:
print (connection_connectstr)
else:
print ('Something wrong')
return connection
try:
emp1 = Config.getSources(var)
except configparser.NoSectionError:
print ("Senction is not correct")
def getTables(connection)
In few words, I get data from Config.ini file, then do some process. Next I want to create next function getTables which as input take result from first function. By the way in getSources I would like to make it as return statement, unfornatelly return is returning null... Print works fine.
You need to return the value or raise an exception:
if source in connection_source:
return (connection_connectstr)
else:
raise configparser.NoSectionError('Something wrong')

Categories

Resources