or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/pypi-hjson

Hjson, a user interface for JSON - human-friendly JSON configuration file format with comments, unquoted keys, and multiline strings

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/hjson@3.1.x

To install, run

npx @tessl/cli install tessl/pypi-hjson@3.1.0

index.mddocs/

Hjson

Hjson (Human JSON) is a user interface for JSON that makes configuration files more readable and maintainable. It extends JSON with comments, unquoted keys, optional commas, multiline strings, and other human-friendly features while maintaining full JSON compatibility. The library provides both Hjson parsing/generation and standard JSON encoding/decoding capabilities with an API that mirrors Python's built-in json module.

Package Information

  • Package Name: hjson
  • Language: Python
  • Installation: pip install hjson
  • Version: 3.1.0
  • License: MIT

Core Imports

import hjson

Direct imports for common functionality:

from hjson import loads, dumps, load, dump
from hjson import dumpsJSON, dumpJSON
from hjson import HjsonDecoder, HjsonEncoder, JSONEncoder
from hjson import HjsonDecodeError, OrderedDict

Basic Usage

import hjson

# Parse Hjson string with human-friendly syntax
hjson_text = """{
  // This is a comment
  name: John Doe
  age: 30
  'quoted key': value with spaces
  multiline: '''
    This is a
    multiline string
  '''
}"""

# Parse to Python object
data = hjson.loads(hjson_text)
print(data)  # OrderedDict([('name', 'John Doe'), ('age', 30), ...])

# Convert Python object to Hjson string
hjson_output = hjson.dumps(data)
print(hjson_output)

# Convert to standard JSON
json_output = hjson.dumpsJSON(data)
print(json_output)  # Standard JSON format

Architecture

Hjson provides dual encoding/decoding capabilities:

  • Hjson Format: Human-readable format with comments, unquoted keys, trailing commas, and multiline strings
  • JSON Format: Standard JSON with performance optimizations and compatibility with Python's json module
  • Flexible Parsing: Extensive customization options for object hooks, number parsing, and encoding settings
  • OrderedDict Support: Preserves key ordering by default using OrderedDict
  • CLI Tool: Command-line interface for converting between formats

Capabilities

Hjson Parsing

Parse Hjson format strings and files into Python objects with support for comments, unquoted keys, and human-friendly syntax.

def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None,
          parse_int=None, object_pairs_hook=None, use_decimal=False, **kw):
    """
    Deserialize Hjson string to Python object.
    
    Parameters:
    - s: str or bytes, Hjson document to parse
    - encoding: str, character encoding (default: 'utf-8')
    - cls: HjsonDecoder subclass for custom decoding
    - object_hook: callable, called with result of every JSON object decoded
    - parse_float: callable, used for parsing JSON floats
    - parse_int: callable, used for parsing JSON integers
    - object_pairs_hook: callable, called with ordered list of pairs
    - use_decimal: bool, use decimal.Decimal for floats (default: False)
    
    Returns:
    Parsed Python object (typically OrderedDict)
    """

def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None,
         parse_int=None, object_pairs_hook=OrderedDict, use_decimal=False,
         namedtuple_as_object=True, tuple_as_array=True, **kw):
    """
    Deserialize Hjson from file-like object to Python object.
    
    Parameters:
    - fp: file-like object with .read() method containing Hjson document
    - encoding: str, character encoding (default: 'utf-8')
    - cls: HjsonDecoder subclass for custom decoding
    - object_hook: callable, called with result of every JSON object decoded
    - parse_float: callable, used for parsing JSON floats
    - parse_int: callable, used for parsing JSON integers
    - object_pairs_hook: callable, called with ordered list of pairs (default: OrderedDict)
    - use_decimal: bool, use decimal.Decimal for floats (default: False)
    - namedtuple_as_object: bool, encode namedtuples as objects (default: True)
    - tuple_as_array: bool, encode tuples as arrays (default: True)
    
    Returns:
    Parsed Python object
    """

