Skip to content

Add MetronInfo v1.2 schema support - #265

Merged
bpepple merged 6 commits into
masterfrom
metroninfo-v1.2
Oct 28, 2026
Merged

bpepple merged 6 commits into
masterfrom
metroninfo-v1.2

Conversation

@bpepple

@bpepple bpepple commented Oct 27, 2026 •

Copy link
Copy Markdown
Member

Summary

Updates darkseid for the stable MetronInfo v1.2 schema.

  • Schema: Bundles the v1.2 schema alongside v1.1 and adds SchemaVersion.METRON_INFO_V1_2. Written files now declare the v1.2 namespace and schemaLocation.
  • New Series fields: Series gains end_year, status and summary, mapped to the new EndYear, Status and Summary elements.
  • Language codes: The Series and AlternativeNames language validators now accept BCP 47 tags such as pt-BR, fil and zh-Hant, and normalize them to canonical form.

Compatibility

SchemaVersion.METRON_INFO_V1_1 is unchanged, and v1.1 files are still reported as METRON_INFO_V1_1. The enum gains a new member, so validate_all() now returns one more entry.

Details

Schema detection. The MetronInfo schemas have no target namespace, and v1.2 accepts every v1.1 document. ValidateMetadata therefore checks v1.1 before v1.2, so a document reports the oldest version it conforms to. A document reports METRON_INFO_V1_2 only when it uses v1.2 features (EndYear, Status, Summary or a BCP 47 language tag).

Writing Series status and end year. Status is matched case-insensitively, so "hiatus" is written as Hiatus. Unknown values are dropped, the same way Format is handled. v1.2 adds two schema assertions: EndYear can't precede StartYear, and an Ongoing series can't have an EndYear. Every MetronInfo write is validated against the schema, so an EndYear that would break either rule is left out instead of failing the write. When a volume is written as the StartYear, that value is the one compared against EndYear.

Language tags. The two validators now share one function, validate_language_tag:

  • The whole value is first looked up as a language code or name, so "English", "ger" and hyphenated names like "Ai-Cham" resolve.
  • Otherwise it's parsed as a tag. The primary subtag can be an ISO 639-1, ISO 639-3 or ISO 639-2/B code (ger-DE → de-DE). It's reduced to the 2-letter code where one exists, and the 3-letter code otherwise.
  • Subtags must follow BCP 47 order: an optional script, an optional region, then any variants. Scripts and letter regions must be known ISO 15924 / ISO 3166-1 codes. Each subtag is normalized to its canonical case (pt-br → pt-BR, zh-hant-tw → zh-Hant-TW).
  • Extended language, extension and private-use subtags (zh-min-nan, en-US-x-foo) are rejected.

Language values read from existing files go through the same validator, so a file containing pt-br is written back as pt-BR.

Bug fix. Previously, a language with no 2-letter code (such as fil or yue) raised AttributeError: alpha_2 instead of being accepted or rejected cleanly. Because the reader runs this validator for AlternativeName elements, reading a MetronInfo file with <AlternativeName lang="fil"> crashed.

Display. str(Metadata) shows the series year range, for example [1970-1975].

ComicInfo has no equivalent for the new Series fields, so they're only stored in MetronInfo.

Tests

  • New tests write and read back the new Series fields, checked against the real v1.2 schema
  • Tests confirm an invalid EndYear is left out and the file still writes
  • ValidateMetadata reports v1.1 for v1.1-compatible documents, reports v1.2 for documents using v1.2 features, and rejects documents that break the new rules
  • Tests cover language names, ISO 639-1/639-3/639-2/B codes, case normalization, and invalid or unsupported BCP 47 tags

Replace the bundled v1.1 schema with the stable v1.2 release and rename SchemaVersion.METRON_INFO_V1_1 to METRON_INFO_V1_2. v1.2 is a strict superset of v1.1, so v1.1 could never be the winning match in the newest-first validation order. Written MetronInfo now declares the v1.2 namespace and schemaLocation.

Add end_year, status and summary to Series, read from and written to the new Series EndYear, Status and Summary elements. Status is matched case-insensitively and unknown values are dropped. An EndYear that the
schema's assertions would reject (before StartYear, or on an Ongoing series) is omitted, so the write doesn't fail validation.

Accept BCP 47 language tags (e.g. pt-BR, zh-Hant) in the Series and AlternativeNames language validators, which now share one implementation. This also fixes an AttributeError for languages without an ISO 639-1
code (e.g. fil, yue), which previously crashed when reading a MetronInfo AlternativeName that used one. Such languages now normalize to their ISO 639-3 code.
@bpepple bpepple self-assigned this Oct 27, 2026
@bpepple bpepple added breaking A breaking API change major Bump the major version on release labels Oct 27, 2026
…rsion.METRON_INFO_V1_2. Since v1.2 is a superset of v1.1, v1.1 is validated first so documents report the oldest version they conform to. Written MetronInfo now declares the v1.2 namespace and schemaLocation.
Look up the whole value as a language code or name before parsing it as a tag. Hyphenated language names now resolve (Ai-Cham -> aih) instead of being split into a primary subtag and bogus subtags (Na-Dene -> na-Dene). Codes are checked before name lookup, since pycountry's lookup() can match a language name equal to another language's code ("En").

Resolve the primary subtag from its ISO 639-1, ISO 639-3 or ISO 639-2/B code whether or not subtags follow, so ger-DE, fre-CA and chi-Hant are accepted like ger, fre and chi.

Parse subtags with BCP 47 rules: an optional script, an optional region and any variants, in that order. Scripts and alphabetic regions must be known ISO 15924 and ISO 3166-1 codes, and each subtag is normalized to its canonical case (pt-br -> pt-BR, zh-hant-tw -> zh-Hant-TW). Extended language, extension and private use subtags are rejected.
Add MetronInfo._match_mapping and use it for series format, series status and ComicRack age ratings, replacing three copies of the same strip/lower/lookup code. Series status now uses a STATUS_MAPPINGS table like FORMAT_MAPPINGS and RATING_MAPPINGS.

ComicRack age ratings are now stripped of surrounding whitespace before matching, like format and status already were.
Give Series.validate_end_year its own docstring and error message instead of aliasing validate_start_year, sharing a _validate_year helper. Year errors now name the field ("End year: 99 length must be 4").

Series now rejects an end year that precedes its start year at construction. The MetronInfo writer keeps its EndYear guard, since fields can be set after construction, a volume may be written as the StartYear, and the Ongoing rule depends on the normalized status.
@bpepple bpepple added minor Bump the minor version on release and removed breaking A breaking API change major Bump the major version on release labels Oct 27, 2026
Run the series language (ComicInfo LanguageISO and MetronInfo Series lang) and MetronInfo AlternativeName languages through validate_language_tag when reading, via a new BaseMetadataHandler._parse_language helper. Series languages were previously stored as read, so pt-br stayed pt-br while alternative names were normalized.

An unknown language is now logged and dropped instead of raising. Previously, an AlternativeName with an unknown lang failed the whole MetronInfo read with ValueError.
@bpepple
bpepple merged commit d0c8d48 into master Oct 28, 2026
11 checks passed
@bpepple
bpepple deleted the metroninfo-v1.2 branch October 28, 2026 00:34
@bpepple bpepple added the enhancement New feature or request label Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request minor Bump the minor version on release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant