rtoml

repository·main·Indexed 19 days ago

https://github.com/samuelcolvin/rtoml

A high-performance TOML library for Python implemented in Rust. It provides functions for parsing TOML via load() and loads(), and serializing Python objects via dump() and dumps(). The library features flexible handling of None values through the none_value parameter and automatic conversion of TOML datetimes into Python datetime, date, and time objects.

Tokens
2.3K
Snippets
11
Records
12
Agent score
65%

What's inside rtoml

  1. Handle None values in TOML

    main

    Unlike many TOML libraries, rtoml allows you to explicitly handle None values during serialization and deserialization using the none_value parameter.

    1. Ignore None values: Set none_value=None (the default) in dumps(). The keys with None values will be omitted from the resulting TOML.
    2. Serialize None as a placeholder: Set none_value to a specific string (e.g., '@None') in dumps(). This converts None into a string literal in the TOML file.
    3. Deserialize placeholder back to None: When using load() or loads(), pass the same string used during serialization to none_value to convert those literals back into Python None objects.
    import rtoml
    
    obj = {'a': None, 'b': 1}
    
    # 1. Serialize as placeholder
    serialized = rtoml.dumps(obj, none_value='@None')
    # Result: a = "@None"
    #         b = 1
    
    # 2. Deserialize back to None
    deserialized = rtoml.load(serialized, none_value='@None')
    assert deserialized['a'] is None
  2. Install rtoml

    main

    Install rtoml using pip. Requires python>=3.10. Binaries are available for Linux, macOS, and Windows. If no binary is available for your system, you must have rust stable installed to build it from source.

    pip install rtoml
  3. How TOML datetimes are parsed into Python

    main

    When using rtoml to parse TOML files, datetime objects are automatically converted into their corresponding Python types based on the TOML structure:

    • Datetime with time: Converted to a datetime.datetime object. If an offset is present in the TOML, it is converted to a timezone-aware object using a TzInfo object.
    • Date only: Converted to a datetime.date object.
    • Time only: Converted to a datetime.time object.

    Offsets are handled via a TzInfo class which represents the UTC offset in hours and minutes.

    # Example of how TOML datetimes map to Python
    # TOML:
    # date = 2023-10-27
    # datetime = 2023-10-27T12:00:00Z
    # time = 12:00:00
    
    # Python results:
    # date -> datetime.date(2023, 10, 27)
    # datetime -> datetime.datetime(2023, 10, 27, 12, 0, tzinfo=...) 
    # time -> datetime.time(12, 0, 0)
  4. Serialize Python objects with dumps() and dump()

    main

    Use dumps() to serialize a Python object to a TOML string, or dump() to write it directly to a file or Path.

    Parameters:

    • obj: The Python object to serialize.
    • pretty: If True, the output uses a more readable format.
    • none_value: Controls how None values are handled.
      • If None (default), None values are ignored/omitted from the output.
      • If a string is provided (e.g., '@None'), None values are serialized as that specific string literal.
    import rtoml
    
    obj = {'a': 1, 'b': None}
    
    # Serialize to string (None is ignored)
    toam_str = rtoml.dumps(obj, none_value=None)
    
    # Serialize to string (None becomes '@None')
    toam_str_with_none = rtoml.dumps(obj, none_value='@None')
  5. Parse TOML with load() and loads()

    main

    Use load() to parse a TOML file or file-like object, or loads() to parse a TOML string. Both return a Python dictionary.

    Parameters:

    • toml: For load(), a str, Path, or file object from open(). For loads(), a str containing TOML.
    • none_value: (Optional) A string that specifies which value in the TOML should be loaded as None in Python. By default, it is None, meaning no values are loaded as None.
    import rtoml
    
    # From a string
    data = rtoml.loads('key = "value"')
    
    # From a file
    with open('config.toml', 'r') as f:
        data = rtoml.load(f)
  6. Handle serialization errors for non-serializable types

    main

    If a Python object cannot be converted to a valid TOML type (e.g., a custom class that doesn't map to a primitive, list, dict, or datetime), the serializer will return a serde::ser::Error.

    The error message follows the format: [object_repr] ([type_name]) is not serializable to TOML.

  7. Deserialize TOML data in Python

    main

    Use the deserialize function to convert a TOML-formatted string into a Python object. You can optionally provide a none_value string to specify which TOML value should be interpreted as Python's None.

    import rtoml
    
    toml_str = 'key = "value"'
    # Basic deserialization
    data = rtoml.deserialize(toml_str)
    
    # Deserialization with a custom None value
    toml_with_none = 'key = "@None"'
    data = rtoml.deserialize(toml_with_none, none_value='@None')
  8. Serialize Python objects to TOML

    main

    Use serialize to convert a Python object into a TOML-formatted string. Use serialize_pretty if you want a human-readable, formatted TOML string. Both functions accept an optional none_value parameter to define how Python None values should be represented in the resulting TOML string.

    import rtoml
    
    data = {"key": "value", "other": None}
    
    # Standard serialization
    toml_str = rtoml.serialize(data, none_value='@None')
    
    # Pretty-printed serialization
    pretty_toml = rtoml.serialize_pretty(data, none_value='@None')
  9. Configure how None values are serialized

    main

    When converting Python objects to TOML, you can control how Python None values are represented in the resulting TOML string.

    By default, if none_value is not provided, None values in dictionaries or lists may be skipped or converted to the string `

    // Note: This is an internal Rust implementation detail of the serialization logic.
    // The behavior is exposed via the `none_value` parameter in `SerializePyObject::new`.
    // If `none_value` is set to `Some("@None")`, Python `None` will be serialized as the string "@None" in TOML.
    // If `none_value` is `None`, Python `None` values in dictionaries are skipped by default.
  10. Handle TOML parsing and serialization errors

    main

    When working with rtoml, errors during the conversion process will raise specific Python exceptions:

    • TomlParsingError: Raised when the input TOML string is malformed or cannot be parsed.
    • TomlSerializationError: Raised when a Python object cannot be converted into a valid TOML representation.
    import rtoml
    
    try:
        data = rtoml.deserialize("invalid = [unclosed bracket")
    except rtoml.TomlParsingError as e:
        print(f"Parsing failed: {e}")
    
    try:
        # Attempting to serialize something incompatible with TOML
        rtoml.serialize({"set": {1, 2, 3}})
    except rtoml.TomlSerializationError as e:
        print(f"Serialization failed: {e}")
  11. TzInfo class for UTC offsets

    main

    The TzInfo class is used internally and exposed via the rtoml._rtoml module to represent UTC offsets for timezone-aware datetime objects. It implements standard Python datetime interface methods.

    Methods:

    • seconds(): Returns the total offset in seconds.
    • utcoffset(dt): Returns a datetime.timedelta representing the offset.
    • tzname(dt): Returns the timezone name as a string (e.g., "UTC" or "UTC+05:30").
    • dst(dt): Returns None (Daylight Saving Time is not supported/calculated).
    • __str__(): Returns the string representation of the offset (e.g., "UTC+01:00").
    # Note: TzInfo is part of the rtoml._rtoml module
    # It is primarily used as the tzinfo for datetime objects parsed from TOML.