Hjson Encoding

Convert Python objects to human-readable Hjson format with customizable formatting options.

def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
          cls=None, indent=None, encoding='utf-8', default=None,
          use_decimal=True, namedtuple_as_object=True, tuple_as_array=True,
          bigint_as_string=False, sort_keys=False, item_sort_key=None,
          for_json=False, int_as_string_bitcount=None, **kw):
    """
    Serialize Python object to Hjson formatted string.
    
    Parameters:
    - obj: Python object to serialize
    - skipkeys: bool, skip non-basic dict keys (default: False)
    - ensure_ascii: bool, escape non-ASCII characters (default: True)
    - check_circular: bool, check for circular references (default: True)
    - cls: HjsonEncoder subclass for custom encoding
    - indent: int or str, indentation for pretty-printing (default: 2 spaces)
    - encoding: str, character encoding (default: 'utf-8')
    - default: callable, called for objects not serializable by default
    - use_decimal: bool, natively serialize Decimal (default: True)
    - namedtuple_as_object: bool, encode namedtuples as objects (default: True)
    - tuple_as_array: bool, encode tuples as arrays (default: True)
    - bigint_as_string: bool, encode large ints as strings (default: False)
    - sort_keys: bool, sort dictionary output by key (default: False)
    - item_sort_key: callable, custom key sorting function
    - for_json: bool, use for_json() method if available (default: False)
    - int_as_string_bitcount: int, bit threshold for string encoding
    
    Returns:
    Hjson formatted string
    """

def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
         cls=None, indent=None, encoding='utf-8', default=None,
         use_decimal=True, namedtuple_as_object=True, tuple_as_array=True,
         bigint_as_string=False, sort_keys=False, item_sort_key=None,
         for_json=False, int_as_string_bitcount=None, **kw):
    """
    Serialize Python object to Hjson formatted stream.
    
    Parameters:
    - obj: Python object to serialize
    - fp: file-like object with .write() method
    - skipkeys: bool, skip non-basic dict keys (default: False)
    - ensure_ascii: bool, escape non-ASCII characters (default: True)
    - check_circular: bool, check for circular references (default: True)
    - cls: HjsonEncoder subclass for custom encoding
    - indent: int or str, indentation for pretty-printing (default: 2 spaces)
    - encoding: str, character encoding (default: 'utf-8')
    - default: callable, called for objects not serializable by default
    - use_decimal: bool, natively serialize Decimal (default: True)
    - namedtuple_as_object: bool, encode namedtuples as objects (default: True)
    - tuple_as_array: bool, encode tuples as arrays (default: True)
    - bigint_as_string: bool, encode large ints as strings (default: False)
    - sort_keys: bool, sort dictionary output by key (default: False)
    - item_sort_key: callable, custom key sorting function
    - for_json: bool, use for_json() method if available (default: False)
    - int_as_string_bitcount: int, bit threshold for string encoding
    
    Returns:
    None (writes to file-like object)
    """

JSON Encoding

Convert Python objects to standard JSON format with performance optimizations and compatibility with Python's json module.

def dumpsJSON(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
              cls=None, indent=None, separators=None, encoding='utf-8',
              default=None, use_decimal=True, namedtuple_as_object=True,
              tuple_as_array=True, bigint_as_string=False, sort_keys=False,
              item_sort_key=None, for_json=False, int_as_string_bitcount=None, **kw):
    """
    Serialize Python object to JSON formatted string.
    
    Parameters:
    - obj: Python object to serialize
    - skipkeys: bool, skip non-basic dict keys (default: False)
    - ensure_ascii: bool, escape non-ASCII characters (default: True)
    - check_circular: bool, check for circular references (default: True)
    - cls: JSONEncoder subclass for custom encoding
    - indent: int or str, indentation for pretty-printing
    - separators: tuple, (item_separator, key_separator) for formatting
    - encoding: str, character encoding (default: 'utf-8')
    - default: callable, called for objects not serializable by default
    - use_decimal: bool, natively serialize Decimal (default: True)
    - namedtuple_as_object: bool, encode namedtuples as objects (default: True)
    - tuple_as_array: bool, encode tuples as arrays (default: True)
    - bigint_as_string: bool, encode large ints as strings (default: False)
    - sort_keys: bool, sort dictionary output by key (default: False)
    - item_sort_key: callable, custom key sorting function
    - for_json: bool, use for_json() method if available (default: False)
    - int_as_string_bitcount: int, bit threshold for string encoding
    
    Returns:
    JSON formatted string
    """

