Skip to content

Define Result as a union of Success and Failure to express a closed sum type#54

Merged
drhagen merged 1 commit into
drhagen:masterfrom
renan-r-santos:make-result-final
Jun 25, 2026
Merged

Define Result as a union of Success and Failure to express a closed sum type#54
drhagen merged 1 commit into
drhagen:masterfrom
renan-r-santos:make-result-final

Conversation

@renan-r-santos

Copy link
Copy Markdown
Contributor

serialite.Result aliases the returns abstract base class Result. A type checker cannot prove a match on it is exhaustive, even when both Success and Failure are handled.

MRE:

from serialite import Failure, Result, Success, raise_errors

def unwrap(r: Result[int]) -> int:
    match r:
        case Success(value):
            return value
        case Failure(errors):
            raise_errors(errors)

Both arms return or raise (raise_errors is NoReturn), so this is exhaustive. pyrefly rejects it:

ERROR Function declared to return `int`, but one or more paths are missing an explicit `return` [bad-return]

A wildcard case _ as other: assert_never(other) shows the subject is never narrowed past the two arms:

ERROR Argument `Result[int, Errors]` is not assignable to parameter `arg` with type `Never` in function `typing.assert_never` [bad-argument-type]

Root cause:

returns.result.Result is an abstract base class. Nominal subclassing is open, so a checker must assume a third subclass could exist. Making Result a union of exactly Success and Failure fixes this. Each case eliminates one arm, and the match narrows to Never. A union is needed because Python has no sealed to close the base class.

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.45%. Comparing base (fd45f6e) to head (1a5ef06).
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@           Coverage Diff           @@
##           master      #54   +/-   ##
=======================================
  Coverage   92.45%   92.45%           
=======================================
  Files          34       34           
  Lines        1524     1524           
  Branches      232      232           
=======================================
  Hits         1409     1409           
  Misses         50       50           
  Partials       65       65           

☔ 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.

@drhagen

drhagen commented Jun 25, 2026

Copy link
Copy Markdown
Owner

I guess until we get the @sealed decorator, this is the best can do.

@drhagen drhagen merged commit 910a810 into drhagen:master Jun 25, 2026
6 checks passed
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.

3 participants