Skip to content

Specify Python's __new__ to declare a constructor instead of __init__#123

Merged
derekpierre merged 3 commits intonucypher:mainfrom
derekpierre:init-to-new
Nov 5, 2025
Merged

Specify Python's __new__ to declare a constructor instead of __init__#123
derekpierre merged 3 commits intonucypher:mainfrom
derekpierre:init-to-new

Conversation

@derekpierre
Copy link
Member

Type of PR:

  • Bugfix
  • Feature
  • Documentation
  • Other

Required reviews:

  • 1
  • 2
  • 3

What this does:
Background info: https://pyo3.rs/main/class.html#constructor

Use __new__(cls, ...) for python bindings constructors instead of __init__(self, ...) .
This resolves long-standing stubtest errors.

Issues fixed/closed:

  • Fixes #...

Why it's needed:

Explain how this PR fits in the greater context of the NuCypher Network.
E.g., if this PR address a nucypher/productdev issue, let reviewers know!

Notes for reviewers:

What should reviewers focus on?
Is there a particular commit/function/section of your PR that requires more attention from reviewers?

@derekpierre derekpierre self-assigned this Nov 4, 2025
@codecov-commenter
Copy link

codecov-commenter commented Nov 4, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 30.05%. Comparing base (e080d33) to head (5d690bc).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #123   +/-   ##
=======================================
  Coverage   30.05%   30.05%           
=======================================
  Files          18       18           
  Lines        2349     2349           
=======================================
  Hits          706      706           
  Misses       1643     1643           

☔ View full report in Codecov by Sentry.
📢 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.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@derekpierre derekpierre requested a review from Copilot November 4, 2025 21:05
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes Python binding constructors by changing from __init__ to __new__ for all PyO3 Rust bindings, which is the correct way to define constructors for immutable Python extension types. The change also removes the now-unnecessary stubtest allowlist.

  • Changed all __init__ methods to __new__ in Python type stub files (.pyi)
  • Removed the stubtest allowlist file that was previously needed to suppress errors
  • Updated CI workflow and documentation to remove stubtest allowlist references

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 17 comments.

Show a summary per file
File Description
nucypher-core-python/stubtest-allowlist.txt Removed the allowlist file as it's no longer needed
nucypher-core-python/nucypher_core/umbral.pyi Changed __init__ to __new__ for Signer, Parameters, and ReencryptionEvidence classes
nucypher-core-python/nucypher_core/ferveo.pyi Changed __init__ to __new__ for Validator, ValidatorMessage, Dkg, and AggregatedTranscript classes
nucypher-core-python/nucypher_core/init.pyi Changed __init__ to __new__ for all class constructors
nucypher-core-python/README.md Removed development documentation about stubtest allowlist
CHANGELOG.md Added changelog entry for version 0.15.1
.github/workflows/nucypher-core.yml Updated CI to remove allowlist flag from stubtest command
Comments suppressed due to low confidence (12)

nucypher-core-python/nucypher_core/ferveo.pyi:109

  • Missing return type annotation. The __new__ method should specify its return type. Add -> Dkg: to match the pattern used by other static factory methods and maintain consistency.
    def __new__(
            cls,
            tau: int,
            shares_num: int,
            security_threshold: int,
            validators: Sequence[Validator],
            me: Validator,
    ):

nucypher-core-python/nucypher_core/init.pyi:73

  • Missing return type annotation. The __new__ method should specify its return type. Add -> MessageKit: to match the pattern used by other static factory methods and maintain consistency.
    def __new__(
            cls,
            policy_encrypting_key: PublicKey,
            plaintext: bytes,
            conditions: Optional[Conditions]
    ):

nucypher-core-python/nucypher_core/init.pyi:103

  • Missing return type annotation. The __new__ method should specify its return type. Add -> HRAC: to match the pattern used by other static factory methods and maintain consistency.
    def __new__(
            cls,
            publisher_verifying_key: PublicKey,
            bob_verifying_key: PublicKey,
            label: bytes,
    ):

nucypher-core-python/nucypher_core/init.pyi:123

  • Missing return type annotation. The __new__ method should specify its return type. Add -> EncryptedKeyFrag: to match the pattern used by other static factory methods and maintain consistency.
    def __new__(
            cls,
            signer: Signer,
            recipient_key: PublicKey,
            hrac: HRAC,
            verified_kfrag: VerifiedKeyFrag,
    ):

