PEP 561 Type Distribution Workflow
The type-check.yml workflow ensures that the Slack MCP Server properly distributes type information according to PEP 561 standards.
Triggers:
- Push to master: When type distribution files are modified
- Pull requests to master: For PEP 561 compliance validation before merge
- Manual dispatch: On-demand validation via workflow dispatch
Purpose: Validates PEP 561 compliance for type information distribution in Python packages.
Note: MyPy type checking of source code is handled by pre-commit hooks (configured in .pre-commit-config.yaml). This workflow focuses exclusively on PEP 561 compliance - ensuring type information is properly packaged and distributed.
Overviewâ
This workflow validates type information distribution:
- đ PEP 561 Compliance - Validates proper type information packaging and distribution
- đĻ Type Imports - Ensures type definitions are accessible and functional after installation
- đ Distribution Verification - Confirms type files are included in built packages
Workflow Jobsâ
1. PEP 561 Compliance Verification (verify-pep561-compliance)â
Validates that the package correctly implements PEP 561 standards for distributing type information with Python packages.
Purpose: Ensures type checkers can automatically discover and use the package's type information after installation.
Validation Process:
Step 1: Marker File Validation
# Verify py.typed marker file exists
if [ ! -f "slack_mcp/py.typed" ]; then
echo "â Error: py.typed marker file not found!"
exit 1
fi
â
py.typed marker file exists
Step 2: Type Module Validation
# Verify types.py module and exports
â
types.py module exists
â
types.py has __all__ export
Step 3: Build Configuration Validation
# Verify pyproject.toml includes type artifacts
â
pyproject.toml includes py.typed in artifacts
Step 4: Distribution Verification
# Build package and verify type files in distributions
uv build --sdist --wheel
# Check source distribution
â
py.typed found in source distribution
â
types.py found in source distribution
# Check wheel distribution
â
py.typed found in wheel distribution
â
types.py found in wheel distribution
PEP Standards Validated:
- PEP 561 - Distributing and Packaging Type Information
- PEP 484 - Type Hints
- PEP 585 - Type Hinting Generics
- PEP 544 - Protocols (Structural Subtyping)
- PEP 695 - Type Parameter Syntax (Python 3.12+)
2. Type Import Testing (test-type-imports)â
Validates that type definitions are correctly exported and accessible for use in application code.
Purpose: Ensures the type system is functional and all type definitions can be imported and used as intended after package installation.
Test Categories:
Module Import Validation
from slack_mcp import types
â
Successfully imported types module
â
Available types: 23 exports
SlackEvent Enum Validation
from slack_mcp import SlackEvent
â
Successfully imported SlackEvent
â
Total events: 99
Type Accessibility Testing
The workflow validates that all major type categories are accessible:
# JSON type definitions
assert hasattr(types, 'JSONValue')
assert hasattr(types, 'JSONDict')
assert hasattr(types, 'JSONList')
assert hasattr(types, 'JSONPrimitive')
â
JSON types accessible
# Slack-specific types
assert hasattr(types, 'SlackChannelID')
assert hasattr(types, 'SlackUserID')
assert hasattr(types, 'SlackTimestamp')
assert hasattr(types, 'SlackToken')
assert hasattr(types, 'SlackEventPayload')
â
Slack types accessible
# Protocol definitions (PEP 544)
assert hasattr(types, 'EventHandlerProtocol')
assert hasattr(types, 'QueueBackendProtocol')
â
Protocol types accessible
# Type guard functions
assert hasattr(types, 'is_slack_channel_id')
assert hasattr(types, 'is_slack_user_id')
assert hasattr(types, 'is_slack_timestamp')
â
Type guards accessible
Type Guard Functionality Testing
Validates runtime type validation functions work correctly:
# Channel ID validation
assert types.is_slack_channel_id('C1234567890') == True
assert types.is_slack_channel_id('#general') == True
assert types.is_slack_channel_id('invalid') == False
â
Channel ID type guard works
# User ID validation
assert types.is_slack_user_id('U1234567890') == True
assert types.is_slack_user_id('W1234567890') == True
assert types.is_slack_user_id('invalid') == False
â
User ID type guard works
# Timestamp validation
assert types.is_slack_timestamp('1234567890.123456') == True
assert types.is_slack_timestamp('invalid') == False
â
Timestamp type guard works
3. PEP 561 Summary (summary)â
Aggregates results from all validation jobs and provides a comprehensive status report.
Purpose: Provides a single source of truth for PEP 561 compliance status.
Dependencies: Requires completion of both previous jobs (verify-pep561-compliance, test-type-imports)
Summary Report Format:
## PEP 561 Type Distribution Results
âšī¸ **Note**: MyPy source code checking is handled by pre-commit hooks
â
PEP 561 compliance: **PASSED**
â
Type imports: **PASSED**
### PEP Standards Verified
- PEP 561: Distributing and Packaging Type Information
- PEP 484: Type Hints
- PEP 585: Type Hinting Generics
- PEP 544: Protocols (Structural Subtyping)
- PEP 695: Type Parameter Syntax (Python 3.12+)
Failure Handling: The workflow fails if any validation job does not succeed, ensuring type distribution compliance is maintained.
Type Definition Standardsâ
The Slack MCP Server follows modern Python typing standards with comprehensive type definitions in slack_mcp/types.py.
PEP 695 Type Aliases (Python 3.12+)â
All type aliases use the modern type statement syntax introduced in PEP 695:
Modern Syntax (PEP 695):
# Simple type aliases
type SlackChannelID = str
type SlackUserID = str
# Generic type aliases
type JSONDict = Dict[str, JSONValue]
type JSONList = List[JSONValue]
# Union type aliases
type JSONPrimitive = Union[str, int, float, bool, None]
type EventHandlerFunc = Union[SyncEventHandlerFunc, AsyncEventHandlerFunc]
# Literal type aliases
type TransportType = Literal["stdio", "sse", "streamable-http"]
Benefits over TypeAlias annotation:
- â Cleaner syntax - More concise and readable
- â Better type inference - Type checkers understand it natively
- â No forward reference quotes - Automatic resolution of forward references
- â SonarQube compliant - Resolves python:S6794 rule violations
- â Modern standard - Recommended for Python 3.12+
Type Categoriesâ
JSON Types:
type JSONPrimitive = Union[str, int, float, bool, None]
type JSONValue = Union[JSONPrimitive, JSONDict, JSONList]
type JSONDict = Dict[str, JSONValue]
type JSONList = List[JSONValue]
Slack Types:
type SlackChannelID = str
type SlackUserID = str
type SlackTimestamp = str
type SlackToken = str
type SlackEventPayload = Dict[str, Any]
Handler Types:
type SyncEventHandlerFunc = Callable[[SlackEventPayload], None]
type AsyncEventHandlerFunc = Callable[[SlackEventPayload], Awaitable[None]]
type EventHandlerFunc = Union[SyncEventHandlerFunc, AsyncEventHandlerFunc]
Protocol Types (PEP 544):
@runtime_checkable
class EventHandlerProtocol(Protocol):
async def handle_event(self, event: SlackEventPayload) -> None: ...
@runtime_checkable
class QueueBackendProtocol(Protocol):
async def publish(self, key: QueueKey, payload: QueuePayload) -> None: ...
async def consume(self, *, group: Optional[str] = None) -> AsyncIterator[QueueMessage]: ...
Type Guardsâ
Runtime type validation functions for Slack-specific types:
def is_slack_channel_id(value: str) -> bool:
"""Check if string is a valid Slack channel ID."""
return value.startswith(("C", "G", "D", "#"))
def is_slack_user_id(value: str) -> bool:
"""Check if string is a valid Slack user ID."""
return value.startswith(("U", "W", "B"))
def is_slack_timestamp(value: str) -> bool:
"""Check if string is a valid Slack timestamp."""
parts = value.split(".")
return len(parts) == 2 and parts[0].isdigit() and parts[1].isdigit()
Local Developmentâ
Developers can run PEP 561 compliance validations locally before pushing changes.
For MyPy source code type checking, use pre-commit hooks:
# Run pre-commit on all files
pre-commit run --all-files
# Run only MyPy hook
pre-commit run mypy --all-files
PEP 561 Validation Commandsâ
Marker File Validation
# Verify py.typed marker exists
ls -la slack_mcp/py.typed
Distribution Testing
# Build package
uv build --sdist --wheel
# Verify type files in source distribution
tar -tzf dist/*.tar.gz | grep -E "(py.typed|types.py)"
# Verify type files in wheel
unzip -l dist/*.whl | grep -E "(py.typed|types.py)"
Type Import Testingâ
Module Import Validation
# Test types module import
uv run python -c "from slack_mcp import types; print(f'Available types: {len(types.__all__)}')"
# Test SlackEvent import
uv run python -c "from slack_mcp import SlackEvent; print(f'Total events: {len(SlackEvent)}')"
Type Guard Testing
# Validate type guard functionality
uv run python -c "
from slack_mcp import types
assert types.is_slack_channel_id('C1234567890')
assert types.is_slack_user_id('U1234567890')
assert types.is_slack_timestamp('1234567890.123456')
print('â
All type guards work correctly')
"
Example Executionâ
Execute Type Checking Examples
# Run type checking example to verify runtime behavior
uv run python examples/type_checking/type_checking_example.py
MyPy validation of examples is handled by pre-commit hooks. Use pre-commit run mypy --all-files to type-check all code including examples.
Automated Verification Scriptâ
The project includes a comprehensive verification script:
# Run full type checking verification
./scripts/ci/verify_type_checking.sh
This script performs all validation steps automatically and provides a detailed report.
Troubleshootingâ
Common Issuesâ
MyPy Type Errors
- Symptom: Type checking fails with incompatible type errors
- Solution: Review MyPy error messages and fix type annotations
- Example Error:
error: Incompatible types in assignment (expression has type "str", variable has type "int")
Missing PEP 561 Marker
- Symptom:
py.typed marker file not founderror in workflow - Solution: Ensure
slack_mcp/py.typedfile exists in the package directory - Verification:
ls -la slack_mcp/py.typed
Type Import Failures
- Symptom: Cannot import types from
slack_mcp.types - Solution: Verify
__all__exports intypes.pyand package__init__.py - Check:
uv run python -c "from slack_mcp import types; print(types.__all__)"
Distribution Issues
- Symptom: Type files not included in built packages
- Solution: Verify
pyproject.tomlincludespy.typedin artifacts configuration - Validation: Build package and check contents with
tar -tzforunzip -l
Workflow Not Triggering
- Symptom: Workflow doesn't run on expected file changes
- Solution: Check file paths match trigger conditions in workflow YAML
- Verification: Review workflow file path patterns and branch names
MyPy Version Conflicts
- Symptom: Different MyPy versions produce different results
- Solution: Ensure consistent MyPy version in
pyproject.toml:[dependency-groups]
pre-commit-ci = [
"mypy>=1.16.1,<2",
]
Missing Dependencies
- Symptom: Import errors during type checking
- Solution: Install all dependencies including extras:
uv sync --all-extras
SonarQube python:S6794 Violations
- Symptom: SonarQube reports "Use PEP 695 type aliases" for
TypeAliasusage - Solution: Use modern
typestatement syntax instead ofTypeAliasannotation - Migration:
# â Old style (triggers S6794)
from typing import TypeAlias
MyType: TypeAlias = str
# â New style (PEP 695)
type MyType = str - Requirement: Python 3.12+ (already required by this project)
Debug Configurationâ
View Workflow Logs
# List recent workflow runs
gh run list --workflow=type-check.yml --limit=5
# View specific run details
gh run view <run-id> --log
Test Configuration Locally
# Run verification script
./scripts/ci/verify_type_checking.sh
# Check specific validation
uv run mypy slack_mcp/ --show-error-codes
Workflow Integrationâ
The type checking workflow integrates with the project's CI/CD system:
Integration Points:â
- Pre-merge Validation â Runs on all pull requests to master
- Post-merge Verification â Validates type safety after merges
- Manual Validation â Available via workflow dispatch for on-demand checks
Monitoring and Maintenance:â
- Workflow status visible via badge:
- Failed workflows trigger notifications for immediate attention
- Regular review ensures type definitions stay current with codebase changes
Navigationâ
- đ CI/CD Overview - Return to main CI/CD hub
- đ Continuous Integration - Main CI workflows and testing
- đ Release System - Production releases and deployment
- âī¸ Additional CI Workflows - Specialized utility workflows
- đ ī¸ Developer Guide - Configuration and troubleshooting