Skip to content

Latest commit

 

History

History
221 lines (160 loc) · 6.88 KB

File metadata and controls

221 lines (160 loc) · 6.88 KB

Development guide

.. seealso:: `Contributing to psutil project <https://github.com/giampaolo/psutil/blob/master/CONTRIBUTING.md>`_

Build, setup and test

  • psutil makes extensive use of C code, so a C compiler and the Python development headers are required. First clone the repository:

    git clone https://github.com/giampaolo/psutil.git
    cd psutil

    On Linux, FreeBSD, OpenBSD, NetBSD and Solaris, install the system deps:

    make install-sysdeps       # compiler + python headers
    make install-sysdeps-test  # CLI tools used by tests

    On macOS, AIX and Windows there's no such target, see :ref:`install_from_source`. Then, everywhere:

    make install-pydeps-dev    # python development deps (linters, etc)
    make build                 # compile the C extension in place
    make test
  • make (via the :src:`Makefile`) is used for building, testing and general development tasks, including on Windows (see below):

    make clean
    make test
    make test-parallel
    make test-memleaks
    make coverage
    make lint-all
    make fix-all
    make uninstall
    make help
  • To run a specific test:

    make test ARGS=tests/test_system.py
    
  • make build compiles the extension in place, so you can import psutil straight from the repo. No need to install it.

  • Don't use sudo, except for the install-sysdeps-* targets, which invoke it themselves when needed.

  • To target a specific Python version, pass PYTHON to every step, so that the extension is built by the same interpreter that runs the tests:

    make install-pydeps-dev PYTHON=python3.13
    make build PYTHON=python3.13
    make test PYTHON=python3.13
    

Windows

  • The recommended way to develop on Windows is to use make.

  • For the build tools, Git Bash and GNU Make setup see :ref:`install_windows`.

  • Once inside a Git Bash shell, run:

    make install-pydeps-dev
    make build
    make test-parallel

Debug mode

If you need to debug unusual situations or report a bug, you can enable debug mode via the :envvar:`PSUTIL_DEBUG` environment variable. In this mode, psutil may print additional information to stderr. Usually these are non-severe error conditions that are ignored instead of causing a crash. Unit tests automatically run with debug mode enabled. To enable debug mode in UNIX (or on Windows + Bash):

$ PSUTIL_DEBUG=1 python3 test_script.py
psutil-debug [psutil/_psutil_linux.c:150]> setmntent() failed (ignored)

On Windows using cmd.exe:

set PSUTIL_DEBUG=1 && python.exe test_script.py
psutil-debug [psutil/arch/windows/proc.c:56]> ReadProcessMemory -> ERROR_NOACCESS (ignored)

Coding style

All style and formatting checks are enforced locally on each git commit and via a GitHub Actions pipeline.

  • Python: follows PEP-8, formatted and linted with black and ruff.
  • C: generally follows PEP-7, formatted with clang-format.
  • Other files (.rst, .toml, .md, .yml): validated by linters.

The pipeline re-runs all checks for consistency (make lint-all).

Run make fix-all before committing; it usually fixes Python issues (via black and ruff) and C issues (via clang-format).

Code organization

Not every API reaches C: many are implemented in python alone (on Linux, by parsing /proc). For those that do, a call travels down through the platform-specific layers. Linux is used here as an example:

import psutil
     │
     ▼
psutil/__init__.py          public API, Process class
     │
     ▼
psutil/_pslinux.py          python layer: parses /proc, calls into C
     │
     ▼
psutil/_psutil_linux.c      C extension entry point (arg parsing)
     │
     ▼
psutil/arch/linux/*.c       platform-specific C implementation
                            + arch/posix/*.c   shared by POSIX
                            + arch/all/*.c     shared by everything

Where things live:

psutil/__init__.py                   # Public API ("import psutil")
psutil/_common.py                    # Generic utilities
psutil/_ntuples.py                   # Named tuples returned by psutil APIs
psutil/_enums.py                     # Enum containers
psutil/_ps{platform}.py              # OS-specific python wrapper
psutil/_psutil_{platform}.c          # OS-specific C extension (entry point)
psutil/arch/all/*.c                  # C code common to all OSes
psutil/arch/posix/*.c                # C code common to POSIX OSes
psutil/arch/bsd/*.c                  # C code common to the BSDs
psutil/arch/{platform}/*.c           # OS-specific C implementation
tests/test_process.py                # Main process API tests
tests/test_system.py                 # Main system API tests
tests/test_{platform}.py             # OS-specific tests

Adding a new API

  • Define the public API in :src:`psutil/__init__.py`.
  • Implement it for each applicable platform in psutil/_ps{platform}.py (e.g. :src:`psutil/_pslinux.py`).
  • If needed, add C code in psutil/arch/{platform}/file.c.
  • Add a generic test in :src:`tests/test_system.py` or :src:`tests/test_process.py`.
  • Add a platform-specific test in tests/test_{platform}.py.
  • Update :src:`docs/api.rst`.
  • Open a pull request.

Make a pull request

  • Fork psutil on GitHub.
  • Clone your fork: git clone git@github.com:YOUR-USERNAME/psutil.git
  • Create a branch: git checkout -b new-feature
  • Stage and commit: git add <files> then git commit -m 'Add some feature'
  • Push: git push origin new-feature
  • Open a pull request (see :src:`CONTRIBUTING.md`).

Continuous integration

Tests run automatically on pull requests and on relevant pushes, covering all regularly tested platforms except AIX. See .github/workflows.

Documentation

  • Source is in the :src:`docs/ <docs/>` directory.

  • To build HTML:

    make install-pydeps-docs
    cd docs/
    make html
  • The documentation is hosted at https://psutil.io. It's a single version, rebuilt and deployed automatically on every push to master.

Releases

For project maintainers:

  • Releases are uploaded to PyPI via make release.
  • Git tags use the vX.Y.Z format (e.g. v7.2.2).
  • The version string is defined in :src:`psutil/__init__.py` (__version__).