Adding languages
Languages in qddate are hand-written pattern tables, not runtime locale data. That is the speed tradeoff: new coverage is a code change plus tests.
English and Russian are the historical cores. Other languages follow the same shape.
Checklist
- Add
qddate/patterns/<code>.pywith month/weekday constants andPATTERNS_<CODE>dicts (key,name,pattern,length,format, flags). - Export the list from
qddate/patterns/__init__.pyand append it toALL_PATTERNS. - Add the code to
SUPPORTED_LANGUAGESandPATTERNS_BY_LANGUAGE. - Stamp each base key in
_PATTERN_METADATAas(language, separator). - Teach prefix matching in
qddate/dirty.pyif the language needs distinct prefixes. - Add month tokens to the detection sets in
qddate/qdparser.pywhen automatic narrowing should see them. Skip tokens that collide with other languages (see Romanianmai/august). - Add tests (
tests/test_<language>.pyand/or JSON fixtures undertests/fixtures/). - Regenerate docs:
python scripts/generate_pattern_docs.py. - Mention the language in the README supported-languages list.
Pattern dict fields
Typical keys:
key— stable id, e.g.dt:date:de_basename— human descriptionpattern— pyparsing grammarlength—{"min": ..., "max": ...}format—strftime-like hint for docsyearshort,noyear,filter— optional flags
Copy an existing language module (de.py, ro.py, uk.py) rather than inventing a new layout.
Metadata table
_PATTERN_METADATA in qddate/patterns/__init__.py is the source of truth for
language and separator. Adding a pattern without an entry there will fail the
oracle tests in tests/test_pattern_metadata.py.
Numeric, language-neutral keys use language=None.
What not to do
- Do not add runtime I/O or CLDR JSON loading on the parse path.
- Do not put new languages in a removed
consts.py/DATE_DATA_TYPES_RAW(older docs mentioned that; patterns now live per-module underqddate/patterns/). - Do not rely on automatic detection to substitute for
languages=in tests — pin the code.