Source code

Revision control

Copy as Markdown

Other Tools

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at
# This file contains utility functions for reading .properties files
import codecs
import re
import sys
import six
if sys.version_info[0] == 3:
str_type = str
str_type = basestring
class DotProperties:
r"""A thin representation of a key=value .properties file."""
def __init__(self, file=None):
self._properties = {}
if file:
def update(self, file):
"""Updates properties from a file name or file-like object.
Ignores empty lines and comment lines."""
if isinstance(file, str_type):
f =, "r", "utf-8")
f = file
for l in f.readlines():
line = l.strip()
if not line or line.startswith("#"):
(k, v) = re.split("\s*=\s*", line, 1)
self._properties[k] = v
def get(self, key, default=None):
return self._properties.get(key, default)
def get_list(self, prefix):
"""Turns {'list.0':'foo', 'list.1':'bar'} into ['foo', 'bar'].
Returns [] to indicate an empty or missing list."""
if not prefix.endswith("."):
prefix = prefix + "."
indexes = []
for k, v in six.iteritems(self._properties):
if not k.startswith(prefix):
key = k[len(prefix) :]
if "." in key:
# We have something like list.sublist.0.
return [self._properties[prefix + str(index)] for index in sorted(indexes)]
def get_dict(self, prefix, required_keys=[]):
"""Turns {'foo.title':'title', ...} into {'title':'title', ...}.
If ``|required_keys|`` is present, it must be an iterable of required key
names. If a required key is not present, ValueError is thrown.
Returns {} to indicate an empty or missing dict."""
if not prefix.endswith("."):
prefix = prefix + "."
D = dict(
(k[len(prefix) :], v)
for k, v in six.iteritems(self._properties)
if k.startswith(prefix) and "." not in k[len(prefix) :]
for required_key in required_keys:
if required_key not in D:
raise ValueError("Required key %s not present" % required_key)
return D