Bug 1692430, black & flake8, pyupgrade, and automation (#5)

* Drop mocked OrderedDict
* Black & flake8
* pyupgrade
* Black & flake8 setup.py
* Add automated testing and linting
This commit is contained in:
Axel Hecht 2021-03-02 21:56:09 +01:00 коммит произвёл GitHub
Родитель e0edd053d3
Коммит 78d8ac042a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
36 изменённых файлов: 1024 добавлений и 1028 удалений

52
.github/workflows/python.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,52 @@
name: Python
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.7, 3.8, 3.9]
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install tox
- name: Test
run: |
tox
flake8:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.9
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install flake8==3.8.4
- name: Lint with flake8
run: |
flake8 .
black:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: psf/black@stable

Просмотреть файл

@ -1,31 +1,24 @@
VERSION = (0, 11, 0, '', 0) VERSION = (0, 11, 0, "", 0)
short_names = { short_names = {"alpha": "a", "beta": "b", "pre": "pre", "final": "", "rc": "rc"}
'alpha': 'a',
'beta': 'b',
'pre': 'pre',
'final': '',
'rc': 'rc'
}
def get_short_version(): def get_short_version():
version = '%s.%s' % (VERSION[0], VERSION[1]) version = "{}.{}".format(VERSION[0], VERSION[1])
if VERSION[2]: if VERSION[2]:
version = '%s.%s' % (version, VERSION[2]) version = "{}.{}".format(version, VERSION[2])
version = '%s%s' % (version, version = "{}{}".format(version, short_names.get(VERSION[3], VERSION[3]))
short_names.get(VERSION[3], VERSION[3])) if VERSION[3] not in ("pre", "final") and VERSION[4]:
if VERSION[3] not in ('pre', 'final') and VERSION[4]: version = "{}{}".format(version, VERSION[4])
version = '%s%s' % (version, VERSION[4])
return version return version
def get_version(): def get_version():
version = '%s.%s' % (VERSION[0], VERSION[1]) version = "{}.{}".format(VERSION[0], VERSION[1])
if VERSION[2]: if VERSION[2]:
version = '%s.%s' % (version, VERSION[2]) version = "{}.{}".format(version, VERSION[2])
if VERSION[3]: if VERSION[3]:
version = '%s %s' % (version, VERSION[3]) version = "{} {}".format(version, VERSION[3])
if VERSION[3] not in ('pre', 'final') and VERSION[4]: if VERSION[3] not in ("pre", "final") and VERSION[4]:
version = '%s %s' % (version, VERSION[4]) version = "{} {}".format(version, VERSION[4])
return version return version

Просмотреть файл

@ -3,4 +3,4 @@ from .list import EntityList
from .structure import Blob, Structure, Comment from .structure import Blob, Structure, Comment
from .package import Package from .package import Package
__all__ = ['Blob', 'Entity', 'EntityList', 'Structure', 'Comment', 'Package'] __all__ = ["Blob", "Entity", "EntityList", "Structure", "Comment", "Package"]

Просмотреть файл

@ -10,27 +10,16 @@ by subclasses of Entity class, and possibly one of the Value classes.
By default silme.core.Value returns one of its more specific subclasses. By default silme.core.Value returns one of its more specific subclasses.
""" """
import copy import copy
from silme.core.types.odict import OrderedDict from collections import OrderedDict
__all__ = ['is_string', 'string', 'is_entity', 'Entity'] __all__ = ["is_string", "is_entity", "Entity"]
try:
basestring
string = unicode
def is_string(v): def is_string(v):
""" """
Tests if the argument is a string Tests if the argument is a string
""" """
return isinstance(v, basestring) return isinstance(v, str)
except:
string = str
def is_string(v):
"""
Tests if the argument is a string
"""
return isinstance(v, str)
def is_entity(v): def is_entity(v):
@ -40,9 +29,9 @@ def is_entity(v):
return isinstance(v, Entity) return isinstance(v, Entity)
class Value(object): class Value:
def __new__(cls, *args, **kwargs): def __new__(cls, *args, **kwargs):
#if cls is not Value: # if cls is not Value:
# return object.__new__(cls) # return object.__new__(cls)
try: try:
i = args[0] i = args[0]
@ -60,24 +49,26 @@ class Value(object):
return ComplexValue(*args, **kwargs) return ComplexValue(*args, **kwargs)
class SimpleValue(string, Value): class SimpleValue(str, Value):
""" """
A simple, string based value for an entity A simple, string based value for an entity
""" """
def get(self, *args, **kwargs): def get(self, *args, **kwargs):
return self return self
def __setitem__(self, key, value): def __setitem__(self, key, value):
raise TypeError("'%s' object does not support item assignment" % raise TypeError(
type(self).__name__) "'%s' object does not support item assignment" % type(self).__name__
)
def __getitem__(self, key): def __getitem__(self, key):
raise TypeError("'%s' object is unsubscriptable" % raise TypeError("'%s' object is unsubscriptable" % type(self).__name__)
type(self).__name__)
def __delitem__(self, key): def __delitem__(self, key):
raise TypeError("'%s' object does not support item deletion" % raise TypeError(
type(self).__name__) "'%s' object does not support item deletion" % type(self).__name__
)
class ComplexValue(Value): class ComplexValue(Value):
@ -103,6 +94,7 @@ class ComplexValue(Value):
else: else:
return val return val
class ListValue(list, ComplexValue): class ListValue(list, ComplexValue):
""" """
A value that is a list of values A value that is a list of values
@ -116,19 +108,21 @@ class DictValue(OrderedDict, ComplexValue):
""" """
A value that is a dictionary of values A value that is a dictionary of values
""" """
def get(self, key=None, *args, **kwargs): def get(self, key=None, *args, **kwargs):
if key is not None: if key is not None:
return self[key] return self[key]
return list(self.values())[0] return list(self.values())[0]
class Entity(object): class Entity:
""" """
An entity is a basic localization data unit with a unique id and a value An entity is a basic localization data unit with a unique id and a value
An ID represents a handler which a developer uses to call for the given An ID represents a handler which a developer uses to call for the given
entity and a value is any sort of localizable data bound to that id. entity and a value is any sort of localizable data bound to that id.
""" """
_select_value = None _select_value = None
def __init__(self, id, value=None): def __init__(self, id, value=None):
@ -181,4 +175,3 @@ class Entity(object):
@property @property
def values(self): def values(self):
return copy.copy(self._value) return copy.copy(self._value)

Просмотреть файл

@ -22,11 +22,12 @@ class EntityList(ComplexDict):
""" """
EntityList is a list of entities bundled together. EntityList is a list of entities bundled together.
""" """
uri = None uri = None
def __init__(self, id, *args, **kwargs): def __init__(self, id, *args, **kwargs):
self.id = id self.id = id
super(EntityList, self).__init__() super().__init__()
for i in args: for i in args:
if is_entitylist(i): if is_entitylist(i):
for entity in i.entities(): for entity in i.entities():
@ -36,8 +37,8 @@ class EntityList(ComplexDict):
def __repr__(self): def __repr__(self):
if not self: if not self:
return '%s()' % (self.__class__.__name__,) return f"{self.__class__.__name__}()"
return '%s(%r)' % (self.__class__.__name__, tuple(self.keys())) return "{}({!r})".format(self.__class__.__name__, tuple(self.keys()))
def add(self, entity): def add(self, entity):
"""Adds new entity to EntityList""" """Adds new entity to EntityList"""
@ -54,8 +55,7 @@ class EntityList(ComplexDict):
return list(self.values()) return list(self.values())
def value(self, id): def value(self, id):
"""Returns entity value from EntityList. """Returns entity value from EntityList."""
"""
return self[id].value return self[id].value
@ -64,8 +64,9 @@ class ValueList(EntityList):
ValueList is a list of entity values - similar to EntityList but with an ValueList is a list of entity values - similar to EntityList but with an
intention to store only the values of entities. intention to store only the values of entities.
""" """
def __init__(self, id, *args, **kwargs): def __init__(self, id, *args, **kwargs):
super(ValueList, self).__init__(id, *args, **kwargs) super().__init__(id, *args, **kwargs)
def add(self, entity): def add(self, entity):
"""Adds new entity to the ValueList""" """Adds new entity to the ValueList"""
@ -79,8 +80,9 @@ class ValueList(EntityList):
def entities(self): def entities(self):
"""Raises a TypeError since ValueList does not support this method""" """Raises a TypeError since ValueList does not support this method"""
raise TypeError("'%s' object does not support entities method" % raise TypeError(
type(self).__name__) "'%s' object does not support entities method" % type(self).__name__
)
def value(self, id): def value(self, id):
"""Returns entity value from the ValueList """Returns entity value from the ValueList

Просмотреть файл

@ -2,11 +2,12 @@ from silme.core.list import is_entitylist
from silme.core.structure import Blob, Structure from silme.core.structure import Blob, Structure
from silme.core.types import LazyDict from silme.core.types import LazyDict
class Package(object):
class Package:
""" """
Package is a container that stores Package is a container that stores
set of data structures (Structures, EntityLists, Blobs) and sub-packages. set of data structures (Structures, EntityLists, Blobs) and sub-packages.
It's easiest to think of it as a filesystem directory that It's easiest to think of it as a filesystem directory that
can store files and nested directories. can store files and nested directories.
It abstracts the package from the file system, so once you load It abstracts the package from the file system, so once you load
@ -16,6 +17,7 @@ class Package(object):
If you load a directory into memory and then serialize it back to disk, If you load a directory into memory and then serialize it back to disk,
the two directories should be identical minus any modifications you made. the two directories should be identical minus any modifications you made.
""" """
uri = None uri = None
def __init__(self, id, lazy=True): def __init__(self, id, lazy=True):
@ -25,17 +27,15 @@ class Package(object):
self.id = id self.id = id
def __len__(self): def __len__(self):
return len(self._packages)+len(self._structures) return len(self._packages) + len(self._structures)
def __iter__(self): def __iter__(self):
for i in self._packages.items(): yield from self._packages.items()
yield i yield from self._structures.items()
for i in self._structures.items():
yield i
raise StopIteration raise StopIteration
def __repr__(self): def __repr__(self):
return '%s(%s)' % (self.__class__.__name__, self.id) return f"{self.__class__.__name__}({self.id})"
def __contains__(self, id): def __contains__(self, id):
if id in self._packages.keys(): if id in self._packages.keys():
@ -73,10 +73,10 @@ class Package(object):
def add_structure(self, struct, path=None): def add_structure(self, struct, path=None):
""" """
Adds a structure to the Package. Adds a structure to the Package.
Optional parameter path allows to define exact position Optional parameter path allows to define exact position
inside the package where the structure should be added. inside the package where the structure should be added.
For example l10npack.add_structure(l10nstruct, 'pkg1/pkg2') is equal to For example l10npack.add_structure(l10nstruct, 'pkg1/pkg2') is equal to
l10npack.get_package('pkg1').get_package('pkg2').add_structure(l10nstruct) l10npack.get_package('pkg1').get_package('pkg2').add_structure(l10nstruct)
with the difference that it will create missing sub packages if needed. with the difference that it will create missing sub packages if needed.
@ -84,22 +84,21 @@ class Package(object):
if not path: if not path:
self._structures[struct.id] = struct self._structures[struct.id] = struct
else: else:
path = path.split('/') path = path.split("/")
if path[0] in self._packages: if path[0] in self._packages:
self._packages[path[0]].add_structure(struct, self._packages[path[0]].add_structure(struct, "/".join(path[1:]))
'/'.join(path[1:]))
else: else:
sub_l10n_pack = Package(path[0]) sub_l10n_pack = Package(path[0])
self.add_package(sub_l10n_pack) self.add_package(sub_l10n_pack)
sub_l10n_pack.add_structure(struct, '/'.join(path[1:])) sub_l10n_pack.add_structure(struct, "/".join(path[1:]))
def add_package(self, package, path=None): def add_package(self, package, path=None):
""" """
Adds a package to Package. Adds a package to Package.
Optional parameter path allows to declare place Optional parameter path allows to declare place
inside the package where the subpackage should be added. inside the package where the subpackage should be added.
For example l10npack.add_package(subl10npack, 'pkg1/pkg2') is similar to For example l10npack.add_package(subl10npack, 'pkg1/pkg2') is similar to
l10npack.get_package('pkg1').get_package('pkg2').add_package(subl10npack) l10npack.get_package('pkg1').get_package('pkg2').add_package(subl10npack)
with the difference that it will create missing sub packages. with the difference that it will create missing sub packages.
@ -107,14 +106,13 @@ class Package(object):
if not path: if not path:
self._packages[package.id] = package self._packages[package.id] = package
else: else:
path = path.split('/') path = path.split("/")
if path[0] in self._packages: if path[0] in self._packages:
self._packages[path[0]].add_package(package, self._packages[path[0]].add_package(package, "/".join(path[1:]))
'/'.join(path[1:]))
else: else:
sub_l10n_pack = Package(path[0]) sub_l10n_pack = Package(path[0])
self._packages[path[0]] = sub_l10n_pack self._packages[path[0]] = sub_l10n_pack
sub_l10n_pack.add_package(package, '/'.join(path[1:])) sub_l10n_pack.add_package(package, "/".join(path[1:]))
def packages(self, ids=False): def packages(self, ids=False):
""" """
@ -127,28 +125,28 @@ class Package(object):
else: else:
return list(self._packages.values()) return list(self._packages.values())
def structures(self, type='all', ids=False): def structures(self, type="all", ids=False):
""" """
Returns a list of structures inside Package. Returns a list of structures inside Package.
If parameter ids is set to True list of If parameter ids is set to True list of
names is returned instead of structures. names is returned instead of structures.
""" """
if type == 'all': if type == "all":
if ids: if ids:
return list(self._structures.keys()) return list(self._structures.keys())
else: else:
return list(self._structures.values()) return list(self._structures.values())
else: else:
l10n_structures = {} l10n_structures = {}
if type == 'list': if type == "list":
type = is_entitylist type = is_entitylist
elif type == 'structure': elif type == "structure":
type = lambda x:isinstance(x, Structure) type = lambda x: isinstance(x, Structure)
elif type == 'blob': elif type == "blob":
type = lambda x:isinstance(x, Blob) type = lambda x: isinstance(x, Blob)
for struct in self._structures: for struct in self._structures:
if type(self._structures[struct]): if type(self._structures[struct]):
l10n_structures[struct] = self._structures[struct] l10n_structures[struct] = self._structures[struct]
if ids: if ids:
return list(l10n_structures.keys()) return list(l10n_structures.keys())
else: else:
@ -157,26 +155,27 @@ class Package(object):
def entities(self, recursive=True, path=False): def entities(self, recursive=True, path=False):
""" """
Returns a list of all entities inside the Package Returns a list of all entities inside the Package
If optional parameter recursive is set to True it will If optional parameter recursive is set to True it will
return all packages from this package and its subpackages. return all packages from this package and its subpackages.
""" """
entities = [] entities = []
if path is True: if path is True:
spath = '' spath = ""
elif path is not False: elif path is not False:
spath='%s/%s' % (path, self.id) if path else self.id spath = f"{path}/{self.id}" if path else self.id
else: else:
spath = path spath = path
if recursive: if recursive:
for pack in self._packages.values(): for pack in self._packages.values():
entities.extend(pack.entities(path=spath)) entities.extend(pack.entities(path=spath))
for i in self._structures: for i in self._structures:
if isinstance(self._structures[i], Structure) or is_entitylist(self._structures[i]): if isinstance(self._structures[i], Structure) or is_entitylist(
self._structures[i]
):
elist = self._structures[i].entities() elist = self._structures[i].entities()
spath2 = '%s/%s' % (spath, i) if spath else i spath2 = f"{spath}/{i}" if spath else i
entities.extend([(e, spath2) for e in elist]) entities.extend([(e, spath2) for e in elist])
return entities return entities
@ -190,32 +189,32 @@ class Package(object):
try: try:
return self._structures[id] return self._structures[id]
except KeyError: except KeyError:
raise KeyError('No such structure: %s' % id) raise KeyError("No such structure: %s" % id)
def package(self, id): def package(self, id):
try: try:
return self._packages[id] return self._packages[id]
except KeyError: except KeyError:
raise KeyError('No such package: %s' % id) raise KeyError("No such package: %s" % id)
def element(self, path): def element(self, path):
""" """
Returns an element from inside Package Returns an element from inside Package
by its path. by its path.
l10npack.element('pkg1/pkg2/structure.po') will return l10npack.element('pkg1/pkg2/structure.po') will return
the same as the same as
l10npack.package('pkg1').get_package('pkg2').structure('structure.po') l10npack.package('pkg1').get_package('pkg2').structure('structure.po')
If the path is empty the result will be None If the path is empty the result will be None
""" """
if not path: if not path:
return None return None
elems = path.split('/') elems = path.split("/")
if len(elems) == 0: if len(elems) == 0:
return None return None
if len(elems) == 2 and elems[1] == '': if len(elems) == 2 and elems[1] == "":
elems = elems[:-1] elems = elems[:-1]
if len(elems) == 1: if len(elems) == 1:
@ -230,13 +229,13 @@ class Package(object):
return None return None
else: else:
try: try:
return self._packages[elems[0]].element('/'.join(elems[1:])) return self._packages[elems[0]].element("/".join(elems[1:]))
except KeyError: except KeyError:
raise raise
def remove_structure(self, id): def remove_structure(self, id):
del self._structures[id] del self._structures[id]
def remove_package(self, id): def remove_package(self, id):
del self._packages[id] del self._packages[id]

Просмотреть файл