def dumpJSON(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
             cls=None, indent=None, separators=None, encoding='utf-8',
             default=None, use_decimal=True, namedtuple_as_object=True,
             tuple_as_array=True, bigint_as_string=False, sort_keys=False,
             item_sort_key=None, for_json=False, int_as_string_bitcount=None, **kw):
    """
    Serialize Python object to JSON formatted stream.
    
    Parameters:
    - obj: Python object to serialize
    - fp: file-like object with .write() method
    - skipkeys: bool, skip non-basic dict keys (default: False)
    - ensure_ascii: bool, escape non-ASCII characters (default: True)
    - check_circular: bool, check for circular references (default: True)
    - cls: JSONEncoder subclass for custom encoding
    - indent: int or str, indentation for pretty-printing
    - separators: tuple, (item_separator, key_separator) for formatting
    - encoding: str, character encoding (default: 'utf-8')
    - default: callable, called for objects not serializable by default
    - use_decimal: bool, natively serialize Decimal (default: True)
    - namedtuple_as_object: bool, encode namedtuples as objects (default: True)
    - tuple_as_array: bool, encode tuples as arrays (default: True)
    - bigint_as_string: bool, encode large ints as strings (default: False)
    - sort_keys: bool, sort dictionary output by key (default: False)
    - item_sort_key: callable, custom key sorting function
    - for_json: bool, use for_json() method if available (default: False)
    - int_as_string_bitcount: int, bit threshold for string encoding
    
    Returns:
    None (writes to file-like object)
    """

Custom Encoding and Decoding

Advanced classes for custom serialization and deserialization behavior.

class HjsonDecoder(object):
    """
    Hjson decoder with customizable parsing behavior.
    """
    def __init__(self, encoding=None, object_hook=None, object_pairs_hook=None,
                 parse_float=None, parse_int=None, strict=True, use_decimal=False):
        """
        Initialize Hjson decoder.
        
        Parameters:
        - encoding: str, character encoding
        - object_hook: callable, called with every decoded object
        - object_pairs_hook: callable, called with ordered pairs
        - parse_float: callable, custom float parsing
        - parse_int: callable, custom int parsing
        - strict: bool, strict parsing mode
        - use_decimal: bool, use Decimal for floats
        """
        
    def decode(self, s, _w=None):
        """
        Decode Hjson string to Python object.
        
        Parameters:
        - s: str, Hjson string to decode
        
        Returns:
        Decoded Python object
        """
        
    def raw_decode(self, s, idx=0):
        """
        Decode Hjson from string starting at given index.
        
        Parameters:
        - s: str, Hjson string
        - idx: int, starting index
        
        Returns:
        tuple: (decoded_object, end_index)
        """

