0

Background

I have a task executioner framework that allows people to write code like this.

class HandleJob(Job):

  @Step()
  def do_work(self, work_order):
    pass

  @Step()
  def continue_with_doing_work(self, work_order):
    pass

The framework calls the steps in a defined order and pass along the work order. The important thing to know though is that the different Steps can be called by different instances of HandleJob, or rather during different executions of the script. This means that a developer CANNOT write stuff to self in one Step and expect it to be available in another Step.

There is a dedicated place to store data needed later and documentation is clear about this. However, I still want to be able to enforce 'fail early'.

Question (TLDR)

Is there some way I can lock down the scope preventing developers from writing variables to self during runtime.

To complicate things further. They should be able to write to self in the constructor.

Hampus
  • 2,769
  • 1
  • 22
  • 38

1 Answers1

1

I found a solution (Overriding __setattr__ at runtime).

class Job:

    _scope_locked = False

    def __init__(self, work_order_id, strict=True):
        if strict:
            self._scope_locked = True

    def __setattr__(self, attr, value):
        if self._scope_locked:
            raise Exception("'self' locked")
        else:
            super(Job, self).__setattr__(attr, value)

The only issue with this solution is that super needs to be called last in the child class constructor. Oh well.

Hampus
  • 2,769
  • 1
  • 22
  • 38
  • To provide a simpler API to the user (without having to remember where to call super-init), you might have `__init__` call `do_init` or something like that at the right place, to be implemeted by the sub-classes. – tobias_k Feb 04 '19 at 11:09