maml-py
A pure Python parser for MAML (Minimal Abstract Markup Language) v0.1.
This is NOT PRODUCTION READY. I have never written a parser before and this is mostly for people to play around with.
MAML is a minimal configuration format designed to be easily readable by humans and easily parsed by machines. It's similar to YAML but with a simpler syntax.
Features
- Pure Python implementation with no external dependencies
- Full support for MAML v0.1 specification
- Type hints throughout for better IDE support
- Comprehensive test coverage
- Simple API similar to Python's
jsonmodule
Installation
pip install maml-py
Quick Start
Installation from Source
git clone https://gitlab.com/matdevdug/maml-py.git
cd maml-py
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -e .
Testing the Installation
python -c "import maml; print(maml.loads('{key: \"value\"}'))"
Expected output:
{'key': 'value'}
Usage
Basic Parsing
import maml
data = maml.loads("""
{
name: "John Doe"
age: 30
active: true
}
""")
print(data)
Output:
{'name': 'John Doe', 'age': 30, 'active': True}
Reading from Files
import maml
with open('config.maml', 'r') as f:
config = maml.load(f)
Writing MAML
import maml
data = {
"name": "John Doe",
"age": 30,
"items": [1, 2, 3]
}
maml_string = maml.dumps(data)
print(maml_string)
Output:
{
name: "John Doe"
age: 30
items: [
1
2
3
]
}
Writing to Files
import maml
data = {"key": "value"}
with open('output.maml', 'w') as f:
maml.dump(data, f)
Error Handling
import maml
try:
data = maml.loads('{ invalid syntax')
except maml.MAMLSyntaxError as e:
print(f"Parse error: {e}")
print(f"Line: {e.line}, Column: {e.column}")
Complete Example
import maml
config_text = """
{
# Database configuration
database: {
host: "localhost"
port: 5432
credentials: {
username: "admin"
password: "secret"
}
}
# Feature flags
features: [
"auth"
"api"
"dashboard"
]
# Settings
debug: true
max_connections: 100
timeout: 30.5
}
"""
config = maml.loads(config_text)
print(f"Database host: {config['database']['host']}")
print(f"Features: {', '.join(config['features'])}")
print(f"Debug mode: {config['debug']}")
Output:
Database host: localhost
Features: auth, api, dashboard
Debug mode: True
MAML Syntax Overview
Values
MAML supports the following value types:
null- null valuetrue,false- booleans42,-100- integers3.14,1.5e10- floats"string"- strings"""multiline string"""- multiline strings[1, 2, 3]- arrays{key: "value"}- objects
Objects
Objects use curly braces with key-value pairs separated by colons:
{
name: "Alice"
age: 25
"quoted key": "value"
}
Keys can be identifiers (alphanumeric, _, -) or quoted strings. Commas and newlines are both valid separators.
Arrays
Arrays use square brackets:
[
"item1"
"item2"
"item3"
]
Like objects, commas and newlines are both valid separators.
Strings
Regular strings use double quotes with standard escape sequences:
"Hello, world!\nNew line here."
Multiline strings use triple quotes and preserve formatting:
"""
This is a
multiline string
with preserved formatting.
"""
Comments
Comments start with # and continue to the end of the line:
{
key: "value" # This is a comment
}
API Reference
maml.loads(s: str) -> Any
Parse a MAML string and return the corresponding Python object.
maml.load(fp: TextIO) -> Any
Read and parse a MAML file.
maml.dumps(obj: Any) -> str
Serialize a Python object to a MAML formatted string.
maml.dump(obj: Any, fp: TextIO) -> None
Serialize a Python object to a MAML formatted string and write to a file.
Exceptions
MAMLError- Base exception for all MAML errorsMAMLSyntaxError- Raised when parsing invalid MAML syntax
Development
Setup
git clone https://gitlab.com/matdevdug/maml-py.git
cd maml-py
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -e .
Running Tests
Run all tests:
python -m unittest discover tests/ -v
Run specific test file:
python -m unittest tests.test_parser -v
Run specific test class:
python -m unittest tests.test_parser.TestParser -v
Run specific test method:
python -m unittest tests.test_parser.TestParser.test_object_simple -v
Test Coverage
The test suite includes 44 comprehensive tests covering:
- All primitive types (null, boolean, integer, float, string)
- String escaping and unicode handling
- Multiline strings with various edge cases
- Arrays (empty, simple, nested, with trailing commas)
- Objects (empty, simple, nested, identifier keys, quoted keys)
- Comments (line comments, inline comments)
- Error handling (syntax errors, invalid escapes, duplicate keys)
- Round-trip encoding and decoding
Quick Test Commands
Test basic parsing:
python -c "import maml; assert maml.loads('null') is None; print('✓ null')"
python -c "import maml; assert maml.loads('true') == True; print('✓ boolean')"
python -c "import maml; assert maml.loads('42') == 42; print('✓ integer')"
python -c "import maml; assert maml.loads('\"hello\"') == 'hello'; print('✓ string')"
python -c "import maml; assert maml.loads('[1,2,3]') == [1,2,3]; print('✓ array')"
python -c "import maml; assert maml.loads('{a:1}') == {'a': 1}; print('✓ object')"
Test encoding:
python -c "import maml; s=maml.dumps({'key':'value'}); print(s)"
Building for Distribution
Build the package:
pip install build
python -m build
This creates distribution files in dist/:
maml_py-0.1.0.tar.gz- Source distributionmaml_py-0.1.0-py3-none-any.whl- Wheel distribution
Publishing to PyPI
pip install twine
twine check dist/*
twine upload dist/*
License
MIT
Specification
This library implements the MAML v0.1 specification. For more details on the MAML format, see the official specification.
Release files for maml-py 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| maml_py-0.1.1.tar.gz | 13.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| maml_py-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.9 kB
Release files / maml_py-0.1.1.tar.gz
| Download URL | maml_py-0.1.1.tar.gz |
|---|---|
| Size | 13.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1cda88933d1179e7197c30e8486bc96ee148211bade58dcaea4f308d045e3682
|
|
BLAKE2b-256 checksum How to use checksums |
f34d9c65da460f18db48056af67fd7e70f52afb228797e4b543127cd9b6d92d9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Release files / maml_py-0.1.1-py3-none-any.whl
| Download URL | maml_py-0.1.1-py3-none-any.whl |
|---|---|
| Size | 9.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ee3b1f2a714c83a50231e23939a84e3d8f4f94878a6b06730db02c19f4b83916
|
|
BLAKE2b-256 checksum How to use checksums |
e3056a559bd9a036234e94820f59ed0d84e478c6ef12f7426016241e95de8ebd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|