This (plus Law of Demeter) is the right way to handle medium-big size projects, though I'm not completely sold on the tooling. I mostly do it manually (yes, it is still doable with dozens of modules since dependency hierarchy doesn't change often).<p>One recommendation I have is to present the hierarchy as DAG. Existing image (<a href="https://sourcery.ai/static/05300f06cb847360719e2aa31dc5a31b/8c857/dependencies.png" rel="nofollow">https://sourcery.ai/static/05300f06cb847360719e2aa31dc5a31b/...</a>) doesn't make it very obvious that api is a highest-level module, even though it is clearly stated in the rules.
Before clicking on this, I expected to see import-linter [0] which achieves something very similar but with, in my opinion, a bit less magic. Another solution in a similar spirit is Pants [1], though this is actually a build system which allows you to constrain dependencies between different artifacts (e.g. which modules are allowed to depend on which modules).<p>To Sourcery's credit, their product looks much more in the realm of "developer experience" -- closer to Copilot (or what I understand of it) than to import-linter. Props to them for at least having a page about security [2] and building a solution which doesn't inherently require all of your source code to be shared with a vendor's server.<p>[0] <a href="https://github.com/seddonym/import-linter" rel="nofollow">https://github.com/seddonym/import-linter</a><p>[1] <a href="https://www.pantsbuild.org/" rel="nofollow">https://www.pantsbuild.org/</a><p>[2] <a href="https://docs.sourcery.ai/Product/Permissions-and-Security/" rel="nofollow">https://docs.sourcery.ai/Product/Permissions-and-Security/</a>
After dealing with that problem and enduring the pain of it for years, I finally switched to C#/.NET. It has the necessary tooling to achieve this and more.<p>Rewriting a lot of things was time well spent rather than trying to tame the dynamic nature of Python and my tendency to overuse it.<p>And I can't believe I'm writing this after all these years evangelizing Python and dynamically typed languages.
I do exactly this in my side project. I have a set of rules which put restrictions on which packages and modules can be included from other packages and modules. For example, a high maturity package is not allowed to depend upon a low maturity package. Similarly, a core library package is not allowed to rely on a package that is specific to a particular product or a particular piece of bespoke development. In this way, much of the potential for circular dependencies is eliminated, and the purpose and internet is clearly communicated.<p>(I don't do this using sourcery though ... I have my own set of rules)
>While Python doesn't allow circular dependencies between modules, it won't stop you from introducing circular dependencies between packages.<p>Just to nitpick, while it is a very potent foot-gun, Python absolutely does allow circular dependencies between regular modules; here's a good write-up about this:<p><a href="https://stackabuse.com/python-circular-imports/" rel="nofollow">https://stackabuse.com/python-circular-imports/</a>
Am I only person that prefers to use raw SQL over of SQLAlchemy? I do not see any real advantage of using SQLAlchemy over raw SQL if I do not plan (which I do not plan) in future to switch DB engine for the application. Do you see any real advantage of using SQLALchemy over raw SQL queries if you do not plan to switch DB engine for your application in future?
I've already seem tools like this for other languages, but never seen someone effectively using them. Does anyone here has good or bad experiences with these architecture rule systems?
This is supported in Bazel with package visibility rules. Once you've got that feature as a way to tame a larger and expanding codebase, you'll wonder why it isn't a feature in more systems.<p><a href="https://bazel.build/concepts/visibility" rel="nofollow">https://bazel.build/concepts/visibility</a>
Is there something like this for react/jsx? I always wished I could constrain component dependencies across the atom > molecule > organism layers.