Skip to main content

Toolbox for Fortran Namelists

Project description

nml-tools

nml-tools logo

Generate Fortran namelist modules, Markdown docs, and template namelists from a small JSON Schema-like specification with Fortran-focused extensions.

Features

  • Schema input in YAML or JSON.
  • Core keywords from JSON schema: type, properties, required, default, examples, title, description.
  • Fortran extensions: x-fortran-namelist, x-fortran-kind, x-fortran-len, x-fortran-shape, x-fortran-flex-tail-dims, x-fortran-default-*.
  • Outputs: Fortran module, helper module, Markdown docs, template namelist.
  • Config-driven CLI for batching multiple schemas.

Missing Fortran features

  • No support for derived types:
    • Only scalars and arrays of scalars are supported.
    • Could be emulated with nested objects, but one would need to decide where the respective fortran types are defined or used from.
  • No support for complex types:
    • JSON doesn't have a native complex type.
    • Could be emulated with:
      • Lists of length 2 with metadata, like f90nml does for JSON conversion.
      • Objects with real and imag properties.
      • Strings with a specific format like pydantic does.

Fortran extensions (x-fortran-*)

These keywords extend JSON Schema with Fortran-specific requirements.

x-fortran-namelist

  • Location: schema root.
  • Type: string.
  • Meaning: name of the Fortran namelist block.

Example:

x-fortran-namelist: optimization

x-fortran-kind

  • Location: integer/number properties or array items.
  • Type: string.
  • Meaning: Fortran kind identifier (mapped via [kinds] in the config).
  • If omitted, plain integer/real is used.

Example:

count:
  type: integer
  x-fortran-kind: i4

x-fortran-len

  • Location: string properties or array items.
  • Type: integer literal or identifier.
  • Meaning: Fortran character length (character(len=...)).
  • Identifiers must be defined in [constants] in the config and be integers.

Example:

name:
  type: string
  x-fortran-len: buf

x-fortran-shape

  • Location: array properties.
  • Type: integer, identifier, or list of integers/identifiers.
  • Meaning: Fortran array dimensions; identifiers are resolved via [constants].
  • Required; deferred-size dimensions are not supported.
  • Nested arrays are not supported. Use a single array with a shape list for multi-dimensional arrays.

Example:

values:
  type: array
  x-fortran-shape: [3, 2, max_iter]
  items:
    type: number
    x-fortran-kind: dp

x-fortran-flex-tail-dims

  • Location: array properties.
  • Type: integer.
  • Meaning: number of trailing dimensions that may be shorter than the declared shape (0 disables flexibility).
  • Must be between 0 and the array rank; only trailing dimensions are supported.
  • Defaults and logical arrays are not supported for flexible arrays.
  • The generated type exposes filled_shape() to compute the used extent.

Example:

values:
  type: array
  x-fortran-shape: [3, 2, max_iter]
  x-fortran-flex-tail-dims: 1
  items:
    type: number
    x-fortran-kind: dp

x-fortran-default-order

  • Location: array properties with default.
  • Type: string (F or C, default F).
  • Meaning: memory order used when reshaping defaults.

Example:

x-fortran-default-order: C

x-fortran-default-repeat

  • Location: array properties with default.
  • Type: boolean.
  • Meaning: repeat the provided default values to fill the full shape.
  • Array defaults must be lists; to broadcast a scalar, set default on items instead.
  • Cannot be used together with x-fortran-default-pad.

Example:

x-fortran-default-repeat: true

x-fortran-default-pad

  • Location: array properties with default.
  • Type: scalar or list of scalars.
  • Meaning: pad values used to fill the array if the default list is shorter than the shape.
  • Cannot be used together with x-fortran-default-repeat.

Example:

x-fortran-default-pad: 0

Combined example:

values_repeat:
  type: array
  x-fortran-shape: [2, 3]
  items:
    type: integer
    x-fortran-kind: i4
  default: [1, 2]
  x-fortran-default-repeat: true

values_pad_c:
  type: array
  x-fortran-shape: [2, 3]
  items:
    type: integer
    x-fortran-kind: i4
  default: [1, 2, 3]
  x-fortran-default-order: C
  x-fortran-default-pad: 0

Validation keywords

Only a subset of JSON Schema validation keywords is implemented. Validation is opt-in: call is_valid() on the generated type to check required values, enum and bound constraints.

Enum support

Enums are supported for strings and integers only. For arrays, enums are defined on items (not on the array itself).

  • Keywords: enum
  • The generated Fortran module exposes public *_enum_values arrays and elemental *_in_enum helpers.
  • String enums compare against trim(value); enum literals are stored with the field length.

