or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

cli.mdcomment-handling.mdglobal-licensing.mdindex.mdproject-management.mdreport-generation.mdreuse-info.mdvcs-integration.md
tile.json

tessl/pypi-reuse

A tool for compliance with the REUSE recommendations for software licensing and copyright management.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/reuse@5.1.x

To install, run

npx @tessl/cli install tessl/pypi-reuse@5.1.0

index.mddocs/

REUSE

REUSE is a comprehensive Python tool for compliance with the REUSE recommendations developed by the Free Software Foundation Europe (FSFE). It simplifies copyright and licensing processes by offering automated tools to choose and provide licenses, add copyright and licensing information to files, and confirm REUSE compliance.

Package Information

  • Package Name: reuse
  • Language: Python
  • Installation: pip install reuse
  • Python Version: 3.9+

Core Imports

import reuse
from reuse import ReuseInfo, SourceType
from reuse.project import Project, GlobalLicensingFound
from reuse.types import StrPath

For working with collections:

from typing import Collection, Optional, Iterator

For report generation:

from reuse.report import ProjectReport, FileReport
from reuse.lint import format_plain, format_json, format_lines, format_lines_subset

CLI usage:

reuse --help

Basic Usage

from reuse.project import Project
from pathlib import Path

# Create a project instance
project = Project.from_directory(Path.cwd())

# Get REUSE information for a file (accepts StrPath)
reuse_info = project.reuse_info_of("src/example.py")
for info in reuse_info:
    print(f"Licenses: {info.spdx_expressions}")
    print(f"Copyright: {info.copyright_lines}")

# Iterate through all files in project
for file_path in project.all_files():
    print(f"Processing: {file_path}")
    
# Get subset of files
files_to_check = ["src/main.py", "src/utils.py"]
for file_path in project.subset_files(files_to_check):
    print(f"Checking: {file_path}")

CLI usage:

# Lint project for REUSE compliance
reuse lint

# Add copyright and license to files
reuse annotate --copyright="2023 Jane Doe" --license="MIT" src/example.py

# Generate SPDX bill of materials
reuse spdx --format=json > project.spdx.json

# Download a license
reuse download MIT

Architecture

The REUSE tool is built around several key components:

  • Project: Central class managing project root, configuration, and file discovery
  • ReuseInfo: Data container holding licensing and copyright information for files
  • Global Licensing: Support for project-wide licensing configuration via .dep5 and REUSE.toml files
  • Comment Handling: Extensible system supporting 25+ file types for comment-based headers
  • VCS Integration: Pluggable version control system support (Git, Mercurial, Jujutsu, Pijul)
  • Report Generation: Comprehensive compliance reporting with multiple output formats

Important: The Python API is documented but NOT guaranteed stable between minor or patch releases. Semantic versioning applies exclusively to the CLI command. Library users should pin to exact versions.

Capabilities

Command Line Interface

Complete CLI with 7 subcommands for REUSE compliance management including linting, annotation, SPDX generation, and license management.

reuse [OPTIONS] COMMAND [ARGS]...

# Global options:
--debug                    Enable debug statements
--suppress-deprecation     Hide deprecation warnings
--include-submodules       Do not skip Git submodules
--include-meson-subprojects Do not skip Meson subprojects
--no-multiprocessing       Do not use multiprocessing
--root PATH                Define project root directory

Command Line Interface

Project Management and Analysis

Core project discovery, configuration management, and file analysis capabilities.

class Project:
    """Central class holding project root and configuration."""
    
    root: Path
    include_submodules: bool = False
    include_meson_subprojects: bool = False
    vcs_strategy: VCSStrategy
    global_licensing: Optional[GlobalLicensing] = None
    license_map: dict[str, dict]
    licenses: dict[str, Path]
    licenses_without_extension: dict[str, Path]
    
    @classmethod
    def from_directory(
        cls, 
        root: StrPath, 
        include_submodules: bool = False,
        include_meson_subprojects: bool = False
    ) -> Project:
        """Factory method to create Project from directory.
        
        Raises:
            FileNotFoundError: if root does not exist.
            NotADirectoryError: if root is not a directory.
            UnicodeDecodeError: if the global licensing config file could not be decoded.
            GlobalLicensingParseError: if the global licensing config file could not be parsed.
            GlobalLicensingConflictError: if more than one global licensing config file is present.
        """
    
    @classmethod
    def find_global_licensing(
        cls,
        root: Path,
        include_submodules: bool = False,
        include_meson_subprojects: bool = False,
        vcs_strategy: Optional[VCSStrategy] = None,
    ) -> list[GlobalLicensingFound]:
        """Find the path and corresponding class of a project directory's GlobalLicensing.
        
        Raises:
            GlobalLicensingConflictError: if more than one global licensing config file is present.
        """
    
    def all_files(self, directory: Optional[StrPath] = None) -> Iterator[Path]:
        """Yield all files in directory and its subdirectories."""
    
    def subset_files(
        self, files: Collection[StrPath], directory: Optional[StrPath] = None
    ) -> Iterator[Path]:
        """Like all_files, but all files that are not in files are filtered out."""
    
    def reuse_info_of(self, path: StrPath) -> list[ReuseInfo]:
        """Return REUSE info of path."""
    
    def relative_from_root(self, path: StrPath) -> Path:
        """Return path relative to the project root."""