@ -21,7 +21,7 @@ from silme.core.list import EntityList
from functools import partial from functools import partial
class Blob(object): class Blob:
""" """
A Blob is a data stream that is not localizable, but may be A Blob is a data stream that is not localizable, but may be
a part of a package of structures. a part of a package of structures.
@ -32,6 +32,7 @@ class Blob(object):
The main use case for the class is to preserve the non-translatable The main use case for the class is to preserve the non-translatable
data in a in-memory representation of a package (a directory etc.) data in a in-memory representation of a package (a directory etc.)
""" """
uri = None uri = None
id = None id = None
source = None source = None
@ -40,7 +41,7 @@ class Blob(object):
self.id = id self.id = id
def __repr__(self): def __repr__(self):
return '%s(%s)' % (self.__class__.__name__, self.id) return f"{self.__class__.__name__}({self.id})"
class Structure(list, Blob): class Structure(list, Blob):
@ -53,6 +54,7 @@ class Structure(list, Blob):
edit it, and save it back preserving as much of the file structure as edit it, and save it back preserving as much of the file structure as
possible which in turn may be important for all VCS's based workflows. possible which in turn may be important for all VCS's based workflows.
""" """
_process_cb = None # process callback function _process_cb = None # process callback function
def __init__(self, id): def __init__(self, id):
@ -76,7 +78,7 @@ class Structure(list, Blob):
""" """
if type(pos) == tuple: if type(pos) == tuple:
p = self.entity_pos(pos[1]) p = self.entity_pos(pos[1])
return p + 1 if pos[0] == 'after' else p return p + 1 if pos[0] == "after" else p
elif pos is None: elif pos is None:
return None return None
else: else:
@ -110,9 +112,9 @@ class Structure(list, Blob):
return self.entity(id).value return self.entity(id).value
def keys(self): def keys(self):
"""returns a list of id's of entities from the Structure """returns a list of id's of entities from the Structure"""
"""
return [item.id for item in self if isinstance(item, Entity)] return [item.id for item in self if isinstance(item, Entity)]
ids = keys ids = keys
def entities(self): def entities(self):
@ -122,31 +124,27 @@ class Structure(list, Blob):
return [item for item in self if is_entity(item)] return [item for item in self if is_entity(item)]
def entitylist(self): def entitylist(self):
"""Returns an EntityList object with entities from the Structure. """Returns an EntityList object with entities from the Structure."""
""" return EntityList(self.id, *[item for item in self if is_entity(item)])
return EntityList(self.id,
*[item for item in self if is_entity(item)])
def entities_with_path(self, path_prefix): def entities_with_path(self, path_prefix):
"""Returns a dict of all entities from the Structure in a form of """Returns a dict of all entities from the Structure in a form of
d[entity.id] = (entity, path) d[entity.id] = (entity, path)
""" """
spath = '%s/%s' % (path_prefix, self.id) if path_prefix else self.id spath = f"{path_prefix}/{self.id}" if path_prefix else self.id
return dict([(item.id, return {item.id: (item, spath) for item in self if is_entity(item)}
(item, spath)) for item in self if is_entity(item)])
def __contains__(self, id): def __contains__(self, id):
"""returns True if an entity with given id exists """returns True if an entity with given id exists"""
"""
for item in self: for item in self:
if is_entity(item) and item.id == id: if is_entity(item) and item.id == id:
return True return True
return False return False
has_entity = __contains__ has_entity = __contains__
def modify_entity(self, id, value): def modify_entity(self, id, value):
"""modifies an entity value """modifies an entity value"""
"""
found = False found = False
for item in self: for item in self:
if is_entity(item) and item.id == id: if is_entity(item) and item.id == id:
@ -156,32 +154,29 @@ class Structure(list, Blob):
if found: if found:
return True return True
else: else:
raise KeyError('No such entity') raise KeyError("No such entity")
def entity(self, id): def entity(self, id):
"""returns an entity for a given id """returns an entity for a given id"""
"""
for item in self: for item in self:
if is_entity(item) and item.id == id: if is_entity(item) and item.id == id:
return item return item
raise KeyError('No such entity') raise KeyError("No such entity")
def entity_pos(self, id): def entity_pos(self, id):
"""returns the position of an entity in the Structure """returns the position of an entity in the Structure"""
"""
for i, item in enumerate(self): for i, item in enumerate(self):
if is_entity(item) and item.id == id: if is_entity(item) and item.id == id:
return i return i
raise KeyError('No such entity') raise KeyError("No such entity")
def remove_entity(self, id): def remove_entity(self, id):
"""removes an entity for the given id or raises KeyError """removes an entity for the given id or raises KeyError"""
"""
for i, item in enumerate(self): for i, item in enumerate(self):
if is_entity(item) and item.id == id: if is_entity(item) and item.id == id:
del self[i] del self[i]
return True return True
raise KeyError('[%s] No such entity: %s' % (self.id, id)) raise KeyError(f"[{self.id}] No such entity: {id}")
def add_comment(self, comment, pos=None): def add_comment(self, comment, pos=None):
self.add_at_pos(comment, pos) self.add_at_pos(comment, pos)
@ -208,9 +203,9 @@ class Structure(list, Blob):
elif item is None: elif item is None:
return 0 return 0
else: else:
raise Exception('Cannot add element of type "' + raise Exception(
type(item).__name__ + f'Cannot add element of type "{type(item).__name__}" to the Structure'
'" to the Structure') )
def add_elements(self, sequence, pos=None): def add_elements(self, sequence, pos=None):
""" """
@ -226,7 +221,7 @@ class Structure(list, Blob):
if isinstance(sequence, dict): if isinstance(sequence, dict):
sequence = sequence.values() sequence = sequence.values()
pos = self._get_pos(pos) pos = self._get_pos(pos)
#a=a[:2]+b+a[2:] ? # a=a[:2]+b+a[2:] ?
for i in sequence: for i in sequence:
shift += self.add(i, pos=(None if pos is None else pos + shift)) shift += self.add(i, pos=(None if pos is None else pos + shift))
return shift return shift
@ -244,7 +239,7 @@ class Structure(list, Blob):
return self._process_cb() return self._process_cb()
except TypeError: except TypeError:
raise Exception('process callback function not specified') raise Exception("process callback function not specified")
def set_process_cb(self, cb): def set_process_cb(self, cb):
self._process_cb = partial(cb, self) self._process_cb = partial(cb, self)
@ -263,13 +258,13 @@ class Comment(Structure):
self.id = None self.id = None
def __repr__(self): def __repr__(self):
string = '<comment: ' string = "<comment: "
for i in self: for i in self:
string += unicode(i) string += str(i)
string += '>' string += ">"
return string return string
def add(self, element, pos=None): def add(self, element, pos=None):
if isinstance(element, Comment): if isinstance(element, Comment):
raise Exception('Cannot add a comment to a comment') raise Exception("Cannot add a comment to a comment")
return Structure.add(self, element, pos) return Structure.add(self, element, pos)

Просмотреть файл

@ -1,3 +1,4 @@
from silme.core.types.odict import OrderedDict
from silme.core.types.lazydict import LazyDict from silme.core.types.lazydict import LazyDict
from silme.core.types.factory import ComplexDict from silme.core.types.factory import ComplexDict
__all__ = ["ComplexDict", "LazyDict"]

Просмотреть файл

@ -1,16 +1,18 @@
from silme.core.types.odict import OrderedDict from collections import OrderedDict
from silme.core.types import LazyDict as LazyDict from silme.core.types import LazyDict as LazyDict
from abc import ABCMeta from abc import ABCMeta
class FactoryMeta(type): class FactoryMeta(type):
def __new__(cls, *args, **kwargs): def __new__(cls, *args, **kwargs):
return cls return cls
_types = { _types = {
'ordered': [OrderedDict, 'Ordered', False], "ordered": [OrderedDict, "Ordered", False],
'lazy': [LazyDict, 'Lazy', False], "lazy": [LazyDict, "Lazy", False],
} }
class LazyDictMeta(ABCMeta, type): class LazyDictMeta(ABCMeta, type):
@ -25,15 +27,13 @@ class LazyDictMeta(ABCMeta, type):
classes.append(t[0]) classes.append(t[0])
name.append(t[1]) name.append(t[1])
attrs.append((key, r)) attrs.append((key, r))
t = type('%s%s' % (''.join(name), cls.__name__), t = type("{}{}".format("".join(name), cls.__name__), tuple(classes), {})
tuple(classes),
{})
cl = t.__new__(t, *args, **kwargs) cl = t.__new__(t, *args, **kwargs)
cl.__init__(*args, **kwargs) cl.__init__(*args, **kwargs)
for attr in attrs: for attr in attrs:
setattr(cl, attr[0], attr[1]) setattr(cl, attr[0], attr[1])
return cl return cl
# metaclass for py2 and py3
ComplexDict = LazyDictMeta('ComplexDict', (dict, ), {})
# metaclass for py2 and py3
ComplexDict = LazyDictMeta("ComplexDict", (dict,), {})

Просмотреть файл

@ -1,4 +1,4 @@
''' """
LazyDict is a subclass of a dict that can additionally store LazyDict is a subclass of a dict that can additionally store
items in a form of a stub that is expanded on the first call. items in a form of a stub that is expanded on the first call.
@ -15,21 +15,22 @@ Example:
d = LazyDict({'a': 1}) d = LazyDict({'a': 1})
d.set_stub('b', resolver, table='items') d.set_stub('b', resolver, table='items')
print(len(d)) # 2 print(len(d)) # 2
x = d['b'] # resolving x = d['b'] # resolving
x2 = d['b'] # x2 = d['b'] #
print(isinstance(x2, QueryValue) # True print(isinstance(x2, QueryValue) # True
''' """
from functools import partial from functools import partial
from collections.abc import MutableMapping, ItemsView, ValuesView from collections.abc import MutableMapping, ItemsView, ValuesView
import datetime
__all__ = ["LazyDict",] __all__ = [
"LazyDict",
]
class LazyItemsView(ItemsView): class LazyItemsView(ItemsView):
def __iter__(self): def __iter__(self):
self._mapping.resolve() self._mapping.resolve()
for key in self._mapping: for key in self._mapping:
@ -37,7 +38,6 @@ class LazyItemsView(ItemsView):
class LazyValuesView(ValuesView): class LazyValuesView(ValuesView):
def __iter__(self): def __iter__(self):
self._mapping.resolve() self._mapping.resolve()
for key in self._mapping: for key in self._mapping:
@ -49,34 +49,33 @@ class LazyDict(dict):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self._stubs = set() self._stubs = set()
super(LazyDict, self).__init__(*args, **kwargs) super().__init__(*args, **kwargs)
def __cmp__(self, other): def __cmp__(self, other):
self.resolve() self.resolve()
return super(LazyDict, self).__cmp__(other) return super().__cmp__(other)
def __eq__(self, other): def __eq__(self, other):
self.resolve() self.resolve()
return super(LazyDict, self).__eq__(other) return super().__eq__(other)
def __setitem__(self, key, item): def __setitem__(self, key, item):
self._stubs.discard(key) self._stubs.discard(key)
super(LazyDict, self).__setitem__(key, item) super().__setitem__(key, item)
def __getitem__(self, key): def __getitem__(self, key):
if key in self._stubs: if key in self._stubs:
super(LazyDict, self).__setitem__(key, super().__setitem__(key, super().__getitem__(key)())
super(LazyDict, self).__getitem__(key)())
self._stubs.remove(key) self._stubs.remove(key)
return super(LazyDict, self).__getitem__(key) return super().__getitem__(key)
def __delitem__(self, key): def __delitem__(self, key):
self._stubs.discard(key) self._stubs.discard(key)
super(LazyDict, self).__delitem__(key) super().__delitem__(key)
def clear(self): def clear(self):
self._stubs.clear() self._stubs.clear()
super(LazyDict, self).clear() super().clear()
def copy(self): def copy(self):
x = self.__class__(self) x = self.__class__(self)
@ -89,7 +88,6 @@ class LazyDict(dict):
setdefault = MutableMapping.setdefault setdefault = MutableMapping.setdefault
__repr__ = MutableMapping.__repr__ __repr__ = MutableMapping.__repr__
def items(self): def items(self):
return LazyItemsView(self) return LazyItemsView(self)
@ -97,6 +95,7 @@ class LazyDict(dict):
return LazyValuesView(self) return LazyValuesView(self)
__marker = object() __marker = object()
def pop(self, key, default=__marker): def pop(self, key, default=__marker):
try: try:
value = self[key] value = self[key]
@ -118,17 +117,15 @@ class LazyDict(dict):
provided by set_default_resolver. provided by set_default_resolver.
""" """
self._stubs.add(key) self._stubs.add(key)
v = partial(rslv if rslv else self._resolver, v = partial(rslv if rslv else self._resolver, key, *args, **kwargs)
key, *args, **kwargs) super().__setitem__(key, v)
super(LazyDict, self).__setitem__(key, v)
def resolve(self): def resolve(self):
""" """
Resolves all stubs Resolves all stubs
""" """
for k in self._stubs: for k in self._stubs:
super(LazyDict, self).__setitem__(k, super().__setitem__(k, super().__getitem__(k)())
super(LazyDict, self).__getitem__(k)())
self._stubs.clear() self._stubs.clear()
def set_resolver(self, resolver): def set_resolver(self, resolver):
@ -136,46 +133,3 @@ class LazyDict(dict):
Sets the default stub resolver Sets the default stub resolver
""" """
self._resolver = resolver self._resolver = resolver
class LazyDictDebug(LazyDict):
"""
This class can be used instead of LazyDict to analyze if the code
base usage make stubs valuable
"""
def __init__(self, *args, **kwargs):
super(LazyDictDebug, self).__init__(*args, **kwargs)
self.stats = {'realitems': 0, 'stubs': 0, 'resolved': 0}
self.timers = {}
def __missing__(self, key):
try:
stub = self._stubs.pop(key)
except KeyError:
raise KeyError(key)
s = stub()
dict.__setitem__(self, key, s)
return s
def __setitem__(self, key, item):
self.stats['realitems'] += 1
LazyDict.__setitem__(self, key, item)
def set_stub(self, key, resolver, *args, **kwargs):
self.stats['stubs']+=1
LazyDict.set_stub(self, key, resolver, *args, **kwargs)
def get_stats(self):
stats = self.stats
if len(self.timers):
stats['time_cost'] = sum(self.timers.values(), 0.0) / len(self.timers)
return stats
def __missing__(self, key):
self.stats['resolved']+=1
t1 = datetime.datetime.now()
LazyDict.__missing__(self, key)
t2 = datetime.datetime.now()
tdiff = t2 - t1
self.timers[key] = tdiff.microseconds

Просмотреть файл

@ -1,105 +0,0 @@
'''This is:
- OrderedDict from p2.7 used if we don't have the collections.* one
'''
try:
from collections import OrderedDict
except:
from UserDict import DictMixin
class OrderedDict(dict, DictMixin):
def __init__(self, *args, **kwds):
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
try:
self.__end
except AttributeError:
self.clear()
self.update(*args, **kwds)
def clear(self):
self.__end = end = []
end += [None, end, end] # sentinel node for doubly linked list
self.__map = {} # key --> [key, prev, next]
dict.clear(self)
def __setitem__(self, key, value):
if key not in self:
end = self.__end
curr = end[1]
curr[2] = end[1] = self.__map[key] = [key, curr, end]
dict.__setitem__(self, key, value)
def __delitem__(self, key):
dict.__delitem__(self, key)
key, prev, next = self.__map.pop(key)
prev[2] = next
next[1] = prev
def __iter__(self):
end = self.__end
curr = end[2]
while curr is not end:
yield curr[0]
curr = curr[2]
def __reversed__(self):
end = self.__end
curr = end[1]
while curr is not end:
yield curr[0]
curr = curr[1]
def popitem(self, last=True):
if not self:
raise KeyError('dictionary is empty')
key = reversed(self).next() if last else iter(self).next()
value = self.pop(key)
return key, value
def __reduce__(self):
items = [[k, self[k]] for k in self]
tmp = self.__map, self.__end
del self.__map, self.__end
inst_dict = vars(self).copy()
self.__map, self.__end = tmp
if inst_dict:
return (self.__class__, (items,), inst_dict)
return self.__class__, (items,)
def keys(self):
return list(self)
setdefault = DictMixin.setdefault
update = DictMixin.update
pop = DictMixin.pop
values = DictMixin.values
items = DictMixin.items
iterkeys = DictMixin.iterkeys
itervalues = DictMixin.itervalues
iteritems = DictMixin.iteritems
def __repr__(self):
if not self:
return '%s()' % (self.__class__.__name__,)
return '%s(%r)' % (self.__class__.__name__, self.items())
def copy(self):
return self.__class__(self)
@classmethod
def fromkeys(cls, iterable, value=None):
d = cls()
for key in iterable:
d[key] = value
return d
def __eq__(self, other):
if isinstance(other, OrderedDict):
return len(self)==len(other) and \
all(p==q for p, q in zip(self.items(), other.items()))
return dict.__eq__(self, other)
def __ne__(self, other):
return not self == other

Просмотреть файл

@ -1,7 +1,8 @@
import os import os
import sys import sys
class Manager(object):
class Manager:
formats = {} formats = {}
names = {} names = {}
path = [] path = []
@ -9,7 +10,7 @@ class Manager(object):
@classmethod @classmethod
def _import(cls, fp): def _import(cls, fp):
added = list(set(cls.path).difference(sys.path)) added = list(set(cls.path).difference(sys.path))
sys.path = added + sys.path # we want to have the locally added in front sys.path = added + sys.path # we want to have the locally added in front
module = __import__(fp, globals(), locals(), [], 1) module = __import__(fp, globals(), locals(), [], 1)
sys.path = list(set(sys.path).difference(added)) sys.path = list(set(sys.path).difference(added))
return module return module
@ -40,9 +41,9 @@ class Manager(object):
try: try:
module = cls._import(name) module = cls._import(name)
module.register(cls) module.register(cls)
except: except Exception:
pass pass
@classmethod @classmethod
def get(cls, name=None, path=None): def get(cls, name=None, path=None):
if name: if name:
@ -52,11 +53,11 @@ class Manager(object):
try: try:
module = cls._import(name) module = cls._import(name)
except ImportError: except ImportError:
raise KeyError ('no matching format') raise KeyError("no matching format")
return module.FormatParser() return module.FormatParser()
elif path: elif path:
try: try:
return cls.formats[os.path.splitext(path)[1][1:].lower()] return cls.formats[os.path.splitext(path)[1][1:].lower()]
except KeyError: except KeyError:
pass pass
raise KeyError('no matching parser') raise KeyError("no matching parser")

Просмотреть файл

@ -1,37 +1,39 @@
from .parser import DTDParser as Parser from .parser import DTDParser as Parser
from .serializer import DTDSerializer as Serializer from .serializer import DTDSerializer as Serializer
class FormatParser():
name = 'dtd' class FormatParser:
desc = 'DTD reader/writer' name = "dtd"
extensions = ['dtd'] desc = "DTD reader/writer"
encoding = 'utf_8' # allowed encoding extensions = ["dtd"]
fallback = ['utf_8_sig'] encoding = "utf_8" # allowed encoding
fallback = ["utf_8_sig"]
@classmethod @classmethod
def dump_structure (cls, l10nobject): def dump_structure(cls, l10nobject):
text = Serializer.serialize(l10nobject) text = Serializer.serialize(l10nobject)
return text return text
@classmethod @classmethod
def dump_entitylist (cls, elist): def dump_entitylist(cls, elist):
text = Serializer.dump_entitylist(elist) text = Serializer.dump_entitylist(elist)
return text return text
@classmethod @classmethod
def get_idlist (cls, text): def get_idlist(cls, text):
l10nobject = Parser.parse_to_idlist(text) l10nobject = Parser.parse_to_idlist(text)
return l10nobject return l10nobject
@classmethod @classmethod
def get_entitylist (cls, text): def get_entitylist(cls, text):
l10nobject = Parser.parse_to_entitylist(text) l10nobject = Parser.parse_to_entitylist(text)
return l10nobject return l10nobject
@classmethod @classmethod
def get_structure (cls, text): def get_structure(cls, text):
l10nobject = Parser.parse(text) l10nobject = Parser.parse(text)
return l10nobject return l10nobject
def register(Manager): def register(Manager):
Manager.register(FormatParser) Manager.register(FormatParser)

Просмотреть файл

@ -4,17 +4,22 @@ from silme.core.list import EntityList
import re import re
class DTDParser(object): class DTDParser:
name_start_char = u':A-Z_a-z\xC0-\xD6\xD8-\xF6\xF8-\u02FF' + \ name_start_char = (
u'\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF'+\ ":A-Z_a-z\xC0-\xD6\xD8-\xF6\xF8-\u02FF"
u'\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD' "\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF"
name_char = name_start_char + r'\-\.0-9' + u'\xB7\u0300-\u036F\u203F-\u2040' "\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD"
name = u'[' + name_start_char + u'][' + name_char + u']*' )
name_char = name_start_char + r"\-\.0-9" + "\xB7\u0300-\u036F\u203F-\u2040"
name = "[" + name_start_char + "][" + name_char + "]*"
patterns = { patterns = {
'id': re.compile(u'<!ENTITY\s+(' + name + u')[^>]*>', re.S | re.U), "id": re.compile(r"<!ENTITY\s+(" + name + ")[^>]*>", re.S | re.U),
'entity': re.compile(u'<!ENTITY\s+(' + name + u')\s+((?:\"[^\"]*\")|(?:\'[^\']*\'))\s*>', re.S | re.U), "entity": re.compile(
'comment': re.compile(u'\<!\s*--(.*?)(?:--\s*\>)', re.M | re.S) r"<!ENTITY\s+(" + name + r")\s+((?:\"[^\"]*\")|(?:'[^']*'))\s*>",
re.S | re.U,
),
"comment": re.compile(r"\<!\s*--(.*?)(?:--\s*\>)", re.M | re.S),
} }
@classmethod @classmethod
@ -25,35 +30,36 @@ class DTDParser(object):
@classmethod @classmethod
def parse_to_idlist(cls, text): def parse_to_idlist(cls, text):
text = cls.patterns['comment'].sub('', text) text = cls.patterns["comment"].sub("", text)
ids = [m[0] for m in cls.patterns['id'].findall(text)] ids = [m[0] for m in cls.patterns["id"].findall(text)]
return ids return ids
@classmethod @classmethod
def parse_to_entitylist(cls, text): def parse_to_entitylist(cls, text):
elist = EntityList(id=None) elist = EntityList(id=None)
text = cls.patterns['comment'].sub('', text) text = cls.patterns["comment"].sub("", text)
for match in cls.patterns['entity'].findall(text): for match in cls.patterns["entity"].findall(text):
elist.add(Entity(match[0], match[1][1:-1])) elist.add(Entity(match[0], match[1][1:-1]))
return elist return elist
@classmethod @classmethod
def parse_entity(cls, text): def parse_entity(cls, text):
match = cls.patterns['entity'].match(text) match = cls.patterns["entity"].match(text)
if not match: if not match:
raise Exception() raise Exception()
entity = Entity(match.group(0)) entity = Entity(match.group(0))
entity.set_value(match.group(1)[1:-1]) entity.set_value(match.group(1)[1:-1])
return entity return entity
@classmethod @classmethod
def build_element_list(cls, text, obj, type='comment', code='default', pointer=0, end=None): def build_element_list(
cls, text, obj, type="comment", code="default", pointer=0, end=None
):
cls.split_comments(text, obj, code) cls.split_comments(text, obj, code)
@classmethod @classmethod
def split_comments(cls, text, obj, code='default', pointer=0, end=None): def split_comments(cls, text, obj, code="default", pointer=0, end=None):
pattern = cls.patterns['comment'] pattern = cls.patterns["comment"]
if end: if end:
match = pattern.search(text, pointer, end) match = pattern.search(text, pointer, end)
else: else:
@ -74,8 +80,8 @@ class DTDParser(object):
cls.split_entities(text, obj, code=code, pointer=pointer) cls.split_entities(text, obj, code=code, pointer=pointer)
@classmethod @classmethod
def split_entities(cls, text, obj, code='default', pointer=0, end=None): def split_entities(cls, text, obj, code="default", pointer=0, end=None):
pattern = cls.patterns['entity'] pattern = cls.patterns["entity"]
if end: if end:
match = pattern.search(text, pointer, end) match = pattern.search(text, pointer, end)
else: else:
@ -87,8 +93,10 @@ class DTDParser(object):
groups = match.groups() groups = match.groups()
entity = Entity(groups[0]) entity = Entity(groups[0])
entity.set_value(groups[1][1:-1]) entity.set_value(groups[1][1:-1])
entity.params['source'] = { entity.params["source"] = {
'type': 'dtd', 'string': match.group(0), 'valpos': match.start(2)+1-st0 "type": "dtd",
"string": match.group(0),
"valpos": match.start(2) + 1 - st0,
} }
obj.append(entity) obj.append(entity)
pointer = match.end(0) pointer = match.end(0)

Просмотреть файл

@ -1,30 +1,32 @@
from ...core import Entity, EntityList, Comment from ...core import Comment
from silme.core.entity import is_entity from silme.core.entity import is_entity
from .structure import DTDStructure
from .parser import DTDParser as Parser from .parser import DTDParser as Parser
class DTDSerializer():
class DTDSerializer:
@classmethod @classmethod
def serialize(cls, l10nobject): def serialize(cls, l10nobject):
string = u''.join([cls.dump_element(element) for element in l10nobject]) string = "".join([cls.dump_element(element) for element in l10nobject])
return string return string
@classmethod @classmethod
def dump_element (cls, element, fallback=None): def dump_element(cls, element, fallback=None):
if is_entity(element): if is_entity(element):
return cls.dump_entity(element, fallback=fallback) return cls.dump_entity(element, fallback=fallback)
elif isinstance(element,Comment): elif isinstance(element, Comment):
return cls.dump_comment(element) return cls.dump_comment(element)
else: else:
return element return element
@classmethod @classmethod
def dump_entity (cls, entity, fallback=None): def dump_entity(cls, entity, fallback=None):
if 'source' in entity.params and entity.params['source']['type']=='dtd': if "source" in entity.params and entity.params["source"]["type"] == "dtd":
match = Parser.patterns['entity'].match(entity.params['source']['string']) match = Parser.patterns["entity"].match(entity.params["source"]["string"])
middle = entity.params['source']['string'][match.end(1):match.start(2)+1] middle = entity.params["source"]["string"][
end = entity.params['source']['string'][match.end(2)-1:] match.end(1) : match.start(2) + 1
]
end = entity.params["source"]["string"][match.end(2) - 1 :]
if middle.endswith('"') and '"' in entity.value: if middle.endswith('"') and '"' in entity.value:
middle = middle.replace('"', "'") middle = middle.replace('"', "'")
@ -33,24 +35,24 @@ class DTDSerializer():
middle = middle.replace("'", '"') middle = middle.replace("'", '"')
end = end.replace("'", '"') end = end.replace("'", '"')
string = entity.params['source']['string'][0:match.start(1)] string = entity.params["source"]["string"][0 : match.start(1)]
string += entity.id string += entity.id
string += middle string += middle
string += entity.value string += entity.value
string += end string += end
else: else:
string = u'<!ENTITY '+entity.id+u' "'+entity.value+u'">' string = "<!ENTITY " + entity.id + ' "' + entity.value + '">'
return string return string
@classmethod @classmethod
def dump_entitylist(cls, elist): def dump_entitylist(cls, elist):
string = u''.join([cls.dump_entity(entity)+'\n' for entity in elist.values()]) string = "".join([cls.dump_entity(entity) + "\n" for entity in elist.values()])
return string return string
@classmethod @classmethod
def dump_comment (cls, comment): def dump_comment(cls, comment):
string = u'<!--' string = "<!--"
for element in comment: for element in comment:
string += cls.dump_element(element) string += cls.dump_element(element)
string += u'-->' string += "-->"
return string return string

Просмотреть файл

@ -1,19 +1,21 @@
from silme.core import Entity, Structure, Comment from silme.core import Entity, Structure
import re import re
def process_entity(entity, subs): def process_entity(entity, subs):
for code in entity._value.keys(): for code in entity._value.keys():
entity._value[code] = re.sub('\&([^$]+)\;', entity._value[code] = re.sub(
lambda m:subs[m.group(1)], r"\&([^$]+)\;", lambda m: subs[m.group(1)], entity._value[code]
entity._value[code]) )
def process(self): def process(self):
if 'exents' not in self.params or \ if "exents" not in self.params or not self.params["exents"]:
not self.params['exents']:
return return
for elem in self: for elem in self:
if isinstance(elem, Entity): if isinstance(elem, Entity):
process_entity(elem, self.params['exents']) process_entity(elem, self.params["exents"])
class DTDStructure(Structure): class DTDStructure(Structure):
def __init__(self, id): def __init__(self, id):

Просмотреть файл

@ -2,30 +2,30 @@ from .parser import IncParser as Parser
from .serializer import IncSerializer as Serializer from .serializer import IncSerializer as Serializer
class FormatParser(object): class FormatParser:
name = 'inc' name = "inc"
desc = "INC reader/writer" desc = "INC reader/writer"
extensions = ['inc'] extensions = ["inc"]
encoding = 'utf_8' # allowed encoding encoding = "utf_8" # allowed encoding
fallback = None fallback = None
@classmethod @classmethod
def dump_structure (cls, l10nobject): def dump_structure(cls, l10nobject):
text = Serializer.serialize(l10nobject) text = Serializer.serialize(l10nobject)
return text return text
@classmethod @classmethod
def dump_entitylist (cls, elist): def dump_entitylist(cls, elist):
text = Serializer.dump_entitylist(elist) text = Serializer.dump_entitylist(elist)
return text return text
@classmethod @classmethod
def get_entitylist (cls, text): def get_entitylist(cls, text):
l10nobject = Parser.parse_to_entitylist(text) l10nobject = Parser.parse_to_entitylist(text)
return l10nobject return l10nobject
@classmethod @classmethod
def get_structure (cls, text): def get_structure(cls, text):
l10nobject = Parser.parse(text) l10nobject = Parser.parse(text)
return l10nobject return l10nobject

Просмотреть файл

@ -2,12 +2,14 @@ from ...core import EntityList, Entity, Comment
from .structure import IncStructure from .structure import IncStructure
import re import re
class IncParser():
patterns = {}
patterns['entity'] = re.compile(r'#define[ \t]+(?P<key>\w+)(?:[ \t](?P<val>[^\n]*))?', re.M)
patterns['comment'] = re.compile('^(# [^\n]*\n?)+',re.M)
#define firefox_about About Us
class IncParser:
patterns = {}
patterns["entity"] = re.compile(
r"#define[ \t]+(?P<key>\w+)(?:[ \t](?P<val>[^\n]*))?", re.M
)
patterns["comment"] = re.compile("^(# [^\n]*\n?)+", re.M)
# define firefox_about About Us
@classmethod @classmethod
def parse(cls, text): def parse(cls, text):
@ -19,15 +21,15 @@ class IncParser():
@classmethod @classmethod
def parse_to_entitylist(cls, text): def parse_to_entitylist(cls, text):
entitylist = EntityList(id=None) entitylist = EntityList(id=None)
text = cls.patterns['comment'].sub('', text) text = cls.patterns["comment"].sub("", text)
matchlist = cls.patterns['entity'].findall(text) matchlist = cls.patterns["entity"].findall(text)
for match in matchlist: for match in matchlist:
entitylist.add(Entity(match[0], match[1])) entitylist.add(Entity(match[0], match[1]))
return entitylist return entitylist
@classmethod @classmethod
def parse_entity(cls, text): def parse_entity(cls, text):
match = self.patterns['entity'].match(text) match = cls.patterns["entity"].match(text)
if not match: if not match:
raise Exception() raise Exception()
entity = Entity(match.group(1)) entity = Entity(match.group(1))
@ -35,12 +37,12 @@ class IncParser():
return entity return entity
@classmethod @classmethod
def build_element_list (cls, text, object, type='comment', pointer=0, end=None): def build_element_list(cls, text, object, type="comment", pointer=0, end=None):
cls.split_comments(text, object) cls.split_comments(text, object)
@classmethod @classmethod
def split_comments(cls, text, object, pointer=0, end=None): def split_comments(cls, text, object, pointer=0, end=None):
pattern = cls.patterns['comment'] pattern = cls.patterns["comment"]
if end: if end:
match = pattern.search(text, pointer, end) match = pattern.search(text, pointer, end)
else: else:
@ -49,9 +51,8 @@ class IncParser():
st0 = match.start(0) st0 = match.start(0)
if st0 > pointer: if st0 > pointer:
cls.split_entities(text, object, pointer=pointer, end=st0) cls.split_entities(text, object, pointer=pointer, end=st0)
groups = match.groups()
comment = Comment() comment = Comment()
cls.split_entities(match.group(0)[2:].replace('\n# ','\n'), comment) cls.split_entities(match.group(0)[2:].replace("\n# ", "\n"), comment)
object.append(comment) object.append(comment)
pointer = match.end(0) pointer = match.end(0)
if end: if end:
@ -63,7 +64,7 @@ class IncParser():
@classmethod @classmethod
def split_entities(cls, text, object, pointer=0, end=None): def split_entities(cls, text, object, pointer=0, end=None):
pattern = cls.patterns['entity'] pattern = cls.patterns["entity"]
if end: if end:
match = pattern.search(text, pointer, end) match = pattern.search(text, pointer, end)
else: else:
@ -74,10 +75,12 @@ class IncParser():
object.append(text[pointer:st0]) object.append(text[pointer:st0])
groups = match.groups() groups = match.groups()
entity = Entity(groups[0]) entity = Entity(groups[0])
entity.set_value(groups[1] or '') entity.set_value(groups[1] or "")
entity.params['source'] = {'type':'inc', entity.params["source"] = {
'string':match.group(0), "type": "inc",
'valpos':match.start(2)-st0} "string": match.group(0),
"valpos": match.start(2) - st0,
}
object.append(entity) object.append(entity)
pointer = match.end(0) pointer = match.end(0)
if end: if end:

Просмотреть файл

@ -1,52 +1,60 @@
from ...core import EntityList, Entity, Comment from ...core import Entity, Comment
from .structure import IncStructure
from .parser import IncParser as Parser from .parser import IncParser as Parser
import re import re
class IncSerializer():
class IncSerializer:
@classmethod @classmethod
def serialize(cls, l10nobject): def serialize(cls, l10nobject):
string = u''.join([cls.dump_element(element) for element in l10nobject]) string = "".join([cls.dump_element(element) for element in l10nobject])
return string return string
@classmethod @classmethod
def dump_element(cls, element, fallback=None): def dump_element(cls, element, fallback=None):
if isinstance(element, Entity): if isinstance(element, Entity):
return cls.dump_entity(element, fallback=fallback) return cls.dump_entity(element, fallback=fallback)
elif isinstance(element,Comment): elif isinstance(element, Comment):
return cls.dump_comment(element) return cls.dump_comment(element)
else: else:
return element return element
@classmethod @classmethod
def dump_entity (cls, entity, fallback=None): def dump_entity(cls, entity, fallback=None):
if 'source' in entity.params and entity.params['source']['type']=='properties': if (
match = Parser.patterns['entity'].match(entity.params['source']['string']) "source" in entity.params
string = entity.params['source']['string'][0:match.start(1)] and entity.params["source"]["type"] == "properties"
):
match = Parser.patterns["entity"].match(entity.params["source"]["string"])
string = entity.params["source"]["string"][0 : match.start(1)]
string += entity.id string += entity.id
string += entity.params['source']['string'][match.end(1):match.start(2)] string += entity.params["source"]["string"][match.end(1) : match.start(2)]
string += entity.get_value(fallback) string += entity.get_value(fallback)
string += entity.params['source']['string'][match.end(2):] string += entity.params["source"]["string"][match.end(2) :]
else: else:
string = u'#define %s %s' % (entity.id, entity.get_value(fallback)) string = "#define {} {}".format(entity.id, entity.get_value(fallback))
return string return string
@classmethod @classmethod
def dump_entitylist(cls, elist, fallback=None): def dump_entitylist(cls, elist, fallback=None):
if not fallback: if not fallback:
fallback = elist.fallback fallback = elist.fallback
string = u''.join([cls.dump_entity(entity, fallback)+'\n' for entity in elist.get_entities()]) string = "".join(
[
cls.dump_entity(entity, fallback) + "\n"
for entity in elist.get_entities()
]
)
return string return string
@classmethod @classmethod
def dump_comment (cls, comment): def dump_comment(cls, comment):
string = u'' string = ""
for element in comment: for element in comment:
string += cls.dump_element(element) string += cls.dump_element(element)
if string: if string:
pattern = re.compile('\n') pattern = re.compile("\n")
string = pattern.sub('\n# ', string) string = pattern.sub("\n# ", string)
string = '# ' + string string = "# " + string
if string.endswith('# '): if string.endswith("# "):
string = string[:-2] string = string[:-2]
return string return string

Просмотреть файл

@ -1,4 +1,5 @@
from ...core.structure import Structure from ...core.structure import Structure
class IncStructure(Structure): class IncStructure(Structure):
pass pass

Просмотреть файл

@ -1,31 +1,31 @@
from .parser import Parser from .parser import Parser
from .structure import Structure
from .serializer import Serializer from .serializer import Serializer
class FormatParser():
name = 'ini' class FormatParser:
name = "ini"
desc = "Ini reader/writer" desc = "Ini reader/writer"
extensions = ['ini'] extensions = ["ini"]
encoding = 'utf_8' # allowed encoding encoding = "utf_8" # allowed encoding
fallback = None fallback = None
@classmethod @classmethod
def dump_structure (cls, l10nobject): def dump_structure(cls, l10nobject):
text = Serializer.serialize(l10nobject) text = Serializer.serialize(l10nobject)
return text return text
@classmethod @classmethod
def dump_entitylist (cls, elist): def dump_entitylist(cls, elist):
text = Serializer.dump_entitylist(elist) text = Serializer.dump_entitylist(elist)
return text return text
@classmethod @classmethod
def get_entitylist (cls, text): def get_entitylist(cls, text):
l10nobject = Parser.parse_to_entitylist(text) l10nobject = Parser.parse_to_entitylist(text)
return l10nobject return l10nobject
@classmethod @classmethod
def get_structure (cls, text): def get_structure(cls, text):
l10nobject = Parser.parse(text) l10nobject = Parser.parse(text)
return l10nobject return l10nobject

Просмотреть файл

@ -1,14 +1,16 @@
from ...core import EntityList, Entity, Comment from ...core import EntityList, Entity, Comment
from .structure import Structure, Section from .structure import Structure, Section
from silme.core.list import EntityList
import re import re
class Parser():
patterns = {}
patterns['entity'] = re.compile('^[ \t]*([^#!\s\n][^=:\n]*?)[ \t]*[:=][ \t]*(.*?)(?<!\\\)(?=\n|\Z)',re.S|re.M)
patterns['comment'] = re.compile('^([;#][^\n]*\n?)+',re.M|re.S)
patterns['section'] = re.compile('^\[([a-z]+)\]', re.S|re.M)
class Parser:
patterns = {}
patterns["entity"] = re.compile(
r"^[ \t]*([^#!\s\n][^=:\n]*?)[ \t]*[:=][ \t]*(.*?)(?<!\\\)(?=\n|\Z)",
re.S | re.M,
)
patterns["comment"] = re.compile(r"^([;#][^\n]*\n?)+", re.M | re.S)
patterns["section"] = re.compile(r"^\[([a-z]+)\]", re.S | re.M)
@classmethod @classmethod
def parse(cls, text): def parse(cls, text):
@ -20,15 +22,15 @@ class Parser():
@classmethod @classmethod
def parse_to_entitylist(cls, text): def parse_to_entitylist(cls, text):
entitylist = EntityList(id=None) entitylist = EntityList(id=None)
text = cls.patterns['comment'].sub('', text) text = cls.patterns["comment"].sub("", text)
matchlist = cls.patterns['entity'].findall(text) matchlist = cls.patterns["entity"].findall(text)
for match in matchlist: for match in matchlist:
entitylist.add(Entity(match[0], match[1])) entitylist.add(Entity(match[0], match[1]))
return entitylist return entitylist
@classmethod @classmethod
def parse_entity(cls, text): def parse_entity(cls, text):
match = self.patterns['entity'].match(text) match = cls.patterns["entity"].match(text)
if not match: if not match:
raise Exception() raise Exception()
entity = Entity(match.group(1)) entity = Entity(match.group(1))
@ -36,13 +38,13 @@ class Parser():
return entity return entity
@classmethod @classmethod
def build_element_list (cls, text, object): def build_element_list(cls, text, object):
cls.split_sections(text, object) cls.split_sections(text, object)
@classmethod @classmethod
def split_sections(cls, text, struct, pointer=0, end=None): def split_sections(cls, text, struct, pointer=0, end=None):
root = struct root = struct
pattern = cls.patterns['section'] pattern = cls.patterns["section"]
if end: if end:
match = pattern.search(text, pointer, end) match = pattern.search(text, pointer, end)
else: else:
@ -62,11 +64,9 @@ class Parser():
if (not end or (end > pointer)) and len(text) > pointer: if (not end or (end > pointer)) and len(text) > pointer:
cls.split_comments(text, struct, pointer=pointer, end=end) cls.split_comments(text, struct, pointer=pointer, end=end)
@classmethod @classmethod
def split_comments(cls, text, object, pointer=0, end=None): def split_comments(cls, text, object, pointer=0, end=None):
pattern = cls.patterns['comment'] pattern = cls.patterns["comment"]
if end: if end:
match = pattern.search(text, pointer, end) match = pattern.search(text, pointer, end)
else: else:
@ -76,7 +76,7 @@ class Parser():
if st0 > pointer: if st0 > pointer:
cls.split_entities(text, object, pointer=pointer, end=st0) cls.split_entities(text, object, pointer=pointer, end=st0)
comment = Comment() comment = Comment()
comment.add(match.group(0)[1:].replace('\n;', '\n').replace('\n#', '\n')) comment.add(match.group(0)[1:].replace("\n;", "\n").replace("\n#", "\n"))
object.append(comment) object.append(comment)
pointer = match.end(0) pointer = match.end(0)
if end: if end:
@ -88,7 +88,7 @@ class Parser():
@classmethod @classmethod
def split_entities(cls, text, object, pointer=0, end=None): def split_entities(cls, text, object, pointer=0, end=None):
pattern = cls.patterns['entity'] pattern = cls.patterns["entity"]
if end: if end:
match = pattern.search(text, pointer, end) match = pattern.search(text, pointer, end)
else: else:
@ -100,9 +100,11 @@ class Parser():
groups = match.groups() groups = match.groups()
entity = Entity(groups[0]) entity = Entity(groups[0])
entity.set_value(groups[1]) entity.set_value(groups[1])
entity.params['source'] = {'type':'ini', entity.params["source"] = {
'string':match.group(0), "type": "ini",
'valpos':match.start(2)-st0} "string": match.group(0),
"valpos": match.start(2) - st0,
}
object.append(entity) object.append(entity)
pointer = match.end(0) pointer = match.end(0)
if end: if end:

Просмотреть файл

@ -4,10 +4,11 @@ from .parser import Parser
from silme.core.entity import is_entity from silme.core.entity import is_entity
import re import re
class Serializer():
class Serializer:
@classmethod @classmethod
def serialize(cls, l10nobject): def serialize(cls, l10nobject):
string = ''.join([cls.dump_element(element) for element in l10nobject]) string = "".join([cls.dump_element(element) for element in l10nobject])
return string return string
@classmethod @classmethod
@ -23,36 +24,36 @@ class Serializer():
@classmethod @classmethod
def dump_entity(cls, entity): def dump_entity(cls, entity):
if 'source' in entity.params and entity.params['source']['type']=='ini': if "source" in entity.params and entity.params["source"]["type"] == "ini":
match = Parser.patterns['entity'].match(entity.params['source']['string']) match = Parser.patterns["entity"].match(entity.params["source"]["string"])
string = entity.params['source']['string'][0:match.start(1)] string = entity.params["source"]["string"][0 : match.start(1)]
string += entity.id string += entity.id
string += entity.params['source']['string'][match.end(1):match.start(2)] string += entity.params["source"]["string"][match.end(1) : match.start(2)]
string += entity.value string += entity.value
string += entity.params['source']['string'][match.end(2):] string += entity.params["source"]["string"][match.end(2) :]
else: else:
string = entity.id+'='+entity.value string = entity.id + "=" + entity.value
return string return string
@classmethod @classmethod
def dump_entitylist(cls, elist): def dump_entitylist(cls, elist):
string = ''.join([cls.dump_entity(entity)+'\n' for entity in elist.values()]) string = "".join([cls.dump_entity(entity) + "\n" for entity in elist.values()])
return string return string
@classmethod @classmethod
def dump_comment(cls, comment): def dump_comment(cls, comment):
string = '' string = ""
for element in comment: for element in comment:
string += cls.dump_element(element) string += cls.dump_element(element)
if string: if string:
pattern = re.compile('\n') pattern = re.compile("\n")
string = pattern.sub('\n#', string) string = pattern.sub("\n#", string)
string = '#' + string string = "#" + string
if string.endswith('#'): if string.endswith("#"):
string = string[:-1] string = string[:-1]
return string return string
@classmethod @classmethod
def dump_section(cls, section): def dump_section(cls, section):
string = '[%s]%s' % (section.id, cls.serialize(section)) string = "[{}]{}".format(section.id, cls.serialize(section))
return string return string

Просмотреть файл

@ -1,10 +1,11 @@
from silme.core.structure import Structure as BaseStructure, Comment from silme.core.structure import Structure as BaseStructure, Comment
from silme.core.entity import is_string, is_entity from silme.core.entity import is_string, is_entity
class Structure(BaseStructure): class Structure(BaseStructure):
def __init__(self, id): def __init__(self, id):
BaseStructure.__init__(self, id) BaseStructure.__init__(self, id)
self.first_section = False # did we encounter sections? self.first_section = False # did we encounter sections?
def add(self, item, pos=None): def add(self, item, pos=None):
"""adds an element (string, entity or comment) to the Structure """adds an element (string, entity or comment) to the Structure
@ -25,16 +26,18 @@ class Structure(BaseStructure):
elif item is None: elif item is None:
return 0 return 0
else: else:
raise Exception('Cannot add element of type "' + raise Exception(
type(item).__name__ + 'Cannot add element of type "'
'" to the Structure') + type(item).__name__
+ '" to the Structure'
)
def add_section(self, section, pos=None): def add_section(self, section, pos=None):
pos = self._get_pos(pos) pos = self._get_pos(pos)
if pos is None: if pos is None:
self.first_section = len(self) self.first_section = len(self)
elif self.first_section is False or self.first_section < pos: elif self.first_section is False or self.first_section < pos:
self.first_section = pos self.first_section = pos
self.add_at_pos(section, pos) self.add_at_pos(section, pos)
return 1 return 1
@ -45,8 +48,9 @@ class Structure(BaseStructure):
('before', 'entity.id'), ('after', 'entity.id') ('before', 'entity.id'), ('after', 'entity.id')
""" """
pos = self._get_pos(pos) pos = self._get_pos(pos)
if self.first_section is not False and \ if self.first_section is not False and (
(pos is None or pos > self.first_section): pos is None or pos > self.first_section
):
raise Exception("Cannot add entity after section") raise Exception("Cannot add entity after section")
self.add_at_pos(entity, pos) self.add_at_pos(entity, pos)
return 1 return 1
@ -65,8 +69,7 @@ class Structure(BaseStructure):
raise KeyError("No such entity or section") raise KeyError("No such entity or section")
def __contains__(self, id): def __contains__(self, id):
"""returns True if an entity with given id exists """returns True if an entity with given id exists"""
"""
for item in self: for item in self:
if is_entity(item) and item.id == id: if is_entity(item) and item.id == id:
return True return True
@ -75,12 +78,11 @@ class Structure(BaseStructure):
return False return False
def section(self, key): def section(self, key):
"""returns a section for a given id """returns a section for a given id"""
"""
for item in self: for item in self:
if isinstance(item, Section) and item.id == key: if isinstance(item, Section) and item.id == key:
return item return item
raise KeyError('No such section') raise KeyError("No such section")
class Section(Structure): class Section(Structure):
@ -103,7 +105,8 @@ class Section(Structure):
elif item is None: elif item is None:
return 0 return 0
else: else:
raise Exception('Cannot add element of type "' + raise Exception(
type(item).__name__ + 'Cannot add element of type "'
'" to the Structure') + type(item).__name__
+ '" to the Structure'
)

Просмотреть файл

@ -7,25 +7,25 @@ if sys.version_info[0] > 2:
unichr = chr unichr = chr
class FormatParser(object): class FormatParser:
name = 'properties' name = "properties"
desc = "Java Properties reader/writer" desc = "Java Properties reader/writer"
extensions = ['properties'] extensions = ["properties"]
encoding = 'utf_8' # allowed encoding encoding = "utf_8" # allowed encoding
fallback = ['utf_8_sig'] fallback = ["utf_8_sig"]
@classmethod @classmethod
def dump_structure (cls, l10nobject): def dump_structure(cls, l10nobject):
text = Serializer.serialize(l10nobject) text = Serializer.serialize(l10nobject)
return text return text
@classmethod @classmethod
def dump_entitylist (cls, elist): def dump_entitylist(cls, elist):
text = Serializer.dump_entitylist(elist) text = Serializer.dump_entitylist(elist)
return text return text
@classmethod @classmethod
def get_entitylist (cls, text, code='default'): def get_entitylist(cls, text, code="default"):
# remove the \ufeff character from the beginning of the file, dirty hack for now # remove the \ufeff character from the beginning of the file, dirty hack for now
if text and (text[0] == unichr(65279)): if text and (text[0] == unichr(65279)):
text = text[1:] text = text[1:]
@ -33,7 +33,7 @@ class FormatParser(object):
return l10nobject return l10nobject
@classmethod @classmethod
def get_structure (cls, text, code='default'): def get_structure(cls, text, code="default"):
# remove the \ufeff character from the beginning of the file, dirty hack for now # remove the \ufeff character from the beginning of the file, dirty hack for now
if text and (text[0] == unichr(65279)): if text and (text[0] == unichr(65279)):
text = text[1:] text = text[1:]

Просмотреть файл

@ -1,16 +1,18 @@
from ...core import EntityList, Entity, Comment from ...core import EntityList, Entity, Comment
from .structure import PropertiesStructure from .structure import PropertiesStructure
from silme.core.list import EntityList
import re import re
class PropertiesParser():
patterns = {}
patterns['entity'] = re.compile('^[ \t]*([^#!\s\n][^=:\n]*?)[ \t]*[:=][ \t]*(.*?)(?<!\\\)(?=\n|\Z|\r)',re.S|re.M)
patterns['comment'] = re.compile('^(#[^\n]*\n?)+',re.M|re.S)
class PropertiesParser:
patterns = {}
patterns["entity"] = re.compile(
r"^[ \t]*([^#!\s\n][^=:\n]*?)[ \t]*[:=][ \t]*(.*?)(?<!\\\)(?=\n|\Z|\r)",
re.S | re.M,
)
patterns["comment"] = re.compile("^(#[^\n]*\n?)+", re.M | re.S)
@classmethod @classmethod
def parse(cls, text, code='default'): def parse(cls, text, code="default"):
prop = PropertiesStructure(id=None) prop = PropertiesStructure(id=None)
cls.build_element_list(text, prop, code=code) cls.build_element_list(text, prop, code=code)
prop.fallback = code prop.fallback = code
@ -20,15 +22,15 @@ class PropertiesParser():
@classmethod @classmethod
def parse_to_entitylist(cls, text): def parse_to_entitylist(cls, text):
entitylist = EntityList(None) entitylist = EntityList(None)
text = cls.patterns['comment'].sub('', text) text = cls.patterns["comment"].sub("", text)
matchlist = cls.patterns['entity'].findall(text) matchlist = cls.patterns["entity"].findall(text)
for match in matchlist: for match in matchlist:
entitylist.add(Entity(match[0], match[1])) entitylist.add(Entity(match[0], match[1]))
return entitylist return entitylist
@classmethod @classmethod
def parse_entity(cls, text, code='default'): def parse_entity(cls, text, code="default"):
match = self.patterns['entity'].match(text) match = cls.patterns["entity"].match(text)
if not match: if not match:
raise Exception() raise Exception()
entity = Entity(match.group(1)) entity = Entity(match.group(1))
@ -36,12 +38,14 @@ class PropertiesParser():
return entity return entity
@classmethod @classmethod
def build_element_list (cls, text, object, type='comment', code='default', pointer=0, end=None): def build_element_list(
cls, text, object, type="comment", code="default", pointer=0, end=None
):
cls.split_comments(text, object, code=code) cls.split_comments(text, object, code=code)
@classmethod @classmethod
def split_comments(cls, text, object, code='default', pointer=0, end=None): def split_comments(cls, text, object, code="default", pointer=0, end=None):
pattern = cls.patterns['comment'] pattern = cls.patterns["comment"]
if end: if end:
match = pattern.search(text, pointer, end) match = pattern.search(text, pointer, end)
else: else:
@ -50,9 +54,8 @@ class PropertiesParser():
st0 = match.start(0) st0 = match.start(0)
if st0 > pointer: if st0 > pointer:
cls.split_entities(text, object, code=code, pointer=pointer, end=st0) cls.split_entities(text, object, code=code, pointer=pointer, end=st0)
groups = match.groups()
comment = Comment() comment = Comment()
comment.add(match.group(0)[1:].replace('\n#', '\n')) comment.add(match.group(0)[1:].replace("\n#", "\n"))
object.append(comment) object.append(comment)
pointer = match.end(0) pointer = match.end(0)
if end: if end:
@ -63,8 +66,8 @@ class PropertiesParser():
cls.split_entities(text, object, code=code, pointer=pointer) cls.split_entities(text, object, code=code, pointer=pointer)
@classmethod @classmethod
def split_entities(cls, text, object, code='default', pointer=0, end=None): def split_entities(cls, text, object, code="default", pointer=0, end=None):
pattern = cls.patterns['entity'] pattern = cls.patterns["entity"]
if end: if end:
match = pattern.search(text, pointer, end) match = pattern.search(text, pointer, end)
else: else:
@ -76,9 +79,11 @@ class PropertiesParser():
groups = match.groups() groups = match.groups()
entity = Entity(groups[0]) entity = Entity(groups[0])
entity.set_value(groups[1]) entity.set_value(groups[1])
entity.params['source'] = {'type':'properties', entity.params["source"] = {
'string':match.group(0), "type": "properties",
'valpos':match.start(2)-st0} "string": match.group(0),
"valpos": match.start(2) - st0,
}
object.append(entity) object.append(entity)
pointer = match.end(0) pointer = match.end(0)
if end: if end:

Просмотреть файл

@ -1,51 +1,54 @@
from ...core import EntityList, Entity, Comment from ...core import Comment
from silme.core.entity import is_entity from silme.core.entity import is_entity
from .structure import PropertiesStructure
from .parser import PropertiesParser as Parser from .parser import PropertiesParser as Parser
import re import re
class PropertiesSerializer():
class PropertiesSerializer:
@classmethod @classmethod
def serialize(cls, l10nobject): def serialize(cls, l10nobject):
string = u''.join([cls.dump_element(element) for element in l10nobject]) string = "".join([cls.dump_element(element) for element in l10nobject])
return string return string
@classmethod @classmethod
def dump_element(cls, element, fallback=None): def dump_element(cls, element, fallback=None):
if is_entity(element): if is_entity(element):
return cls.dump_entity(element) return cls.dump_entity(element)
elif isinstance(element,Comment): elif isinstance(element, Comment):
return cls.dump_comment(element) return cls.dump_comment(element)
else: else:
return element return element
@classmethod @classmethod
def dump_entity (cls, entity): def dump_entity(cls, entity):
if 'source' in entity.params and entity.params['source']['type']=='properties': if (
match = Parser.patterns['entity'].match(entity.params['source']['string']) "source" in entity.params
string = entity.params['source']['string'][0:match.start(1)] and entity.params["source"]["type"] == "properties"
):
match = Parser.patterns["entity"].match(entity.params["source"]["string"])
string = entity.params["source"]["string"][0 : match.start(1)]
string += entity.id string += entity.id
string += entity.params['source']['string'][match.end(1):match.start(2)] string += entity.params["source"]["string"][match.end(1) : match.start(2)]
string += entity.value string += entity.value
string += entity.params['source']['string'][match.end(2):] string += entity.params["source"]["string"][match.end(2) :]
else: else:
string = entity.id+u' = '+entity.value string = entity.id + " = " + entity.value
return string return string
@classmethod @classmethod
def dump_entitylist(cls, elist): def dump_entitylist(cls, elist):
string = u''.join([cls.dump_entity(entity)+'\n' for entity in elist.values()]) string = "".join([cls.dump_entity(entity) + "\n" for entity in elist.values()])
return string return string
@classmethod @classmethod
def dump_comment (cls, comment): def dump_comment(cls, comment):
string = u'' string = ""
for element in comment: for element in comment:
string += cls.dump_element(element) string += cls.dump_element(element)
if string: if string:
pattern = re.compile('\n') pattern = re.compile("\n")
string = pattern.sub('\n#', string) string = pattern.sub("\n#", string)
string = '#' + string string = "#" + string
if string.endswith('#'): if string.endswith("#"):
string = string[:-1] string = string[:-1]
return string return string

Просмотреть файл

@ -1,4 +1,5 @@
from ...core.structure import Structure from ...core.structure import Structure
class PropertiesStructure(Structure): class PropertiesStructure(Structure):
pass pass

6
pyproject.toml Normal file
Просмотреть файл

@ -0,0 +1,6 @@
[build-system]
requires = ["setuptools>=40.8.0", "wheel"]
build-backend = "setuptools.build_meta"
[tool.black]
line-length = 88

6
setup.cfg Normal file
Просмотреть файл

@ -0,0 +1,6 @@
[flake8]
max-line-length = 88
ignore =
E203,
E731,
W503,

Просмотреть файл

@ -1,16 +1,17 @@
"""Python localization library from setuptools import setup, find_packages
import sys
import os.path
"""Python localization library
New library for localization written in Python. New library for localization written in Python.
""" """
docstrings = __doc__.split("\n") docstrings = __doc__.split("\n")
from setuptools import setup, find_packages sys.path.insert(0, os.path.join(os.path.dirname(__file__), "lib"))
import sys
import os.path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'lib'))
import silme import silme # noqa: E402
classifiers = """\ classifiers = """\
Development Status :: 4 - Beta Development Status :: 4 - Beta
@ -27,17 +28,18 @@ Topic :: Software Development :: Libraries :: Python Modules
Topic :: Software Development :: Localization Topic :: Software Development :: Localization
""" """
setup(name="silme", setup(
version=silme.get_short_version(), name="silme",
author="Zbigniew Braniecki", version=silme.get_short_version(),
author_email="gandalf@mozilla.com", author="Zbigniew Braniecki",
description=docstrings[0], author_email="gandalf@mozilla.com",
long_description="\n".join(docstrings[2:]), description=docstrings[0],
license="MPL 1.1/GPL 2.0/LGPL 2.1", long_description="\n".join(docstrings[2:]),
url="https://github.com/mathjazz/silme", license="MPL 1.1/GPL 2.0/LGPL 2.1",
classifiers=filter(None, classifiers.split("\n")), url="https://github.com/mathjazz/silme",
platforms=["any"], classifiers=filter(None, classifiers.split("\n")),
package_dir={'': 'lib'}, platforms=["any"],
packages=find_packages('lib'), package_dir={"": "lib"},
keywords="localization, l10n" packages=find_packages("lib"),
) keywords="localization, l10n",
)

Просмотреть файл

@ -1,141 +1,140 @@
import unittest import unittest
import sys
from silme.core.entity import Entity, ComplexValue from silme.core.entity import Entity, ComplexValue
from silme.core.types import OrderedDict from collections import OrderedDict
class EntityTestCase(unittest.TestCase): class EntityTestCase(unittest.TestCase):
def setUp(self): def setUp(self):
self.entity = Entity('test') self.entity = Entity("test")
def test_id(self): def test_id(self):
self.assertEqual(self.entity.id, 'test') self.assertEqual(self.entity.id, "test")
def test_value1(self): def test_value1(self):
self.entity.value = 'testvalue' self.entity.value = "testvalue"
self.assertEqual(self.entity.value, 'testvalue') self.assertEqual(self.entity.value, "testvalue")
self.assertEqual(self.entity.get_value(), self.entity.value) self.assertEqual(self.entity.get_value(), self.entity.value)
def test_value3(self): def test_value3(self):
self.entity = Entity('test', 'testvalue') self.entity = Entity("test", "testvalue")
self.assertEqual(self.entity.value, 'testvalue') self.assertEqual(self.entity.value, "testvalue")
self.assertEqual(self.entity.get_value(), self.entity.value) self.assertEqual(self.entity.get_value(), self.entity.value)
def test_value5(self): def test_value5(self):
self.assertEqual(self.entity.get_value(), None) self.assertEqual(self.entity.get_value(), None)
def test_value6(self): def test_value6(self):
self.entity.value = 'foo' self.entity.value = "foo"
self.assertEqual(self.entity.value, 'foo') self.assertEqual(self.entity.value, "foo")
def test_list1(self): def test_list1(self):
self.entity.value = ['foo','foo2'] self.entity.value = ["foo", "foo2"]
self.assertEqual(self.entity.value, 'foo') self.assertEqual(self.entity.value, "foo")
def test_list2(self): def test_list2(self):
self.entity.value = ['foo','foo2'] self.entity.value = ["foo", "foo2"]
self.assertEqual(self.entity[0], 'foo') self.assertEqual(self.entity[0], "foo")
self.assertEqual(self.entity[1], 'foo2') self.assertEqual(self.entity[1], "foo2")
def test_list3(self): def test_list3(self):
self.entity.value = ['foo','foo2'] self.entity.value = ["foo", "foo2"]
self.assertEqual(self.entity.get_value(0), 'foo') self.assertEqual(self.entity.get_value(0), "foo")
self.assertEqual(self.entity.get_value(1), 'foo2') self.assertEqual(self.entity.get_value(1), "foo2")
def test_list4(self): def test_list4(self):
self.entity = Entity('test', ['old','old2']) self.entity = Entity("test", ["old", "old2"])
self.entity[0] = 'foo' self.entity[0] = "foo"
self.entity[1] = 'foo2' self.entity[1] = "foo2"
self.assertEqual(self.entity.get_value(0), 'foo') self.assertEqual(self.entity.get_value(0), "foo")
self.assertEqual(self.entity.get_value(1), 'foo2') self.assertEqual(self.entity.get_value(1), "foo2")
def test_list5(self): def test_list5(self):
self.entity.value = ['foo','foo2'] self.entity.value = ["foo", "foo2"]
del self.entity[1] del self.entity[1]
self.assertEqual(self.entity.get_value(0), 'foo') self.assertEqual(self.entity.get_value(0), "foo")
self.assertRaises(IndexError, self.entity.get_value, 1) self.assertRaises(IndexError, self.entity.get_value, 1)
def test_dict1(self): def test_dict1(self):
self.entity = Entity('test', {'male':'Foo','female':'Foo2'}) self.entity = Entity("test", {"male": "Foo", "female": "Foo2"})
self.assertTrue(self.entity.value in ('Foo', 'Foo2')) self.assertTrue(self.entity.value in ("Foo", "Foo2"))
def test_dict2(self): def test_dict2(self):
self.entity.value = {'male':'Foo','female':'Foo2'} self.entity.value = {"male": "Foo", "female": "Foo2"}
self.assertTrue(self.entity.value in ('Foo', 'Foo2')) self.assertTrue(self.entity.value in ("Foo", "Foo2"))
def test_dict3(self): def test_dict3(self):
self.entity.value = {'male':'Foo','female':'Foo2'} self.entity.value = {"male": "Foo", "female": "Foo2"}
self.assertTrue(self.entity.get_value() in ('Foo', 'Foo2')) self.assertTrue(self.entity.get_value() in ("Foo", "Foo2"))
def test_dict4(self): def test_dict4(self):
self.entity.value = {'male':'Foo','female':'Foo2'} self.entity.value = {"male": "Foo", "female": "Foo2"}
self.assertEqual(self.entity.get_value('male'), 'Foo') self.assertEqual(self.entity.get_value("male"), "Foo")
self.assertEqual(self.entity.get_value('female'), 'Foo2') self.assertEqual(self.entity.get_value("female"), "Foo2")
def test_dict5(self): def test_dict5(self):
self.entity.value = {'male':'Foo','female':'Foo2'} self.entity.value = {"male": "Foo", "female": "Foo2"}
self.assertEqual(self.entity['male'], 'Foo') self.assertEqual(self.entity["male"], "Foo")
self.assertEqual(self.entity['female'], 'Foo2') self.assertEqual(self.entity["female"], "Foo2")
def test_dict6(self): def test_dict6(self):
self.entity.value = {'male':'Foo','female':'Foo2'} self.entity.value = {"male": "Foo", "female": "Foo2"}
self.entity['male']='Foo3' self.entity["male"] = "Foo3"
self.assertEqual(self.entity['male'], 'Foo3') self.assertEqual(self.entity["male"], "Foo3")
self.assertEqual(self.entity['female'], 'Foo2') self.assertEqual(self.entity["female"], "Foo2")
def test_dict7(self): def test_dict7(self):
self.entity.value = {'male':'Foo','female':'Foo2'} self.entity.value = {"male": "Foo", "female": "Foo2"}
del self.entity['male'] del self.entity["male"]
self.assertEqual(self.entity['female'], 'Foo2') self.assertEqual(self.entity["female"], "Foo2")
self.assertRaises(KeyError, self.entity.get_value, 'male') self.assertRaises(KeyError, self.entity.get_value, "male")
def test_complex5(self): def test_complex5(self):
self.entity.value = ComplexValue({'male':'Foo2','female':'Foo3'}) self.entity.value = ComplexValue({"male": "Foo2", "female": "Foo3"})
self.assertEqual(self.entity['male'], 'Foo2') self.assertEqual(self.entity["male"], "Foo2")
def test_complex6(self): def test_complex6(self):
self.entity.value = ComplexValue(['foo','foo4']) self.entity.value = ComplexValue(["foo", "foo4"])
self.assertEqual(self.entity[1], 'foo4') self.assertEqual(self.entity[1], "foo4")
def test_complex7(self): def test_complex7(self):
self.entity.value = ComplexValue('Foo') self.entity.value = ComplexValue("Foo")
self.assertRaises(TypeError, self.entity.__getitem__, 0) self.assertRaises(TypeError, self.entity.__getitem__, 0)
def test_complex8(self): def test_complex8(self):
self.entity.value = ComplexValue('Foo') self.entity.value = ComplexValue("Foo")
self.assertRaises(TypeError, self.entity.__getitem__, 0) self.assertRaises(TypeError, self.entity.__getitem__, 0)
self.entity.value = ComplexValue(['Foo3','Foo4']) self.entity.value = ComplexValue(["Foo3", "Foo4"])
self.assertEqual(self.entity[1], 'Foo4') self.assertEqual(self.entity[1], "Foo4")
self.entity.value = ComplexValue({'one':'Foo5','few':'Foo6','many':'Foo7'}) self.entity.value = ComplexValue({"one": "Foo5", "few": "Foo6", "many": "Foo7"})
self.assertEqual(self.entity['few'], 'Foo6') self.assertEqual(self.entity["few"], "Foo6")
def test_complex9(self): def test_complex9(self):
self.entity.value = ComplexValue('Foo') self.entity.value = ComplexValue("Foo")
self.assertEqual(self.entity.value, 'Foo') self.assertEqual(self.entity.value, "Foo")
self.entity.value = ComplexValue(['Foo3','Foo4']) self.entity.value = ComplexValue(["Foo3", "Foo4"])
self.assertEqual(self.entity.value, 'Foo3') self.assertEqual(self.entity.value, "Foo3")
self.entity.value = ComplexValue(OrderedDict((('one','Foo5'),('few','Foo6'),('many','Foo7')))) self.entity.value = ComplexValue(
self.assertEqual(self.entity.value, 'Foo5') OrderedDict((("one", "Foo5"), ("few", "Foo6"), ("many", "Foo7")))
)
self.assertEqual(self.entity.value, "Foo5")
def test_custom1(self): def test_custom1(self):
def plural_form(value, n=1): def plural_form(value, n=1):
return value[0 if n==1 else 1] return value[0 if n == 1 else 1]
self.entity._select_value = plural_form self.entity._select_value = plural_form
self.entity.value = ['Firefox', 'Firefoxes'] self.entity.value = ["Firefox", "Firefoxes"]
self.assertEqual(self.entity.value, 'Firefox') self.assertEqual(self.entity.value, "Firefox")
self.assertEqual(self.entity.get_value(1), 'Firefox') self.assertEqual(self.entity.get_value(1), "Firefox")
self.assertEqual(self.entity.get_value(5), 'Firefoxes') self.assertEqual(self.entity.get_value(5), "Firefoxes")
def test_values1(self): def test_values1(self):
vals = ['foo', 'foo2'] vals = ["foo", "foo2"]
self.entity.value = vals self.entity.value = vals
vals.pop() vals.pop()
self.assertNotEqual(self.entity.values, vals) self.assertNotEqual(self.entity.values, vals)
#x = self.entity.values # x = self.entity.values
#x.pop() # x.pop()
#self.assertEqual(x, vals) # self.assertEqual(x, vals)
#self.assertNotEqual(self.entity.values, x) # self.assertNotEqual(self.entity.values, x)

Просмотреть файл

@ -1,127 +1,125 @@
import random
import unittest import unittest
import sys
import silme.core import silme.core
class EntityTestCase(unittest.TestCase):
class EntityTestCase(unittest.TestCase):
def setUp(self): def setUp(self):
self.entity_list = silme.core.EntityList('test') self.entity_list = silme.core.EntityList("test")
def test_init1(self): def test_init1(self):
self.assertEqual(self.entity_list.id, 'test') self.assertEqual(self.entity_list.id, "test")
def test_init2(self): def test_init2(self):
self.assertRaises(AttributeError, silme.core.EntityList, 'test', 'foo') self.assertRaises(AttributeError, silme.core.EntityList, "test", "foo")
def test_init3(self): def test_init3(self):
entity1 = silme.core.Entity('x') entity1 = silme.core.Entity("x")
entity2 = silme.core.Entity('y') entity2 = silme.core.Entity("y")
self.entity_list = silme.core.EntityList('test', entity1, entity2) self.entity_list = silme.core.EntityList("test", entity1, entity2)
self.assertEqual(self.entity_list['x'], entity1) self.assertEqual(self.entity_list["x"], entity1)
self.assertEqual(self.entity_list['y'], entity2) self.assertEqual(self.entity_list["y"], entity2)
def test_init4(self): def test_init4(self):
entity1 = silme.core.Entity('x') entity1 = silme.core.Entity("x")
entity2 = silme.core.Entity('y') entity2 = silme.core.Entity("y")
entity_list = silme.core.EntityList('test', entity1, entity2) entity_list = silme.core.EntityList("test", entity1, entity2)
self.entity_list = silme.core.EntityList('id2', entity_list) self.entity_list = silme.core.EntityList("id2", entity_list)
self.assertEqual(self.entity_list['x'], entity1) self.assertEqual(self.entity_list["x"], entity1)
self.assertEqual(self.entity_list['y'], entity2) self.assertEqual(self.entity_list["y"], entity2)
def test_has_entity1(self): def test_has_entity1(self):
entity1 = silme.core.Entity('x') entity1 = silme.core.Entity("x")
self.entity_list.add(entity1) self.entity_list.add(entity1)
self.assertEqual('x' in self.entity_list, True) self.assertEqual("x" in self.entity_list, True)
def test_get_entities1(self): def test_get_entities1(self):
entity1 = silme.core.Entity('x') entity1 = silme.core.Entity("x")
entity2 = silme.core.Entity('y') entity2 = silme.core.Entity("y")
self.entity_list.add(entity1) self.entity_list.add(entity1)
self.entity_list.add(entity2) self.entity_list.add(entity2)
l = self.entity_list.entities() entities = self.entity_list.entities()
self.assertTrue(l[0].id in ('x', 'y')) self.assertTrue(entities[0].id in ("x", "y"))
self.assertTrue(l[1].id in ('x', 'y')) self.assertTrue(entities[1].id in ("x", "y"))
self.assertNotEqual(l[0].id, l[1].id) self.assertNotEqual(entities[0].id, entities[1].id)
def test_iter_entities(self): def test_iter_entities(self):
entity1 = silme.core.Entity('x') entity1 = silme.core.Entity("x")
entity2 = silme.core.Entity('y') entity2 = silme.core.Entity("y")
entity3 = silme.core.Entity('z') entity3 = silme.core.Entity("z")
self.entity_list.add(entity1) self.entity_list.add(entity1)
self.entity_list.add(entity2) self.entity_list.add(entity2)
self.entity_list.add(entity3) self.entity_list.add(entity3)
for id in self.entity_list: for id in self.entity_list:
self.assertTrue(id in ('x','y','z')) self.assertTrue(id in ("x", "y", "z"))
def test_entity_ids1(self): def test_entity_ids1(self):
entity1 = silme.core.Entity('x') entity1 = silme.core.Entity("x")
entity2 = silme.core.Entity('y') entity2 = silme.core.Entity("y")
self.entity_list.add(entity1) self.entity_list.add(entity1)
self.entity_list.add(entity2) self.entity_list.add(entity2)
ids = self.entity_list.keys() ids = self.entity_list.keys()
self.assertEqual('x' in ids, True) self.assertEqual("x" in ids, True)
self.assertEqual('y' in ids, True) self.assertEqual("y" in ids, True)
def test_modify_entity1(self): def test_modify_entity1(self):
entity1 = silme.core.Entity('x') entity1 = silme.core.Entity("x")
self.entity_list.add(entity1) self.entity_list.add(entity1)
self.entity_list.modify('x', 'test2') self.entity_list.modify("x", "test2")
self.assertEqual(self.entity_list['x'].value, 'test2') self.assertEqual(self.entity_list["x"].value, "test2")
def test_modify_entity2(self): def test_modify_entity2(self):
entity1 = silme.core.Entity('x', 'foo') entity1 = silme.core.Entity("x", "foo")
entity1.set_value('heh') entity1.set_value("heh")
self.entity_list.add(entity1) self.entity_list.add(entity1)
self.entity_list.modify('x', 'test2') self.entity_list.modify("x", "test2")
self.assertEqual(self.entity_list['x'].get_value(), 'test2') self.assertEqual(self.entity_list["x"].get_value(), "test2")
def test_entity1(self): def test_entity1(self):
entity1 = silme.core.Entity('x', 'foo') entity1 = silme.core.Entity("x", "foo")
self.entity_list.add(entity1) self.entity_list.add(entity1)
self.assertEqual(self.entity_list['x'], entity1) self.assertEqual(self.entity_list["x"], entity1)
def test_get_value(self): def test_get_value(self):
entity1 = silme.core.Entity('x') entity1 = silme.core.Entity("x")
entity1.set_value('test') entity1.set_value("test")
self.entity_list.add(entity1) self.entity_list.add(entity1)
self.assertEqual(self.entity_list.value('x'), 'test') self.assertEqual(self.entity_list.value("x"), "test")
def test_ordered_list(self): def test_ordered_list(self):
self.entity_list = silme.core.EntityList('test', ordered=True) self.entity_list = silme.core.EntityList("test", ordered=True)
ids = ('id1', 'id2', 'id3') ids = ("id1", "id2", "id3")
for i in ids: for i in ids:
self.entity_list.add(silme.core.Entity(i)) self.entity_list.add(silme.core.Entity(i))
n = 0 n = 0
for i in self.entity_list.keys(): for i in self.entity_list.keys():
self.assertEqual(i, ids[n]) self.assertEqual(i, ids[n])
n+=1 n += 1
n = 0 n = 0
for i in self.entity_list: for i in self.entity_list:
self.assertEqual(i, ids[n]) self.assertEqual(i, ids[n])
n+=1 n += 1
def test_lazy_list(self): def test_lazy_list(self):
self.entity_list = silme.core.EntityList('test', lazy=True) self.entity_list = silme.core.EntityList("test", lazy=True)
def resolve(key, value): def resolve(key, value):
return silme.core.Entity(key, value) return silme.core.Entity(key, value)
self.entity_list.set_stub('id1', resolve, 'Foo1') self.entity_list.set_stub("id1", resolve, "Foo1")
self.assertTrue(len(self.entity_list._stubs), 1) self.assertTrue(len(self.entity_list._stubs), 1)
self.assertTrue(self.entity_list._stubs, set('id1')) self.assertTrue(self.entity_list._stubs, set("id1"))
e = self.entity_list['id1'] e = self.entity_list["id1"]
self.assertEqual(e.id, 'id1') self.assertEqual(e.id, "id1")
self.assertEqual(e.value, 'Foo1') self.assertEqual(e.value, "Foo1")
self.assertEqual(len(self.entity_list._stubs), 0) self.assertEqual(len(self.entity_list._stubs), 0)
def test_value_list1(self): def test_value_list1(self):
vlist = silme.core.list.ValueList('test') vlist = silme.core.list.ValueList("test")
vlist.add(silme.core.Entity('id1', 'Foo1')) vlist.add(silme.core.Entity("id1", "Foo1"))
self.assertEqual(vlist['id1'], 'Foo1') self.assertEqual(vlist["id1"], "Foo1")
def test_value_list2(self): def test_value_list2(self):
vlist = silme.core.list.ValueList('test') vlist = silme.core.list.ValueList("test")
vlist.add(silme.core.Entity('id1', 'Foo1')) vlist.add(silme.core.Entity("id1", "Foo1"))
self.assertRaises(TypeError, vlist.entities) self.assertRaises(TypeError, vlist.entities)

Просмотреть файл

@ -1,88 +1,89 @@
import random
import unittest import unittest
import sys
import silme.core import silme.core
class EntityTestCase(unittest.TestCase):
class EntityTestCase(unittest.TestCase):
def setUp(self): def setUp(self):
self.l10npackage = silme.core.Package('test') self.l10npackage = silme.core.Package("test")
def test_id(self): def test_id(self):
self.assertEqual(self.l10npackage.id, 'test') self.assertEqual(self.l10npackage.id, "test")
def test_add_structure(self): def test_add_structure(self):
l10nobject = silme.core.Structure('foo') l10nobject = silme.core.Structure("foo")
self.l10npackage.add_structure(l10nobject) self.l10npackage.add_structure(l10nobject)
self.assertEqual(len(self.l10npackage.structures()), 1) self.assertEqual(len(self.l10npackage.structures()), 1)
def test_add_structure2(self): def test_add_structure2(self):
l10nobject = silme.core.Structure('foo') l10nobject = silme.core.Structure("foo")
self.l10npackage.add_structure(l10nobject, 'test2/test3') self.l10npackage.add_structure(l10nobject, "test2/test3")
self.assertEqual(len(self.l10npackage.packages()), 1) self.assertEqual(len(self.l10npackage.packages()), 1)
self.assertEqual(self.l10npackage.packages()[0].id, 'test2') self.assertEqual(self.l10npackage.packages()[0].id, "test2")
self.assertEqual(self.l10npackage.packages()[0].packages()[0].id, 'test3') self.assertEqual(self.l10npackage.packages()[0].packages()[0].id, "test3")
self.assertEqual(self.l10npackage.packages()[0].packages()[0].structure('foo').id, 'foo') self.assertEqual(
self.l10npackage.packages()[0].packages()[0].structure("foo").id, "foo"
)
def test_add_package(self): def test_add_package(self):
l10npack = silme.core.Package('foo') l10npack = silme.core.Package("foo")
self.l10npackage.add_package(l10npack) self.l10npackage.add_package(l10npack)
self.assertEqual(len(self.l10npackage.packages()), 1) self.assertEqual(len(self.l10npackage.packages()), 1)
def test_add_package2(self): def test_add_package2(self):
l10npack = silme.core.Package('foo') l10npack = silme.core.Package("foo")
self.l10npackage.add_package(l10npack, 'test2/test3') self.l10npackage.add_package(l10npack, "test2/test3")
self.assertEqual(len(self.l10npackage.packages()), 1) self.assertEqual(len(self.l10npackage.packages()), 1)
self.assertEqual(self.l10npackage.packages()[0].id, 'test2') self.assertEqual(self.l10npackage.packages()[0].id, "test2")
self.assertEqual(self.l10npackage.packages()[0].packages()[0].id, 'test3') self.assertEqual(self.l10npackage.packages()[0].packages()[0].id, "test3")
self.assertEqual(self.l10npackage.packages()[0].packages()[0].package('foo').id, 'foo') self.assertEqual(
self.l10npackage.packages()[0].packages()[0].package("foo").id, "foo"
)
def test_get_objects(self): def test_get_objects(self):
self.l10npackage.add_structure(silme.core.Structure('foo')) self.l10npackage.add_structure(silme.core.Structure("foo"))
self.l10npackage.add_structure(silme.core.Structure('foo2')) self.l10npackage.add_structure(silme.core.Structure("foo2"))
self.l10npackage.add_structure(silme.core.Structure('foo3')) self.l10npackage.add_structure(silme.core.Structure("foo3"))
self.assertEqual(self.l10npackage.structures()[0].id, 'foo') self.assertEqual(self.l10npackage.structures()[0].id, "foo")
self.assertEqual(self.l10npackage.structures()[1].id, 'foo2') self.assertEqual(self.l10npackage.structures()[1].id, "foo2")
self.assertEqual(self.l10npackage.structures()[2].id, 'foo3') self.assertEqual(self.l10npackage.structures()[2].id, "foo3")
def test_get_objects2(self): def test_get_objects2(self):
self.l10npackage.add_structure(silme.core.Structure('foo')) self.l10npackage.add_structure(silme.core.Structure("foo"))
self.l10npackage.add_structure(silme.core.Structure('foo2')) self.l10npackage.add_structure(silme.core.Structure("foo2"))
self.l10npackage.add_structure(silme.core.Structure('foo3')) self.l10npackage.add_structure(silme.core.Structure("foo3"))
self.assertEqual(self.l10npackage.structures(ids=True), ['foo', 'foo2', 'foo3']) self.assertEqual(self.l10npackage.structures(ids=True), ["foo", "foo2", "foo3"])
def test_get_packages(self): def test_get_packages(self):
self.l10npackage.add_package(silme.core.Package('foo')) self.l10npackage.add_package(silme.core.Package("foo"))
self.l10npackage.add_package(silme.core.Package('foo2')) self.l10npackage.add_package(silme.core.Package("foo2"))
self.l10npackage.add_package(silme.core.Package('foo3')) self.l10npackage.add_package(silme.core.Package("foo3"))
self.assertEqual(self.l10npackage.packages()[0].id, 'foo') self.assertEqual(self.l10npackage.packages()[0].id, "foo")
self.assertEqual(self.l10npackage.packages()[1].id, 'foo2') self.assertEqual(self.l10npackage.packages()[1].id, "foo2")
self.assertEqual(self.l10npackage.packages()[2].id, 'foo3') self.assertEqual(self.l10npackage.packages()[2].id, "foo3")
def test_get_packages2(self): def test_get_packages2(self):
self.l10npackage.add_package(silme.core.Package('foo')) self.l10npackage.add_package(silme.core.Package("foo"))
self.l10npackage.add_package(silme.core.Package('foo2')) self.l10npackage.add_package(silme.core.Package("foo2"))
self.l10npackage.add_package(silme.core.Package('foo3')) self.l10npackage.add_package(silme.core.Package("foo3"))
self.assertEqual(self.l10npackage.packages(ids=True), ['foo', 'foo2', 'foo3']) self.assertEqual(self.l10npackage.packages(ids=True), ["foo", "foo2", "foo3"])
def test_get_entities(self): def test_get_entities(self):
l10nobject = silme.core.Structure('foo') l10nobject = silme.core.Structure("foo")
l10nobject.add_entity(silme.core.Entity('entid')) l10nobject.add_entity(silme.core.Entity("entid"))
l10nobject2 = silme.core.Structure('foo2') l10nobject2 = silme.core.Structure("foo2")
l10nobject2.add_entity(silme.core.Entity('entid2')) l10nobject2.add_entity(silme.core.Entity("entid2"))
self.l10npackage.add_structure(l10nobject) self.l10npackage.add_structure(l10nobject)
self.l10npackage.add_structure(l10nobject2) self.l10npackage.add_structure(l10nobject2)
entities = self.l10npackage.entities() entities = self.l10npackage.entities()
self.assertEqual(len(entities), 2) self.assertEqual(len(entities), 2)
def test_get_entities2(self): def test_get_entities2(self):
l10nobject = silme.core.Structure('foo') l10nobject = silme.core.Structure("foo")
l10nobject.add_entity(silme.core.Entity('entid')) l10nobject.add_entity(silme.core.Entity("entid"))
l10nobject2 = silme.core.Structure('foo2') l10nobject2 = silme.core.Structure("foo2")
l10nobject.add_entity(silme.core.Entity('entid2')) l10nobject.add_entity(silme.core.Entity("entid2"))
l10npack = silme.core.Package('test2') l10npack = silme.core.Package("test2")
l10npack.add_structure(l10nobject) l10npack.add_structure(l10nobject)
l10npack.add_structure(l10nobject2) l10npack.add_structure(l10nobject2)
self.l10npackage.add_package(l10npack) self.l10npackage.add_package(l10npack)
@ -92,53 +93,61 @@ class EntityTestCase(unittest.TestCase):
self.assertEqual(len(entities), 0) self.assertEqual(len(entities), 0)
def test_get_entities_with_path(self): def test_get_entities_with_path(self):
l10nobject = silme.core.Structure('foo') l10nobject = silme.core.Structure("foo")
l10nobject.add_entity(silme.core.Entity('entid')) l10nobject.add_entity(silme.core.Entity("entid"))
l10nobject2 = silme.core.Structure('foo2') l10nobject2 = silme.core.Structure("foo2")
l10nobject.add_entity(silme.core.Entity('entid2')) l10nobject.add_entity(silme.core.Entity("entid2"))
l10npack = silme.core.Package('test2') l10npack = silme.core.Package("test2")
l10npack.add_structure(l10nobject) l10npack.add_structure(l10nobject)
l10npack.add_structure(l10nobject2) l10npack.add_structure(l10nobject2)
self.l10npackage.add_package(l10npack) self.l10npackage.add_package(l10npack)
entities = self.l10npackage.entities(recursive=True, path=True) entities = self.l10npackage.entities(recursive=True, path=True)
self.assertEqual(entities[0][1], 'test2/foo') self.assertEqual(entities[0][1], "test2/foo")
entities = self.l10npackage.package('test2').entities(recursive=True, path=True) entities = self.l10npackage.package("test2").entities(recursive=True, path=True)
self.assertEqual(entities[0][1], 'foo') self.assertEqual(entities[0][1], "foo")
def test_package_lazy_by_default(self): def test_package_lazy_by_default(self):
self.assertEqual(self.l10npackage.lazy, True) self.assertEqual(self.l10npackage.lazy, True)
def test_package__stub_exceptions_if_not_lazy(self): def test_package__stub_exceptions_if_not_lazy(self):
pack = silme.core.Package('id1', lazy=False) pack = silme.core.Package("id1", lazy=False)
self.assertRaises(Exception, pack.add_package_stub, self.assertRaises(
'id1', Exception,
lambda x:silme.core.Package('test1')) pack.add_package_stub,
self.assertRaises(Exception, pack.add_structure_stub, "id1",
'id1', lambda x: silme.core.Package("test1"),
lambda x:silme.core.Structure('id1')) )
self.assertRaises(
Exception,
pack.add_structure_stub,
"id1",
lambda x: silme.core.Structure("id1"),
)
def test_package_add_structure_stub(self): def test_package_add_structure_stub(self):
def resolver(id): def resolver(id):
return silme.core.Structure(id) return silme.core.Structure(id)
pack = silme.core.Package('id1', lazy=True)
pack.add_structure_stub('id1', resolver) pack = silme.core.Package("id1", lazy=True)
pack.add_structure_stub("id1", resolver)
self.assertEqual(len(pack), 1) self.assertEqual(len(pack), 1)
self.assertEqual('id1' in pack, True) self.assertEqual("id1" in pack, True)
self.assertEqual(len(pack.structures(ids=True)), 1) self.assertEqual(len(pack.structures(ids=True)), 1)
self.assertEqual(len(pack._structures._stubs), 1) self.assertEqual(len(pack._structures._stubs), 1)
self.assertEqual(pack.has_structure('id1'), True) self.assertEqual(pack.has_structure("id1"), True)
self.assertEqual(pack.structure('id1').id, 'id1') self.assertEqual(pack.structure("id1").id, "id1")
self.assertEqual(len(pack._structures._stubs), 0) self.assertEqual(len(pack._structures._stubs), 0)
def test_package_add_package_stub(self): def test_package_add_package_stub(self):
def resolver(id): def resolver(id):
return silme.core.Package(id) return silme.core.Package(id)
pack = silme.core.Package('id1', lazy=True)
pack.add_package_stub('id1', resolver) pack = silme.core.Package("id1", lazy=True)
pack.add_package_stub("id1", resolver)
self.assertEqual(len(pack), 1) self.assertEqual(len(pack), 1)
self.assertEqual('id1' in pack, True) self.assertEqual("id1" in pack, True)
self.assertEqual(len(pack.packages(ids=True)), 1) self.assertEqual(len(pack.packages(ids=True)), 1)
self.assertEqual(len(pack._packages._stubs), 1) self.assertEqual(len(pack._packages._stubs), 1)
self.assertEqual(pack.has_package('id1'), True) self.assertEqual(pack.has_package("id1"), True)
self.assertEqual(pack.package('id1').id, 'id1') self.assertEqual(pack.package("id1").id, "id1")
self.assertEqual(len(pack._packages._stubs), 0) self.assertEqual(len(pack._packages._stubs), 0)

Просмотреть файл

@ -1,154 +1,153 @@
import random
import unittest import unittest
import sys
import re import re
import silme.core import silme.core
class structureTestCase(unittest.TestCase):
class structureTestCase(unittest.TestCase):
def setUp(self): def setUp(self):
self.structure = silme.core.Structure('id') self.structure = silme.core.Structure("id")
def test_id(self): def test_id(self):
self.structure.id = 'test' self.structure.id = "test"
self.assertEqual(self.structure.id, 'test') self.assertEqual(self.structure.id, "test")
def test_add_element(self): def test_add_at_pos(self):
entity = silme.core.Entity('entid') entity = silme.core.Entity("entid")
entity2 = silme.core.Entity('entid2') entity2 = silme.core.Entity("entid2")
self.structure.add_at_pos(entity, 0) self.structure.add_at_pos(entity, 0)
self.structure.add_at_pos(entity2, 0) self.structure.add_at_pos(entity2, 0)
self.assertEqual(self.structure.get_entity_pos('entid'), 1) self.assertEqual(self.structure.entity_pos("entid"), 1)
self.assertEqual(self.structure.get_entity_pos('entid2'), 0) self.assertEqual(self.structure.entity_pos("entid2"), 0)
def test_add_entity(self): def test_add_entity(self):
entity = silme.core.Entity('entid') entity = silme.core.Entity("entid")
entity2 = silme.core.Entity('entid2') entity2 = silme.core.Entity("entid2")
entity3 = silme.core.Entity('entid3') entity3 = silme.core.Entity("entid3")
entity4 = silme.core.Entity('entid4') entity4 = silme.core.Entity("entid4")
# make sure add_entity returns 1 # make sure add_entity returns 1
self.assertEqual(self.structure.add_entity(entity), 1) self.assertEqual(self.structure.add_entity(entity), 1)
self.structure.add_entity(entity2, 1) self.structure.add_entity(entity2, 1)
self.structure.add_entity(entity3, 0) self.structure.add_entity(entity3, 0)
self.structure.add_entity(entity4, 1) self.structure.add_entity(entity4, 1)
self.assertEqual(self.structure.entity_pos('entid'), 2) self.assertEqual(self.structure.entity_pos("entid"), 2)
self.assertEqual(self.structure.entity_pos('entid2'), 3) self.assertEqual(self.structure.entity_pos("entid2"), 3)
self.assertEqual(self.structure.entity_pos('entid3'), 0) self.assertEqual(self.structure.entity_pos("entid3"), 0)
self.assertEqual(self.structure.entity_pos('entid4'), 1) self.assertEqual(self.structure.entity_pos("entid4"), 1)
def test_get_value(self): def test_get_value(self):
entity = silme.core.Entity('entid') entity = silme.core.Entity("entid")
entity.set_value('foo') entity.set_value("foo")
self.structure.add_entity(entity) self.structure.add_entity(entity)
self.assertEqual(self.structure.value('entid'), 'foo') self.assertEqual(self.structure.value("entid"), "foo")
def test_entities(self):
def test_get_entity(self): self.structure.add_entity(silme.core.Entity("entid"))
self.structure.add_entity(silme.core.Entity('entid')) self.structure.add_entity(silme.core.Entity("entid2"))
self.structure.add_entity(silme.core.Entity('entid2')) self.assertEqual(len(self.structure.entities()), 2)
self.assertEqual(len(self.structure.get_entities()), 2) self.assertEqual(self.structure.entities()[0].id, "entid")
self.assertEqual(self.structure.get_entities()[0].id, 'entid') self.assertEqual(self.structure.entities()[1].id, "entid2")
self.assertEqual(self.structure.get_entities()[1].id, 'entid2')
def test_get_entity_ids(self): def test_get_entity_ids(self):
self.structure.add_entity(silme.core.Entity('entid')) self.structure.add_entity(silme.core.Entity("entid"))
self.structure.add_entity(silme.core.Entity('entid2')) self.structure.add_entity(silme.core.Entity("entid2"))
self.assertEqual(self.structure.ids(), ['entid', 'entid2']) self.assertEqual(self.structure.ids(), ["entid", "entid2"])
def test_has_entity(self): def test_has_entity(self):
self.structure.add_entity(silme.core.Entity('entid')) self.structure.add_entity(silme.core.Entity("entid"))
self.structure.add_entity(silme.core.Entity('entid2')) self.structure.add_entity(silme.core.Entity("entid2"))
self.assertEqual(len(self.structure.entities()), 2) self.assertEqual(len(self.structure.entities()), 2)
self.assertEqual(self.structure.has_entity('entid'), True) self.assertEqual(self.structure.has_entity("entid"), True)
self.assertEqual(self.structure.has_entity('entid3'), False) self.assertEqual(self.structure.has_entity("entid3"), False)
def test_modify_entity(self): def test_modify_entity(self):
entity = silme.core.Entity('entid') entity = silme.core.Entity("entid")
entity.set_value('testvalue') entity.set_value("testvalue")
self.structure.add_entity(entity) self.structure.add_entity(entity)
self.assertEqual(self.structure.modify_entity('entid', 'newvalue'), True) self.assertEqual(self.structure.modify_entity("entid", "newvalue"), True)
self.assertEqual(entity.get_value(), 'newvalue') self.assertEqual(entity.get_value(), "newvalue")
def test_modify_entity2(self): def test_modify_entity2(self):
entity = silme.core.Entity('entid') entity = silme.core.Entity("entid")
entity.set_value('testvalue') entity.set_value("testvalue")
self.structure.add_entity(entity) self.structure.add_entity(entity)
self.assertRaises(KeyError, self.structure.modify_entity, 'endid', 'newvalue') self.assertRaises(KeyError, self.structure.modify_entity, "endid", "newvalue")
def test_modify_entity3(self): def test_modify_entity3(self):
entity = silme.core.Entity('entid') entity = silme.core.Entity("entid")
entity.default_code = 'pl' entity.default_code = "pl"
entity.set_value('testvalue') entity.set_value("testvalue")
self.structure.add_entity(entity) self.structure.add_entity(entity)
self.structure.modify_entity('entid', 'newvalue') self.structure.modify_entity("entid", "newvalue")
self.assertEqual(entity.get_value(), 'newvalue') self.assertEqual(entity.get_value(), "newvalue")
def test_get_entity(self): def test_get_entity(self):
entity = silme.core.Entity('entid') entity = silme.core.Entity("entid")
self.structure.add_entity(entity) self.structure.add_entity(entity)
self.assertEqual(self.structure.entity('entid'), entity) self.assertEqual(self.structure.entity("entid"), entity)
self.assertRaises(KeyError, self.structure.entity, 'endid') self.assertRaises(KeyError, self.structure.entity, "endid")
def test_get_entity_pos(self): def test_get_entity_pos(self):
entity = silme.core.Entity('entid') entity = silme.core.Entity("entid")
self.structure.add_string('foo') self.structure.add_string("foo")
self.structure.add_entity(silme.core.Entity('entityid2')) self.structure.add_entity(silme.core.Entity("entityid2"))
self.structure.add_string('foo') self.structure.add_string("foo")
self.structure.add_entity(entity) self.structure.add_entity(entity)
self.structure.add_string('foo') self.structure.add_string("foo")
self.assertEqual(self.structure.entity_pos('entid'), 3) self.assertEqual(self.structure.entity_pos("entid"), 3)
def test_remove_entity(self): def test_remove_entity(self):
entity = silme.core.Entity('entid') entity = silme.core.Entity("entid")
self.structure.add_entity(silme.core.Entity('entityid3')) self.structure.add_entity(silme.core.Entity("entityid3"))
self.structure.add_entity(entity) self.structure.add_entity(entity)
self.structure.add_entity(silme.core.Entity('entityid2')) self.structure.add_entity(silme.core.Entity("entityid2"))
self.assertEqual(self.structure.remove_entity('entid'), True) self.assertEqual(self.structure.remove_entity("entid"), True)
self.assertRaises(KeyError, self.structure.entity, 'endid') self.assertRaises(KeyError, self.structure.entity, "endid")
def test_add_element(self): def test_add_element(self):
entity = silme.core.Entity('entid') entity = silme.core.Entity("entid")
comment = silme.core.Comment() comment = silme.core.Comment()
comment.add('foo') comment.add("foo")
str = 'foo' str = "foo"
self.assertEqual(self.structure.add(entity), 1) self.assertEqual(self.structure.add(entity), 1)
self.assertEqual(self.structure.add(comment), 1) self.assertEqual(self.structure.add(comment), 1)
self.assertEqual(self.structure.add(str), 1) self.assertEqual(self.structure.add(str), 1)
self.assertRaises(Exception, self.structure.add, sys) self.assertRaises(Exception, self.structure.add, {})
def test_add_elements(self): def test_add_elements(self):
entity = silme.core.Entity('entid') entity = silme.core.Entity("entid")
comment = silme.core.Comment() comment = silme.core.Comment()
comment.add('foo') comment.add("foo")
str = 'foo' str = "foo"
list = [entity, comment, entity, str] list = [entity, comment, entity, str]
self.assertEqual(self.structure.add_elements(list), 4) self.assertEqual(self.structure.add_elements(list), 4)
def test_get_entitylist(self): def test_get_entitylist(self):
self.structure.add_string('foo') self.structure.add_string("foo")
self.structure.add_entity(silme.core.Entity('entid')) self.structure.add_entity(silme.core.Entity("entid"))
self.structure.add_string('foo') self.structure.add_string("foo")
self.structure.add_entity(silme.core.Entity('entid2')) self.structure.add_entity(silme.core.Entity("entid2"))
self.structure.add_string('foo') self.structure.add_string("foo")
entitylist = self.structure.entitylist() entitylist = self.structure.entitylist()
self.assertEqual(len(entitylist.entities()), 2) self.assertEqual(len(entitylist.entities()), 2)
self.assertEqual(entitylist['entid'].id, 'entid') self.assertEqual(entitylist["entid"].id, "entid")
self.assertEqual(entitylist['entid2'].id, 'entid2') self.assertEqual(entitylist["entid2"].id, "entid2")
def test_process(self): def test_process(self):
def process_entity(entity, subs): def process_entity(entity, subs):
entity.value = re.sub(r'\&([^$]+)\;', entity.value = re.sub(
lambda m:subs[m.group(1)], r"\&([^$]+)\;", lambda m: subs[m.group(1)], str(entity.value)
str(entity.value)) )
def process(self): def process(self):
for elem in self: for elem in self:
if isinstance(elem, silme.core.Entity): if isinstance(elem, silme.core.Entity):
process_entity(elem, self.params['exents']) process_entity(elem, self.params["exents"])
self.structure.set_process_cb(process) self.structure.set_process_cb(process)
entity1 = silme.core.Entity('id', 'Test &varMe; it') entity1 = silme.core.Entity("id", "Test &varMe; it")
self.structure.params = {} self.structure.params = {}
self.structure.params['exents'] = {'varMe': 'Woo'} self.structure.params["exents"] = {"varMe": "Woo"}
self.structure.add_entity(entity1) self.structure.add_entity(entity1)
self.structure.process() self.structure.process()
self.assertEqual(self.structure.value('id'), 'Test Woo it') self.assertEqual(self.structure.value("id"), "Test Woo it")

Просмотреть файл

@ -1,8 +1,8 @@
import unittest import unittest
import sys
from silme.core.types.lazydict import LazyDict from silme.core.types.lazydict import LazyDict
class LazyDictTestCase(unittest.TestCase): class LazyDictTestCase(unittest.TestCase):
def test_constructor(self): def test_constructor(self):
# calling built-in types without argument must return empty # calling built-in types without argument must return empty
@ -18,65 +18,66 @@ class LazyDictTestCase(unittest.TestCase):
def test_keys(self): def test_keys(self):
d = LazyDict() d = LazyDict()
self.assertEqual(set(d.keys()), set()) self.assertEqual(set(d.keys()), set())
d = LazyDict({'a': 1, 'b': 2}) d = LazyDict({"a": 1, "b": 2})
k = d.keys() k = d.keys()
self.assertTrue('a' in d) self.assertTrue("a" in d)
self.assertTrue('b' in d) self.assertTrue("b" in d)
self.assertEqual(set(k), {'a','b'}) self.assertEqual(set(k), {"a", "b"})
self.assertRaises(TypeError, d.keys, None) self.assertRaises(TypeError, d.keys, None)
def test_values(self): def test_values(self):
d = LazyDict() d = LazyDict()
self.assertEqual(set(d.values()), set()) self.assertEqual(set(d.values()), set())
d = LazyDict({1:2}) d = LazyDict({1: 2})
self.assertEqual(set(d.values()), {2}) self.assertEqual(set(d.values()), {2})
self.assertRaises(TypeError, d.values, None) self.assertRaises(TypeError, d.values, None)
#self.assertEqual(repr(dict(a=1).values()), "dict_values([1])") # self.assertEqual(repr(dict(a=1).values()), "dict_values([1])")
def test_items(self): def test_items(self):
d = LazyDict() d = LazyDict()
self.assertEqual(set(d.items()), set()) self.assertEqual(set(d.items()), set())
d = LazyDict({1:2}) d = LazyDict({1: 2})
self.assertEqual(set(d.items()), {(1, 2)}) self.assertEqual(set(d.items()), {(1, 2)})
self.assertRaises(TypeError, d.items, None) self.assertRaises(TypeError, d.items, None)
def test_contains(self): def test_contains(self):
d = LazyDict() d = LazyDict()
self.assertNotIn('a', d) self.assertNotIn("a", d)
self.assertFalse('a' in d) self.assertFalse("a" in d)
self.assertTrue('a' not in d) self.assertTrue("a" not in d)
d = LazyDict({'a': 1, 'b': 2}) d = LazyDict({"a": 1, "b": 2})
self.assertIn('a', d) self.assertIn("a", d)
self.assertIn('b', d) self.assertIn("b", d)
self.assertNotIn('c', d) self.assertNotIn("c", d)
self.assertRaises(TypeError, d.__contains__) self.assertRaises(TypeError, d.__contains__)
def test_len(self): def test_len(self):
d = LazyDict() d = LazyDict()
self.assertEqual(len(d), 0) self.assertEqual(len(d), 0)
d = LazyDict({'a': 1, 'b': 2}) d = LazyDict({"a": 1, "b": 2})
self.assertEqual(len(d), 2) self.assertEqual(len(d), 2)
def test_getitem(self): def test_getitem(self):
d = LazyDict({'a': 1, 'b': 2}) d = LazyDict({"a": 1, "b": 2})
self.assertEqual(d['a'], 1) self.assertEqual(d["a"], 1)
self.assertEqual(d['b'], 2) self.assertEqual(d["b"], 2)
d['c'] = 3 d["c"] = 3
d['a'] = 4 d["a"] = 4
self.assertEqual(d['c'], 3) self.assertEqual(d["c"], 3)
self.assertEqual(d['a'], 4) self.assertEqual(d["a"], 4)
del d['b'] del d["b"]
self.assertEqual(d, {'a': 4, 'c': 3}) self.assertEqual(d, {"a": 4, "c": 3})
self.assertRaises(TypeError, d.__getitem__) self.assertRaises(TypeError, d.__getitem__)
class BadEq(object): class BadEq:
def __eq__(self, other): def __eq__(self, other):
raise Exc() raise Exc()
def __hash__(self): def __hash__(self):
return 24 return 24
@ -84,10 +85,12 @@ class LazyDictTestCase(unittest.TestCase):
d[BadEq()] = 42 d[BadEq()] = 42
self.assertRaises(KeyError, d.__getitem__, 23) self.assertRaises(KeyError, d.__getitem__, 23)
class Exc(Exception): pass class Exc(Exception):
pass
class BadHash(object): class BadHash:
fail = False fail = False
def __hash__(self): def __hash__(self):
if self.fail: if self.fail:
raise Exc() raise Exc()
@ -100,7 +103,7 @@ class LazyDictTestCase(unittest.TestCase):
self.assertRaises(Exc, d.__getitem__, x) self.assertRaises(Exc, d.__getitem__, x)
def test_clear(self): def test_clear(self):
d = LazyDict({1:1, 2:2, 3:3}) d = LazyDict({1: 1, 2: 2, 3: 3})
d.clear() d.clear()
self.assertEqual(d, {}) self.assertEqual(d, {})
@ -108,33 +111,39 @@ class LazyDictTestCase(unittest.TestCase):
def test_update(self): def test_update(self):
d = LazyDict() d = LazyDict()
d.update({1:100}) d.update({1: 100})
d.update({2:20}) d.update({2: 20})
d.update({1:1, 2:2, 3:3}) d.update({1: 1, 2: 2, 3: 3})
self.assertEqual(d, {1:1, 2:2, 3:3}) self.assertEqual(d, {1: 1, 2: 2, 3: 3})
d.update() d.update()
self.assertEqual(d, {1:1, 2:2, 3:3}) self.assertEqual(d, {1: 1, 2: 2, 3: 3})
self.assertRaises((TypeError, AttributeError), d.update, None) self.assertRaises((TypeError, AttributeError), d.update, None)
class SimpleUserDict: class SimpleUserDict:
def __init__(self): def __init__(self):
self.d = {1:1, 2:2, 3:3} self.d = {1: 1, 2: 2, 3: 3}
def keys(self): def keys(self):
return self.d.keys() return self.d.keys()
def __getitem__(self, i): def __getitem__(self, i):
return self.d[i] return self.d[i]
d.clear() d.clear()
d.update(SimpleUserDict()) d.update(SimpleUserDict())
self.assertEqual(d, {1:1, 2:2, 3:3}) self.assertEqual(d, {1: 1, 2: 2, 3: 3})
class Exc(Exception): pass class Exc(Exception):
pass
d.clear() d.clear()
class FailingUserDict: class FailingUserDict:
def keys(self): def keys(self):
raise Exc raise Exc
self.assertRaises(Exc, d.update, FailingUserDict()) self.assertRaises(Exc, d.update, FailingUserDict())
class FailingUserDict: class FailingUserDict:
@ -142,43 +151,57 @@ class LazyDictTestCase(unittest.TestCase):
class BogonIter: class BogonIter:
def __init__(self): def __init__(self):
self.i = 1 self.i = 1
def __iter__(self): def __iter__(self):
return self return self
def __next__(self): def __next__(self):
if self.i: if self.i:
self.i = 0 self.i = 0
return 'a' return "a"
raise Exc raise Exc
next = __next__ next = __next__
return BogonIter() return BogonIter()
def __getitem__(self, key): def __getitem__(self, key):
return key return key
self.assertRaises(Exc, d.update, FailingUserDict()) self.assertRaises(Exc, d.update, FailingUserDict())
class FailingUserDict: class FailingUserDict:
def keys(self): def keys(self):
class BogonIter: class BogonIter:
def __init__(self): def __init__(self):
self.i = ord('a') self.i = ord("a")
def __iter__(self): def __iter__(self):
return self return self
def __next__(self): def __next__(self):
if self.i <= ord('z'): if self.i <= ord("z"):
rtn = chr(self.i) rtn = chr(self.i)
self.i += 1 self.i += 1
return rtn return rtn
raise StopIteration raise StopIteration
next = __next__ next = __next__
return BogonIter() return BogonIter()
def __getitem__(self, key): def __getitem__(self, key):
raise Exc raise Exc
self.assertRaises(Exc, d.update, FailingUserDict()) self.assertRaises(Exc, d.update, FailingUserDict())
class badseq(object): class badseq:
def __iter__(self): def __iter__(self):
return self return self
def __next__(self): def __next__(self):
raise Exc() raise Exc()
next = __next__ next = __next__
self.assertRaises(Exc, {}.update, badseq()) self.assertRaises(Exc, {}.update, badseq())
@ -186,30 +209,38 @@ class LazyDictTestCase(unittest.TestCase):
self.assertRaises(ValueError, {}.update, [(1, 2, 3)]) self.assertRaises(ValueError, {}.update, [(1, 2, 3)])
def test_fromkeys(self): def test_fromkeys(self):
self.assertEqual(LazyDict().fromkeys('abc'), {'a':None, 'b':None, 'c':None}) self.assertEqual(LazyDict().fromkeys("abc"), {"a": None, "b": None, "c": None})
d = LazyDict() d = LazyDict()
self.assertIsNot(d.fromkeys('abc'), d) self.assertIsNot(d.fromkeys("abc"), d)
self.assertEqual(d.fromkeys('abc'), LazyDict({'a':None, 'b':None, 'c':None})) self.assertEqual(d.fromkeys("abc"), LazyDict({"a": None, "b": None, "c": None}))
self.assertEqual(d.fromkeys((4,5),0), LazyDict({4:0, 5:0})) self.assertEqual(d.fromkeys((4, 5), 0), LazyDict({4: 0, 5: 0}))
self.assertEqual(d.fromkeys([]), LazyDict()) self.assertEqual(d.fromkeys([]), LazyDict())
def g(): def g():
yield 1 yield 1
self.assertEqual(d.fromkeys(g()), LazyDict({1:None}))
self.assertEqual(d.fromkeys(g()), LazyDict({1: None}))
self.assertRaises(TypeError, {}.fromkeys, 3) self.assertRaises(TypeError, {}.fromkeys, 3)
class dictlike(LazyDict): pass
self.assertEqual(dictlike.fromkeys('a'), LazyDict({'a':None})) class dictlike(LazyDict):
self.assertEqual(dictlike().fromkeys('a'), LazyDict({'a':None})) pass
self.assertTrue(type(dictlike.fromkeys('a')) is dictlike)
self.assertTrue(type(dictlike().fromkeys('a')) is dictlike) self.assertEqual(dictlike.fromkeys("a"), LazyDict({"a": None}))
self.assertEqual(dictlike().fromkeys("a"), LazyDict({"a": None}))
self.assertTrue(type(dictlike.fromkeys("a")) is dictlike)
self.assertTrue(type(dictlike().fromkeys("a")) is dictlike)
class mydict(LazyDict): class mydict(LazyDict):
def __new__(cls): def __new__(cls):
return LazyDict() return LazyDict()
ud = mydict.fromkeys('ab')
self.assertEqual(ud, LazyDict({'a':None, 'b':None})) ud = mydict.fromkeys("ab")
self.assertEqual(ud, LazyDict({"a": None, "b": None}))
self.assertTrue(isinstance(ud, LazyDict)) self.assertTrue(isinstance(ud, LazyDict))
self.assertRaises(TypeError, dict.fromkeys) self.assertRaises(TypeError, dict.fromkeys)
class Exc(Exception): pass class Exc(Exception):
pass
class baddict1(LazyDict): class baddict1(LazyDict):
def __init__(self): def __init__(self):
@ -225,42 +256,44 @@ class LazyDictTestCase(unittest.TestCase):
# test fast path for dictionary inputs # test fast path for dictionary inputs
d = LazyDict(zip(range(6), range(6))) d = LazyDict(zip(range(6), range(6)))
self.assertEqual(LazyDict.fromkeys(d, 0), LazyDict(zip(range(6), [0]*6))) self.assertEqual(LazyDict.fromkeys(d, 0), LazyDict(zip(range(6), [0] * 6)))
def test_copy(self): def test_copy(self):
d = LazyDict({1:1, 2:2, 3:3}) d = LazyDict({1: 1, 2: 2, 3: 3})
self.assertEqual(d.copy(), LazyDict({1:1, 2:2, 3:3})) self.assertEqual(d.copy(), LazyDict({1: 1, 2: 2, 3: 3}))
self.assertEqual(LazyDict().copy(), LazyDict()) self.assertEqual(LazyDict().copy(), LazyDict())
self.assertRaises(TypeError, d.copy, None) self.assertRaises(TypeError, d.copy, None)
def test_get(self): def test_get(self):
d = LazyDict() d = LazyDict()
self.assertIs(d.get('c'), None) self.assertIs(d.get("c"), None)
self.assertEqual(d.get('c', 3), 3) self.assertEqual(d.get("c", 3), 3)
d = LazyDict({'a': 1, 'b': 2}) d = LazyDict({"a": 1, "b": 2})
self.assertIs(d.get('c'), None) self.assertIs(d.get("c"), None)
self.assertEqual(d.get('c', 3), 3) self.assertEqual(d.get("c", 3), 3)
self.assertEqual(d.get('a'), 1) self.assertEqual(d.get("a"), 1)
self.assertEqual(d.get('a', 3), 1) self.assertEqual(d.get("a", 3), 1)
self.assertRaises(TypeError, d.get) self.assertRaises(TypeError, d.get)
self.assertRaises(TypeError, d.get, None, None, None) self.assertRaises(TypeError, d.get, None, None, None)
def test_setdefault(self): def test_setdefault(self):
# dict.setdefault() # dict.setdefault()
d = LazyDict() d = LazyDict()
self.assertIs(d.setdefault('key0'), None) self.assertIs(d.setdefault("key0"), None)
d.setdefault('key0', []) d.setdefault("key0", [])
self.assertIs(d.setdefault('key0'), None) self.assertIs(d.setdefault("key0"), None)
d.setdefault('key', []).append(3) d.setdefault("key", []).append(3)
self.assertEqual(d['key'][0], 3) self.assertEqual(d["key"][0], 3)
d.setdefault('key', []).append(4) d.setdefault("key", []).append(4)
self.assertEqual(len(d['key']), 2) self.assertEqual(len(d["key"]), 2)
self.assertRaises(TypeError, d.setdefault) self.assertRaises(TypeError, d.setdefault)
class Exc(Exception): pass class Exc(Exception):
pass
class BadHash(object): class BadHash:
fail = False fail = False
def __hash__(self): def __hash__(self):
if self.fail: if self.fail:
raise Exc() raise Exc()
@ -278,7 +311,7 @@ class LazyDictTestCase(unittest.TestCase):
# -1: b has same structure as a # -1: b has same structure as a
# +1: b is a.copy() # +1: b is a.copy()
for log2size in range(12): for log2size in range(12):
size = 2**log2size size = 2 ** log2size
a = LazyDict() a = LazyDict()
b = LazyDict() b = LazyDict()
for i in range(size): for i in range(size):
@ -302,9 +335,9 @@ class LazyDictTestCase(unittest.TestCase):
def test_pop(self): def test_pop(self):
# Tests for pop with specified key # Tests for pop with specified key
d = LazyDict() d = LazyDict()
k, v = 'abc', 'def' k, v = "abc", "def"
d[k] = v d[k] = v
self.assertRaises(KeyError, d.pop, 'ghi') self.assertRaises(KeyError, d.pop, "ghi")
self.assertEqual(d.pop(k), v) self.assertEqual(d.pop(k), v)
self.assertEqual(len(d), 0) self.assertEqual(len(d), 0)
@ -315,7 +348,7 @@ class LazyDictTestCase(unittest.TestCase):
# (for 64-bit archs). See SF bug #689659. # (for 64-bit archs). See SF bug #689659.
x = 4503599627370496 x = 4503599627370496
y = 4503599627370496 y = 4503599627370496
h = LazyDict({x: 'anything', y: 'something else'}) h = LazyDict({x: "anything", y: "something else"})
self.assertEqual(h[x], h[y]) self.assertEqual(h[x], h[y])
self.assertEqual(d.pop(k, v), v) self.assertEqual(d.pop(k, v), v)
@ -324,10 +357,12 @@ class LazyDictTestCase(unittest.TestCase):
self.assertRaises(TypeError, d.pop) self.assertRaises(TypeError, d.pop)
class Exc(Exception): pass class Exc(Exception):
pass
class BadHash(object): class BadHash:
fail = False fail = False
def __hash__(self): def __hash__(self):
if self.fail: if self.fail:
raise Exc() raise Exc()
@ -341,18 +376,18 @@ class LazyDictTestCase(unittest.TestCase):
def test_mutatingiteration(self): def test_mutatingiteration(self):
# changing dict size during iteration # changing dict size during iteration
#d = LazyDict() # d = LazyDict()
#d[1] = 1 # d[1] = 1
#with self.assertRaises(RuntimeError): # with self.assertRaises(RuntimeError):
# for i in d: # for i in d:
# d[i+1] = 1 # d[i+1] = 1
pass pass
def test_repr(self): def test_repr(self):
#d = LazyDict() # d = LazyDict()
#self.assertEqual(repr(d), 'LazyDict()') # self.assertEqual(repr(d), 'LazyDict()')
#d[1] = 2 # d[1] = 2
#self.assertEqual(repr(d), 'LazyDict(dict_keys([1]))') # self.assertEqual(repr(d), 'LazyDict(dict_keys([1]))')
pass pass
def test_missing(self): def test_missing(self):
@ -362,18 +397,22 @@ class LazyDictTestCase(unittest.TestCase):
# (E) subclass defines __missing__ method raising RuntimeError # (E) subclass defines __missing__ method raising RuntimeError
# (F) subclass sets __missing__ instance variable (no effect) # (F) subclass sets __missing__ instance variable (no effect)
# (G) subclass doesn't define __missing__ at a all # (G) subclass doesn't define __missing__ at a all
class D(dict): class D(dict):
def __missing__(self, key): def __missing__(self, key):
return 42 return 42
d = D({1: 2, 3: 4}) d = D({1: 2, 3: 4})
self.assertEqual(d[1], 2) self.assertEqual(d[1], 2)
self.assertEqual(d[3], 4) self.assertEqual(d[3], 4)
self.assertTrue(2 not in d) self.assertTrue(2 not in d)
self.assertTrue(2 not in d.keys()) self.assertTrue(2 not in d.keys())
self.assertEqual(d[2], 42) self.assertEqual(d[2], 42)
class E(dict): class E(dict):
def __missing__(self, key): def __missing__(self, key):
raise RuntimeError(key) raise RuntimeError(key)
e = E() e = E()
try: try:
e[42] e[42]
@ -381,10 +420,12 @@ class LazyDictTestCase(unittest.TestCase):
self.assertEqual(err.args, (42,)) self.assertEqual(err.args, (42,))
else: else:
self.fail("e[42] didn't raise RuntimeError") self.fail("e[42] didn't raise RuntimeError")
class F(dict): class F(dict):
def __init__(self): def __init__(self):
# An instance variable __missing__ should have no effect # An instance variable __missing__ should have no effect
self.__missing__ = lambda key: None self.__missing__ = lambda key: None
f = F() f = F()
try: try:
f[42] f[42]
@ -392,8 +433,10 @@ class LazyDictTestCase(unittest.TestCase):
self.assertEqual(err.args, (42,)) self.assertEqual(err.args, (42,))
else: else:
self.fail("f[42] didn't raise KeyError") self.fail("f[42] didn't raise KeyError")
class G(dict): class G(dict):
pass pass
g = G() g = G()
try: try:
g[42] g[42]
@ -402,7 +445,6 @@ class LazyDictTestCase(unittest.TestCase):
else: else:
self.fail("g[42] didn't raise KeyError") self.fail("g[42] didn't raise KeyError")
def test_tuple_keyerror(self): def test_tuple_keyerror(self):
# SF #1576657 # SF #1576657
d = LazyDict() d = LazyDict()
@ -429,9 +471,9 @@ class LazyDictTestCase(unittest.TestCase):
d = LazyDict() d = LazyDict()
x1 = BadDictKey() x1 = BadDictKey()
x2 = BadDictKey()
d[x1] = 1 d[x1] = 1
#for stmt in ['d[x2] = 2', # x2 = BadDictKey()
# for stmt in ['d[x2] = 2',
# 'z = d[x2]', # 'z = d[x2]',
# 'x2 in d', # 'x2 in d',
# 'x2 in d', # 'x2 in d',
@ -442,82 +484,84 @@ class LazyDictTestCase(unittest.TestCase):
# with self.assertRaises(CustomException): # with self.assertRaises(CustomException):
# exec stmt in locals() # exec stmt in locals()
########## ##########
def test_lazy_keys(self): def test_lazy_keys(self):
def resolver(id): def resolver(id):
p = {'b': 2, 'c': 3} p = {"b": 2, "c": 3}
return p[id] return p[id]
d = LazyDict({'a': 1})
d.set_stub('b', resolver) d = LazyDict({"a": 1})
d.set_stub('c', resolver) d.set_stub("b", resolver)
d['d'] = 4 d.set_stub("c", resolver)
d["d"] = 4
k = d.keys() k = d.keys()
self.assertTrue('a' in d) self.assertTrue("a" in d)
self.assertTrue('b' in d) self.assertTrue("b" in d)
self.assertTrue('c' in d) self.assertTrue("c" in d)
self.assertTrue('d' in d) self.assertTrue("d" in d)
self.assertEqual(set(k), {'a','b','c','d'}) self.assertEqual(set(k), {"a", "b", "c", "d"})
def test_lazy_values(self): def test_lazy_values(self):
def resolver(id): def resolver(id):
p = {'c': 3} p = {"c": 3}
return p[id] return p[id]
d = LazyDict() d = LazyDict()
self.assertEqual(set(d.values()), set()) self.assertEqual(set(d.values()), set())
d = LazyDict({1:2}) d = LazyDict({1: 2})
d.set_stub('c', resolver) d.set_stub("c", resolver)
v = d.values() v = d.values()
self.assertEqual(set(v), {2,3}) self.assertEqual(set(v), {2, 3})
self.assertRaises(TypeError, d.values, None) self.assertRaises(TypeError, d.values, None)
def test_lazy_items(self): def test_lazy_items(self):
d = LazyDict() d = LazyDict()
d.set_stub(1, lambda x:x) d.set_stub(1, lambda x: x)
self.assertEqual(set(d.items()), {(1, 1)}) self.assertEqual(set(d.items()), {(1, 1)})
d = LazyDict({1:2}) d = LazyDict({1: 2})
d.set_stub(2, lambda x:x) d.set_stub(2, lambda x: x)
self.assertEqual(set(d.items()), {(1, 2), (2, 2)}) self.assertEqual(set(d.items()), {(1, 2), (2, 2)})
def test_lazy_contains(self): def test_lazy_contains(self):
d = LazyDict() d = LazyDict()
self.assertNotIn('a', d) self.assertNotIn("a", d)
self.assertFalse('a' in d) self.assertFalse("a" in d)
self.assertTrue('a' not in d) self.assertTrue("a" not in d)
d = LazyDict({'a': 1, 'b': 2}) d = LazyDict({"a": 1, "b": 2})
self.assertIn('a', d) self.assertIn("a", d)
self.assertIn('b', d) self.assertIn("b", d)
self.assertNotIn('c', d) self.assertNotIn("c", d)
self.assertRaises(TypeError, d.__contains__) self.assertRaises(TypeError, d.__contains__)
def test_lazy_len(self): def test_lazy_len(self):
d = LazyDict({'1':1}) d = LazyDict({"1": 1})
self.assertEqual(len(d), 1) self.assertEqual(len(d), 1)
d['2'] = 2 d["2"] = 2
self.assertEqual(len(d), 2) self.assertEqual(len(d), 2)
d.set_stub('3', lambda x: x) d.set_stub("3", lambda x: x)
self.assertEqual(len(d), 3) self.assertEqual(len(d), 3)
def test_lazy_getitem(self): def test_lazy_getitem(self):
d = LazyDict({'a': 1, 'b': 2}) d = LazyDict({"a": 1, "b": 2})
self.assertEqual(d['a'], 1) self.assertEqual(d["a"], 1)
self.assertEqual(d['b'], 2) self.assertEqual(d["b"], 2)
d['c'] = 3 d["c"] = 3
d['a'] = 4 d["a"] = 4
self.assertEqual(d['c'], 3) self.assertEqual(d["c"], 3)
self.assertEqual(d['a'], 4) self.assertEqual(d["a"], 4)
del d['b'] del d["b"]
self.assertEqual(d, {'a': 4, 'c': 3}) self.assertEqual(d, {"a": 4, "c": 3})
self.assertRaises(TypeError, d.__getitem__) self.assertRaises(TypeError, d.__getitem__)
class BadEq(object): class BadEq:
def __eq__(self, other): def __eq__(self, other):
raise Exc() raise Exc()
def __hash__(self): def __hash__(self):
return 24 return 24
@ -525,10 +569,12 @@ class LazyDictTestCase(unittest.TestCase):
d[BadEq()] = 42 d[BadEq()] = 42
self.assertRaises(KeyError, d.__getitem__, 23) self.assertRaises(KeyError, d.__getitem__, 23)
class Exc(Exception): pass class Exc(Exception):
pass
class BadHash(object): class BadHash:
fail = False fail = False
def __hash__(self): def __hash__(self):
if self.fail: if self.fail:
raise Exc() raise Exc()
@ -541,8 +587,8 @@ class LazyDictTestCase(unittest.TestCase):
self.assertRaises(Exc, d.__getitem__, x) self.assertRaises(Exc, d.__getitem__, x)
def test_lazy_clear(self): def test_lazy_clear(self):
d = LazyDict({1:1, 2:2, 3:3}) d = LazyDict({1: 1, 2: 2, 3: 3})
d.set_stub(4, lambda x:x) d.set_stub(4, lambda x: x)
d.clear() d.clear()
self.assertEqual(d, {}) self.assertEqual(d, {})
self.assertEqual(set(d.keys()), set()) self.assertEqual(set(d.keys()), set())
@ -552,74 +598,79 @@ class LazyDictTestCase(unittest.TestCase):
def test_lazy_update(self): def test_lazy_update(self):
d = LazyDict() d = LazyDict()
d.set_stub(4, lambda x:x) d.set_stub(4, lambda x: x)
d.update(LazyDict({1:100})) d.update(LazyDict({1: 100}))
d.update(LazyDict({2:20})) d.update(LazyDict({2: 20}))
d.update({4:5}) d.update({4: 5})
d.update(LazyDict({1:1, 2:2, 3:3})) d.update(LazyDict({1: 1, 2: 2, 3: 3}))
self.assertEqual(d, {1:1, 2:2, 3:3, 4:5}) self.assertEqual(d, {1: 1, 2: 2, 3: 3, 4: 5})
d.update() d.update()
self.assertEqual(d, {1:1, 2:2, 3:3, 4:5}) self.assertEqual(d, {1: 1, 2: 2, 3: 3, 4: 5})
self.assertRaises((TypeError, AttributeError), d.update, None) self.assertRaises((TypeError, AttributeError), d.update, None)
class SimpleUserDict: class SimpleUserDict:
def __init__(self): def __init__(self):
self.d = {1:1, 2:2, 3:3} self.d = {1: 1, 2: 2, 3: 3}
def keys(self): def keys(self):
return self.d.keys() return self.d.keys()
def __getitem__(self, i): def __getitem__(self, i):
return self.d[i] return self.d[i]
d.clear() d.clear()
d.update(SimpleUserDict()) d.update(SimpleUserDict())
self.assertEqual(d, {1:1, 2:2, 3:3}) self.assertEqual(d, {1: 1, 2: 2, 3: 3})
def test_lazy_copy(self): def test_lazy_copy(self):
d = LazyDict({'1':1}) d = LazyDict({"1": 1})
d['2'] = 2 d["2"] = 2
x = d.copy() x = d.copy()
self.assertEqual(len(x), 2) self.assertEqual(len(x), 2)
i = {'num': 0} i = {"num": 0}
def r(key, i): def r(key, i):
i['num'] += 1 i["num"] += 1
return i['num'] return i["num"]
d.set_stub('3', r, i)
d.set_stub("3", r, i)
x = d.copy() x = d.copy()
self.assertEqual(d['3'], 1) self.assertEqual(d["3"], 1)
self.assertEqual(len(d._stubs), 0) self.assertEqual(len(d._stubs), 0)
self.assertEqual(len(x._stubs), 1) self.assertEqual(len(x._stubs), 1)
self.assertEqual(x['3'], 2) self.assertEqual(x["3"], 2)
self.assertEqual(len(x._stubs), 0) self.assertEqual(len(x._stubs), 0)
x = d.copy() x = d.copy()
self.assertEqual(d['3'], 1) self.assertEqual(d["3"], 1)
self.assertEqual(x['3'], 1) self.assertEqual(x["3"], 1)
def test_lazy_get(self): def test_lazy_get(self):
d = LazyDict({'a': 1, 'b': 2}) d = LazyDict({"a": 1, "b": 2})
d.set_stub('d', lambda x:x) d.set_stub("d", lambda x: x)
self.assertIs(d.get('c'), None) self.assertIs(d.get("c"), None)
self.assertEqual(d.get('c', 3), 3) self.assertEqual(d.get("c", 3), 3)
self.assertEqual(d.get('a'), 1) self.assertEqual(d.get("a"), 1)
self.assertEqual(d.get('a', 3), 1) self.assertEqual(d.get("a", 3), 1)
self.assertEqual(d.get('d'), 'd') self.assertEqual(d.get("d"), "d")
self.assertEqual(d.get('d', 3), 'd') self.assertEqual(d.get("d", 3), "d")
self.assertRaises(TypeError, d.get) self.assertRaises(TypeError, d.get)
self.assertRaises(TypeError, d.get, None, None, None) self.assertRaises(TypeError, d.get, None, None, None)
def test_lazy_setdefault(self): def test_lazy_setdefault(self):
d = LazyDict() d = LazyDict()
self.assertIs(d.setdefault('key0'), None) self.assertIs(d.setdefault("key0"), None)
d.set_stub('key0', lambda x:'value0') d.set_stub("key0", lambda x: "value0")
self.assertIs(d.setdefault('key0'), 'value0') self.assertIs(d.setdefault("key0"), "value0")
d.set_stub('key0', lambda x:'value0') d.set_stub("key0", lambda x: "value0")
self.assertEqual(d.setdefault('key1', 'value1'), 'value1') self.assertEqual(d.setdefault("key1", "value1"), "value1")
self.assertEqual(d['key1'], 'value1') self.assertEqual(d["key1"], "value1")
self.assertEqual(d.setdefault('key0', 'value2'), 'value0') self.assertEqual(d.setdefault("key0", "value2"), "value0")
def test_lazy_popitem(self): def test_lazy_popitem(self):
d = LazyDict({1: 1}) d = LazyDict({1: 1})
d.set_stub(2, lambda x:x) d.set_stub(2, lambda x: x)
k, v = d.popitem() k, v = d.popitem()
self.assertEqual(k, v) self.assertEqual(k, v)
k, v = d.popitem() k, v = d.popitem()
@ -630,9 +681,9 @@ class LazyDictTestCase(unittest.TestCase):
def test_lazy_pop(self): def test_lazy_pop(self):
d = LazyDict() d = LazyDict()
k, v = ('abc', 'def') k, v = ("abc", "def")
d.set_stub(k, lambda x:'def') d.set_stub(k, lambda x: "def")
self.assertRaises(KeyError, d.pop, 'ghi') self.assertRaises(KeyError, d.pop, "ghi")
self.assertEqual(d.pop(k), v) self.assertEqual(d.pop(k), v)
self.assertEqual(len(d), 0) self.assertEqual(len(d), 0)
@ -640,25 +691,25 @@ class LazyDictTestCase(unittest.TestCase):
self.assertRaises(KeyError, d.pop, k) self.assertRaises(KeyError, d.pop, k)
self.assertEqual(d.pop(k, v), v) self.assertEqual(d.pop(k, v), v)
d.set_stub(k, lambda x:v) d.set_stub(k, lambda x: v)
self.assertEqual(d.pop(k, 1), v) self.assertEqual(d.pop(k, 1), v)
self.assertRaises(TypeError, d.pop) self.assertRaises(TypeError, d.pop)
def test_lazy_delitem(self): def test_lazy_delitem(self):
d = LazyDict() d = LazyDict()
d['1'] = 1 d["1"] = 1
d['2'] = 2 d["2"] = 2
del d['1'] del d["1"]
self.assertEqual(len(d), 1) self.assertEqual(len(d), 1)
self.assertRaises(KeyError, d.__getitem__, '1') self.assertRaises(KeyError, d.__getitem__, "1")
d.set_stub('1', lambda x:x) d.set_stub("1", lambda x: x)
self.assertEqual(len(d), 2) self.assertEqual(len(d), 2)
del d['1'] del d["1"]
self.assertEqual(len(d), 1) self.assertEqual(len(d), 1)
self.assertRaises(KeyError, d.__getitem__, '1') self.assertRaises(KeyError, d.__getitem__, "1")
d.set_stub('1', lambda x:x) d.set_stub("1", lambda x: x)
self.assertEqual(d['1'], '1') self.assertEqual(d["1"], "1")
del d['1'] del d["1"]
self.assertEqual(len(d), 1) self.assertEqual(len(d), 1)
self.assertRaises(KeyError, d.__getitem__, '1') self.assertRaises(KeyError, d.__getitem__, "1")