I argue that it is possible to reduce [repeating yourself](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) without inheritance.
Inheritance is often used in the following contexts:
1. (As an *interface*.) When objects must demonstrate that they have a method with the expected signature. For instance, any object that implements `ICanSpeak` necessarily has a method `speak(str)` with that exact signature:
```python
def say_hello(speaker: ICanSpeak):
speaker.speak("hello")
```
2. When there is an explicit default behavior, that is inarguably nearly always correct with a probability p.
The threshold for (2) depends on the culture and conventions of those who work with the code. Is p ≥ 10% enough? 50%? 98%? 100%? Everyone's tastes are different. If that threshold is not met, all is not lost. A fierce storm of complexity rages around us, but we may still keep DRY.
For instance,
```python
def common(self, *args, **kwargs):
...
class BruceSpringsteen:
def request(self, *args):
return common(self, *args)
class BillyJoel:
def request(self, *args):
return common(self, *args)
class BruceDickinson:
def request(self, *args):
return common(self, *args, needs_more_cowbell=True)
```
In this example, the `common` function reduces some amount of repetition. The desired functionality must be explicitly provided. There are even optional feature flags should one decide to customize the common behavior.