class HjsonEncoder(object):
    """
    Hjson encoder with customizable formatting behavior.
    """
    def __init__(self, skipkeys=False, ensure_ascii=True, check_circular=True,
                 indent=None, encoding='utf-8', default=None, use_decimal=True,
                 namedtuple_as_object=True, tuple_as_array=True,
                 bigint_as_string=False, sort_keys=False, item_sort_key=None,
                 for_json=False, int_as_string_bitcount=None):
        """
        Initialize Hjson encoder.
        
        Parameters:
        - skipkeys: bool, skip non-basic dict keys
        - ensure_ascii: bool, escape non-ASCII characters
        - check_circular: bool, check for circular references
        - indent: int or str, indentation for pretty-printing
        - encoding: str, character encoding
        - default: callable, fallback for non-serializable objects
        - use_decimal: bool, natively serialize Decimal
        - namedtuple_as_object: bool, encode namedtuples as objects
        - tuple_as_array: bool, encode tuples as arrays
        - bigint_as_string: bool, encode large ints as strings
        - sort_keys: bool, sort dictionary keys
        - item_sort_key: callable, custom key sorting function
        - for_json: bool, use for_json() method if available
        - int_as_string_bitcount: int, bit threshold for string encoding
        """
        
    def default(self, o):
        """
        Override to implement custom encoding for objects.
        
        Parameters:
        - o: object to encode
        
        Returns:
        Serializable representation of object
        
        Raises:
        TypeError: if object is not serializable
        """
        
    def encode(self, o):
        """
        Encode Python object to Hjson string.
        
        Parameters:
        - o: object to encode
        
        Returns:
        Hjson formatted string
        """
        
    def iterencode(self, o, _one_shot=False):
        """
        Encode Python object as iterator of string chunks.
        
        Parameters:
        - o: object to encode
        - _one_shot: bool, internal optimization flag
        
        Yields:
        str: chunks of encoded Hjson
        """

class JSONEncoder(object):
    """
    JSON encoder compatible with Python's json module.
    """
    def __init__(self, skipkeys=False, ensure_ascii=True, check_circular=True,
                 indent=None, separators=None, encoding='utf-8', default=None,
                 use_decimal=True, namedtuple_as_object=True, tuple_as_array=True,
                 bigint_as_string=False, sort_keys=False, item_sort_key=None,
                 for_json=False, int_as_string_bitcount=None):
        """
        Initialize JSON encoder.
        
        Parameters:
        - skipkeys: bool, skip non-basic dict keys
        - ensure_ascii: bool, escape non-ASCII characters
        - check_circular: bool, check for circular references
        - indent: int or str, indentation for pretty-printing
        - separators: tuple, (item_separator, key_separator)
        - encoding: str, character encoding
        - default: callable, fallback for non-serializable objects
        - use_decimal: bool, natively serialize Decimal
        - namedtuple_as_object: bool, encode namedtuples as objects
        - tuple_as_array: bool, encode tuples as arrays
        - bigint_as_string: bool, encode large ints as strings
        - sort_keys: bool, sort dictionary keys
        - item_sort_key: callable, custom key sorting function
        - for_json: bool, use for_json() method if available
        - int_as_string_bitcount: int, bit threshold for string encoding
        """
        
    def default(self, o):
        """
        Override to implement custom encoding for objects.
        
        Parameters:
        - o: object to encode
        
        Returns:
        Serializable representation of object
        
        Raises:
        TypeError: if object is not serializable
        """
        
    def encode(self, o):
        """
        Encode Python object to JSON string.
        
        Parameters:
        - o: object to encode
        
        Returns:
        JSON formatted string
        """
        
    def iterencode(self, o, _one_shot=False):
        """
        Encode Python object as iterator of string chunks.
        
        Parameters:
        - o: object to encode
        - _one_shot: bool, internal optimization flag
        
        Yields:
        str: chunks of encoded JSON
        """

Utility Functions and Classes

Helper functions and data structures for enhanced functionality.

def simple_first(kv):
    """
    Helper function for item_sort_key to sort simple elements first.
    
    Sorts simple data types (strings, numbers, booleans, None) before
    container types (lists, dicts, tuples) in dictionary output.
    
    Parameters:
    - kv: tuple, (key, value) pair from dictionary
    
    Returns:
    tuple: sort key tuple for ordering
    """

