mafw.scaffold.renderer

Rendering of the canonical project template.

The canonical template is shipped as package data under mafw/scaffold/template and read back through importlib.resources, so it travels with the installed MAFw distribution and works identically from a wheel, a source install, or an isolated uvx environment.

Rendering uses the standard-library string.Template with a small, closed set of placeholders. string.Template.substitute() (never safe_substitute) is used so that an unknown or missing placeholder is a hard error, turning template drift into an immediate failure rather than silent corruption. Each placeholder value is escaped once per target format (TOML, Python, Markdown, path) before substitution.

Added in version 2.4.

Module Attributes

TEMPLATE_PACKAGE

Package that owns the bundled template resource tree.

TEMPLATE_DIRNAME

Name of the template resource directory within TEMPLATE_PACKAGE.

TEMPLATE_SUFFIX

Suffix marking a template file; stripped from the rendered output name.

IMPORT_NAME_PLACEHOLDER

Directory-name token in the template tree replaced by the project import name.

PLACEHOLDER_KEYS

The closed set of placeholder keys available to every template.

EXAMPLE_PROCESSOR_NAME

Class name of the generated example Processor (also its registered name).

Functions

build_context(spec)

Build the placeholder substitution context from a project specification.

discover_placeholders([mapping])

Return the set of placeholder identifiers referenced across all templates.

render_project(spec)

Render every template file for the given project specification.

Classes

RenderedFile(relative_path, content)

A single rendered output file.

class mafw.scaffold.renderer.RenderedFile(relative_path: PurePosixPath, content: str)[source]

Bases: object

A single rendered output file.

Variables:
  • relative_path – The output path relative to the project root, using POSIX separators.

  • content – The fully rendered file content.

mafw.scaffold.renderer._iter_template_files(node: Traversable, prefix: PurePosixPath) → Iterator[tuple[PurePosixPath, str]][source]

Recursively yield (relative_path, raw_text) pairs for every template file.

Parameters:
  • node (Traversable) – The current traversable node (file or directory).

  • prefix (PurePosixPath) – The accumulated relative path of node.

Returns:

An iterator of relative paths and their raw template text.

Return type:

Iterator[tuple[PurePosixPath, str]]

mafw.scaffold.renderer._render_output_name(name: str) → str[source]

Map a template file name to its rendered output name.

This strips the .tmpl suffix and applies the special-name table (for example gitignore becomes .gitignore).

Parameters:

name (str) – The template file name.

Returns:

The rendered output file name.

Return type:

str

mafw.scaffold.renderer._render_path(relative: PurePosixPath, import_name: str) → PurePosixPath[source]

Render a template-relative path into its output path.

Directory tokens equal to IMPORT_NAME_PLACEHOLDER are replaced by the project import name, and the final component is mapped through _render_output_name().

Parameters:
  • relative (PurePosixPath) – The template-relative path.

  • import_name (str) – The project import name.

Returns:

The rendered output path, relative to the project root.

Return type:

PurePosixPath

mafw.scaffold.renderer._template_root() → Traversable[source]

Return the root of the bundled template resource tree.

Returns:

A traversable pointing at the template directory.

Return type:

Traversable

Raises:

mafw.scaffold.errors.MissingTemplateError – If the template directory is absent.

mafw.scaffold.renderer._toml_basic_string(value: str) → str[source]

Escape a value for inclusion as a TOML basic string body (without quotes).

Only the characters that are illegal inside a TOML basic string are escaped, which is sufficient for the controlled values (description, names) placed into the generated pyproject.toml.

Parameters:

value (str) – The raw value to escape.

Returns:

The escaped value, safe to embed between double quotes in TOML.

Return type:

str

mafw.scaffold.renderer.build_context(spec: ProjectSpec) → dict[str, str][source]

Build the placeholder substitution context from a project specification.

Values are escaped per target format where needed. The import name is already validated to the identifier grammar, so it needs no escaping; free-text values that land in TOML (the description, the distribution name) are escaped as TOML basic strings.

Parameters:

spec (mafw.scaffold.spec.ProjectSpec) – The validated project specification.

Returns:

A mapping from placeholder key to its rendered string value.

Return type:

dict[str, str]

mafw.scaffold.renderer.discover_placeholders(mapping: Mapping[str, str] | None = None) → set[str][source]

Return the set of placeholder identifiers referenced across all templates.

This is used by the test-suite to assert that templates reference only keys in mafw.scaffold.renderer.PLACEHOLDER_KEYS.

Parameters:

mapping (Mapping[str, str] | None) – Unused; kept for API symmetry with callers that pass a context.

Returns:

The set of placeholder identifiers found in the templates.

Return type:

set[str]

mafw.scaffold.renderer.render_project(spec: ProjectSpec) → list[RenderedFile][source]

Render every template file for the given project specification.

Parameters:

spec (mafw.scaffold.spec.ProjectSpec) – The validated project specification.

Returns:

The list of rendered files, each with its project-relative path.

Return type:

list[RenderedFile]

Raises:
mafw.scaffold.renderer.EXAMPLE_PROCESSOR_NAME = 'ExampleProcessor'

Class name of the generated example Processor (also its registered name).

mafw.scaffold.renderer.IMPORT_NAME_PLACEHOLDER = '__import_name__'

Directory-name token in the template tree replaced by the project import name.

mafw.scaffold.renderer.PLACEHOLDER_KEYS = frozenset({'author_email', 'author_name', 'description', 'distribution_name', 'example_processor_name', 'import_name', 'license_id', 'mafw_version', 'python_version', 'requires_python', 'year'})

The closed set of placeholder keys available to every template.

A unit test asserts that the placeholders discovered across the shipped templates are a subset of these keys, so a template can never reference an undefined placeholder.

mafw.scaffold.renderer.TEMPLATE_DIRNAME = 'template'

Name of the template resource directory within TEMPLATE_PACKAGE.

mafw.scaffold.renderer.TEMPLATE_PACKAGE = 'mafw.scaffold'

Package that owns the bundled template resource tree.

mafw.scaffold.renderer.TEMPLATE_SUFFIX = '.tmpl'

Suffix marking a template file; stripped from the rendered output name.