[PATCH 2/2] python-linux-procfs: Add AGENTS.md and update copyright to 2026

John Kacur <[email protected]> Tue, 16 Jun 2026 15:47:02 -0400
Newsgroups org.kernel.vger.linux-rt-users
Message-ID <[email protected]>
Add comprehensive AGENTS.md documentation for AI coding assistants
working with the python-linux-procfs codebase. This guide covers project
architecture, development guidelines, core components, usage examples,
and contribution workflow.

Replace CLAUDE.md with AGENTS.md to match the documentation format used
in other RT userspace programs (rteval, tuna, rt-tests).

Update copyright notices to 2026 in all source files to reflect current
year of modification.

Fix spelling: "superseeded" -> "superseded" in pflags comment.

Assisted-by: Claude Sonnet 4.5 <[email protected]>
Signed-off-by: John Kacur <[email protected]>
---
 AGENTS.md           | 313 ++++++++++++++++++++++++++++++++++++++++++++
 CLAUDE.md           | 102 ---------------
 bitmasklist_test.py |   2 +-
 pflags              |   4 +-
 procfs/__init__.py  |   4 +-
 procfs/procfs.py    |   2 +-
 procfs/utilist.py   |   2 +-
 7 files changed, 320 insertions(+), 109 deletions(-)
 create mode 100644 AGENTS.md
 delete mode 100644 CLAUDE.md

diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 000000000000..08e50b4d2243
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,313 @@
+SPDX-License-Identifier: GPL-2.0-only
+
+Copyright 2026 John Kacur <[email protected]>
+
+# AGENTS.md - AI Coding Assistant Guide for python-linux-procfs
+
+This document provides guidance for AI coding assistants working with the python-linux-procfs codebase.
+
+## Project Overview
+
+**python-linux-procfs** is a Python library that provides abstractions to extract information from the Linux kernel /proc filesystem. It's used by system programming tools for process introspection, CPU topology detection, interrupt handling, and system state monitoring.
+
+- **License**: GPL-2.0-only
+- **Language**: Python 3.10+
+- **Primary Maintainer**: John Kacur <[email protected]>
+- **Original Author**: Arnaldo Carvalho de Melo <[email protected]>
+- **Repository**: https://git.kernel.org/pub/scm/libs/python/python-linux-procfs/python-linux-procfs.git
+
+## Architecture
+
+### Directory Structure
+
+```
+python-linux-procfs/
+├── procfs/                       # Core Python package
+│   ├── __init__.py              # Package initialization, exports all classes
+│   ├── procfs.py                # Main module with /proc abstraction classes
+│   └── utilist.py               # Bitmask utility functions
+├── pflags                        # Command-line utility to display process flags
+├── bitmasklist_test.py          # Unit tests for bitmask functions
+├── pyproject.toml               # Modern Python project metadata
+├── setup.py                     # Legacy setuptools configuration
+├── Makefile                     # Build targets (clean, tags)
+├── MANIFEST                     # Python packaging manifest
+├── COPYING                      # License file (GPL-2.0-only)
+└── .gitignore                   # Git ignore patterns
+```
+
+### Core Components
+
+The library consists of a single `procfs` package with two main modules:
+
+**procfs/procfs.py** - Main module containing all /proc abstraction classes:
+
+1. **Process Information Classes**
+   - `pidstat` - Parses /proc/PID/stat files for process statistics
+   - `pidstatus` - Parses /proc/PID/status files for additional process info
+   - `process` - Combines stat and status data, lazy-loads cmdline, threads, cgroups, environ
+   - `pidstats` - Collection of all processes in the system with find/search methods
+
+2. **System Information Classes**
+   - `interrupts` - Parses /proc/interrupts for IRQ information
+   - `cmdline` - Parses /proc/cmdline for kernel boot parameters
+   - `cpuinfo` - Parses /proc/cpuinfo for CPU information and topology
+   - `cpustat`/`cpusstats` - Parses /proc/stat for CPU usage statistics
+
+3. **Memory Information Classes**
+   - `smaps` - Parses /proc/PID/smaps for memory mapping information
+   - `smaps_lib` - Aggregates memory maps by library
+
+**procfs/utilist.py** - Utility functions for bitmask conversions:
+- `bitmasklist()` - Converts hex CPU affinity masks to lists of CPU numbers
+- `hexbitmask()` - Converts CPU number lists to hex bitmask format
+
+### Command Line Tools
+
+**pflags** - Utility to display process flags for running processes:
+- Can filter by PID, process name, or glob patterns
+- Shows kernel process flags (PF_*) in human-readable format
+- Handles superseded flags (removes old flag names when new ones exist)
+
+### Design Patterns
+
+1. **Lazy Loading**: The `process` class implements lazy loading via `__getitem__` - attributes like "stat", "status", "cmdline", "threads", "cgroups", and "environ" are only loaded when accessed.
+
+2. **Dictionary-like Interfaces**: Most classes implement dict-like access patterns (`__getitem__`, `keys()`, `values()`, `items()`, `__contains__`) for intuitive data access.
+
+3. **Ephemeral Process Handling**: Code throughout handles processes disappearing mid-query by catching `FileNotFoundError` and `IOError` exceptions.
+
+4. **basedir Parameter**: Most classes accept a `basedir` parameter (default "/proc") to support testing with mock /proc filesystems or accessing /proc from containers.
+
+### Key Implementation Details
+
+- **Process flags**: `pidstat` class defines PF_* constants matching kernel's include/linux/sched.h. Some flags have duplicate values representing kernel API changes (e.g., PF_THREAD_BOUND and PF_NO_SETAFFINITY both = 0x04000000).
+
+- **Thread handling**: Threads are loaded from /proc/PID/task/ with the thread leader (matching the PID) removed from the collection.
+
+- **CPU topology**: `cpuinfo` class calculates `nr_sockets` and `nr_cores` based on "physical id", "siblings", and "cpu cores" fields. Has special handling for s390/s390x architectures.
+
+- **Interrupt affinity**: The `interrupts` class reads both /proc/interrupts and /proc/irq/*/smp_affinity to provide complete IRQ information.
+
+## Development Guidelines
+
+### Code Style
+
+- Follow PEP 8 Python style guidelines
+- Use 4-space indentation (no tabs)
+- SPDX license identifier at top of each file: `# SPDX-License-Identifier: GPL-2.0-only`
+- Use descriptive variable names
+- Add docstrings for modules, classes, and public methods
+- Docstrings should use Python 3 syntax (e.g., `print()` with parentheses)
+
+### Python Version
+
+- Target Python 3.10+ for compatibility with RHEL 9+
+- No Python 2 compatibility code needed
+- Use modern Python features (type hints encouraged)
+
+### Dependencies
+
+**Required**:
+- Python >= 3.10
+- No external dependencies (stdlib only)
+
+**Optional** (for development):
+- ctags (for code navigation)
+
+### Error Handling
+
+- Use exceptions for error conditions
+- Handle processes disappearing by catching `FileNotFoundError` and `IOError`
+- Handle binary data in /proc files with `UnicodeDecodeError`
+- Provide informative error messages
+- Return `None` for missing or inaccessible data
+
+## Build and Installation
+
+### Build Commands
+
+```bash
+# Run unit tests
+python3 bitmasklist_test.py
+
+# Clean Python cache files
+make pyclean
+
+# Generate ctags
+make tags
+
+# Full clean
+make clean
+```
+
+### Installation
+
+```bash
+# Install with pip (development mode)
+pip install -e .
+
+# Install with setup.py
+python3 setup.py install
+
+# Install via system package manager (Fedora/RHEL)
+dnf install python3-linux-procfs
+```
+
+## Testing
+
+### Test Structure
+
+**Unit Tests** (`bitmasklist_test.py`):
+- Tests for CPU bitmask/list conversions
+- Tests for hexbitmask generation
+- Run with: `python3 bitmasklist_test.py`
+
+### Important Testing Notes
+
+- Most functionality requires /proc filesystem access
+- Tests should handle permission errors gracefully
+- Docstring examples are illustrative but system-dependent (won't pass doctest on most systems)
+
+## Common Tasks
+
+### Using Process Information
+
+```python
+import procfs
+
+# Get all processes
+ps = procfs.pidstats()
+
+# Find process by name
+pids = ps.find_by_name("firefox")
+
+# Access process info
+if pids:
+    proc = ps[pids[0]]
+    print(proc["stat"]["comm"])      # Process name
+    print(proc["stat"]["state"])     # Process state
+    print(proc["status"]["VmRSS"])   # Resident memory
+```
+
+### Working with CPU Topology
+
+```python
+import procfs
+
+# Get CPU information
+cpus = procfs.cpuinfo()
+print(cpus.nr_cpus)           # Total CPU count
+print(len(cpus.sockets))      # Number of sockets
+print(cpus["model name"])     # CPU model
+```
+
+### Working with Interrupts
+
+```python
+import procfs
+
+# Get interrupt information
+interrupts = procfs.interrupts()
+
+# Find specific interrupt
+irq = interrupts.find_by_user("ethernet")
+if irq:
+    print(interrupts[irq]["affinity"])  # CPU affinity
+    print(interrupts[irq]["cpu"])       # Per-CPU counters
+```
+
+### Converting CPU Bitmasks
+
+```python
+from procfs import bitmasklist, hexbitmask
+
+# Convert hex mask to CPU list
+cpus = bitmasklist("f", 8)  # Returns [0, 1, 2, 3]
+
+# Convert CPU list to hex mask
+mask = hexbitmask([0, 2, 4], 8)  # Returns [0x15]
+```
+
+## Key Files
+
+- `procfs/procfs.py` - Core /proc abstraction classes
+- `procfs/utilist.py` - Bitmask utility functions
+- `pflags` - Process flags display utility
+- `pyproject.toml` - Modern Python project metadata
+- `setup.py` - Legacy setuptools configuration
+
+## Package Configuration
+
+The project uses modern Python packaging with both:
+- `pyproject.toml` - Modern build configuration (preferred)
+- `setup.py` - Legacy setup script for backwards compatibility
+
+Both files must be kept in sync for version numbers and metadata.
+
+## Common Gotchas
+
+1. **Process Disappearance**: Processes can vanish between enumeration and access - always handle FileNotFoundError
+2. **Binary Data in cmdline**: Some processes have binary/non-UTF-8 data in arguments - handle UnicodeDecodeError
+3. **Thread Leader**: When loading threads, the thread leader (TID == PID) is removed from the collection
+4. **basedir for Testing**: Use the `basedir` parameter to point to mock /proc filesystems for testing
+5. **CPU Topology on s390**: Special handling exists for s390/s390x architectures
+6. **has_key() Methods**: Classes define `has_key()` for backwards compatibility, but `key in obj` syntax is preferred
+7. **Docstring Examples**: Examples in docstrings are illustrative and won't pass doctest on most systems
+
+## Recent Changes
+
+Check `git log` for recent commits. Notable recent development:
+
+**Python 3 Migration:**
+- Updated docstring examples to use Python 3 print() syntax
+- Removed confusing TODO comment about UnicodeDecodeError handling
+- Updated copyright notices to 2026
+
+**Modernization:**
+- Added pyproject.toml for modern Python packaging
+- Removed Python 2 compatibility code
+- Added SPDX license identifiers
+- Updated copyright statements
+
+## Support and Contact
+
+- Maintainer: John Kacur <[email protected]>
+- Mailing list: [email protected]
+- Bug reports: Send to maintainer with mailing list CC'd
+
+## Git Workflow
+
+- **Main branch**: `main`
+- **Repository**: https://git.kernel.org/pub/scm/libs/python/python-linux-procfs/python-linux-procfs.git
+- **Patch submission**: Use standard git format-patch/send-email, send to maintainer with mailing list CC'd
+- **Mailing list**: [email protected]
+
+### Development Workflow
+
+1. Make changes to code
+2. Run unit tests: `python3 bitmasklist_test.py`
+3. Test manually with specific use cases
+4. Update documentation if needed
+5. Submit patches to maintainer with mailing list CC'd
+
+## Additional Notes for AI Assistants
+
+1. **Python Version**: Target Python 3.10+ for RHEL 9+ compatibility
+2. **No External Dependencies**: Library uses only Python stdlib
+3. **Error Recovery**: Handle ephemeral processes and missing data gracefully
+4. **Dictionary Interface**: Most classes provide dict-like access for convenience
+5. **Lazy Loading**: Process attributes are loaded on-demand to minimize overhead
+6. **Kernel Versions**: Process flags and /proc file formats may vary across kernel versions
+7. **Architecture Support**: Code should work on x86_64, aarch64, ppc64le, s390x
+
+## Related Projects
+
+Projects that use python-linux-procfs:
+
+- **tuna**: Thread and IRQ tuning tool - https://git.kernel.org/pub/scm/utils/tuna/tuna.git
+
+---
+
+**Last Updated**: 2026-06-16
+**Document Version**: 1.0
diff --git a/CLAUDE.md b/CLAUDE.md
deleted file mode 100644
index 7cfcc5c0a03c..000000000000
--- a/CLAUDE.md
+++ /dev/null
@@ -1,102 +0,0 @@
-# CLAUDE.md
-
-This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
-
-## Project Overview
-
-python-linux-procfs is a Python library that provides abstractions to extract information from the Linux kernel /proc filesystem. It's a GPL-2.0-only licensed library maintained by Red Hat developers, primarily for Linux system programming and process introspection.
-
-## Build and Test Commands
-
-### Installation
-```bash
-# Install the package locally for development
-python3 -m pip install -e .
-
-# Or using setup.py directly
-python3 setup.py install
-```
-
-### Testing
-```bash
-# Run the bitmasklist unit tests
-python3 bitmasklist_test.py
-```
-
-### Clean
-```bash
-# Remove temporary files and tags
-make clean
-
-# Remove only Python cache files
-make pyclean
-```
-
-### Tags Generation
-```bash
-# Generate ctags for code navigation
-make tags
-```
-
-## Architecture
-
-### Core Module Structure
-
-The library consists of a single `procfs` package with two main modules:
-
-**procfs/procfs.py** - Main module containing all /proc abstraction classes:
-- `pidstat` - Parses /proc/PID/stat files for process statistics
-- `pidstatus` - Parses /proc/PID/status files for additional process info
-- `process` - Combines stat and status data, lazy-loads cmdline, threads, cgroups, environ
-- `pidstats` - Collection of all processes in the system with find/search methods
-- `interrupts` - Parses /proc/interrupts for IRQ information
-- `cmdline` - Parses /proc/cmdline for kernel boot parameters
-- `cpuinfo` - Parses /proc/cpuinfo for CPU information and topology
-- `cpustat`/`cpusstats` - Parses /proc/stat for CPU usage statistics
-- `smaps`/`smaps_lib` - Parses /proc/PID/smaps for memory mapping information
-
-**procfs/utilist.py** - Utility functions for bitmask conversions:
-- `bitmasklist()` - Converts hex CPU affinity masks to lists of CPU numbers
-- `hexbitmask()` - Converts CPU number lists to hex bitmask format
-
-### Design Patterns
-
-1. **Lazy Loading**: The `process` class implements lazy loading via `__getitem__` - attributes like "stat", "status", "cmdline", "threads", "cgroups", and "environ" are only loaded when accessed.
-
-2. **Dictionary-like Interfaces**: Most classes implement dict-like access patterns (`__getitem__`, `keys()`, `values()`, `items()`, `__contains__`) for intuitive data access.
-
-3. **Ephemeral Process Handling**: Code throughout handles processes disappearing mid-query by catching `FileNotFoundError` and `IOError` exceptions.
-
-4. **basedir Parameter**: Most classes accept a `basedir` parameter (default "/proc") to support testing with mock /proc filesystems or accessing /proc from containers.
-
-### Key Implementation Details
-
-- **Process flags**: `pidstat` class defines PF_* constants matching kernel's include/linux/sched.h. Some flags have duplicate values representing kernel API changes (e.g., PF_THREAD_BOUND and PF_NO_SETAFFINITY both = 0x04000000).
-
-- **Thread handling**: Threads are loaded from /proc/PID/task/ with the thread leader (matching the PID) removed from the collection.
-
-- **CPU topology**: `cpuinfo` class calculates `nr_sockets` and `nr_cores` based on "physical id", "siblings", and "cpu cores" fields. Has special handling for s390/s390x architectures.
-
-- **Interrupt affinity**: The `interrupts` class reads both /proc/interrupts and /proc/irq/*/smp_affinity to provide complete IRQ information.
-
-## Command Line Tools
-
-**pflags** - Utility to display process flags for running processes:
-- Can filter by PID, process name, or glob patterns
-- Shows kernel process flags (PF_*) in human-readable format
-- Handles superseded flags (removes old flag names when new ones exist)
-- Note: Currently imports from `six.moves` which should be removed as Python 2 support is no longer needed (requires-python = ">=3.10")
-
-## Python Version Requirements
-
-- Minimum Python version: 3.10
-- The codebase has been migrated away from Python 2/3 compatibility
-- Still has one remaining `six` import in `pflags` that should be removed
-
-## Package Configuration
-
-The project uses modern Python packaging with both:
-- `pyproject.toml` - Modern build configuration (preferred)
-- `setup.py` - Legacy setup script for backwards compatibility
-
-Both files must be kept in sync for version numbers and metadata.
diff --git a/bitmasklist_test.py b/bitmasklist_test.py
index 30197da5304f..a54730989268 100755
--- a/bitmasklist_test.py
+++ b/bitmasklist_test.py
@@ -1,7 +1,7 @@
 #!/usr/bin/python3
 # SPDX-License-Identifier: GPL-2.0-only
 #
