'if passed a function, directly sets attributes on the function
which will make it discoverable to register().  If passed no function,
returns a decorator which can be applied to a function later using
the attributes supplied.
If optionalhook is True a missing matching hook specification will not result
in an error (by default it is an error if no matching spec is found).
If tryfirst is True this hook implementation will run as early as possible
in the chain of N hook implementations for a specfication.
If trylast is True this hook implementation will run as late as possible
in the chain of N hook implementations.
If hookwrapper is True the hook implementations needs to execute exactly
one "yield".  The code before the yield is run early before any non-hookwrapper
function is run.  The code after the yield is run after all non-hookwrapper
function have run.  The yield receives an ``_CallOutcome`` object representing
the exception or result outcome of the inner calls (including other hookwrapper
calls).'

def __call__(self, function=None, hookwrapper=False, optionalhook=False, tryfirst=False, trylast=False):

    def setattr_hookimpl_opts(func):
        setattr(func, (self.project_name + '_impl'), dict(hookwrapper=hookwrapper, optionalhook=optionalhook, tryfirst=tryfirst, trylast=trylast))
        return func
    if (function is None):
        return setattr_hookimpl_opts
    else:
        return setattr_hookimpl_opts(function)
