Skip to content

feat: migrate from IPy to netaddr for IP address handling#377

Merged
jathanism merged 6 commits intomainfrom
issue-376-ipy-to-netaddr
Feb 24, 2026
Merged

feat: migrate from IPy to netaddr for IP address handling#377
jathanism merged 6 commits intomainfrom
issue-376-ipy-to-netaddr

Conversation

@jathanism
Copy link
Copy Markdown
Member

@jathanism jathanism commented Feb 23, 2026

Summary

Migrate the entire codebase from the IPy library to netaddr for IP address handling.

Changes

  • TIP class (): Rewritten to subclass netaddr.IPNetwork instead of IPy.IP
    • Handles partial IPv4 addresses (e.g. 10/810.0.0.0/8)
    • Prevents netaddr's iteration/subscript protocol from interfering with RangeList
    • Compatibility methods (net(), strNormal()) preserved for existing call sites
  • make_inverse_mask(): Returns netaddr.IPAddress instead of TIP for raw integer masks
  • inverse_mask_table (trigger/acl/ios.py): Uses string keys for consistent lookup
  • All IPy call sites updated: global_settings.py, tools.py, netscreen.py, cmds.py
  • Property access: prefixlen()prefixlen, netmask()netmask (netaddr uses properties)
  • Dependency: Replaced IPy>=1.01 with netaddr>=1.0.0,<2 in pyproject.toml

Test Results

All 164 tests pass (excluding 2 pre-existing failures unrelated to this change: test_ping and test_reachability fail due to missing ping binary in CI).

Closes #376


Note

Medium Risk
Touches core ACL parsing/comparison and vendor-specific rendering paths; subtle differences between IPy and netaddr (string forms, containment, sorting) could change rule ordering or output in edge cases.

Overview
Switches Trigger’s IP/network primitive from IPy to netaddr across ACL parsing, output formatting, and interface parsing, including updating settings defaults and helper utilities to construct/compare networks using netaddr semantics.

Rewrites TIP to subclass netaddr.IPNetwork (with except/inactive handling), updates prefix/netmask/inverse-mask logic and IOS inverse-mask parsing, and adds guards so TIP is not treated as an iterable/sequence by RangeList. Dependencies are updated to drop IPy in favor of netaddr, and a new benchmarks/ipy_vs_netaddr.py script is added to compare performance on ACL-like workloads.

Written by Cursor Bugbot for commit 9e4ff57. This will update automatically on new commits. Configure here.

Benchmarks realistic ACL-scale operations: object creation, containment,
sorting, string roundtrip, host iteration, prefix introspection, and
CIDR merging.

Results: netaddr 1.3.0 wins 5/7 tests. IPy only wins sorting (3.5×)
and prefix introspection (1.7×), both negligible at real ACL scale.

Ref: #376
Replace IPy dependency with netaddr>=1.0.0,<2 across the entire codebase:

- Rewrite TIP class to subclass netaddr.IPNetwork instead of IPy.IP
- Update make_inverse_mask() to return netaddr.IPAddress
- Handle partial IPv4 addresses (e.g. '10/8') by expanding octets
- Prevent netaddr's iteration protocol from interfering with RangeList
- Update inverse_mask_table in ios.py to use string keys
- Replace IPy.IP() calls in global_settings.py, tools.py, netscreen.py, cmds.py
- Update prefixlen() method calls to prefixlen property access
- Update netmask() method calls to netmask property access

Closes #376
@github-actions
Copy link
Copy Markdown

github-actions bot commented Feb 23, 2026

Release Preview

Next Version: 2.3.0

Changelog Preview

Bug Fixes

  • Guard against missing negated attr in _compare_to for non-TIP objects
    (9e4ff57)

  • Handle negated /32|/128 in junos_str and skip IPv4 expansion for IPv6 CIDR
    (7c370de)

  • Replace remaining IPy-specific APIs with netaddr equivalents
    (bd75ca1)

  • Return TIP objects from IP functions and zero host bits in _make_cidrs
    (5133b5c)

Features

  • Migrate from IPy to netaddr for IP address handling
    (cce2849)

  • benchmarks: Add IPy vs netaddr benchmark for ACL workloads
    (afd13a7)


This version will be automatically released when this PR is merged to main.

Reminder: Use conventional commits:

  • fix: → Patch release (2.0.0 → 2.0.1)
  • feat: → Minor release (2.0.0 → 2.1.0)
  • feat!: or BREAKING CHANGE: → Major release (2.0.0 → 3.0.0)

- cmds.py: Replace make_net=True with manual network/prefix construction
  in IPsubnet, and .make_net(mask) with f-string in _make_cidrs
- acl/tools.py: Wrap addresses with TIP instead of plain netaddr.IPNetwork
  in _add_addr so strNormal() is available downstream
- acl/support.py: Force /32 and /128 prefix display in junos_str output
  since TIP.__str__ omits prefix for non-negated single hosts
…_cidrs

- _make_ipy, IPsubnet, and IPhost now return TIP objects instead of plain
  IPNetwork, preserving strNormal() compatibility for callers.
- _make_cidrs now uses .cidr to zero out host bits, matching the old
  IPy.IP(make_net=True) behavior.
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

@jathanism jathanism merged commit 69aaf96 into main Feb 24, 2026
7 checks passed
@jathanism jathanism deleted the issue-376-ipy-to-netaddr branch February 24, 2026 01:42
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.

feat: Migrate from IPy to netaddr

1 participant