Skip to main content

Domain Types Linter

A static code analyzer that enforces the use of domain-specific types in business logic code instead of universal types.

Description

Domain Types Linter is a tool that helps maintain better code organization and type safety by ensuring that your business logic layer uses only explicit business logic objects, not universal types. It analyzes Python type annotations and reports violations of domain type rules.

The linter detects three types of problems:

  • Using an alias for a universal type (e.g., alias_str = str)
  • Using a universal base type directly (e.g., str, int)
  • Using a generic type without domain-specific parameters (e.g., List without proper domain types)

Installation

Requirements

  • Python 3.10 or higher

Basic Installation

pip install domain-types-linter

Installation with Flake8 Support

pip install domain-types-linter[flake8]

Usage

Command Line Interface

You can run the linter directly from the command line:

dt-linter path/to/file_or_directory

The linter will scan the specified file or directory recursively and report any domain type violations. It will exit with code 1 if problems are found.

Flake8 Plugin

If you have installed the linter with Flake8 support, you can use it as a Flake8 plugin:

flake8 path/to/file_or_directory

The domain type violations will be reported along with other Flake8 errors.

Examples

Disallowed Types

The following types are not allowed in business logic code:

# Universal base types
def disallowed_base_types(
    my_str: str,
    my_int: int,
    my_float: float,
    my_complex: complex,
    my_bytes: bytes,
    my_bytearray: bytearray,
    my_any: Any,
    my_decimal: Decimal,
):
    ...

# Aliases of universal types
alias_str = str
typing_type_alias_str: TypeAlias = str

def disallowed_aliases(
    my_alias_str: alias_str,
    my_typing_alias: typing_type_alias_str,
):
    ...

# Generic types with universal type parameters
def disallowed_generic_types(
    my_list_str: list[str],
    my_dict_str_int: Dict[str, int],
    my_set_int: Set[int],
    my_tuple_int: Tuple[int, ...],
    my_optional_int: Optional[int],
):
    ...

# Generic types without parameters
def disallowed_generic_types_without_params(
    my_list: list,
    my_dict: dict,
    my_set: set,
    my_tuple: tuple,
    my_iterable: Iterable,
):
    ...

Allowed Types

The following types are allowed in business logic code:

# Domain-specific types
UserId = NewType("UserId", int)

class DomainDataType:
    ...

# Using domain-specific types
def allowed_types(
    my_bool: bool,  # bool is allowed
    my_none: None,  # None is allowed
    my_callable: Callable,  # Callable is allowed without parameters
    my_userid: UserId,  # Domain-specific type
    my_domain_type: DomainDataType,  # Domain-specific class
):
    ...

# Generic types with domain-specific parameters
def allowed_generic_types(
    my_list_userid: List[UserId],
    my_dict_userid_domain: Dict[UserId, DomainDataType],
    my_set_userid: Set[UserId],
    my_tuple_userid: Tuple[UserId, ...],
    my_optional_userid: Optional[UserId],
):
    ...

Problem Codes

The linter uses the following problem codes:

  • DT001: Using an alias for a universal type
  • DT003 - DT011: Using universal base types (str, int, float, etc.)
  • DT100 - DT125: Using parameterized types without domain-specific parameters

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Download files

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

Source Distribution

domain_types_linter-1.0.1.tar.gz (17.6 kB view details)

Uploaded Source

Built Distribution

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

domain_types_linter-1.0.1-py3-none-any.whl (8.5 kB view details)

Uploaded Python 3

File details

Details for the file domain_types_linter-1.0.1.tar.gz.

File metadata

  • Download URL: domain_types_linter-1.0.1.tar.gz
  • Upload date:
  • Size: 17.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.3

File hashes

Hashes for domain_types_linter-1.0.1.tar.gz
Algorithm Hash digest
SHA256 f4f77a3bd3a8c0de4e07738df26de9735e97f314a3e1aca469d608f4391f40d2
MD5 748a9b807b50945e6d3e90f9356e1f05
BLAKE2b-256 3a35428d3c38a99365634237cdfbcffc6f3c8458b8b5c05c192d7a66829688c7

See more details on using hashes here.

File details

Details for the file domain_types_linter-1.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for domain_types_linter-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 131fd6630f6809cb37dccc874fc967b7ede01719caff92e82ab8e37efd885ce2
MD5 6068ad3d5573fd2d5449efc9eff2961b
BLAKE2b-256 49a0bf9aac8332759887486951bc8177b35971c8203ce807a1590914b11443d4

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 files

1.0.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page