Here is my code :
from fabric2 import Connection
cbis = Connection.local()
with cbis.cd('/home/bussiere/Workspace/Stack/Event/'):
cbis.run('git add .')
but i have this error :
TypeError: local() missing 1 required positional argument: 'self'
how to launch a command on local with fabric2
Apparently, you should instantiate the Connection class somehow, like this:
cbis = Connection(possibly some arguments).local()
This error happens because classes are objects in Python. You could write your own example that would produce the same error:
class Test:
def function(self):
print('hey')
Test.function()
Test().function()
Here the first call does not instantiate a Test object, and thus, no implicit first argument is supplied to function. This results in an error. The second call calls the function of an instance of Test and does pass the implicit first argument (that is, that same instance) to function. This function expects exactly one argument, so everything works fine.
Related
I have looked for this on the forum but i could find anything precisely dealing with functool wrapped...
I have a class with a function copyfile and a decorator fileprocessing defined as :
class Sync():
...
def fileprocessing(func):
"decorator for copyfile methods"
#functools.wraps(func)
def wrapped_f(*args):
...#some code invoking copyfile
return wrapped_f
#fileprocessing
def copyfile(self,src, dst, file):
"try copying with shutil file in src folder to dst folder, otherwise with python"
try:
shutil.copy2(f'{src}/{file}',f'{dst}/{file}', follow_symlinks=False)
except Exception as err:
print(err)
self.pythoncopyfile(f'{src}/{file}',f'{dst}/{file}')
I am trying to test this function with pytest and it works fine when it is decorated.
However, i want to test the undecorated function.
I put in my test_file.py :
def test_undecorated_copyfile():
sync=Sync()
for file in range(3):
sync.copyfile.__wrapped__('source_folder', 'dest_folder', f'{file}.txt')
And when i run pytest, it throws me "TypeError: copyfile() missing 1 required positional argument: 'file' "
So i guess this has something to do with how to handle "self" in the copyfile arguments, but i dont know where to begin with to understand what .__wrapped__ is doing wrong
I tried to look on the forum but all i get is how to undecorate a function (with ._wrapped_ ), how to deal with self in normal situations.
I dont know how to deal with this error and which objects or methods to use to investigate
So i guess this has something to do with how to handle "self" in the copyfile arguments, but i dont know where to begin with to understand what .__wrapped__ is doing wrong
You're exactly right.
The .__wrapped__ attribute is an (unbound) function here (not a method)
print(sync.copyfile.__wrapped__)
# prints <function Sync.copyfile ...>,
# not <bound method Sync.copyfile of <__main__.Sync object ...>
and therefore needs a "self" argument supplied explicitly, e.g.:
# Change
sync.copyfile.__wrapped__('source_folder', 'dest_folder', f'{file}.txt')
# to ↓↓↓↓
sync.copyfile.__wrapped__(sync, 'source_folder', 'dest_folder', f'{file}.txt')
I'm having a hell of a time getting pytest, relative import, and patch to cooperate.
I have the following:
from .. import cleanup
class CleanupTest(unittest.TestCase):
#patch.object(cleanup, 'get_s3_url_components', MagicMock())
#patch.object(cleanup, 'get_db_session', MagicMock(return_value={'bucket', 'key'}))
#patch('time.time')
def test_cleanup(self, mock_time, mock_session, mock_components):
...
I've tried a few variations.
The currently shown one. Pytest returns 'TypeError: test_cleanup() takes exactly 4 arguments (2 given)'. It's not recognizing the patch.objects, even though I'm pretty sure I'm using them correctly according to https://docs.python.org/3/library/unittest.mock-examples.html
Changing the patch.objects over to simple patches causes them to throw 'no module named cleanup'. I can't figure out how to use patch with a relative import.
Edit: I'm using Python 2.7 in case that's relevant.
this actually doesn't have anything to do with pytest and is merely the behaviour of the mock decorators
From the docs
If patch() is used as a decorator and new is omitted, the created mock is passed in as an extra argument to the decorated function
that is, because you're passing a replacement object the signature-mutation doesn't occur
For example:
from unittest import mock
class x:
def y(self):
return 'q'
#mock.patch.object(x, 'y', mock.Mock(return_value='z'))
def t(x): ...
t() # TypeError: t() missing 1 required positional argument: 'x'
Fortunately, if you're producing a mock object, you rarely need to actually pass in the new argument and can use the keyword options
For your particular example this should work fine:
#patch.object(cleanup, 'get_s3_url_components')
#patch.object(cleanup, 'get_db_session', return_value={'bucket', 'key'})
#patch('time.time')
def test_cleanup(self, mock_time, mock_session, mock_components): ...
If you absolutely need them to be MagicMocks, you can use the new_callable=MagicMock keyword argument
I started a python project and attempted to have it OOP.
I used a script to call function from classes, in the following way:
class Object():
def function(input):
print(input)
The command Object.Object.function("example") used to work fine.
I had to reinstall pycharm, and now when running the same code I get the error of not sending enough input.
This can be solved by changing the call to Object.Object().function("example"),
and the function definition to def function(a,input):
Where the variable a is never used. This however causes new problems when using libraries.
How can I use the previous configuration?
Object.Object.function("example") and Object.Object().function("example") are different beasts entirely. The first run invokes the method function on the class Object.Object, while in the latter, Object.Object() creates an instance of type Object.Object and invokes function on that instance (which fails as you must provide the instance itself as the first parameter to the method). It sounds like you are trying to make something like a staticmethod,
class A:
#staticmethod
def f(input):
print(input)
for which both A.f and A().f will act as print.
I am trying to get some args working in a class, I already got it running in a function from How to use *args in a function?.
I'm trying to get that function into a class but I don't seem to understand how to initialize that class which has an init function taking *args. The code is as following :
class classname(object):
def __init__(self, *args):
<code-snip>
...
</code-snip>
if __name__ == "__main__":
start = classname()
start()
So here I'm confused on what to do with 'start()'. Do I have to use 'start(*sys.argv[1:])' or 'start()'. Both doesn't seem to work. I want to get the *args which is expected in init to be passed properly.
Any pointers please.
Thanks a ton..
======
I'm sorry if I wasn't clear on detailing how it didn't work.
a) While using start(*sys.argv[1:])
Traceback (most recent call last):
File "check.py", line 126, in <module>
start(*sys.argv[1:])
TypeError: 'check' object is not callable
b) While using start(), I get :
Traceback (most recent call last):
File "check.py", line 126, in <module>
start()
TypeError: 'check' object is not callable
These were the errors which came up.
#alko, yes you are correct. I was looking on how to get the *args in init passed properly.
Objects are instantiated by passing arguments to class constructor. They are in turn initalized with __init__ function. In your example this would be
start = ClassName(*sys.argv[1:])
that expression is processed as follows:
New instance of classname is instantiated with object.__new__(ClassName, *sys.argv[1:]) named start in local namespace. From now on start object may be referenced inside your if __name__ == "__main__" script.
Its contents are in turn initialized invoking start.__init__(*sys.argv[1:]). Note that args to __init__ are the same passed to constructor.
And read PEP 8 for python naming convention. That is:
Class names should normally use the CapWords convention.
Your example contains a class which is first instantiated - which involves calling __init__() - and then called - which is done by calling __call__().
So your stuff should be put in the call start = classname(...) in order to be passed to __init__().
The call to the newly instantiated object will fail, however, unless it contains a __call__() method. That would have been easier to answer if you had told us what
Both doesn't seem to work.
exactly means.
Suppose we have a hash table that maps strings to functions. In my example I'll call it COMMANDS. If I place the definition for some function (let's call it cmd_add) after the hash table that maps it to a string, and then I attempt to invoke it, I get an error:
COMMANDS = {'add': cmd_add}
def cmd_add():
print 'ADD'
COMMANDS['add']()
# NameError: name 'cmd_add' is not defined
Now notice that if I simply move the function definition to before the definition of COMMANDS, it works out just fine:
def cmd_add():
print 'ADD'
COMMANDS = {'add': cmd_add}
COMMANDS['add']()
# NO ERROR!
Why is this true? Is there something about Python binding that I do not understand?
Well, the module is interpreted from top to bottom. In your first snippet, it hasn't seen cmd_add yet, so it throws a NameError
You can do it like your second snippet, or something like this:
COMMANDS = {}
def cmd_add():
print 'ADD'
def register_commands():
COMMANDS.update({'add': cmd_add})
register_commands()
Or you could get fancy and wrap cmd_add with a decorator that registers it in the COMMANDS
COMMANDS = {}
# command decorator to register command functions
class command(object):
def __init__(self, name):
self.name = name
def __call__(self, func):
COMMANDS[self.name] = func
return func
#command('add')
def cmd_add():
print 'ADD'
COMMANDS['add']()
Remember that Python is a dynamic language, even though cmd_add is a reference to a function in your source there is nothing stopping it from referring to a different object at different times.
Python will creating the binding as the interpreter passes the line where the function is defined and it will reference that function until you delete the reference or rebind it to something else
In a Python script, the expressions are evaluated from top to bottom, therefore you can't reference a function before defining it.