Numeric bounds

You can add minimum/maximum constraints for integer or real values. For arrays, the bounds apply to each item and must be defined on items.

  • Keywords: minimum, maximum, exclusiveMinimum, exclusiveMaximum
  • Applies to: integer and number (real in Fortran)
  • For arrays: bounds belong on items, not the array property

Example (scalars):

tolerance:
  type: number
  x-fortran-kind: dp
  minimum: 0.0
  exclusiveMaximum: 1.0

Example (array items):

counts:
  type: array
  x-fortran-shape: 3
  items:
    type: integer
    minimum: 1

Configuration (nml-config.toml)

The CLI reads a TOML config file. Paths are resolved relative to the config file location.

[helper]

Controls the generated helper module.

  • path (string, required to generate helper): output file for the helper module.
  • module (string, optional): Fortran module name (default: nml_helper).
  • buffer (int, optional): line buffer length for the helper module.
  • header (string, optional): text inserted at the top of the helper file.

[constants]

Named constants used for dimensions and string lengths.

  • Each entry is a table with value (int/float) and optional doc.
  • Values must be plain numbers (no kind suffixes).

Example:

[constants.max_iter]
value = 4
doc = "Maximum number of iterations."

[kinds]

Defines the kind module and allowed kinds.

  • module (string): Fortran module to use.
  • real (list of strings): allowed real kinds.
  • integer (list of strings): allowed integer kinds.
  • map (table, optional): schema kind name → module kind name.

[documentation]

Optional extra module documentation appended after the generated \brief and \details. Multiline strings are supported and Doxygen formatting is allowed.

namelists (array)

Schema entries to generate per-namelist outputs.

  • schema (string): schema file path.
  • mod_path (string, optional): Fortran module output path.
  • doc_path (string, optional): Markdown output path.

If a path is omitted, that output is not generated.

templates (array)

Template namelist output configuration.

  • output (string): template namelist output path.
  • schemas (list of strings): schemas included in the template file.
  • doc_mode: plain or documented.
  • value_mode: empty, filled, minimal-empty, or minimal-filled.

Optional values can override per-namelist fields for filled modes:

[templates.values.optimization]
niterations = 4
tolerance = 0.1

CLI

The command line interface is available as nml-tools or nmlt. Common flags: -h/--help, -V/--version, -v/-q (repeatable).

Primary subcommands:

  • generate: run the full pipeline (helper, Fortran modules, docs, templates).
  • gen-fortran: generate helper + Fortran modules only.
  • gen-markdown: generate Markdown docs only.
  • gen-template: generate template namelists only.
  • validate: validate a namelist file against schema definitions.

Generation

Generate all outputs:

nml-tools generate --config nml-config.toml

Generate specific outputs:

nml-tools gen-fortran --config nml-config.toml
nml-tools gen-markdown --config nml-config.toml
nml-tools gen-template --config nml-config.toml

Validation

Validation is check-only (defaults are not applied) and implements only a subset of JSON Schema constraints (types, required, enums, bounds, string length, array shape/flex). Unknown keys in a namelist or namelist blocks not covered by provided schemas are errors.

Config-driven:

nml-tools validate --config nml-config.toml input.nml

Schema-only:

nml-tools validate --schema demo.yml --input demo.nml
nml-tools validate --schema a.yml --schema b.yml combined.nml

Constants are resolved from [constants] in the config, or provided ad hoc:

nml-tools validate --schema demo.yml --constants MAX_ITER=10 input.nml

Array values are validated as rectangular lists in Fortran order (outer list corresponds to the last Fortran index), matching f90nml parsing.

Error handling

Generated type-bound procedures return integer status codes and accept an optional errmsg argument. No error stop is emitted by generated code.

Status codes (defined in the helper module):

Code Meaning
NML_OK (0) success
NML_ERR_FILE_NOT_FOUND (1) file does not exist
NML_ERR_OPEN (2) failed to open file
NML_ERR_NOT_OPEN (3) file not open
NML_ERR_NML_NOT_FOUND (4) namelist not found
NML_ERR_READ (5) read/parse error
NML_ERR_CLOSE (6) close error
NML_ERR_REQUIRED (10) required field missing
NML_ERR_ENUM (11) enum constraint failed
NML_ERR_NOT_SET (12) field not set (sentinel)
NML_ERR_PARTLY_SET (13) array partially set
NML_ERR_BOUNDS (14) bounds constraint failed
NML_ERR_INVALID_NAME (20) unknown field name
NML_ERR_INVALID_INDEX (21) invalid index for array access

