Skip to content

Flag Dependencies to a Library

Sometimes, you might want to remove dependencies to a library that you've been using.

That can have multiple reasons:

  • A security vulnerability has been exposed.
  • The library has been deprecated.
  • The library is still active and safe, but you've decided to replace it with another similar-purpose library.

In such cases, a thorough cleanup might make sense. Having 3 different libraries e.g. for parsing markdown scattered around your codebase can lead to surprising bugs and inconsistencies.

Find Dependencies via Sourcery Custom Rules

Currently, you need to define 2 Sourcery custom rules to flag all dependencies to a library. 1 flags import statements and 1 flags from ... import statements.

Here is an example to flag all the dependencies to the library requests. If you want to see these rules "in action", you can also check out this no-dependency-to-library-example on GitHub.

rules:
  - id: no-dependency-requests-import
    description: Do not use the `requests` library
    pattern: import ..., ${module}, ...
    condition: module.matches_regex(r"^requests\b")
    explanation: use `httpx` instead of `requests`
    tests:
      - match: import requests
      - match: import requests as r
      - match: import requests.auth as requests_auth
      - match: import requests, json
      - match: import json, requests.auth as ra, datetime
      - no-match: import requestsx
      - no-match: import xrequests

  - id: no-dependency-requests-from
    description: Do not use the `requests` library
    pattern: from ${module} import ${names+}
    condition: module.matches_regex(r"^requests\b")
    explanation: use `httpx` instead of `requests`
    tests:
      - match: from requests import util
      - match: from requests import util, auth
      - match: from requests.adapters import HTTPAdapter
      - match: from requests.level.other import util, other
      - match: from requests import util as u, auth as a
      - match: from requests import *
      - match: from requests.adapters import *
      - no-match: from requests2 import util

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 function
  • importlib

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: