Thanks for the explanations on DI in Python.
The solutions look quite heavy and inflexible though. It is much easier to use some component framework (either simple home-made or zope.interface , etc) to achieve the next level in the implementation of builder: namely, declarative way.
That is, the builder can use lets say JSON declaration (which can be stored in the db) to build the necessary objects. And then dispatching can be done from strings by finding registered classes, providing specific interfaces and possibly having specific ids.
I understand, that the focus of the article was DI, but that alone (depending on the project!) is not big enough incentive to go into all that syntactic trouble you exemplify by:
`.with_person_repository()` etc.
It may be, it's more like my own bias towards problem domain to be expressed as much as possible in declarative way, but in the bigger project it usually makes sense instead of creating rigid Python code.
There are also other ways for DI. For instance, metaprogramming, dynamic attributes (and methods), because Python is quite dynamic.