nucypher-core-python/nucypher_core/init.pyi:152

  • Missing return type annotation. The __new__ method should specify its return type. Add -> TreasureMap: to match the pattern used by other static factory methods and maintain consistency.
    def __new__(
            cls,
            signer: Signer,
            hrac: HRAC,
            policy_encrypting_key: PublicKey,
            assigned_kfrags: Mapping[Address, Tuple[PublicKey, VerifiedKeyFrag]],
            threshold: int,
    ):

nucypher-core-python/nucypher_core/init.pyi:206

  • Missing return type annotation. The __new__ method should specify its return type. Add -> ReencryptionRequest: to match the pattern used by other static factory methods and maintain consistency.
    def __new__(
            cls,
            capsules: Sequence[Capsule],
            hrac: HRAC,
            encrypted_kfrag: EncryptedKeyFrag,
            publisher_verifying_key: PublicKey,
            bob_verifying_key: PublicKey,

nucypher-core-python/nucypher_core/init.pyi:242

  • Missing return type annotation. The __new__ method should specify its return type. Add -> ReencryptionResponse: to match the pattern used by other static factory methods and maintain consistency.
    def __new__(
            cls,
            signer: Signer,
            capsules_and_vcfrags:
            Sequence[Tuple[Capsule, VerifiedCapsuleFrag]]
    ):

nucypher-core-python/nucypher_core/init.pyi:275

  • Missing return type annotation. The __new__ method should specify its return type. Add -> RetrievalKit: to match the pattern used by other static factory methods and maintain consistency.
    def __new__(
            cls,
            capsule: Capsule,
            queried_addresses: Set[Address],
            conditions: Optional[Conditions],
    ):

nucypher-core-python/nucypher_core/init.pyi:300

  • Missing return type annotation. The __new__ method should specify its return type. Add -> RevocationOrder: to match the pattern used by other static factory methods and maintain consistency.
    def __new__(
            cls,
            signer: Signer,
            staking_provider_address: Address,
            encrypted_kfrag: EncryptedKeyFrag,
    ):

nucypher-core-python/nucypher_core/init.pyi:1

  • Missing return type annotation. The __new__ method should specify its return type. Add -> NodeMetadataPayload: to match the pattern used by other static factory methods and maintain consistency.
from typing import Dict, List, Mapping, Optional, Sequence, Set, Tuple, final

nucypher-core-python/nucypher_core/init.pyi:1

  • Missing return type annotation. The __new__ method should specify its return type. Add -> ThresholdDecryptionRequest: to match the pattern used by other static factory methods and maintain consistency.
from typing import Dict, List, Mapping, Optional, Sequence, Set, Tuple, final

nucypher-core-python/nucypher_core/umbral.pyi:234

  • Missing return type annotation. The __new__ method should specify its return type. Add -> ReencryptionEvidence: to match the pattern used by other static factory methods and maintain consistency.
    def __new__(
            cls,
            capsule: Capsule,
            vcfrag: VerifiedCapsuleFrag,
            verifying_pk: PublicKey,
            delegating_pk: PublicKey,
            receiving_pk: PublicKey,
    ):

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…; this caused stubtest errors.

Add type annotations for constructor.
Remove stubtest allowlist file now that these errors are resolved.
@fjarri
Copy link
Contributor

fjarri commented Nov 4, 2025

I was planning to do that as a part of #122

But I guess the __new__ specifically can be fixed independently

@derekpierre
Copy link
Member Author

derekpierre commented Nov 4, 2025

I was planning to do that as a part of #122

But I guess the __new__ specifically can be fixed independently

Didn't realize you moved over to nucypher-core work already. If this PR is independent enough of a chunk then let's keep the work separate, and you can base your changes over this one.

I have some work in nucypher-core (#113) that I would like to merge soonish that needs similar __init__ to __new__ updates so I figured I would be proactive since I knew this change was eventually coming when you eventually shifted your focus to nucypher-core, and I'd need to rebase.

@derekpierre derekpierre marked this pull request as ready for review November 4, 2025 21:38
@derekpierre derekpierre merged commit 08765f5 into nucypher:main Nov 5, 2025
13 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.

6 participants