class OrderedDict(dict):
    """
    Dictionary that preserves insertion order of keys.
    
    Used as default object_pairs_hook to maintain key ordering
    when parsing Hjson/JSON documents. Provides full dict interface
    with ordering preservation.
    """
    def __init__(self, *args, **kwargs):
        """Initialize ordered dictionary."""
        
    # Standard dict methods with ordering preservation
    def __setitem__(self, key, value): ...
    def __delitem__(self, key): ...
    def __iter__(self): ...
    def keys(self): ...
    def values(self): ...
    def items(self): ...
    def popitem(self, last=True): ...
    def move_to_end(self, key, last=True): ...

class HjsonDecodeError(ValueError):
    """
    Exception raised when Hjson decoding fails.
    
    Provides detailed error information including position
    and context for debugging malformed Hjson documents.
    """
    def __init__(self, msg, doc, pos):
        """
        Initialize decode error.
        
        Parameters:
        - msg: str, error message
        - doc: str, source document
        - pos: int, character position of error
        """
        
    @property
    def lineno(self):
        """int: Line number where error occurred."""
        
    @property  
    def colno(self):
        """int: Column number where error occurred."""
        
    @property
    def msg(self):
        """str: Error message."""
        
    @property
    def doc(self):
        """str: Source document."""
        
    @property
    def pos(self):
        """int: Character position of error."""

Command Line Interface

Hjson includes a command-line tool for converting between Hjson and JSON formats.

Installation and Usage

After installing the package with pip install hjson, the hjson command becomes available:

# Convert Hjson to formatted Hjson (default)
echo '{name: value}' | hjson

# Convert to formatted JSON
echo '{name: value}' | hjson -j

# Convert to compact JSON
echo '{name: value}' | hjson -c

# Process files
hjson input.hjson
hjson -j input.hjson > output.json

# Show help
hjson --help

# Show version
hjson --version

CLI Options

  • Default: Output as formatted Hjson
  • -j: Output as formatted JSON with indentation
  • -c: Output as compact JSON without extra whitespace
  • -h, --help: Show help message
  • -V, --version: Show version information

Advanced Usage Examples

Custom Object Hooks

import hjson
from decimal import Decimal

# Custom parsing with Decimal for high precision
def decimal_hook(pairs):
    result = {}
    for key, value in pairs:
        if isinstance(value, float):
            result[key] = Decimal(str(value))
        else:
            result[key] = value
    return result

data = hjson.loads('{"price": 19.99}', object_pairs_hook=decimal_hook)
print(type(data['price']))  # <class 'decimal.Decimal'>

Custom Encoding

import hjson
from datetime import datetime

class DateTimeEncoder(hjson.HjsonEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.isoformat()
        return super().default(obj)

data = {'timestamp': datetime.now(), 'value': 42}
result = hjson.dumps(data, cls=DateTimeEncoder)
print(result)

Preserving Key Order

import hjson

# OrderedDict is used by default for object_pairs_hook
hjson_text = """{
  z: last
  a: first
  m: middle
}"""

data = hjson.loads(hjson_text)
print(list(data.keys()))  # ['z', 'a', 'm'] - preserves original order

Error Handling

import hjson

try:
    # Invalid Hjson syntax
    data = hjson.loads('{invalid syntax}')
except hjson.HjsonDecodeError as e:
    print(f"Parse error at line {e.lineno}, column {e.colno}: {e.msg}")
    print(f"Position {e.pos} in document")

Configuration Management Example

import hjson
import os

def load_config(config_path):
    """Load configuration from Hjson file with environment variable support."""
    with open(config_path, 'r') as f:
        config_text = f.read()
    
    # Parse Hjson configuration
    config = hjson.load(f)
    
    # Override with environment variables
    if 'DATABASE_URL' in os.environ:
        config['database']['url'] = os.environ['DATABASE_URL']
    
    return config

# config.hjson:
# {
#   // Database configuration
#   database: {
#     url: localhost:5432
#     pool_size: 10
#   }
#   // Feature flags
#   features: {
#     caching: true
#     analytics: false
#   }
# }

config = load_config('config.hjson')
print(hjson.dumps(config, indent=2))