Skip to content

Let custom generators declare their own source includes#100

Merged
kwabenantim merged 5 commits into
developfrom
custom-generator-source-includes
Jul 23, 2026
Merged

Let custom generators declare their own source includes#100
kwabenantim merged 5 commits into
developfrom
custom-generator-source-includes

Conversation

@kwabenantim

Copy link
Copy Markdown
Member

Fixes #99

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds support for custom generators to declare additional #include headers needed by code they emit, addressing Issue #99 so users don’t have to duplicate long source_includes lists in YAML when the generator already “knows” what it needs.

Changes:

  • Introduces Custom.get_source_includes() (default []) for custom generators to supply wrapper source includes.
  • Extends ClassWriter.includes_block() to append generator-provided includes (with deduplication).
  • Adds unit tests and README documentation covering the new generator include mechanism.

Reviewed changes

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

File Description
tests/test_class_writer.py Adds tests verifying generator-provided source includes are emitted, deduped, and skipped in common-include mode.
README.md Documents get_source_includes() and provides an example of declaring includes from a custom generator.
cppwg/writers/class_writer.py Appends generator-provided includes into the wrapper #include block.
cppwg/templates/custom.py Adds the new get_source_includes() hook to the Custom base class.

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

Comment thread cppwg/writers/class_writer.py Outdated
Add a get_source_includes() hook to the Custom generator base (returns [] by
default). The class writer folds a generator's returned headers into the
wrapper's deduplicated #include block (non-common branch; a no-op with
common_include_file, supporting quoted and <...> forms).

This covers the one dependency auto_includes cannot: types a custom generator
names only in its emitted code - e.g. a template-method instantiation like
AddCellWriter<CellAgesWriter> built from a hard-coded list - which never appear
in the parsed signatures. The generator can now supply those headers itself,
keeping the type list and its includes in one place instead of duplicating them
under source_includes.

Treat every custom-generator hook as optional and route them through a shared
call_generator_hook() helper, so a generator that does not subclass Custom (and
so omits a hook) degrades to the default instead of raising AttributeError. This
keeps the new get_source_includes() backward compatible and makes all five hooks
(pre/def-code, module pre/code, source-includes) consistent.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

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

Comment thread cppwg/writers/class_writer.py Outdated
Comment thread tests/test_class_writer.py Outdated
includes_block() returned at the common_include_file branch before the
get_source_includes() loop, so a custom generator's declared headers were
silently dropped whenever common_include_file was enabled. That is not
harmless: those headers can be <...> system headers or category-D headers
(named only in the generator's emitted code, e.g. AddCellWriter<CellAgesWriter>)
that the wrapper header collection does not pull in.

Hoist the get_source_includes() loop above the common-include early return,
next to the type-caster loop, so generator-provided headers are emitted in
both modes. Update the test that asserted the old skip-in-common behaviour to
assert they are emitted (including a <...> system header).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

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

Comment thread cppwg/templates/custom.py Outdated
Comment thread README.md Outdated
Comment thread tests/test_class_writer.py Outdated
kwabenantim and others added 3 commits July 23, 2026 16:15
Fix stale or misleading documentation surfaced while reviewing the
get_source_includes() work and auditing the docs:

- get_source_includes() docstring (custom.py) and README: spell out that
  header entries are bare (Foo.hpp) or angle-bracket (<foo>) and that cppwg
  adds the quotes, so users do not pass literal quotes.
- typecasters docstring (package_info.py): show the header example without
  literal quotes, matching how the config is written.
- test_class_writer.py: correct a dedup-order comment (generator includes now
  emit before source_includes).
- ensure_trailing_newline docstring (utils.py): drop the claim that custom
  generators must subclass Custom; call_generator_hook duck-types them.
- module_writer.py: correct the module main-cpp filename to
  _packagename_modulename.main.cppwg.cpp (docstring and path comment).
- README usage synopsis: add the missing [--overwrite] flag.
- custom.py: fix a "base classs" typo.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
has_shared_ptr has been hardcoded True since the original PyChaste import
(398f0d9) and is never reassigned, so the guard "has_shared_ptr and
smart_ptr_type" is equivalent to just "smart_ptr_type". It was an unimplemented
placeholder for per-class holder detection; a field that is always True only
invites confusion. Drop the field and its attribute doc, and simplify the
guard. No behaviour change: every class still gets a smart-pointer holder when
smart_ptr_type is set (the global boost::shared_ptr holder is required by
Chaste's shared_ptr-based API anyway).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The shapes example's mesh module was removed in #20, but the hand-authored
Python package src/py/pyshapes/mesh/__init__.py was left behind. It imports
pyshapes.mesh._pyshapes_mesh, which is no longer generated or built (no mesh
config module and no mesh C++ sources), so importing it would fail. Nothing
references it. Delete it to finish #20's removal.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kwabenantim
kwabenantim marked this pull request as ready for review July 23, 2026 15:39
@kwabenantim
kwabenantim merged commit ce1f4b2 into develop Jul 23, 2026
13 checks passed
@kwabenantim
kwabenantim deleted the custom-generator-source-includes branch July 23, 2026 15:45
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.

Allow custom templates to insert includes

2 participants