Skip to main content

Oida is Oda's linter that enforces code style and modularization in our Django projects.

Project description

๐Ÿ’…
Oida

Oida is Oda's linter that enforces code style and modularization in our Django projects.

Warning This project is still in early development. Expect breaking changes.

Installation

Oida requires Python 3.10 or newer and can be installed from PyPI:

pip install oida

Usage

Oida is mainly intended to be used as a flake8 plugin. Once you have installed Oida and flake8 you can enable the linting rules in the flake8 config:

[flake8]
extend-select = ODA

This will enable all our linting rules. You can also enable them one by one, for a complete list of the various violations we report on see the oida/checkers/base.py file.

Oida also provides its own command line tool. This can also be used to run the linting rules, but its main purpose is to provide tools to help transitioning an existing codebase into one that's modularized. For details see oida --help, but below is a quick summary of the provided commands:

oida lint

This command is just another way of running the same checks that can be run through flake8. This command supports # noida comments to ignore specific violations on individual lines (see below for details).

oida config

This command will generate configuration files for components, which will be automatically pre-filled with ignore rules for isolation violations. See below for details on the configuration files.

oida componentize

This command moves or renames a Django app, for example for moving an app into a component. In addition to moving the files in the app it also updates (or adds if needed) the app config and updates imports elsewhere in the project.

Concepts

Oida is a static code analyzer, that also looks at the project structure. The codebase is expected to be structured with a project as the top package and then Django apps or components as submodules below this, something like this:

project/
โ”œโ”€โ”€ pyproject.toml
โ”œโ”€โ”€ setup.cfg
โ””โ”€โ”€ project/
    โ”œโ”€โ”€ __init__.py
    โ”œโ”€โ”€ my_component/
    โ”‚   โ”œโ”€โ”€ __init__.py
    โ”‚   โ”œโ”€โ”€ first_app/
    โ”‚   โ”‚   โ”œโ”€โ”€ __init__.py
    โ”‚   โ”‚   โ”œโ”€โ”€ models.py
    โ”‚   โ”‚   โ””โ”€โ”€ ...
    โ”‚   โ”œโ”€โ”€ second_app/
    โ”‚   โ”‚   โ”œโ”€โ”€ __init__.py
    โ”‚   โ”‚   โ””โ”€โ”€ ....
    โ”‚   โ””โ”€โ”€ ...
    โ”œโ”€โ”€ third_app/
    โ”‚   โ”œโ”€โ”€ __init__.py
    โ”‚   โ””โ”€โ”€ ...
    โ””โ”€โ”€ ...

A component is basically a collection of Django apps. Oida will enforce isolation of the apps inside the component, meaning that no code elsewhere in the project will be allowed to import from the apps inside a component. Instead a component should expose a public interface at the top level.

Because Oida is intended to be introduced in mature projects it's also possible to grandfather in existing violations. That's done through a confcomponent.py file placed at the root of the component. The only allowed statement in this file is assigning a list of string literals to ALLOWED_IMPORTS:

ALLOWED_IMPORTS = ["my_component.app.models.MyModel"]

This will silence any warnings when importing my_component.app.models.MyModel in the current app/component.

Ignoring Violations with # noida Comments

You can use inline # noida comments to ignore specific violations on individual lines:

# Ignore all violations on this line
from project.other_component.app.models import Model  # noida

# Ignore a specific violation code
from project.other_component.app.models import Model  # noida: ODA005

# Ignore multiple specific violation codes
from project.other_component.app.models import Model  # noida: ODA005, ODA001

The # noida comments work with the oida lint command. Note that we use noida instead of noqa to avoid conflicts with ruff, which doesn't accept noqa comments that don't match ruff rules.

Checks

These are the checks currently implemented in Oida:

  • component-isolation: Checks that relative imports do not cross app boundaries.
  • config: Checks that component configuration files are valid
  • relative-imports: Checks that no imports are done across components.
  • django-select-for-update: Checks that all .select_for_update() usage sets the of argument, to prevent unintended locking of tables
  • service-selector-keyword-only: Checks that all functions in service and selector modules use keyword-only parameters (with the * separator). This applies to files named services.py or selectors.py, or files within services/ or selectors/ directories. Inner functions and methods of nested classes are excluded from this check.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

oida-0.3.1.tar.gz (20.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

oida-0.3.1-py3-none-any.whl (26.6 kB view details)

Uploaded Python 3

File details

Details for the file oida-0.3.1.tar.gz.

File metadata

  • Download URL: oida-0.3.1.tar.gz
  • Upload date:
  • Size: 20.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.12.3 Linux/6.11.0-1018-azure

File hashes

Hashes for oida-0.3.1.tar.gz
Algorithm Hash digest
SHA256 090217a855d858517bafd87123d69e483fb87c2c3bbbd92d3c41783fd5a1495d
MD5 3cb79513f00974b09006bfb1c2e626c7
BLAKE2b-256 ef49cea244138eda3c3f95da6e088440a2df287d6efaa08103cc3c4376eadab3

See more details on using hashes here.

File details

Details for the file oida-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: oida-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 26.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.12.3 Linux/6.11.0-1018-azure

File hashes

Hashes for oida-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 53a2d6e44985699cbf3c0abea16bac9b1c53eac965f82c96a89a51969783b509
MD5 65379cf40a38929cd7cee55f6e0485dc
BLAKE2b-256 b625eec0044208d5459ffed2dca5a8a79aa167362f1ac2d0cf01f88a296f8e85

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page