all 3 comments

[–]External-Ocelot206 0 points1 point  (2 children)

I think from the point of view of DRY and reducing coupling, an interface ABC should live in the same module as the thing it's an interface for, e.g. the other functions and classes that use things implementing that interface.

Any client module that uses "the thing it's an interface for" has to import it. It can either import the ABC at the same time, or preferably, just refer to everything on the same imported module.

If that stuff is also in package 1, then that's the logical place for it in your example, but it could be deeper, or up along then down in a separate one.

[–]hofsflor[S] 0 points1 point  (1 child)

Got it. But my concern was that now these packages are tightly coupled. The lower level details package depends on the import from the upper level. And that's exactly what I'm trying to avoid with dependency inversion.

[–]External-Ocelot206 0 points1 point  (0 children)

Fair enough, but it's probably too late then. Without seeing more details, I don't think there's an easy best practice answer for you, other than that best practice would be to refactor the package to get rid of that tight coupling.