htpio.decorators API documentation
Description: This module implement various decorators such as function calls and exception logging. Decorators are used to implement additional functionality to a …

# Module `htpio.decorators`

This module implement various decorators such as function calls and exception logging. Decorators are used to implement additional functionality to a method or function without changing its name.

Currently the following decorators are implemented :

- @countcalls - Counts the number of function calls
- @logger(filename) - Logs function exceptions to a give file

Example:

        from htpio.decorators import Countcalls, Logger

        @Countcalls
        def f():
            pass

        count = 0
        for i in range(100):
            count = i + 1
            f()

        print(f.count(), count)

        @Countcalls
        @Logger(LOGFILE)
        def f():
            return 1 / 0

        # Function under test
        raised = False
        try:
            f()
        except:
            raised = True
            logger.log.info("Number of calls==[{0}]".format(f.count()))

Source code

    # Copyright (c) Hilscher GmbH. All Rights Reserved.
    #
    # $Author: bgeorgiev $
    # $Date: 2019-05-16 11:34:02 +0300 (Thu, 16 May 2019) $
    # $Revision: 654 $

    """
    This module implement various decorators such as function calls and exception
    logging. Decorators are used to implement additional functionality to a method
    or function without changing its name.

    Currently the following decorators are implemented :

     + @countcalls                - Counts the number of function calls
     + @logger(filename)          - Logs function exceptions to a give file

    *** Example: ***

    ```python

        from htpio.decorators import Countcalls, Logger

        @Countcalls
        def f():
            pass

        count = 0
        for i in range(100):
            count = i + 1
            f()

        print(f.count(), count)
    ```

    ```python
        @Countcalls
        @Logger(LOGFILE)
        def f():
            return 1 / 0

        # Function under test
        raised = False
        try:
            f()
        except:
            raised = True
            logger.log.info("Number of calls==[{0}]".format(f.count()))
    ```
    """

    # Compatibility imports
    from __future__ import unicode_literals
    from __future__ import print_function
    from __future__ import absolute_import

    # System imports
    import logging
    import functools

    """
    #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    #  DECORATORS
    #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    """

    class Countcalls(object):
        """
        Decorator that keeps track of the number of times a function is called.
        https://wiki.python.org/moin/PythonDecoratorLibrary

        ***Example***:

        ```python
        from htpio.decorators import Countcalls

        @Countcalls
        def f():
            pass

        @Countcalls
        def g():
            pass

        count = 0
        for i in range(100):
            count = i + 1
            f()
            g()

        print(f.count())  # Number of calls for funciton f
        print(g.count())  # Number of calls for function g
        print(Countcalls.counts()) # Dump number of calls for f and g
        ```
        """

        instances = {}
        """ Stores the function names and number of calls"""

        """
        #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        #  __init__ : countcalls constructor
        #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        """

        def __init__(self, f):
            self.f = f
            self.numcalls = 0
            Countcalls.instances[f] = self
            functools.update_wrapper(self, f)

        """
        #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        #  __call__ : Actions performed when referencing the class
        #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        """

        def __call__(self, *args, **kwargs):
            """
            Wrapping call to original funciton.
            """

            self.numcalls += 1
            return self.f(*args, **kwargs)

        """
        #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        #  count : Returns the number of calls for the decorated function
        #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        """

        def count(self):
            """
            Return the number of times the function was called.
            """

            return Countcalls.instances[self.f].numcalls

        """
        #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        #  counts : Returns the value of the internal dictionary
        #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        """

        @staticmethod
        def counts():
            """
            Return a dictionary for all registered functions is keys and the
            number of function calls as values.
            """

            result = []
            for f in Countcalls.instances:
                result.append((f.__name__, Countcalls.instances[f].numcalls))

            return dict(result)

    class Logger(object):
        """
        Decorator that logs exceptions into a given file.

        *** Example: ***

        ```python
        from htpio.decorators import Logger

        @Logger('c:\\test.log')
        def f():
            return 1 / 0

        # Function under test
        raised = False
        try:
            f()
        except:
            raised = True
            logger.log.info("Number of calls==[{0}]".format(f.count()))
        ```
        """

        log = logging.getLogger()
        """ Instance of a logging object"""

        logfile = ""
        """ Log file use to store the logs"""

        """
        #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        #  __init__ : logger constructor
        # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        """

        def __init__(self, logfile):

            Logger.logfile = logfile

            # logger instantiation
            Logger.log = logging.getLogger()
            Logger.log.setLevel(logging.INFO)

            # format output
            fmt = '%(asctime)s :: %(name)s :: %(levelname)s :: %(message)s'
            formatter = logging.Formatter(fmt)

            # create the logging file handler
            fh = logging.FileHandler(Logger.logfile)
            fh.setFormatter(formatter)

            # add handler to logger object
            Logger.log.addHandler(fh)

        """
        #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        #  __call__ : Action performed when referencing the class
        #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        """

        def __call__(self, function):
            """
            Wrapping call to original function.
            """

            @functools.wraps(function)
            def wrapper(*args, **kwargs):
                try:
                    return function(*args, **kwargs)

                except Exception:

                    # log the exception
                    err = "Exception in  "
                    err += function.__name__
                    Logger.log.exception(err)

                    # re-raise the exception
                    raise

            return wrapper

