Advanced usage

Apply decorators inline

Sometime you may need to activate just a particular call into your function. Let’s say we have something like:

class MyWriter:
    def read_db_and_write_result_to_file(self):
        # read something from database
        result = query_result()

        # write it to file
        try:
            with open('file.txt', 'a') as f:
                f.write(result)
            return True
        except:
            return False

and you need to give dryrun functionality just to the file writing thing. Remember that decorators are just funcions (or classes) which get in input an other function. Thus you can wrap it with either sham:

# write it to file
try:
    with open('file.txt', 'a') as f:
        f.write = sham(f.write)
        f.write(result)
    ...

or sheriff, and provide a deputy:

# write it to file
try:
    with open('file.txt', 'a') as f:
        f.write = sheriff(f.write)
        f.write.deputy(self._deputy_of_write)
        f.write(result)
    ...

where self._deputy_of_write should be defined with the same args of f.write or with *args, **kw.

Important

If you apply the decorator inline as in the following example:

...
shutil.copy = sham(shutil.copy)
...

be sure to call this block of code just once, or you may incur into a RecursionError: maximum recursion depth exceeded. A good solution is to pack all the dryrun configuration in a specific function and call it when activating the dryrun mode:

def setup_dryrun():
    ...
    shutil.copy = sham(shutil.copy)
    ...

if activate_dryrun:
    setup_dryrun()
    dryrun(True)