Notes:

  • errmsg, when present, is filled with a short message (including iomsg on read errors).
  • is_set returns NML_ERR_NOT_SET if a value is missing, and NML_ERR_INVALID_NAME/NML_ERR_INVALID_INDEX on misuse.

Documentation format

Generated Fortran doc-strings are currently tailored for Doxygen. Future versions may make this configurable to support other tools such as FORD or the Sphinx Fortran domain.

Installation

pip install nml-tools

Minimal example

Schema (demo.yml):

title: Demo namelist
description: Small example namelist for nml-tools.
x-fortran-namelist: demo
type: object
required: [count]
properties:
  count:
    type: integer
    title: Number of steps
    x-fortran-kind: i4
  name:
    type: string
    title: Run label
    x-fortran-len: 64
    default: run1
  weights:
    type: array
    title: Weight vector
    x-fortran-shape: 3
    items:
      type: number
      x-fortran-kind: dp
    default: [0.1, 0.2, 0.3]

Config (nml-config.toml):

[helper]
path = "out/nml_helper.f90"
module = "nml_helper"
buffer = 1024

[kinds]
module = "iso_fortran_env"
real = ["real64"]
integer = ["int32"]
map = { dp = "real64", i4 = "int32" }

[[namelists]]
schema = "demo.yml"
mod_path = "out/nml_demo.f90"
doc_path = "out/nml_demo.md"

[[templates]]
output = "out/demo.nml"
schemas = ["demo.yml"]
doc_mode = "documented"
value_mode = "filled"

Generate outputs:

nml-tools generate --config nml-config.toml

Expected outputs:

  • out/nml_helper.f90
  • out/nml_demo.f90
  • out/nml_demo.md
  • out/demo.nml

Comparison to JSON Schema

This project implements a focused subset of JSON Schema aimed at Fortran namelist workflows, plus extensions for Fortran-specific types and shapes.

Main missing features compared to JSON Schema:

  • No $ref/$defs or remote schema resolution.
  • No composition keywords: allOf, anyOf, oneOf, not.
  • No conditional keywords: if/then/else.
  • No object constraints: additionalProperties, patternProperties, propertyNames, dependencies.
  • No advanced array constraints: tuple typing, contains, minItems, maxItems, uniqueItems.
  • No numeric or string validation keywords like multipleOf, minLength, maxLength, pattern, format (bounds are supported via minimum, maximum, exclusiveMinimum, and exclusiveMaximum).
  • No nested object schemas; properties are scalars or arrays of scalars only.

Use the x-fortran-* extensions to express kind, length, and shape information needed for code generation.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nml_tools-0.1.0rc1.tar.gz (43.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nml_tools-0.1.0rc1-py3-none-any.whl (41.3 kB view details)

Uploaded Python 3

File details

Details for the file nml_tools-0.1.0rc1.tar.gz.

File metadata

  • Download URL: nml_tools-0.1.0rc1.tar.gz
  • Upload date:
  • Size: 43.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nml_tools-0.1.0rc1.tar.gz
Algorithm Hash digest
SHA256 238ed7f7f16c82795d240a2ccd935bcf0aae6a3b11f4e0505706697f7ece5527
MD5 ccc0aab4dcf2854440c81c7a91400866
BLAKE2b-256 5bf090bfc2efa62b3f6925d4b01fc28e952b1867a05267c7b62b113403ba6e63

See more details on using hashes here.

Provenance

The following attestation bundles were made for nml_tools-0.1.0rc1.tar.gz:

Publisher: publish.yml on MuellerSeb/nml-tools

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nml_tools-0.1.0rc1-py3-none-any.whl.

File metadata

  • Download URL: nml_tools-0.1.0rc1-py3-none-any.whl
  • Upload date:
  • Size: 41.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nml_tools-0.1.0rc1-py3-none-any.whl
Algorithm Hash digest
SHA256 b71d42aff781ac46aba34037ff1f5551a3a29a5c098835fac76ba3c05fca1dba
MD5 ad28d128395b6180f8656a8f30857966
BLAKE2b-256 5dd34ebd150aa1817769620cb85a3d8f0adc5c24a7f0edc2e17122b08b77cce9

See more details on using hashes here.

Provenance

The following attestation bundles were made for nml_tools-0.1.0rc1-py3-none-any.whl:

Publisher: publish.yml on MuellerSeb/nml-tools

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page