02 — Discovery rules¶
Source: examples/cookbook/02-discovery.
One WELDER_MODULE line binds a whole namespace; everything else in this recipe
is steered from the declarations. It is the annotation
vocabulary exercised end to end: policies, marks,
nested-namespace recursion, and weld_as renames.
The moves, one by one¶
The whole module in one line — the namespace token doubles as the module
name, its doc becomes the module docstring, and the optional trailing block is
hand-written post-glue (Namespaces & modules):
namespace [[=welder::doc("A small warehouse inventory.")]] inventory { ... }
WELDER_MODULE(inventory, pybind11) {
module.attr("SCHEMA_VERSION") = 2;
}
automatic vs opt_in — the default policy binds every public member unless
excluded; opt_in binds only what is explicitly included:
struct [[=welder::weld(welder::lang::py)]]
Item {
std::string name; // bound
[[=welder::mark::exclude]] std::uint64_t cache_key{0}; // bound nowhere
};
struct [[=welder::weld(welder::lang::py), =welder::policy::opt_in]]
AuditRecord {
int internal_id{0}; // not included -> not bound
[[=welder::mark::include]] std::string note; // bound
};
Renaming with weld_as — the bound name is forced verbatim (never through a
name style); the C++ spelling is not exposed:
Nested namespaces — a nested namespace with bound content becomes a
submodule; mark::exclude on a namespace prunes it wholesale, even when its
contents carry weld markers (the usual way to keep detail/impl out):
namespace pricing { ... } // -> inventory.pricing
namespace [[=welder::mark::exclude]] detail { ... } // pruned wholesale
Overloads — a welded overload set binds under one name with call-time
dispatch; restock(item, 5) and restock(item) both work.
What the check asserts¶
Everything above, from the Python side: Crate exists and BigWoodenBox does
not; the unwelded Ledger is invisible; AuditRecord exposes only the included
fields; inventory.pricing.discounted(...) is a submodule function;
inventory.detail does not exist.