Establish Rules for Dependencies Between Your Packages¶
If you're working on a bigger and more complex application, you probably follow some structure and organize your code into packages. In that case, it might make sense to establish some rules how these packages communicate with each other.
Here are some ideas that might make sense depending on your project's structure:
- The
api
package can depend on any other package. But no other package in your project should depend onapi
. - Only the
api
package should use theapi_utils
package. - Only the
core
package should use thedb
package.
Establish Rules for Dependencies Between Your Packages with Sourcery Custom Rules¶
Currently, you need to define 2 Sourcery custom rules to flag various ways of
dependency. 1 flags import
statements and 1 flags from ... import
statements.
Here is an example to flag all the cases when another package in your project
depends on api
:
rules:
- id: no-dependency-api-import
description: Do not import the `api` library in other packages
pattern: import ..., ${module}, ...
condition: module.matches_regex(r"^api\b")
paths:
exclude:
- api/
- test/
tests:
- match: import api
- match: import api.auth
- match: import api as my_api
- match: import api.auth as api_auth
- match: import json, api, datetime
- no-match: import apiness
- id: no-dependency-api-from
description: Do not import the `api` library in other packages
pattern: from ${module} import ...
condition: module.matches_regex(r"^api\b")
paths:
exclude:
- api/
- test/
tests:
- match: from api import util
- match: from api import util, auth
- match: from api.whatever import SomeApiStuff
- match: from api.level.other import util, other
- match: from api import util as u, auth as a
- match: from api import *
- match: from api.books import *
- no-match: from apiness import util
- no-match: from api2 import util
Checklist for Dependency Rules¶
- Always create 2 Sourcery custom rules: 1 for
import
statements, 1 forfrom ... import
statements. - Add
exclude paths
: Imports within the package itself and in tests should be allowed.
Out of Scope¶
Please note that these rules find only direct references to a library in
import
and from ... import
statements. The following is out of scope:
- reimporting imported names
__import__
built-in functionimportlib
General Import Conventions¶
We recommend to follow some conventions for imports. That makes your code easier to read for humans and easier to work with for tools.
Follow the import rules of the Google Python Style Guide:
- Do not use relative imports.
- Do not use star imports.
You can enforce these rules by enabling the gpsg-import
rule package in your
Sourcery config file:
rule_settings:
enable:
- default
- gpsg-import
Use a tool to sort and format your imports. Great options include: