Skip to content

refactor: connect() defined once, vertex kinds supply an _attach hook - #35

Merged
petercorke merged 2 commits into
mainfrom
refactor/vertex-connect-hook
Oct 11, 2026
Merged

petercorke merged 2 commits into
mainfrom
refactor/vertex-connect-hook

Conversation

@petercorke

Copy link
Copy Markdown
Owner

Summary

UVertex.connect() and DVertex.connect() were the same few lines (call super().connect(), then append the edge to one or two edge lists) differing only in that last line, and each repeated the full signature and docstring. A new vertex kind had to know to call super() first, and the edge rules had to be documented three times.

connect() is now defined once, on BaseVertex, and the vertex kinds supply a single bookkeeping hook, _attach (Template Method):

class BaseVertex:
    def connect(self, dest, edge=None, cost=None, data=None) -> Edge:
        ...validate, bind the edge's endpoints, register it with the graph...
        self._attach(e, dest)      # the one thing that differs
        return e

class UVertex(BaseVertex):
    def _attach(self, edge, dest):
        self._edgelist.append(edge); dest._edgelist.append(edge)   # both ends

class DVertex(BaseVertex):
    def _attach(self, edge, dest):
        self._edgelist.append(edge)                                # source only

Why not make connect() itself abstract

BaseVertex is documented as constructible (policy.rst), and a bare BaseVertex can never join a graph anyway (connect() raises ValueError, add_vertex() raises TypeError), so abstractness would break the documented behavior and prevent nothing. The hook is what varies, so the hook is what a subclass supplies; the base one raises NotImplementedError.

Behavior

None. Signature, return value, exceptions and edge-list contents are unchanged, add_edge() and Edge.connect() both still go through connect(), and the full existing suite passes untouched.

Docs

The "unlike the directed counterpart" text and the per-kind example moved from the removed overrides to the UVertex/DVertex class docstrings, and BaseVertex.connect gains one note stating who holds the edge and the endpoint rule for each kind.

Tests

tests/test_vertex_hook.py, 18 tests: connect is defined once (UVertex.connect is BaseVertex.connect), the hook is called exactly once and after the edge is registered, nothing is attached when validation refuses (wrong graph, wrong endpoints, ungraphed), self-loops are held twice by an undirected and once by a directed vertex, a bare BaseVertex is still constructible but cannot connect or be added, and a user vertex kind can change the bookkeeping by overriding only _attach. Suite: 233 passing, mypy clean.

🤖 Generated with Claude Code

petercorke and others added 2 commits October 11, 2026 15:24
…hook

Fails on main: UVertex/DVertex override connect() and there is no _attach.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…tach hook

UVertex.connect and DVertex.connect were the same sequence -- super().connect(),
then append the edge to one or two edge lists -- differing only in that last
line, and each repeated the full signature and docstring. A new vertex kind had
to know to call super() first.

BaseVertex.connect now validates, registers the edge with the graph and then
calls self._attach(edge, dest). UVertex._attach records the edge at both ends,
DVertex._attach at the source only, and BaseVertex._attach raises
NotImplementedError. BaseVertex itself stays instantiable (policy.rst) and can
still never join a graph, so the base hook is unreachable in practice.

The public signature and behaviour are unchanged. The per-kind description and
example move from the removed overrides to the UVertex/DVertex class
docstrings and one note on BaseVertex.connect.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 21 complexity · 0 duplication

Metric Results
Complexity 21
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@codecov

codecov Bot commented Oct 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.54%. Comparing base (d22408d) to head (66aff65).

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #35      +/-   ##
==========================================
+ Coverage   93.27%   93.54%   +0.27%     
==========================================
  Files           3        3              
  Lines        1055     1054       -1     
==========================================
+ Hits          984      986       +2     
+ Misses         71       68       -3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@petercorke
petercorke merged commit f34c61e into main Oct 11, 2026
14 checks passed
@petercorke
petercorke deleted the refactor/vertex-connect-hook branch October 11, 2026 21:49
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.

1 participant