Skip to content

Derive DisciplineServer from the servicer base class (#70) - #86

Merged
chrislupp merged 1 commit into
developfrom
fix/discipline-server-servicer-base
Aug 31, 2026
Merged

Derive DisciplineServer from the servicer base class (#70)#86
chrislupp merged 1 commit into
developfrom
fix/discipline-server-servicer-base

Conversation

@chrislupp

Copy link
Copy Markdown
Collaborator

Closes #70.

DisciplineServer derived from disc.DisciplineService, which despite the name
is the generated experimental client-side API — a set of @staticmethods that
each open a one-shot channel to a target address. The servicer base that
add_DisciplineServiceServicer_to_server is written against is
DisciplineServiceServicer. ExplicitServer and ImplicitServer already mixed
in the correct servicers, so the inconsistency was confined to the base class.

Impact

No shipping code path reached the difference. The registration helper looks
handlers up by name rather than by type, and DisciplineServer overrides all
eight RPCs itself, so the inherited staticmethods were always shadowed. This is
a latent-correctness fix, not a fix for an active bug.

What it protects is an RPC left undefined — realistically one added to the
.proto and regenerated but not yet implemented here. Note that the issue
describes that case incorrectly: it claims an AttributeError at registration
time. Registration actually succeeds, because the static API supplies the
attribute. The failure lands at call time instead, and its shape depends on
whether anything in the process has imported grpc.experimental:

  • without it — AttributeError: module 'grpc' has no attribute 'experimental'
  • with it — the staticmethod binds gRPC's context argument to its own target
    parameter and fails with TypeError: Argument 'target' has incorrect type (expected bytes, got Mock) while trying to dial the ServicerContext as a
    network address

Either way the handler raises without setting a status, so the client sees
UNKNOWN on a live request. After this change the servicer default sets
UNIMPLEMENTED and reports it properly.

MRO

Both subclasses resolve cleanly:

  • ExplicitServer → DisciplineServer → DisciplineServiceServicer → ExplicitServiceServicer → object
  • ImplicitServer → DisciplineServer → DisciplineServiceServicer → ImplicitServiceServicer → object

Tests

Two regression tests in tests/test_discipline_server.py: one asserts the base
class directly, the other rebuilds DisciplineServer without its own GetInfo
and checks the inherited method is the servicer's UNIMPLEMENTED default rather
than the static client stub. Both were confirmed to fail against the old base and
pass against the new one, so they catch a revert.

Full suite: 335 passed.

DisciplineServer inherited disc.DisciplineService, the generated
experimental static-call API, rather than DisciplineServiceServicer,
which is what add_DisciplineServiceServicer_to_server is written
against. Nothing broke in practice -- the registration helper looks
handlers up by name and DisciplineServer defines all eight RPCs itself
-- but the class did not inherit the UNIMPLEMENTED defaults a servicer
base provides, so a subclass omitting an RPC would resolve to a static
network-call stub instead of returning a clean UNIMPLEMENTED status.

ExplicitServer and ImplicitServer already mixed in the correct
servicers; this brings the base class in line.
@codecov

codecov Bot commented Aug 31, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@chrislupp chrislupp self-assigned this Aug 31, 2026
@chrislupp chrislupp added this to the Version 0.9.0 milestone Aug 31, 2026
@chrislupp chrislupp added the bug Something isn't working label Aug 31, 2026
@chrislupp
chrislupp merged commit f7daf10 into develop Aug 31, 2026
8 checks passed
@chrislupp
chrislupp deleted the fix/discipline-server-servicer-base branch August 31, 2026 01:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant