type-hints-best-practices
Type hints best practices with mypy strict mode for Python 3.13. PROACTIVELY activate for: (1) Writing type annotations, (2) Configuring mypy, (3) Creating Generic types, (4) Defining Protocol interfaces, (5) Setting up CI type checking. Triggers: "type hints", "mypy", "typing", "Generic", "Protocol", "TypeAlias", "strict mode", "type checking"
What this skill does
# Type Hints Best Practices with mypy Strict Mode
## Core Principles
**All Python code in Vibekit MUST pass mypy in strict mode** with zero errors. Type hints are not optional - they are a fundamental requirement for code quality and maintainability.
## Explicit Return Type Annotations
Every exported function must declare its return type:
```python
# ✅ REQUIRED: Explicit return types for all exported functions
def calculate_total(items: list[float]) -> float:
"""Calculate sum of items."""
return sum(items)
def get_user_by_id(user_id: int) -> User | None:
"""Retrieve user or None if not found."""
result = database.query(user_id)
return result
def process_data(data: str) -> None:
"""Process data with no return value."""
print(data.upper())
# ❌ FORBIDDEN: Implicit Any return type
def bad_function(x): # Returns Any - rejected by strict mypy
return x * 2
# ❌ FORBIDDEN: No return type annotation
def also_bad(x: int): # Missing return type
return x * 2
# ✅ GOOD: Explicit return type
def good_function(x: int) -> int:
return x * 2
```
## Using Built-in Generic Types
Use built-in types for generic annotations (Python 3.9+):
```python
# ✅ REQUIRED: Use built-in generics
def process_items(items: list[str]) -> dict[str, int]:
"""Process items and return counts."""
return {item: len(item) for item in items}
def merge_configs(
config1: dict[str, any],
config2: dict[str, any]
) -> dict[str, any]:
"""Merge two configuration dictionaries."""
return {**config1, **config2}
def get_first_item(items: list[int]) -> int | None:
"""Get first item or None."""
return items[0] if items else None
# ❌ FORBIDDEN: Legacy typing imports
from typing import List, Dict, Optional
def old_style(items: List[str]) -> Dict[str, int]: # Don't use these!
pass
```
## Type Aliases for Complex Types
Use the `type` statement for readable type aliases:
```python
# ✅ REQUIRED: Use type statement for type aliases (Python 3.12+)
type UserId = int
type UserData = dict[str, str | int | bool]
type ValidationResult = tuple[bool, str]
def validate_user(user_id: UserId, data: UserData) -> ValidationResult:
"""Validate user data."""
if user_id < 0:
return False, "Invalid user ID"
return True, "Valid"
# For Python 3.9-3.11, use TypeAlias
from typing import TypeAlias
UserIdLegacy: TypeAlias = int
UserDataLegacy: TypeAlias = dict[str, str | int | bool]
# ❌ FORBIDDEN: Inline complex types
def process(
data: dict[str, str | int | bool | list[dict[str, any]]] # Too complex!
) -> tuple[bool, str, dict[str, any]]:
pass
# ✅ GOOD: Named type alias
type ComplexData = dict[str, str | int | bool | list[dict[str, any]]]
type ProcessResult = tuple[bool, str, dict[str, any]]
def process(data: ComplexData) -> ProcessResult:
pass
```
## Generic Types and Classes
Create reusable generic functions and classes:
```python
from typing import TypeVar, Generic
# ✅ REQUIRED: Use TypeVar for generic functions
T = TypeVar('T')
def get_first(items: list[T]) -> T | None:
"""Get first item from list, preserving type."""
return items[0] if items else None
# Usage preserves types
first_int: int | None = get_first([1, 2, 3]) # Type: int | None
first_str: str | None = get_first(["a", "b"]) # Type: str | None
# Generic class
class Stack(Generic[T]):
"""Generic stack implementation."""
def __init__(self) -> None:
self._items: list[T] = []
def push(self, item: T) -> None:
"""Add item to stack."""
self._items.append(item)
def pop(self) -> T | None:
"""Remove and return top item."""
return self._items.pop() if self._items else None
# Usage
int_stack: Stack[int] = Stack()
int_stack.push(1)
int_stack.push(2)
str_stack: Stack[str] = Stack()
str_stack.push("hello")
```
## Protocol for Structural Typing
Use Protocol to define interfaces without inheritance:
```python
from typing import Protocol
# ✅ REQUIRED: Use Protocol for structural subtyping
class Closable(Protocol):
"""Protocol for objects that can be closed."""
def close(self) -> None:
"""Close the resource."""
...
class Serializable(Protocol):
"""Protocol for serializable objects."""
def to_dict(self) -> dict[str, any]:
"""Convert to dictionary."""
...
def cleanup_resource(resource: Closable) -> None:
"""Clean up any closable resource."""
resource.close()
# Any class with a close() method satisfies the protocol
class FileHandler:
def close(self) -> None:
print("Closing file")
class DatabaseConnection:
def close(self) -> None:
print("Closing connection")
# Both work with cleanup_resource
cleanup_resource(FileHandler()) # ✅ Works
cleanup_resource(DatabaseConnection()) # ✅ Works
```
## mypy Strict Mode Configuration
Configure mypy for maximum type safety:
```python
# pyproject.toml
[tool.mypy]
python_version = "3.13"
strict = true
warn_return_any = true
warn_unused_configs = true
disallow_any_generics = true
disallow_subclassing_any = true
disallow_untyped_calls = true
disallow_untyped_defs = true
disallow_incomplete_defs = true
check_untyped_defs = true
disallow_untyped_decorators = true
no_implicit_optional = true
warn_redundant_casts = true
warn_unused_ignores = true
warn_no_return = true
warn_unreachable = true
strict_equality = true
# For gradual typing of legacy code
[[tool.mypy.overrides]]
module = "legacy.module.*"
disallow_untyped_defs = false # Temporarily disable for legacy
```
## Union Types with | Operator
Use the modern union syntax:
```python
# ✅ REQUIRED: Use | for union types
def process_value(value: str | int | float) -> str:
"""Handle multiple types."""
return str(value)
def find_user(query: str) -> User | None:
"""Return User or None if not found."""
result = database.find(query)
return result
# ✅ REQUIRED: None always comes last in unions
def get_config(key: str) -> str | int | None:
"""Get configuration value."""
return config.get(key)
# ❌ FORBIDDEN: Legacy Union and Optional
from typing import Union, Optional
def old_style(value: Union[str, int]) -> Optional[User]: # Don't use
pass
# ✅ GOOD: Modern style
def new_style(value: str | int) -> User | None:
pass
```
## Literal Types for Specific Values
Use Literal for exact value matching:
```python
from typing import Literal
# ✅ REQUIRED: Use Literal for specific string/int values
def set_log_level(level: Literal["DEBUG", "INFO", "WARNING", "ERROR"]) -> None:
"""Set logging level to specific value."""
logging.setLevel(level)
def get_status_code(status: Literal[200, 404, 500]) -> str:
"""Get status message for specific codes."""
messages = {200: "OK", 404: "Not Found", 500: "Error"}
return messages[status]
# Usage
set_log_level("DEBUG") # ✅ OK
set_log_level("INFO") # ✅ OK
set_log_level("TRACE") # ❌ Type error: "TRACE" not in Literal
```
## TypedDict for Structured Dictionaries
Define exact dictionary structures:
```python
from typing import TypedDict
# ✅ REQUIRED: Use TypedDict for structured dicts
class UserDict(TypedDict):
"""Typed dictionary for user data."""
id: int
email: str
username: str
is_active: bool
def create_user(data: UserDict) -> User:
"""Create user from typed dict."""
return User(
id=data["id"],
email=data["email"],
username=data["username"],
is_active=data["is_active"]
)
# Usage
user_data: UserDict = {
"id": 1,
"email": "[email protected]",
"username": "user",
"is_active": True
}
user = create_user(user_data)
# ❌ Type error: missing required key
bad_data: UserDict = {"id": 1, "email": "[email protected]"} # Missing username
```
## Any vs object
Use `object` instead of `Any` when possible:
```python
from typing import Any
# ❌ BAD: Any disables type checking
def log_anything(value: Any) -> None:
print(str(value)) # No type safety
# ✅ GORelated in Cloud & DevOps
appbuilder-action-scaffolder
IncludedCreate, implement, deploy, and debug Adobe Runtime actions with consistent layout, validation, and error handling. Use this skill whenever the user needs to add actions to an App Builder project, understand action structure (params, response format, web/raw actions), configure actions in the manifest, use App Builder SDKs (State, Files, Events, database), deploy and invoke actions via CLI, debug action issues, or implement patterns such as webhook receivers, custom event providers, journaling consumers, large payload redirects, action sequence pipelines, and Asset Compute workers. Also trigger when users mention serverless functions in Adobe context, action logging, IMS authentication for actions, or cron-style scheduled actions.
orchestrating-datacloud
IncludedSalesforce Data Cloud product orchestrator for connect→prepare→harmonize→segment→act workflows. Use this skill when the user needs a multi-step Data Cloud pipeline, cross-phase troubleshooting, or data space and data kit management. TRIGGER when: user needs a multi-step Data Cloud pipeline, asks to set up or troubleshoot Data Cloud across phases, manages data spaces or data kits, or wants a cross-phase sf data360 workflow. DO NOT TRIGGER when: work is isolated to a single phase (use the matching phase-specific skill), the task is STDM/session tracing/parquet telemetry (use observing-agentforce), standard CRM SOQL (use querying-soql), or Apex implementation (use generating-apex).
github-project-automation
IncludedAutomate GitHub repository setup with CI/CD workflows, issue templates, Dependabot, and CodeQL security scanning. Includes 12 production-tested workflows and prevents 18 errors: YAML syntax, action pinning, and configuration. Use when: setting up GitHub Actions CI/CD, creating issue/PR templates, enabling Dependabot or CodeQL scanning, deploying to Cloudflare Workers, implementing matrix testing, or troubleshooting YAML indentation, action version pinning, secrets syntax, runner versions, or CodeQL configuration. Keywords: github actions, github workflow, ci/cd, issue templates, pull request templates, dependabot, codeql, security scanning, yaml syntax, github automation, repository setup, workflow templates, github actions matrix, secrets management, branch protection, codeowners, github projects, continuous integration, continuous deployment, workflow syntax error, action version pinning, runner version, github context, yaml indentation error
sf-datacloud
IncludedSalesforce Data Cloud product orchestrator for connect→prepare→harmonize→segment→act workflows. TRIGGER when: user needs a multi-step Data Cloud pipeline, asks to set up or troubleshoot Data Cloud across phases, manages data spaces or data kits, or wants a cross-phase `sf data360` workflow. DO NOT TRIGGER when: work is isolated to a single phase (use the matching sf-datacloud-* skill), the task is STDM/session tracing/parquet telemetry (use sf-ai-agentforce-observability), standard CRM SOQL (use sf-soql), or Apex implementation (use sf-apex).
fabric-cli
IncludedUse this skill for Fabric.so CLI workflows with the `fabric` terminal command: diagnose/install/login, search or browse a Fabric library, save notes/links/files, create folders, ask the Fabric AI assistant, manage tasks/workspaces, generate shell completion, check subscription usage, produce JSON output, and use Fabric as persistent agent memory. Do not use for Microsoft Fabric/Azure/Power BI `fab`, Daniel Miessler's Fabric framework, Python Fabric SSH, Fabric.js, or textile/fashion fabric.
lark
IncludedLark/Feishu CLI skills: lark-cli operations for docs, markdown, sheets, base, calendar, im, mail, task, okr, drive, wiki, slides, whiteboard, apps, approval, attendance, contact, vc, minutes, event. Use when the user needs to operate Lark/Feishu resources via lark-cli, send messages, manage documents, spreadsheets, calendars, tasks, OKRs, deploy web pages, or any Feishu/Lark workspace operations.