-# Copyright (C) 2025 Red Hat, Inc.
+# Copyright (C) 2025-2026 Red Hat, Inc.
 # John Kacur <[email protected]>
 
 """ Module to test bitmasklist functionality """
diff --git a/pflags b/pflags
index f5e107785166..3adf21d0d9b6 100755
--- a/pflags
+++ b/pflags
@@ -4,7 +4,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 #
 #   print process flags
-#   Copyright (C) 2015-2025 Red Hat, Inc.
+#   Copyright (C) 2015-2026 Red Hat, Inc.
 #   Arnaldo Carvalho de Melo <[email protected]>
 #   John Kacur <[email protected]>
 
@@ -62,7 +62,7 @@ def main(argv):
             flags = ps[pid].stat.process_flags()
         except AttributeError:
             continue
-        # Remove flags that were superseeded
+        # Remove flags that were superseded
         if "PF_THREAD_BOUND" in flags and "PF_NO_SETAFFINITY" in flags:
             flags.remove("PF_THREAD_BOUND")
         if "PF_FLUSHER" in flags and "PF_NPROC_EXCEEDED" in flags:
diff --git a/procfs/__init__.py b/procfs/__init__.py
index 6deedf41c650..4c048a477b6c 100644
--- a/procfs/__init__.py
+++ b/procfs/__init__.py
@@ -3,10 +3,10 @@
 # -*- coding: utf-8 -*-
 # SPDX-License-Identifier: GPL-2.0-only
 #
