Skip to content

Conversation

@ducky64
Copy link
Collaborator

@ducky64 ducky64 commented Nov 23, 2025

Optimization that changes Block model (pre-binding) instantiation to be a BlockPrototype that holds the target block class, args, and kwargs, without running its init. The Block init is only run on binding time.

BlockPrototype generates error on any attempt to access it. This should not change user-facing HDL.

Shaves about a minute off of the test suite.

It does not seem possible to apply the same pattern to Ports, since Port model operations in user-facing library HDL do use their data (eg, DigitalSource.from_bidir(model) requires inspecting the model's properties and would leak (more) the prototype mechanics into user-facing HDL. Ports occupy a odd space in that they both contain user HDL (like Blocks, but not ConstraintExpr) and where model components can be used (unlike Blocks, which only allow interaction on bound objects through parameters and ports).

Other changes:

  • Removes _post_init as infrastructure
  • Removes the post_init elaboration state
  • Replace Block._bind with BlockPrototype._bind
  • Removes the ElementMeta metaclass that saves initializer args and context. Initializer args no longer needed for Blocks are are only used for Ports.

@ducky64 ducky64 requested a review from Copilot November 23, 2025 03:22
@ducky64 ducky64 marked this pull request as ready for review November 23, 2025 03:22
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 introduces a BlockPrototype optimization that defers Block __init__ execution until binding time, significantly improving test suite performance by approximately one minute. The key changes replace immediate block instantiation with a lightweight BlockPrototype that stores the target class, args, and kwargs without running the full initialization.

Key Changes

  • Introduces BlockPrototype class that delays Block.init execution until binding time via Block.new hook
  • Removes the _post_init infrastructure and post_init elaboration state enum value
  • Removes ElementMeta metaclass and consolidates its functionality into BaseBlockMeta for blocks and InitializerContextMeta for ports

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
edg/core/HierarchyBlock.py Adds BlockPrototype class and modifies Block.new to return prototypes; updates Block() and with_mixin() methods to handle BlockPrototype instances
edg/core/test_block_prototype.py New test file validating BlockPrototype functionality including attribute access restrictions and binding behavior
edg/core/Core.py Removes ElementMeta metaclass and _post_init infrastructure from LibraryElement
edg/core/Blocks.py Adds BaseBlockMeta metaclass to replace ElementMeta for blocks; removes _bind method and post_init elaboration state
edg/core/Ports.py Introduces InitializerContextMeta to preserve initializer_args functionality for Ports; adds _next_bind assignment in _bridge method
edg/core/Link.py Updates LinkMeta to inherit from BaseBlockMeta instead of ElementMeta
edg/core/MultipackBlock.py Updates PackedPart to handle BlockPrototype instances using issubclass checks
edg/core/init.py Removes ElementMeta from exports
edg/core/DesignTop.py Updates elaboration state assertion from post_init to init; adds assertion for _elt_sample existence
edg/core/Generator.py Updates elaboration state assertion from post_init to init
edg/electronics_model/KiCadSchematicBlock.py Moves isinstance assertion to after Block binding to properly check instantiated block type

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

def __call__(cls, *args, **kwargs):
"""Hook on construction to store some metadata about its creation.
This hooks the top-level __init__ only."""
# TODO initializer_args should be replaced with the prototype system
Copy link

Copilot AI Nov 23, 2025

Choose a reason for hiding this comment

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

This TODO comment is misleading. According to the PR description, initializer_args are still needed for Ports and are only being removed for Blocks. The prototype system is specifically for Blocks, not Ports. This comment should be removed or clarified.

Suggested change
# TODO initializer_args should be replaced with the prototype system
# Note: initializer_args are still required for Ports; the prototype system only applies to Blocks.

Copilot uses AI. Check for mistakes.
@ducky64 ducky64 merged commit 26f6bc1 into master Nov 23, 2025
12 checks passed
@ducky64 ducky64 deleted the metaclass-prototypes branch November 23, 2025 08:54
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.

2 participants