from __future__ import absolute_import
import inspect
import os
import sys
import psutil

from collections import namedtuple
from functools import wraps
from pikos.abstract_monitors import AbstractMonitor

__all__ = [
    'FunctionLogger',
    'FunctionRecord',
]

FunctionRecord = namedtuple('FunctionRecord',
                            ['type', 'filename', 'lineNo', 'function'])

class FunctionLogger(AbstractMonitor):

    _fields = FunctionRecord._fields

    def __init__(self, recorder):
        ''' Initialize the logger class.

        Parameters
        ----------
        function : callable
            The callable to profile

        output : str
            The file in which to store profiling results.

        '''
        super(FunctionLogger, self).__init__(None)
        self._recorder = recorder
        self._process = None
        self._old_profile_function = None

    def __call__(self, function):
        self._item = function
        @wraps(function)
        def wrapper(*args, **kwds):
             return self.run(*args, **kwds)
        return wrapper

    def setup(self):
        self._recorder.prepare(self._fields)
        self._process = psutil.Process(os.getpid())
        self._old_profile_function = sys.getprofile()
        sys.setprofile(self.on_function_event)

    def teardown(self):
        sys.setprofile(self._old_profile_function)
        self._process = None
        self._recorder.finalize()

    def on_function_event(self, frame, event, arg):
        filename, lineno, function, _, _ = \
            inspect.getframeinfo(frame, context=0)
        if event.startswith('c_'):
            function = arg.__name__
        record = FunctionRecord(event, filename, lineno, function)
        self._recorder.record(record)



from __future__ import absolute_import
import inspect

from collections import namedtuple
from pikos._profile_functions import ProfileFunctions
from pikos._trace_functions import TraceFunctions

__all__ = [
    'FunctionLogger',
    'FunctionRecord',
]

FunctionRecord = namedtuple('FunctionRecord',
                            ['type', 'filename', 'lineNo', 'function'])

class FunctionLogger(object):

    _fields = FunctionRecord._fields

    def __init__(self, recorder):
        self._recorder = recorder
        self._profiler = ProfileFunctions()

    def __enter__(self):
        self._recorder.prepare(self._fields)
        self._profiler.set(self.on_function_event)

    def __exit__(self, exc_type, exc_val, exc_tb):
        self._profiler.unset()
        self._recorder.finalize()

    def on_function_event(self, frame, event, arg):
        filename, lineno, function, _, _ = \
            inspect.getframeinfo(frame, context=0)
        if event.startswith('c_'):
            function = arg.__name__
        record = FunctionRecord(event, filename, lineno, function)
        self._recorder.record(record)



Make the FunctionLogger a context manager
Make the FunctionLogger a context manager

  from __future__ import absolute_import
  import inspect
- import os
- import sys
- import psutil
  
  from collections import namedtuple
- from functools import wraps
- from pikos.abstract_monitors import AbstractMonitor
+ from pikos._profile_functions import ProfileFunctions
+ from pikos._trace_functions import TraceFunctions
  
  __all__ = [
      'FunctionLogger',
      'FunctionRecord',
  ]
  
  FunctionRecord = namedtuple('FunctionRecord',
                              ['type', 'filename', 'lineNo', 'function'])
  
- class FunctionLogger(AbstractMonitor):
+ class FunctionLogger(object):
  
      _fields = FunctionRecord._fields
  
      def __init__(self, recorder):
-         ''' Initialize the logger class.
+         self._recorder = recorder
+         self._profiler = ProfileFunctions()
  
+     def __enter__(self):
+         self._recorder.prepare(self._fields)
+         self._profiler.set(self.on_function_event)
-         Parameters
-         ----------
-         function : callable
-             The callable to profile
  
+     def __exit__(self, exc_type, exc_val, exc_tb):
+         self._profiler.unset()
-         output : str
-             The file in which to store profiling results.
- 
-         '''
-         super(FunctionLogger, self).__init__(None)
-         self._recorder = recorder
-         self._process = None
-         self._old_profile_function = None
- 
-     def __call__(self, function):
-         self._item = function
-         @wraps(function)
-         def wrapper(*args, **kwds):
-              return self.run(*args, **kwds)
-         return wrapper
- 
-     def setup(self):
-         self._recorder.prepare(self._fields)
-         self._process = psutil.Process(os.getpid())
-         self._old_profile_function = sys.getprofile()
-         sys.setprofile(self.on_function_event)
- 
-     def teardown(self):
-         sys.setprofile(self._old_profile_function)
-         self._process = None
          self._recorder.finalize()
  
      def on_function_event(self, frame, event, arg):
          filename, lineno, function, _, _ = \
              inspect.getframeinfo(frame, context=0)
          if event.startswith('c_'):
              function = arg.__name__
          record = FunctionRecord(event, filename, lineno, function)
          self._recorder.record(record)
  
  
  
Make the FunctionLogger a context manager
## Code Before:
from __future__ import absolute_import
import inspect
import os
import sys
import psutil

from collections import namedtuple
from functools import wraps
from pikos.abstract_monitors import AbstractMonitor

__all__ = [
    'FunctionLogger',
    'FunctionRecord',
]

FunctionRecord = namedtuple('FunctionRecord',
                            ['type', 'filename', 'lineNo', 'function'])

class FunctionLogger(AbstractMonitor):

    _fields = FunctionRecord._fields

    def __init__(self, recorder):
        ''' Initialize the logger class.

        Parameters
        ----------
        function : callable
            The callable to profile

        output : str
            The file in which to store profiling results.

        '''
        super(FunctionLogger, self).__init__(None)
        self._recorder = recorder
        self._process = None
        self._old_profile_function = None

    def __call__(self, function):
        self._item = function
        @wraps(function)
        def wrapper(*args, **kwds):
             return self.run(*args, **kwds)
        return wrapper

    def setup(self):
        self._recorder.prepare(self._fields)
        self._process = psutil.Process(os.getpid())
        self._old_profile_function = sys.getprofile()
        sys.setprofile(self.on_function_event)

    def teardown(self):
        sys.setprofile(self._old_profile_function)
        self._process = None
        self._recorder.finalize()

    def on_function_event(self, frame, event, arg):
        filename, lineno, function, _, _ = \
            inspect.getframeinfo(frame, context=0)
        if event.startswith('c_'):
            function = arg.__name__
        record = FunctionRecord(event, filename, lineno, function)
        self._recorder.record(record)



## Instruction:
Make the FunctionLogger a context manager
## Code After:
from __future__ import absolute_import
import inspect

from collections import namedtuple
from pikos._profile_functions import ProfileFunctions
from pikos._trace_functions import TraceFunctions

__all__ = [
    'FunctionLogger',
    'FunctionRecord',
]

FunctionRecord = namedtuple('FunctionRecord',
                            ['type', 'filename', 'lineNo', 'function'])

class FunctionLogger(object):

    _fields = FunctionRecord._fields

    def __init__(self, recorder):
        self._recorder = recorder
        self._profiler = ProfileFunctions()

    def __enter__(self):
        self._recorder.prepare(self._fields)
        self._profiler.set(self.on_function_event)

    def __exit__(self, exc_type, exc_val, exc_tb):
        self._profiler.unset()
        self._recorder.finalize()

    def on_function_event(self, frame, event, arg):
        filename, lineno, function, _, _ = \
            inspect.getframeinfo(frame, context=0)
        if event.startswith('c_'):
            function = arg.__name__
        record = FunctionRecord(event, filename, lineno, function)
        self._recorder.record(record)


