Skip to content

chore: migrate to pyproject.toml, drop orphaned test.py#23

Merged
bluecmd merged 5 commits into
masterfrom
chore/pyproject-migration
Jul 23, 2026
Merged

chore: migrate to pyproject.toml, drop orphaned test.py#23
bluecmd merged 5 commits into
masterfrom
chore/pyproject-migration

Conversation

@bluecmd

@bluecmd bluecmd commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Modernizes packaging and removes dead test code.

pyproject.toml migration

  • Moves all static project metadata to pyproject.toml (PEP 621): name, version, description, readme, license, authors/maintainers, URLs, classifiers.
  • setup.py is slimmed to just the netsnmp.client_intf C extension. Its net-snmp libraries are discovered dynamically via net-snmp-config (including the Windows sh wrapper + ws2_32), which can't be expressed declaratively — this is the standard hybrid pyproject+setup.py pattern for C extensions.
  • Drops dead code from the old setup.py: the shadowed distutils.core import, unused string import, and the broken py2-era --basedir parsing.

Remove netsnmp/tests/test.py

It's the legacy monolithic bindings test and is not executed by CI:

  • system-tests.yml runs python3 -m unittest discover -s netsnmp/tests/system -p 'test_*.py'; test.py is in the parent dir and doesn't match test_*.py.
  • Its only hook was test_suite = "netsnmp.tests.test" in setup.py (fired only by the removed-in-modern-setuptools setup.py test), which is dropped here.

The structured netsnmp/tests/system/ suite supersedes and expands its coverage, and is what actually runs (plus Valgrind, ASan/UBSan, and gcov coverage).

Validation

Packaging is exercised by existing CI: windows.yml (MSYS2 build) and system-tests.yml (build + full test suite under sanitizers) both build via setup.py/backend on this branch.

🤖 Generated with Claude Code

bluecmd and others added 2 commits July 23, 2026 20:29
Move static project metadata to pyproject.toml (PEP 621). setup.py is
slimmed to just the C extension, whose net-snmp libraries are still
discovered dynamically via net-snmp-config and can't be declared statically.

Also remove netsnmp/tests/test.py: it is the legacy monolithic bindings
test, not run by CI (the tests/system/ suite superseded it) and not
matched by the unittest discover glob. The stale test_suite= reference in
setup.py pointing at it is dropped along with the old dead distutils/
string imports and broken --basedir parsing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014KG1c9XtKawkvig5PnZjC8
Markus Häll has contributed to the project (including the memory
ownership fixes in netsnmp_walk) and is added alongside Christian
Svensson in the project maintainers metadata.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014KG1c9XtKawkvig5PnZjC8
@bluecmd
bluecmd requested a review from SoundGoof July 23, 2026 20:24
@SoundGoof

Copy link
Copy Markdown
Collaborator

I tested the PR with both Python 3.7 and Python 3.6 using the PEP 517 build path.

Python 3.7 works correctly:

  • The sdist and wheel built successfully.
  • The generated cp37 wheel installed successfully in a clean environment.
  • import netsnmp succeeded and reported version 1.1a2.

Python 3.6 fails while creating the isolated build environment. This is because pyproject.toml requires setuptools>=61, while setuptools 61 requires Python 3.7 or newer.

The declared minimum version should therefore be changed from:

requires-python = ">=3.6"

to:

requires-python = ">=3.7"

I also found a less obvious test coverage regression in the removal of netsnmp/tests/test.py. That file contains the repository's only SNMPv3 test case, covering:

  • Version=3
  • authPriv
  • SecName
  • AuthPass
  • PrivPass

The current system-test suite only covers SNMPv1 and SNMPv2c. Removing the legacy file therefore removes all existing SNMPv3 coverage.

I suggest adding an SNMPv3 user to the test snmpd configuration and adding an SNMPv3 system test before deleting the legacy test.

bluecmd and others added 3 commits July 23, 2026 23:09
Addresses PR review feedback:

- requires-python is raised from >=3.6 to >=3.7. The build-system pin of
  setuptools>=61 cannot be satisfied on 3.6, so the PEP 517 build failed
  while creating the isolated build env.

- Removing the legacy netsnmp/tests/test.py dropped the only SNMPv3
  coverage, as the system suite only exercised v1/v2c. Add an SNMPv3
  authPriv (SHA/AES) user to the test snmpd config and a test_v3.py
  covering get, getnext, getbulk, set, walk and the session API. Unlike
  the legacy test, which only printed results, these assert. A negative
  case with a bad AuthPass proves the agent really enforces authPriv, so
  the positive tests cannot silently pass unauthenticated.

Also ignore __pycache__/*.pyc, which were previously untracked-but-noisy.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014KG1c9XtKawkvig5PnZjC8
The wrong-password test passed authentication because net-snmp caches
localized USM keys per (engineID, username) for the process lifetime. An
earlier test had already authenticated as testuser with the correct
passphrase, so the cached key was reused and the bad passphrase never
reached the agent -- the test was asserting on the cache, not the agent.

Use a dedicated 'baduser' that no passing test ever authenticates as, so
its cache entry is only ever populated from the wrong passphrase. Also
add an unknown-user case, which is rejected agent-side and so cannot be
affected by client caching at all.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014KG1c9XtKawkvig5PnZjC8
snmp_duplicate_objid() allocates the securityAuthProto and
securityPrivProto OIDs, but they were never released. snmp_sess_open()
duplicates them into the session it returns, so the local copies are the
caller's to free -- they leaked on every SNMPv3 session creation
(1440 bytes over 18 blocks across the new v3 tests).

Caught by Valgrind once the new test_v3.py gave the v3 code path its
first coverage. Freeing at the 'end' label also covers the early goto
paths, where an unsupported privacy protocol returns after the
authentication protocol OID was already duplicated. session is {0}
initialised, so free() on the unset paths is a no-op.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014KG1c9XtKawkvig5PnZjC8

@SoundGoof SoundGoof left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@bluecmd
bluecmd merged commit 0990061 into master Jul 23, 2026
4 checks passed
@bluecmd
bluecmd deleted the chore/pyproject-migration branch July 23, 2026 21:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants