# Buggy code
def __call__(self, function):
    """
    Callable method of the decorator object when
    the decorated function is gets called.

    :param function:
    :return:
    """
    _DeprecationDecorator.__call__(self, function)

    def _decorate(*args, **kwargs):
        """
        Decorator function.

        :param args:
        :param kwargs:
        :return:
        """
        if self._curr_version < self._exp_version:
            msg = [
                'The function "{f_name}" is deprecated and will '
                'expire in version "{version_name}".'.format(
                    f_name=self._function.__name__, version_name=self._exp_version_name
                )
            ]
            if self._successor:
                msg.append(
                    'Use successor "{successor}" instead.'.format(
                        successor=self._successor
                    )
                )
            log.warning(" ".join(msg))
        else:
            msg = [
                'The lifetime of the function "{f_name}" expired.'.format(
                    f_name=self._function.__name__
                )
            ]
            if self._successor:
                msg.append(
                    'Please use its successor "{successor}" instead.'.format(
                        successor=self._successor
                    )
                )
            log.warning(" ".join(msg))
            raise CommandExecutionError(" ".join(msg))
        return self._call_function(kwargs)

    return _decorate


# Traceback (AttributeError)
[ERROR   ] An un-handled exception was caught by salt's global exception handler:
AttributeError: 'module' object has no attribute '__opts__'
Traceback (most recent call last):
File "/usr/bin/salt-call", line 11, in <module>
salt_call()
File "/usr/lib/python2.7/site-packages/salt/scripts.py", line 391, in salt_call
client.run()
File "/usr/lib/python2.7/site-packages/salt/cli/call.py", line 58, in run
caller.run()
File "/usr/lib/python2.7/site-packages/salt/cli/caller.py", line 134, in run
ret = self.call()
File "/usr/lib/python2.7/site-packages/salt/cli/caller.py", line 204, in call
ret['return'] = func(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/salt/modules/state.py", line 593, in apply_
return highstate(**kwargs)
File "/usr/lib/python2.7/site-packages/salt/modules/state.py", line 892, in highstate
orchestration_jid=orchestration_jid)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 3695, in call_highstate
return self.state.call_high(high, orchestration_jid)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2531, in call_high
ret = self.call_chunks(chunks)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2017, in call_chunks
running = self.call_chunk(low, running, chunks)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2345, in call_chunk
running = self.call_chunk(chunk, running, chunks)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 2362, in call_chunk
self.pre[tag] = self.call(low, chunks, running)
File "/usr/lib/python2.7/site-packages/salt/state.py", line 1796, in call
test = sys.modules[self.states[cdata['full']].__module__].__opts__['test']
AttributeError: 'module' object has no attribute '__opts__'

# Fixed code
def __call__(self, function):
    """
    Callable method of the decorator object when
    the decorated function is gets called.

    :param function:
    :return:
    """
    _DeprecationDecorator.__call__(self, function)

    @wraps(function)
    def _decorate(*args, **kwargs):
        """
        Decorator function.

        :param args:
        :param kwargs:
        :return:
        """
        if self._curr_version < self._exp_version:
            msg = [
                'The function "{f_name}" is deprecated and will '
                'expire in version "{version_name}".'.format(
                    f_name=self._function.__name__, version_name=self._exp_version_name
                )
            ]
            if self._successor:
                msg.append(
                    'Use successor "{successor}" instead.'.format(
                        successor=self._successor
                    )
                )
            log.warning(" ".join(msg))
        else:
            msg = [
                'The lifetime of the function "{f_name}" expired.'.format(
                    f_name=self._function.__name__
                )
            ]
            if self._successor:
                msg.append(
                    'Please use its successor "{successor}" instead.'.format(
                        successor=self._successor
                    )
                )
            log.warning(" ".join(msg))
            raise CommandExecutionError(" ".join(msg))
        return self._call_function(kwargs)

    return _decorate