from bonobo.execution.base import LoopingExecutionContext, recoverable


class PluginExecutionContext(LoopingExecutionContext):
    PERIOD = 0.5

    def __init__(self, wrapped, parent):
        # Instanciate plugin. This is not yet considered stable, as at some point we may need a way to configure
        # plugins, for example if it depends on an external service.
        super().__init__(wrapped(self), parent)

    def start(self):
        super().start()

        with recoverable(self.handle_error):
            self.wrapped.initialize()

    def shutdown(self):
        with recoverable(self.handle_error):
            self.wrapped.finalize()
        self.alive = False

    def step(self):
        with recoverable(self.handle_error):
            self.wrapped.run()

from bonobo.execution.base import LoopingExecutionContext, recoverable


class PluginExecutionContext(LoopingExecutionContext):
    PERIOD = 0.5

    def __init__(self, wrapped, parent):
        # Instanciate plugin. This is not yet considered stable, as at some point we may need a way to configure
        # plugins, for example if it depends on an external service.
        super().__init__(wrapped(self), parent)

    def start(self):
        super().start()

        with recoverable(self.handle_error):
            self.wrapped.initialize()

    def shutdown(self):
        if self.started:
            with recoverable(self.handle_error):
                self.wrapped.finalize()
        self.alive = False

    def step(self):
        with recoverable(self.handle_error):
            self.wrapped.run()

Check if PluginExecutionContext was started before shutting it down.
Check if PluginExecutionContext was started before shutting it down.

If a `PluginExecutionContext().shutdown()` is called _before_
`PluginExecutionContext().start()` was called,
this leads to an `AttributeError` exception since finalizer tries to
access to attributes which were never defined.

  from bonobo.execution.base import LoopingExecutionContext, recoverable
  
  
  class PluginExecutionContext(LoopingExecutionContext):
      PERIOD = 0.5
  
      def __init__(self, wrapped, parent):
          # Instanciate plugin. This is not yet considered stable, as at some point we may need a way to configure
          # plugins, for example if it depends on an external service.
          super().__init__(wrapped(self), parent)
  
      def start(self):
          super().start()
  
          with recoverable(self.handle_error):
              self.wrapped.initialize()
  
      def shutdown(self):
+         if self.started:
-         with recoverable(self.handle_error):
+             with recoverable(self.handle_error):
-             self.wrapped.finalize()
+                 self.wrapped.finalize()
          self.alive = False
  
      def step(self):
          with recoverable(self.handle_error):
              self.wrapped.run()
  
Check if PluginExecutionContext was started before shutting it down.
## Code Before:
from bonobo.execution.base import LoopingExecutionContext, recoverable


class PluginExecutionContext(LoopingExecutionContext):
    PERIOD = 0.5

    def __init__(self, wrapped, parent):
        # Instanciate plugin. This is not yet considered stable, as at some point we may need a way to configure
        # plugins, for example if it depends on an external service.
        super().__init__(wrapped(self), parent)

    def start(self):
        super().start()

        with recoverable(self.handle_error):
            self.wrapped.initialize()

    def shutdown(self):
        with recoverable(self.handle_error):
            self.wrapped.finalize()
        self.alive = False

    def step(self):
        with recoverable(self.handle_error):
            self.wrapped.run()

## Instruction:
Check if PluginExecutionContext was started before shutting it down.
## Code After:
from bonobo.execution.base import LoopingExecutionContext, recoverable


class PluginExecutionContext(LoopingExecutionContext):
    PERIOD = 0.5

    def __init__(self, wrapped, parent):
        # Instanciate plugin. This is not yet considered stable, as at some point we may need a way to configure
        # plugins, for example if it depends on an external service.
        super().__init__(wrapped(self), parent)

    def start(self):
        super().start()

        with recoverable(self.handle_error):
            self.wrapped.initialize()

    def shutdown(self):
        if self.started:
            with recoverable(self.handle_error):
                self.wrapped.finalize()
        self.alive = False

    def step(self):
        with recoverable(self.handle_error):
            self.wrapped.run()
