Skip to main content

A Python tool to guard against incorrect usage of python modules.

Project description

image image image [image][https://github.com/Never-Over/modguard/actions/workflows/ci.yml] Ruff

modguard

A Python tool to support and enforce a modular package architecture within a monorepo.

What is modguard?

Modguard enables you to explicitly define the public interface for a given module. Marking a package with a Boundary makes all of its internals private by default, exposing only the members marked with the @public decorator.

This enforces an architecture of decoupled and well defined modules, and ensures the communication between domains is only done through their expected public interfaces.

Modguard is incredibly lightweight, and has no impact on the runtime of your code. Instead, its checks are performed through a static analysis CLI tool.

Installation

pip install modguard

Usage

Add a Boundary to the __init__.py of the module you're creating an interface for.

# core/__init__.py
from modguard import Boundary

Boundary(__name__)

Add the public decorator to any callable in the module that should be exported.

# core/main.py
from modguard import public

# Adding the decorator here signifies this function is public
@public
def public_function(user_id: int) -> str:
    ...

# This function will be considered private
def private_function():
    ...

Modguard will now flag any incorrect dependencies between modules.

> # From the root of your project
> modguard .
❌ ./utils/helpers.py: Import 'core.main.private_function' in ./utils/helpers.py is blocked by boundary 'core.main'

Advanced Usage

Modguard also supports specific allow lists within the public() decorator.

@public(allowlist=['utils.helpers'])
def public_function(user_id: int) -> str:
    ...

This will allow for public_function to be imported and used in utils.helpers, but restrict it's usage elsewhere.

Alternatively, you can mark an import with the modguard-ignore comment:

# modguard-ignore
from core.main import private_function

This will stop modguard from flagging this import as a boundary violation.

Given that python allows for dynamic importing at runtime, modguard will fail if a whole module is imported without being declared public.

from core import main # contains public and private members
> # From the root of your project
> modguard .
❌ ./utils/helpers.py: Import 'core.main' in ./utils/helpers.py is blocked by boundary 'core.main'

If you expect to be able to import the entire contents of your module, you can declare an entire module as public to avoid this:

# core/main.py
from modguard import public
public()

...

This syntax also supports the allowlist parameter.

Details

Modguard works by analyzing the abstract syntax tree (AST) of your codebase. The Boundary class and @public decorator have no runtime impact, and are detected by modguard statically. Boundary violations are detected at the import layer; specific nonstandard custom syntax to access modules/submodules such as getattr or dynamically generated namespaces may not be caught by modguard.

PyPi Package

License

GNU GPLv3

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

modguard-0.3.3.tar.gz (24.0 kB view details)

Uploaded Source

Built Distribution

modguard-0.3.3-py3-none-any.whl (24.6 kB view details)

Uploaded Python 3

File details

Details for the file modguard-0.3.3.tar.gz.

File metadata

  • Download URL: modguard-0.3.3.tar.gz
  • Upload date:
  • Size: 24.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.18

File hashes

Hashes for modguard-0.3.3.tar.gz
Algorithm Hash digest
SHA256 91fe3c0d2ab06fded0a57e9ade7325c429d2418a34f339cbd91bb62abc78f309
MD5 818c49e355c85aad71c9678dfbf7d3e2
BLAKE2b-256 a867a68e4b880151054993769789c289be06de853430520112e67b398eae3cba

See more details on using hashes here.

File details

Details for the file modguard-0.3.3-py3-none-any.whl.

File metadata

  • Download URL: modguard-0.3.3-py3-none-any.whl
  • Upload date:
  • Size: 24.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.18

File hashes

Hashes for modguard-0.3.3-py3-none-any.whl
Algorithm Hash digest
SHA256 0f4317f860eac6a38466f6c2666da199b33da6c1683bcb34c5ad9237e16820de
MD5 3a01955bf02bede0db673777f95225ba
BLAKE2b-256 2f213f1b95eaaa697570ec3dce7c16c3f3bbdaa47eb536e0d43acb90bd1e056f

See more details on using hashes here.

Supported by

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