I've tried to implement my own force flag on some tasks, and come to the conclusion that it's very difficult to do properly.
The issue is stateful-ness. When you say "force" this task, what you're saying is "disregard the presence of its targets, but only ONCE". Remember that target checking is performed before a task runs, but also after it runs, in the pre-check(s) for any of its dependent tasks. When those happen, you do want the presence check.
This can easily be implemented on your own with a parameter *as long as you don't use multiple workers*. If you have multiple workers, instances of your task classes are being created in different processes, so anything stateful in those classes is lost. If you only have one process, you can be stateful.
In order to implement --force in a way that's compatible with multiple workers, you would need to externalize the bit of state that records "have I skipped the output check yet?". This more-or-less requires a database, so implementing it inside Luigi itself would create a highly non-trivial new dependency. But if you have a database you can use, implementing it yourself is possible.
Here's an outline of the one-worker-only solution:
class SomeTask(luigi.Task):
# other parameters...
force = luigi.BooleanParameter(default=False, significant=False)
has_been_forced = False
def output(self):
target = SomeTarget(...)
if self.force and not self.has_been_forced:
target.remove()
self.has_been_forced = True
return target
Another approach is to build a parallel network of tasks whose job it is to erase the output of your real tasks, in the spirit of "make clean". This is not really as easy as it sounds, and obviously creates a maintenance headache.