## Classes

`class Countcalls (f)`

  Decorator that keeps track of the number of times a function is called. https://wiki.python.org/moin/PythonDecoratorLibrary

  Example:

      from htpio.decorators import Countcalls

      @Countcalls
      def f():
          pass

      @Countcalls
      def g():
          pass

      count = 0
      for i in range(100):
          count = i + 1
          f()
          g()

      print(f.count())  # Number of calls for funciton f
      print(g.count())  # Number of calls for function g
      print(Countcalls.counts()) # Dump number of calls for f and g

  Source code

      class Countcalls(object):
          """
          Decorator that keeps track of the number of times a function is called.
          https://wiki.python.org/moin/PythonDecoratorLibrary

          ***Example***:

          ```python
          from htpio.decorators import Countcalls

          @Countcalls
          def f():
              pass

          @Countcalls
          def g():
              pass

          count = 0
          for i in range(100):
              count = i + 1
              f()
              g()

          print(f.count())  # Number of calls for funciton f
          print(g.count())  # Number of calls for function g
          print(Countcalls.counts()) # Dump number of calls for f and g
          ```
          """

          instances = {}
          """ Stores the function names and number of calls"""

          """
          #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
          #  __init__ : countcalls constructor
          #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
          """

          def __init__(self, f):
              self.f = f
              self.numcalls = 0
              Countcalls.instances[f] = self
              functools.update_wrapper(self, f)

          """
          #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
          #  __call__ : Actions performed when referencing the class
          #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
          """

          def __call__(self, *args, **kwargs):
              """
              Wrapping call to original funciton.
              """

              self.numcalls += 1
              return self.f(*args, **kwargs)

          """
          #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
          #  count : Returns the number of calls for the decorated function
          #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
          """

          def count(self):
              """
              Return the number of times the function was called.
              """

              return Countcalls.instances[self.f].numcalls

          """
          #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
          #  counts : Returns the value of the internal dictionary
          #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
          """

          @staticmethod
          def counts():
              """
              Return a dictionary for all registered functions is keys and the
              number of function calls as values.
              """

              result = []
              for f in Countcalls.instances:
                  result.append((f.__name__, Countcalls.instances[f].numcalls))

              return dict(result)

  ### Class variables

  `var instances`

    Stores the function names and number of calls

  ### Static methods

  `def counts()`

    Return a dictionary for all registered functions is keys and the number of function calls as values.

    Source code

        @staticmethod
        def counts():
            """
            Return a dictionary for all registered functions is keys and the
            number of function calls as values.
            """

            result = []
            for f in Countcalls.instances:
                result.append((f.__name__, Countcalls.instances[f].numcalls))

            return dict(result)

  ### Methods

  `def count(self)`

    Return the number of times the function was called.

    Source code

        def count(self):
            """
            Return the number of times the function was called.
            """

            return Countcalls.instances[self.f].numcalls

`class Logger (logfile)`

  Decorator that logs exceptions into a given file.

  Example:

      from htpio.decorators import Logger

      @Logger('c:\test.log')
      def f():
          return 1 / 0

      # Function under test
      raised = False
      try:
          f()
      except:
          raised = True
          logger.log.info("Number of calls==[{0}]".format(f.count()))

  Source code

      class Logger(object):
          """
          Decorator that logs exceptions into a given file.

          *** Example: ***

          ```python
          from htpio.decorators import Logger

          @Logger('c:\\test.log')
          def f():
              return 1 / 0

          # Function under test
          raised = False
          try:
              f()
          except:
              raised = True
              logger.log.info("Number of calls==[{0}]".format(f.count()))
          ```
          """

          log = logging.getLogger()
          """ Instance of a logging object"""

          logfile = ""
          """ Log file use to store the logs"""

          """
          #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
          #  __init__ : logger constructor
          # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
          """

          def __init__(self, logfile):

              Logger.logfile = logfile

              # logger instantiation
              Logger.log = logging.getLogger()
              Logger.log.setLevel(logging.INFO)

              # format output
              fmt = '%(asctime)s :: %(name)s :: %(levelname)s :: %(message)s'
              formatter = logging.Formatter(fmt)

              # create the logging file handler
              fh = logging.FileHandler(Logger.logfile)
              fh.setFormatter(formatter)

              # add handler to logger object
              Logger.log.addHandler(fh)

          """
          #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
          #  __call__ : Action performed when referencing the class
          #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
          """

          def __call__(self, function):
              """
              Wrapping call to original function.
              """

              @functools.wraps(function)
              def wrapper(*args, **kwargs):
                  try:
                      return function(*args, **kwargs)

                  except Exception:

                      # log the exception
                      err = "Exception in  "
                      err += function.__name__
                      Logger.log.exception(err)

                      # re-raise the exception
                      raise

              return wrapper

  ### Class variables

  `var log`

    Instance of a logging object

  `var logfile`

    Log file use to store the logs