Project Management

REUSE Information Processing

Data structures and functions for processing REUSE licensing and copyright information.

@dataclass(frozen=True)
class ReuseInfo:
    spdx_expressions: set[Expression] = field(default_factory=set)
    copyright_lines: set[str] = field(default_factory=set)
    contributor_lines: set[str] = field(default_factory=set)
    path: Optional[str] = None
    source_path: Optional[str] = None
    source_type: Optional[SourceType] = None
    
    def copy(self, **kwargs: Any) -> ReuseInfo: ...
    def union(self, value: ReuseInfo) -> ReuseInfo: ...
    def contains_copyright_or_licensing(self) -> bool: ...

class SourceType(Enum):
    DOT_LICENSE = "dot-license"
    FILE_HEADER = "file-header"
    DEP5 = "dep5"
    REUSE_TOML = "reuse-toml"

REUSE Information Processing

Comment Handling System

Extensible comment processing system supporting 25+ file types for adding and parsing copyright headers.

def get_comment_style(path: Path) -> Optional[Type[CommentStyle]]: ...
def is_uncommentable(path: Path) -> bool: ...
def has_style(path: Path) -> bool: ...

class CommentStyle:
    # Base class for comment style implementations
    pass

Comment Handling

Global Licensing Configuration

Support for project-wide licensing configuration through .reuse/dep5 and REUSE.toml files.

class GlobalLicensing(ABC):
    # Abstract base class for global licensing
    pass

class ReuseDep5(GlobalLicensing):
    # Implementation for .reuse/dep5 files
    pass

class ReuseTOML(GlobalLicensing):
    # Implementation for REUSE.toml files
    pass

Global Licensing

Report Generation

Comprehensive compliance reporting with multiple output formats including plain text, JSON, and line-based formats.

class ProjectReport:
    """Object that holds linting report about the project."""
    
    # Main attributes
    path: StrPath
    licenses: dict[str, Path]
    missing_licenses: dict[str, set[Path]]
    bad_licenses: dict[str, set[Path]]
    deprecated_licenses: set[str]
    read_errors: set[Path]
    file_reports: set[FileReport]
    licenses_without_extension: dict[str, Path]
    
    def __init__(self, do_checksum: bool = True): ...
    
    # Properties
    @property
    def used_licenses(self) -> set[str]: ...
    
    @property  
    def unused_licenses(self) -> set[str]: ...
    
    @property
    def files_without_licenses(self) -> set[Path]: ...
    
    @property
    def files_without_copyright(self) -> set[Path]: ...
    
    @property
    def is_compliant(self) -> bool: ...

class FileReport:
    """Report for individual file compliance."""
    pass

# Formatting functions (from reuse.lint module)
def format_plain(report: ProjectReport) -> str:
    """Format report as plain text."""

def format_json(report: ProjectReport) -> str:
    """Format report as JSON."""

def format_lines(report: ProjectReport) -> str:
    """Format report as line-based output."""

def format_lines_subset(report: ProjectReportSubsetProtocol) -> str:
    """Format subset report as line-based output."""

Report Generation

VCS Integration

Pluggable version control system support for Git, Mercurial, Jujutsu, and Pijul.

class VCSStrategy(ABC):
    # Abstract base class for VCS strategies
    pass

def find_root(cwd: Optional[StrPath] = None) -> Optional[Path]: ...
def all_vcs_strategies() -> Generator[Type[VCSStrategy], None, None]: ...

VCS Integration

Core Data Types

# Type definitions
StrPath = Union[str, PathLike[str]]

# Named tuples
class MultiLineSegments(NamedTuple):
    start: str
    middle: str
    end: str

class GlobalLicensingFound(NamedTuple):
    path: Path
    cls: Type[GlobalLicensing]

Exception Hierarchy

class ReuseError(Exception):
    """Base exception for all REUSE-specific errors"""
    pass

class SpdxIdentifierNotFoundError(ReuseError):
    """Could not find SPDX identifier for license file"""
    pass

class GlobalLicensingParseError(ReuseError):
    """Error parsing GlobalLicensing file"""
    def __init__(self, *args, source: Optional[str] = None): ...

class GlobalLicensingParseTypeError(GlobalLicensingParseError, TypeError):
    """Type error while parsing a GlobalLicensing file"""
    pass

class GlobalLicensingParseValueError(GlobalLicensingParseError, ValueError):
    """Value error while parsing a GlobalLicensing file"""
    pass

class GlobalLicensingConflictError(ReuseError):
    """Two global licensing files in the project are not compatible"""
    pass

class MissingReuseInfoError(ReuseError):
    """Missing REUSE information from result"""
    pass

class CommentError(ReuseError):
    """Error during comment interaction"""
    pass

class CommentCreateError(Exception):
    """Error occurred during the creation of a comment"""
    pass

class CommentParseError(Exception):
    """Error occurred during the parsing of a comment"""
    pass