-# Copyright (C) 2008, 2009  Red Hat, Inc.
+# Copyright (C) 2007-2026 Red Hat, Inc.
 #
 """
-Copyright (c) 2008, 2009  Red Hat Inc.
+Copyright (C) 2007-2026 Red Hat, Inc.
 
 Abstractions to extract information from the Linux kernel /proc files.
 """
diff --git a/procfs/procfs.py b/procfs/procfs.py
index 945f11471a2e..a2dddd35e93a 100755
--- a/procfs/procfs.py
+++ b/procfs/procfs.py
@@ -3,7 +3,7 @@
 # -*- coding: utf-8 -*-
 # SPDX-License-Identifier: GPL-2.0-only
 #
-# Copyright (C) 2007-2025 Red Hat, Inc.
+# Copyright (C) 2007-2026 Red Hat, Inc.
 # Arnaldo Carvalho de Melo <[email protected]>
 # John Kacur <[email protected]>
 #
diff --git a/procfs/utilist.py b/procfs/utilist.py
index 831ef85d51f1..f5ad302b7658 100755
--- a/procfs/utilist.py
+++ b/procfs/utilist.py
@@ -3,7 +3,7 @@
 # -*- coding: utf-8 -*-
 # SPDX-License-Identifier: GPL-2.0-only
 #
-# Copyright (C) 2007-2025 Red Hat, Inc.
+# Copyright (C) 2007-2026 Red Hat, Inc.
 #
 
 def hexbitmask(l, nr_entries):
-- 
2.54.0