-
Notifications
You must be signed in to change notification settings - Fork 12
BlockPrototype #435
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BlockPrototype #435
Conversation
There was a problem hiding this 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.
edg/core/Ports.py
Outdated
| 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 |
Copilot
AI
Nov 23, 2025
There was a problem hiding this comment.
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.
| # 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. |
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: