From 1d5b59561ab28a86c4c9e0c9a902fde99e249865 Mon Sep 17 00:00:00 2001 From: JeanExtreme002 Date: Sun, 7 Jun 2026 20:39:54 -0300 Subject: [PATCH] docs: document bitness detection API (strict_bitness, is_64bit, pointer_size, BitnessDetectionError) Add missing documentation for: - strict_bitness constructor parameter - is_64bit, is_bitness_certain, pointer_size properties - BitnessDetectionError exception class and hierarchy entry --- docs/api/errors.md | 31 +++++++++++++++++++++++++++++++ docs/api/openprocess.md | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/docs/api/errors.md b/docs/api/errors.md index 6084023..8ad21d9 100644 --- a/docs/api/errors.md +++ b/docs/api/errors.md @@ -18,6 +18,7 @@ except PyMemoryEditorError as exc: ```text Exception └── PyMemoryEditorError + ├── BitnessDetectionError ├── ClosedProcess ├── ProcessIDNotExistsError ├── ProcessNotFoundError @@ -112,6 +113,36 @@ except AmbiguousProcessNameError as exc: process = OpenProcess(pid=exc.pids[0]) ``` +### `BitnessDetectionError` + +Raised when `strict_bitness=True` and the target's 32-/64-bit width could +not be read from its own headers (the ELF class on Linux, the Mach-O magic +on macOS, `IsWow64Process` on Windows). + +Without strict mode the library falls back to the host word size — a guess +that may silently produce wrong pointer-width defaults. + +```{eval-rst} +.. py:exception:: BitnessDetectionError + + .. py:attribute:: pid + :type: int + + The PID whose bitness could not be determined. +``` + +Example: + +```python +from PyMemoryEditor import OpenProcess, BitnessDetectionError + +try: + with OpenProcess(pid=1234, strict_bitness=True) as process: + print(process.is_64bit) +except BitnessDetectionError as exc: + print(f"Could not detect bitness of PID {exc.pid}") +``` + ## Standard exceptions diff --git a/docs/api/openprocess.md b/docs/api/openprocess.md index 32a2169..c6796f0 100644 --- a/docs/api/openprocess.md +++ b/docs/api/openprocess.md @@ -23,7 +23,7 @@ All three subclass `AbstractProcess` and share the API documented below. ## Construction ```{eval-rst} -.. py:class:: OpenProcess(*, name=None, pid=None, permission=, case_sensitive=, exact_match=True) +.. py:class:: OpenProcess(*, name=None, pid=None, permission=, case_sensitive=, exact_match=True, strict_bitness=False) Open a target process. ``OpenProcess`` resolves to the concrete backend for the host OS, so the ``permission`` and ``case_sensitive`` defaults are @@ -44,6 +44,11 @@ All three subclass `AbstractProcess` and share the API documented below. ignores case. Default is ``False`` on Windows, ``True`` elsewhere. :param bool exact_match: when ``False``, ``name`` matches as a substring (``"chrome"`` matches ``"chrome.exe"``). + :param bool strict_bitness: when ``True``, :py:attr:`is_64bit` raises + :py:exc:`BitnessDetectionError` if the target's 32-/64-bit width + can't be read from its headers, instead of falling back to the host + word size. Use it when a wrong pointer-width default would be worse + than a hard failure. :raises ProcessNotFoundError: no process matches ``name``. :raises ProcessIDNotExistsError: ``pid`` doesn't exist. @@ -92,6 +97,33 @@ with OpenProcess( The conventional "main thread" of the target — by convention, the thread with the smallest ``tid``. Returns ``None`` if the process has no listable threads (rare). + +.. py:attribute:: is_64bit + :type: bool + + ``True`` if the target process is 64-bit, ``False`` if it is 32-bit. + Detected once on first access (via headers: ELF class on Linux, Mach-O + magic on macOS, ``IsWow64Process`` on Windows) and cached. + + When the backend can't read the headers, the result depends on + ``strict_bitness``: ``False`` (default) falls back to the host word size + and logs a WARNING; ``True`` raises + :py:exc:`BitnessDetectionError`. + +.. py:attribute:: is_bitness_certain + :type: bool + + ``True`` if :py:attr:`is_64bit` was read from the target's own headers, + ``False`` if it fell back to a guess of the host word size. + + When ``False`` the automatic ``ptr_size`` default may be wrong for a + cross-bitness target — pass ``ptr_size`` explicitly to the pointer APIs. + +.. py:attribute:: pointer_size + :type: int + + Pointer width of the target process in bytes — ``8`` for a 64-bit target, + ``4`` for a 32-bit one. Derived from :py:attr:`is_64bit`. ``` ## Methods