Tool for validating Python wheel contents to detect common packaging errors and ensure proper distribution structure
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Flexible configuration system supporting multiple file formats (TOML, INI) and command-line overrides. Handles check selection, package expectations, directory traversal patterns, and integration with various project configuration files.
Automatic discovery and parsing of configuration files in multiple formats, with support for project-specific settings and hierarchical configuration resolution.
class Configuration:
"""Container for WheelChecker configuration values"""
def __init__(self, select: set[Check] | None = None,
ignore: set[Check] | None = None,
toplevel: list[str] | None = None,
package_paths: list[Path] | None = None,
src_dirs: list[Path] | None = None,
package_omit: list[str] | None = None):
"""
Initialize configuration container.
Parameters:
- select: Set of checks to enable, or None for default
- ignore: Set of checks to disable, or None for none
- toplevel: Expected toplevel library entries for W2 checks
- package_paths: Paths specified with --package option
- src_dirs: Paths specified with --src-dir option
- package_omit: Patterns to exclude when traversing package/src dirs
"""
@classmethod
def from_config_file(cls, path: str | None = None) -> 'Configuration':
"""
Read configuration from file or discover automatically.
Parameters:
- configpath: Explicit config file path, or None to auto-discover
Returns:
Configuration instance with loaded settings
Raises:
- UserInputError: If config file is invalid or contains errors
"""
@classmethod
def from_command_options(cls, select: set[Check] | None = None,
ignore: set[Check] | None = None,
toplevel: list[str] | None = None,
package: tuple[str, ...] = (),
src_dir: tuple[str, ...] = (),
package_omit: list[str] | None = None) -> 'Configuration':
"""Construct Configuration from command line options"""Support for multiple configuration file formats with automatic format detection and parsing.
# Configuration file search order (first found with relevant section is used)
CONFIG_FILES = [
"pyproject.toml", # TOML format in [tool.check-wheel-contents]
"tox.ini", # INI format in [check-wheel-contents]
"setup.cfg", # INI format in [tool:check-wheel-contents]
"check-wheel-contents.cfg", # INI format in [check-wheel-contents]
".check-wheel-contents.cfg" # INI format in [check-wheel-contents]
]
CONFIG_SECTION = "check-wheel-contents" # Default INI section name
# Default exclusion patterns for package/src-dir traversal
TRAVERSAL_EXCLUSIONS = [
".*", "CVS", "RCS", "*.pyc", "*.pyo", "*.egg-info"
]Functionality for building expected package structures from source directories and package specifications.
def build_package_tree(self, package_paths: list[Path],
src_dir_paths: list[Path],
package_omit: list[str] | None = None) -> Directory:
"""
Build expected package tree from source paths.
Parameters:
- package_paths: List of package directories to include
- src_dir_paths: List of source directories to include contents of
- package_omit: Patterns to exclude during traversal
Returns:
Directory representing expected package structure
Raises:
- UserInputError: If paths are invalid or inaccessible
"""
def traverse_tree(self, dirpath: Path,
exclusions: list[str] | None = None) -> Directory:
"""
Traverse a directory tree with exclusion patterns.
Parameters:
- dirpath: Root directory to traverse
- exclusions: Glob patterns to exclude
Returns:
Directory tree representation
"""from pathlib import Path
from check_wheel_contents.config import Configuration, CONFIG_FILES
from check_wheel_contents.errors import UserInputError
# Auto-discover configuration
try:
config = Configuration.read_config()
print(f"Loaded configuration from auto-discovered file")
except UserInputError as e:
print(f"Configuration error: {e}")
# Load from specific file
config_path = Path("pyproject.toml")
if config_path.exists():
config = Configuration.read_config(config_path)
print(f"Loaded configuration from {config_path}")
# Create configuration programmatically
from check_wheel_contents.checks import parse_checks_string
config = Configuration(
select=parse_checks_string("W1,W2"),
ignore=parse_checks_string("W005"),
toplevel=["mypackage"],
package_paths=[Path("src/mypackage")],
package_omit=["*.pyc", ".*", "__pycache__"]
)
# Check configuration values
selected = config.get_checks_selected()
if selected:
print(f"Selected checks: {[c.name for c in selected]}")
ignored = config.get_checks_ignored()
if ignored:
print(f"Ignored checks: {[c.name for c in ignored]}")
# Example pyproject.toml configuration:
"""
[tool.check-wheel-contents]
select = ["W1", "W2"]
ignore = ["W005"]
toplevel = ["mypackage", "mypackage.ext"]
package = ["src/mypackage"]
src-dir = ["src"]
package-omit = ["*.pyc", ".*", "__pycache__", "tests"]
"""
# Example setup.cfg configuration:
"""
[tool:check-wheel-contents]
select = W1,W2
ignore = W005
toplevel = mypackage,mypackage.ext
package = src/mypackage
src-dir = src
package-omit = *.pyc,.*,__pycache__,tests
"""
# Manual configuration file discovery
for filename in CONFIG_FILES:
config_path = Path(filename)
if config_path.exists():
try:
config = Configuration.read_config(config_path)
print(f"Using config from {filename}")
break
except UserInputError:
continue
else:
print("No configuration file found, using defaults")
config = Configuration()Install with Tessl CLI
npx tessl i tessl/pypi-check-wheel-contents