BD004: ImportSucceeds

Overview

Property Value
ID BD004
Name ImportSucceeds
Group build
Severity ERROR

Description

Verifies that the package can be imported after installation.

This check catches issues that only appear at import time:

  • Circular imports between modules
  • Missing runtime dependencies
  • Syntax errors not caught during build
  • Import-time side effects that fail
  • Missing __init__.py files

What it checks

After installing in a temporary virtual environment, the check runs import <package>:

  • PASSED: Import succeeds without errors
  • FAILED: Import fails (reports the import error)
  • NOT_APPLICABLE: Cannot determine package name or build package not installed

How to fix

Test import locally

# In a fresh environment
python -c "import my_package"

Common failure causes

1. Circular imports

# module_a.py
from my_package.module_b import func_b  # Circular!

# module_b.py
from my_package.module_a import func_a  # Circular!

Fix: Move imports inside functions or restructure modules:

# module_a.py
def func_a():
    from my_package.module_b import func_b  # Import when needed
    return func_b()

2. Missing __init__.py

src/
  my_package/
    module.py       # No __init__.py!

Fix: Add __init__.py:

src/
  my_package/
    __init__.py     # Required for package
    module.py

3. Import-time side effects

# __init__.py
import os
config = load_config(os.environ["CONFIG_PATH"])  # Fails if not set!

Fix: Use lazy loading or handle missing config:

# __init__.py
import os
config = None

def get_config():
    global config
    if config is None:
        config = load_config(os.environ.get("CONFIG_PATH", "default.yaml"))
    return config

4. Missing runtime dependencies

Dependencies might be marked as optional but required for import:

[project]
dependencies = []  # Missing required dependency!

[project.optional-dependencies]
full = ["pandas"]  # But pandas is imported unconditionally

Fix: Move to main dependencies:

[project]
dependencies = ["pandas>=1.0.0"]

Debug import errors

Get detailed import information:

python -v -c "import my_package" 2>&1 | grep my_package

Why ERROR severity?

This check is an ERROR because:

  • A package that cannot be imported is completely unusable
  • Import errors cause immediate failures for all users
  • These issues often only appear in production environments

Configuration

Timeout

The default timeout is 600 seconds (10 minutes):

[tool.pycmdcheck.checks.BD004]
timeout = 900  # 15 minutes

Skip this check

[tool.pycmdcheck]
skip = ["BD004"]

For faster local development:

[tool.pycmdcheck]
skip_groups = ["build"]

CLI

pycmdcheck --skip BD004
# or skip all build checks
pycmdcheck --skip-group build

Package name conversion

The check converts the package name from pyproject.toml to the import name:

  • my-package becomes my_package
  • Hyphens are converted to underscores (PEP 503)

If your import name differs from the package name, ensure the package structure matches.