зеркало из https://github.com/mozilla/silme.git
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:
Родитель
e0edd053d3
Коммит
78d8ac042a
|
@ -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 = {
|
||||
'alpha': 'a',
|
||||
'beta': 'b',
|
||||
'pre': 'pre',
|
||||
'final': '',
|
||||
'rc': 'rc'
|
||||
}
|
||||
short_names = {"alpha": "a", "beta": "b", "pre": "pre", "final": "", "rc": "rc"}
|
||||
|
||||
|
||||
def get_short_version():
|
||||
version = '%s.%s' % (VERSION[0], VERSION[1])
|
||||
version = "{}.{}".format(VERSION[0], VERSION[1])
|
||||
if VERSION[2]:
|
||||
version = '%s.%s' % (version, VERSION[2])
|
||||
version = '%s%s' % (version,
|
||||
short_names.get(VERSION[3], VERSION[3]))
|
||||
if VERSION[3] not in ('pre', 'final') and VERSION[4]:
|
||||
version = '%s%s' % (version, VERSION[4])
|
||||
version = "{}.{}".format(version, VERSION[2])
|
||||
version = "{}{}".format(version, short_names.get(VERSION[3], VERSION[3]))
|
||||
if VERSION[3] not in ("pre", "final") and VERSION[4]:
|
||||
version = "{}{}".format(version, VERSION[4])
|
||||
return version
|
||||
|
||||
|
||||
def get_version():
|
||||
version = '%s.%s' % (VERSION[0], VERSION[1])
|
||||
version = "{}.{}".format(VERSION[0], VERSION[1])
|
||||
if VERSION[2]:
|
||||
version = '%s.%s' % (version, VERSION[2])
|
||||
version = "{}.{}".format(version, VERSION[2])
|
||||
if VERSION[3]:
|
||||
version = '%s %s' % (version, VERSION[3])
|
||||
if VERSION[3] not in ('pre', 'final') and VERSION[4]:
|
||||
version = '%s %s' % (version, VERSION[4])
|
||||
version = "{} {}".format(version, VERSION[3])
|
||||
if VERSION[3] not in ("pre", "final") and VERSION[4]:
|
||||
version = "{} {}".format(version, VERSION[4])
|
||||
return version
|
||||
|
|
|
@ -3,4 +3,4 @@ from .list import EntityList
|
|||
from .structure import Blob, Structure, Comment
|
||||
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.
|
||||
"""
|
||||
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):
|
||||
"""
|
||||
Tests if the argument is a string
|
||||
"""
|
||||
return isinstance(v, basestring)
|
||||
except:
|
||||
string = str
|
||||
|
||||
def is_string(v):
|
||||
"""
|
||||
Tests if the argument is a string
|
||||
"""
|
||||
return isinstance(v, str)
|
||||
def is_string(v):
|
||||
"""
|
||||
Tests if the argument is a string
|
||||
"""
|
||||
return isinstance(v, str)
|
||||
|
||||
|
||||
def is_entity(v):
|
||||
|
@ -40,9 +29,9 @@ def is_entity(v):
|
|||
return isinstance(v, Entity)
|
||||
|
||||
|
||||
class Value(object):
|
||||
class Value:
|
||||
def __new__(cls, *args, **kwargs):
|
||||
#if cls is not Value:
|
||||
# if cls is not Value:
|
||||
# return object.__new__(cls)
|
||||
try:
|
||||
i = args[0]
|
||||
|
@ -60,24 +49,26 @@ class Value(object):
|
|||
return ComplexValue(*args, **kwargs)
|
||||
|
||||
|
||||
class SimpleValue(string, Value):
|
||||
class SimpleValue(str, Value):
|
||||
"""
|
||||
A simple, string based value for an entity
|
||||
"""
|
||||
|
||||
def get(self, *args, **kwargs):
|
||||
return self
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
raise TypeError("'%s' object does not support item assignment" %
|
||||
type(self).__name__)
|
||||
raise TypeError(
|
||||
"'%s' object does not support item assignment" % type(self).__name__
|
||||
)
|
||||
|
||||
def __getitem__(self, key):
|
||||
raise TypeError("'%s' object is unsubscriptable" %
|
||||
type(self).__name__)
|
||||
raise TypeError("'%s' object is unsubscriptable" % type(self).__name__)
|
||||
|
||||
def __delitem__(self, key):
|
||||
raise TypeError("'%s' object does not support item deletion" %
|
||||
type(self).__name__)
|
||||
raise TypeError(
|
||||
"'%s' object does not support item deletion" % type(self).__name__
|
||||
)
|
||||
|
||||
|
||||
class ComplexValue(Value):
|
||||
|
@ -103,6 +94,7 @@ class ComplexValue(Value):
|
|||
else:
|
||||
return val
|
||||
|
||||
|
||||
class ListValue(list, ComplexValue):
|
||||
"""
|
||||
A value that is a list of values
|
||||
|
@ -116,19 +108,21 @@ class DictValue(OrderedDict, ComplexValue):
|
|||
"""
|
||||
A value that is a dictionary of values
|
||||
"""
|
||||
|
||||
def get(self, key=None, *args, **kwargs):
|
||||
if key is not None:
|
||||
return self[key]
|
||||
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 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.
|
||||
"""
|
||||
|
||||
_select_value = None
|
||||
|
||||
def __init__(self, id, value=None):
|
||||
|
@ -181,4 +175,3 @@ class Entity(object):
|
|||
@property
|
||||
def values(self):
|
||||
return copy.copy(self._value)
|
||||
|
||||
|
|
|
@ -22,11 +22,12 @@ class EntityList(ComplexDict):
|
|||
"""
|
||||
EntityList is a list of entities bundled together.
|
||||
"""
|
||||
|
||||
uri = None
|
||||
|
||||
def __init__(self, id, *args, **kwargs):
|
||||
self.id = id
|
||||
super(EntityList, self).__init__()
|
||||
super().__init__()
|
||||
for i in args:
|
||||
if is_entitylist(i):
|
||||
for entity in i.entities():
|
||||
|
@ -36,8 +37,8 @@ class EntityList(ComplexDict):
|
|||
|
||||
def __repr__(self):
|
||||
if not self:
|
||||
return '%s()' % (self.__class__.__name__,)
|
||||
return '%s(%r)' % (self.__class__.__name__, tuple(self.keys()))
|
||||
return f"{self.__class__.__name__}()"
|
||||
return "{}({!r})".format(self.__class__.__name__, tuple(self.keys()))
|
||||
|
||||
def add(self, entity):
|
||||
"""Adds new entity to EntityList"""
|
||||
|
@ -54,8 +55,7 @@ class EntityList(ComplexDict):
|
|||
return list(self.values())
|
||||
|
||||
def value(self, id):
|
||||
"""Returns entity value from EntityList.
|
||||
"""
|
||||
"""Returns entity value from EntityList."""
|
||||
return self[id].value
|
||||
|
||||
|
||||
|
@ -64,8 +64,9 @@ class ValueList(EntityList):
|
|||
ValueList is a list of entity values - similar to EntityList but with an
|
||||
intention to store only the values of entities.
|
||||
"""
|
||||
|
||||
def __init__(self, id, *args, **kwargs):
|
||||
super(ValueList, self).__init__(id, *args, **kwargs)
|
||||
super().__init__(id, *args, **kwargs)
|
||||
|
||||
def add(self, entity):
|
||||
"""Adds new entity to the ValueList"""
|
||||
|
@ -79,8 +80,9 @@ class ValueList(EntityList):
|
|||
|
||||
def entities(self):
|
||||
"""Raises a TypeError since ValueList does not support this method"""
|
||||
raise TypeError("'%s' object does not support entities method" %
|
||||
type(self).__name__)
|
||||
raise TypeError(
|
||||
"'%s' object does not support entities method" % type(self).__name__
|
||||
)
|
||||
|
||||
def value(self, id):
|
||||
"""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.types import LazyDict
|
||||
|
||||
class Package(object):
|
||||
|
||||
class Package:
|
||||
"""
|
||||
Package is a container that stores
|
||||
set of data structures (Structures, EntityLists, Blobs) and sub-packages.
|
||||
|
||||
|
||||
It's easiest to think of it as a filesystem directory that
|
||||
can store files and nested directories.
|
||||
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,
|
||||
the two directories should be identical minus any modifications you made.
|
||||
"""
|
||||
|
||||
uri = None
|
||||
|
||||
def __init__(self, id, lazy=True):
|
||||
|
@ -25,17 +27,15 @@ class Package(object):
|
|||
self.id = id
|
||||
|
||||
def __len__(self):
|
||||
return len(self._packages)+len(self._structures)
|
||||
return len(self._packages) + len(self._structures)
|
||||
|
||||
def __iter__(self):
|
||||
for i in self._packages.items():
|
||||
yield i
|
||||
for i in self._structures.items():
|
||||
yield i
|
||||
yield from self._packages.items()
|
||||
yield from self._structures.items()
|
||||
raise StopIteration
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(%s)' % (self.__class__.__name__, self.id)
|
||||
return f"{self.__class__.__name__}({self.id})"
|
||||
|
||||
def __contains__(self, id):
|
||||
if id in self._packages.keys():
|
||||
|
@ -73,10 +73,10 @@ class Package(object):
|
|||
def add_structure(self, struct, path=None):
|
||||
"""
|
||||
Adds a structure to the Package.
|
||||
|
||||
|
||||
Optional parameter path allows to define exact position
|
||||
inside the package where the structure should be added.
|
||||
|
||||
|
||||
For example l10npack.add_structure(l10nstruct, 'pkg1/pkg2') is equal to
|
||||
l10npack.get_package('pkg1').get_package('pkg2').add_structure(l10nstruct)
|
||||
with the difference that it will create missing sub packages if needed.
|
||||
|
@ -84,22 +84,21 @@ class Package(object):
|
|||
if not path:
|
||||
self._structures[struct.id] = struct
|
||||
else:
|
||||
path = path.split('/')
|
||||
path = path.split("/")
|
||||
if path[0] in self._packages:
|
||||
self._packages[path[0]].add_structure(struct,
|
||||
'/'.join(path[1:]))
|
||||
self._packages[path[0]].add_structure(struct, "/".join(path[1:]))
|
||||
else:
|
||||
sub_l10n_pack = Package(path[0])
|
||||
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):
|
||||
"""
|
||||
Adds a package to Package.
|
||||
|
||||
|
||||
Optional parameter path allows to declare place
|
||||
inside the package where the subpackage should be added.
|
||||
|
||||
|
||||
For example l10npack.add_package(subl10npack, 'pkg1/pkg2') is similar to
|
||||
l10npack.get_package('pkg1').get_package('pkg2').add_package(subl10npack)
|
||||
with the difference that it will create missing sub packages.
|
||||
|
@ -107,14 +106,13 @@ class Package(object):
|
|||
if not path:
|
||||
self._packages[package.id] = package
|
||||
else:
|
||||
path = path.split('/')
|
||||
path = path.split("/")
|
||||
if path[0] in self._packages:
|
||||
self._packages[path[0]].add_package(package,
|
||||
'/'.join(path[1:]))
|
||||
self._packages[path[0]].add_package(package, "/".join(path[1:]))
|
||||
else:
|
||||
sub_l10n_pack = Package(path[0])
|
||||
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):
|
||||
"""
|
||||
|
@ -127,28 +125,28 @@ class Package(object):
|
|||
else:
|
||||
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.
|
||||
If parameter ids is set to True list of
|
||||
names is returned instead of structures.
|
||||
"""
|
||||
if type == 'all':
|
||||
if type == "all":
|
||||
if ids:
|
||||
return list(self._structures.keys())
|
||||
else:
|
||||
return list(self._structures.values())
|
||||
else:
|
||||
l10n_structures = {}
|
||||
if type == 'list':
|
||||
if type == "list":
|
||||
type = is_entitylist
|
||||
elif type == 'structure':
|
||||
type = lambda x:isinstance(x, Structure)
|
||||
elif type == 'blob':
|
||||
type = lambda x:isinstance(x, Blob)
|
||||
elif type == "structure":
|
||||
type = lambda x: isinstance(x, Structure)
|
||||
elif type == "blob":
|
||||
type = lambda x: isinstance(x, Blob)
|
||||
for struct in self._structures:
|
||||
if type(self._structures[struct]):
|
||||
l10n_structures[struct] = self._structures[struct]
|
||||
l10n_structures[struct] = self._structures[struct]
|
||||
if ids:
|
||||
return list(l10n_structures.keys())
|
||||
else:
|
||||
|
@ -157,26 +155,27 @@ class Package(object):
|
|||
def entities(self, recursive=True, path=False):
|
||||
"""
|
||||
Returns a list of all entities inside the Package
|
||||
|
||||
|
||||
If optional parameter recursive is set to True it will
|
||||
return all packages from this package and its subpackages.
|
||||
"""
|
||||
entities = []
|
||||
|
||||
|
||||
|
||||
if path is True:
|
||||
spath = ''
|
||||
spath = ""
|
||||
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:
|
||||
spath = path
|
||||
if recursive:
|
||||
for pack in self._packages.values():
|
||||
entities.extend(pack.entities(path=spath))
|
||||
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()
|
||||
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])
|
||||
return entities
|
||||
|
||||
|
@ -190,32 +189,32 @@ class Package(object):
|
|||
try:
|
||||
return self._structures[id]
|
||||
except KeyError:
|
||||
raise KeyError('No such structure: %s' % id)
|
||||
|
||||
raise KeyError("No such structure: %s" % id)
|
||||
|
||||
def package(self, id):
|
||||
try:
|
||||
return self._packages[id]
|
||||
except KeyError:
|
||||
raise KeyError('No such package: %s' % id)
|
||||
raise KeyError("No such package: %s" % id)
|
||||
|
||||
def element(self, path):
|
||||
"""
|
||||
Returns an element from inside Package
|
||||
by its path.
|
||||
|
||||
|
||||
l10npack.element('pkg1/pkg2/structure.po') will return
|
||||
the same as
|
||||
l10npack.package('pkg1').get_package('pkg2').structure('structure.po')
|
||||
|
||||
|
||||
If the path is empty the result will be None
|
||||
"""
|
||||
if not path:
|
||||
return None
|
||||
elems = path.split('/')
|
||||
elems = path.split("/")
|
||||
if len(elems) == 0:
|
||||
return None
|
||||
|
||||
if len(elems) == 2 and elems[1] == '':
|
||||
if len(elems) == 2 and elems[1] == "":
|
||||
elems = elems[:-1]
|
||||
|
||||
if len(elems) == 1:
|
||||
|
@ -230,13 +229,13 @@ class Package(object):
|
|||
return None
|
||||
else:
|
||||
try:
|
||||
return self._packages[elems[0]].element('/'.join(elems[1:]))
|
||||
return self._packages[elems[0]].element("/".join(elems[1:]))
|
||||
except KeyError:
|
||||
raise
|
||||
|
||||
def remove_structure(self, id):
|
||||
del self._structures[id]
|
||||
|
||||
|
||||
def remove_package(self, id):
|
||||
del self._packages[id]
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ from silme.core.list import EntityList
|
|||
from functools import partial
|
||||
|
||||
|
||||
class Blob(object):
|
||||
class Blob:
|
||||
"""
|
||||
A Blob is a data stream that is not localizable, but may be
|
||||
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
|
||||
data in a in-memory representation of a package (a directory etc.)
|
||||
"""
|
||||
|
||||
uri = None
|
||||
id = None
|
||||
source = None
|
||||
|
@ -40,7 +41,7 @@ class Blob(object):
|
|||
self.id = id
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(%s)' % (self.__class__.__name__, self.id)
|
||||
return f"{self.__class__.__name__}({self.id})"
|
||||
|
||||
|
||||
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
|
||||
possible which in turn may be important for all VCS's based workflows.
|
||||
"""
|
||||
|
||||
_process_cb = None # process callback function
|
||||
|
||||
def __init__(self, id):
|
||||
|
@ -76,7 +78,7 @@ class Structure(list, Blob):
|
|||
"""
|
||||
if type(pos) == tuple:
|
||||
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:
|
||||
return None
|
||||
else:
|
||||
|
@ -110,9 +112,9 @@ class Structure(list, Blob):
|
|||
return self.entity(id).value
|
||||
|
||||
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)]
|
||||
|
||||
ids = keys
|
||||
|
||||
def entities(self):
|
||||
|
@ -122,31 +124,27 @@ class Structure(list, Blob):
|
|||
return [item for item in self if is_entity(item)]
|
||||
|
||||
def entitylist(self):
|
||||
"""Returns an EntityList object with entities from the Structure.
|
||||
"""
|
||||
return EntityList(self.id,
|
||||
*[item for item in self if is_entity(item)])
|
||||
"""Returns an EntityList object with entities from the Structure."""
|
||||
return EntityList(self.id, *[item for item in self if is_entity(item)])
|
||||
|
||||
def entities_with_path(self, path_prefix):
|
||||
"""Returns a dict of all entities from the Structure in a form of
|
||||
d[entity.id] = (entity, path)
|
||||
"""
|
||||
spath = '%s/%s' % (path_prefix, self.id) if path_prefix else self.id
|
||||
return dict([(item.id,
|
||||
(item, spath)) for item in self if is_entity(item)])
|
||||
spath = f"{path_prefix}/{self.id}" if path_prefix else self.id
|
||||
return {item.id: (item, spath) for item in self if is_entity(item)}
|
||||
|
||||
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:
|
||||
if is_entity(item) and item.id == id:
|
||||
return True
|
||||
return False
|
||||
|
||||
has_entity = __contains__
|
||||
|
||||
def modify_entity(self, id, value):
|
||||
"""modifies an entity value
|
||||
"""
|
||||
"""modifies an entity value"""
|
||||
found = False
|
||||
for item in self:
|
||||
if is_entity(item) and item.id == id:
|
||||
|
@ -156,32 +154,29 @@ class Structure(list, Blob):
|
|||
if found:
|
||||
return True
|
||||
else:
|
||||
raise KeyError('No such entity')
|
||||
raise KeyError("No such entity")
|
||||
|
||||
def entity(self, id):
|
||||
"""returns an entity for a given id
|
||||
"""
|
||||
"""returns an entity for a given id"""
|
||||
for item in self:
|
||||
if is_entity(item) and item.id == id:
|
||||
return item
|
||||
raise KeyError('No such entity')
|
||||
raise KeyError("No such entity")
|
||||
|
||||
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):
|
||||
if is_entity(item) and item.id == id:
|
||||
return i
|
||||
raise KeyError('No such entity')
|
||||
raise KeyError("No such entity")
|
||||
|
||||
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):
|
||||
if is_entity(item) and item.id == id:
|
||||
del self[i]
|
||||
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):
|
||||
self.add_at_pos(comment, pos)
|
||||
|
@ -208,9 +203,9 @@ class Structure(list, Blob):
|
|||
elif item is None:
|
||||
return 0
|
||||
else:
|
||||
raise Exception('Cannot add element of type "' +
|
||||
type(item).__name__ +
|
||||
'" to the Structure')
|
||||
raise Exception(
|
||||
f'Cannot add element of type "{type(item).__name__}" to the Structure'
|
||||
)
|
||||
|
||||
def add_elements(self, sequence, pos=None):
|
||||
"""
|
||||
|
@ -226,7 +221,7 @@ class Structure(list, Blob):
|
|||
if isinstance(sequence, dict):
|
||||
sequence = sequence.values()
|
||||
pos = self._get_pos(pos)
|
||||
#a=a[:2]+b+a[2:] ?
|
||||
# a=a[:2]+b+a[2:] ?
|
||||
for i in sequence:
|
||||
shift += self.add(i, pos=(None if pos is None else pos + shift))
|
||||
return shift
|
||||
|
@ -244,7 +239,7 @@ class Structure(list, Blob):
|
|||
|
||||
return self._process_cb()
|
||||
except TypeError:
|
||||
raise Exception('process callback function not specified')
|
||||
raise Exception("process callback function not specified")
|
||||
|
||||
def set_process_cb(self, cb):
|
||||
self._process_cb = partial(cb, self)
|
||||
|
@ -263,13 +258,13 @@ class Comment(Structure):
|
|||
self.id = None
|
||||
|
||||
def __repr__(self):
|
||||
string = '<comment: '
|
||||
string = "<comment: "
|
||||
for i in self:
|
||||
string += unicode(i)
|
||||
string += '>'
|
||||
string += str(i)
|
||||
string += ">"
|
||||
return string
|
||||
|
||||
def add(self, element, pos=None):
|
||||
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)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from silme.core.types.odict import OrderedDict
|
||||
from silme.core.types.lazydict import LazyDict
|
||||
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 abc import ABCMeta
|
||||
|
||||
|
||||
class FactoryMeta(type):
|
||||
def __new__(cls, *args, **kwargs):
|
||||
return cls
|
||||
|
||||
|
||||
_types = {
|
||||
'ordered': [OrderedDict, 'Ordered', False],
|
||||
'lazy': [LazyDict, 'Lazy', False],
|
||||
}
|
||||
"ordered": [OrderedDict, "Ordered", False],
|
||||
"lazy": [LazyDict, "Lazy", False],
|
||||
}
|
||||
|
||||
|
||||
class LazyDictMeta(ABCMeta, type):
|
||||
|
@ -25,15 +27,13 @@ class LazyDictMeta(ABCMeta, type):
|
|||
classes.append(t[0])
|
||||
name.append(t[1])
|
||||
attrs.append((key, r))
|
||||
t = type('%s%s' % (''.join(name), cls.__name__),
|
||||
tuple(classes),
|
||||
{})
|
||||
t = type("{}{}".format("".join(name), cls.__name__), tuple(classes), {})
|
||||
cl = t.__new__(t, *args, **kwargs)
|
||||
cl.__init__(*args, **kwargs)
|
||||
for attr in attrs:
|
||||
setattr(cl, attr[0], attr[1])
|
||||
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
|
||||
items in a form of a stub that is expanded on the first call.
|
||||
|
||||
|
@ -15,21 +15,22 @@ Example:
|
|||
|
||||
d = LazyDict({'a': 1})
|
||||
d.set_stub('b', resolver, table='items')
|
||||
|
||||
|
||||
print(len(d)) # 2
|
||||
x = d['b'] # resolving
|
||||
x2 = d['b'] #
|
||||
print(isinstance(x2, QueryValue) # True
|
||||
|
||||
'''
|
||||
"""
|
||||
from functools import partial
|
||||
from collections.abc import MutableMapping, ItemsView, ValuesView
|
||||
import datetime
|
||||
|
||||
__all__ = ["LazyDict",]
|
||||
__all__ = [
|
||||
"LazyDict",
|
||||
]
|
||||
|
||||
|
||||
class LazyItemsView(ItemsView):
|
||||
|
||||
def __iter__(self):
|
||||
self._mapping.resolve()
|
||||
for key in self._mapping:
|
||||
|
@ -37,7 +38,6 @@ class LazyItemsView(ItemsView):
|
|||
|
||||
|
||||
class LazyValuesView(ValuesView):
|
||||
|
||||
def __iter__(self):
|
||||
self._mapping.resolve()
|
||||
for key in self._mapping:
|
||||
|
@ -49,34 +49,33 @@ class LazyDict(dict):
|
|||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._stubs = set()
|
||||
super(LazyDict, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def __cmp__(self, other):
|
||||
self.resolve()
|
||||
return super(LazyDict, self).__cmp__(other)
|
||||
return super().__cmp__(other)
|
||||
|
||||
def __eq__(self, other):
|
||||
self.resolve()
|
||||
return super(LazyDict, self).__eq__(other)
|
||||
return super().__eq__(other)
|
||||
|
||||
def __setitem__(self, key, item):
|
||||
self._stubs.discard(key)
|
||||
super(LazyDict, self).__setitem__(key, item)
|
||||
super().__setitem__(key, item)
|
||||
|
||||
def __getitem__(self, key):
|
||||
if key in self._stubs:
|
||||
super(LazyDict, self).__setitem__(key,
|
||||
super(LazyDict, self).__getitem__(key)())
|
||||
super().__setitem__(key, super().__getitem__(key)())
|
||||
self._stubs.remove(key)
|
||||
return super(LazyDict, self).__getitem__(key)
|
||||
return super().__getitem__(key)
|
||||
|
||||
def __delitem__(self, key):
|
||||
self._stubs.discard(key)
|
||||
super(LazyDict, self).__delitem__(key)
|
||||
super().__delitem__(key)
|
||||
|
||||
def clear(self):
|
||||
self._stubs.clear()
|
||||
super(LazyDict, self).clear()
|
||||
super().clear()
|
||||
|
||||
def copy(self):
|
||||
x = self.__class__(self)
|
||||
|
@ -89,7 +88,6 @@ class LazyDict(dict):
|
|||
setdefault = MutableMapping.setdefault
|
||||
__repr__ = MutableMapping.__repr__
|
||||
|
||||
|
||||
def items(self):
|
||||
return LazyItemsView(self)
|
||||
|
||||
|
@ -97,6 +95,7 @@ class LazyDict(dict):
|
|||
return LazyValuesView(self)
|
||||
|
||||
__marker = object()
|
||||
|
||||
def pop(self, key, default=__marker):
|
||||
try:
|
||||
value = self[key]
|
||||
|
@ -118,17 +117,15 @@ class LazyDict(dict):
|
|||
provided by set_default_resolver.
|
||||
"""
|
||||
self._stubs.add(key)
|
||||
v = partial(rslv if rslv else self._resolver,
|
||||
key, *args, **kwargs)
|
||||
super(LazyDict, self).__setitem__(key, v)
|
||||
v = partial(rslv if rslv else self._resolver, key, *args, **kwargs)
|
||||
super().__setitem__(key, v)
|
||||
|
||||
def resolve(self):
|
||||
"""
|
||||
Resolves all stubs
|
||||
"""
|
||||
for k in self._stubs:
|
||||
super(LazyDict, self).__setitem__(k,
|
||||
super(LazyDict, self).__getitem__(k)())
|
||||
super().__setitem__(k, super().__getitem__(k)())
|
||||
self._stubs.clear()
|
||||
|
||||
def set_resolver(self, resolver):
|
||||
|
@ -136,46 +133,3 @@ class LazyDict(dict):
|
|||
Sets the default stub 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 sys
|
||||
|
||||
class Manager(object):
|
||||
|
||||
class Manager:
|
||||
formats = {}
|
||||
names = {}
|
||||
path = []
|
||||
|
@ -9,7 +10,7 @@ class Manager(object):
|
|||
@classmethod
|
||||
def _import(cls, fp):
|
||||
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)
|
||||
sys.path = list(set(sys.path).difference(added))
|
||||
return module
|
||||
|
@ -40,9 +41,9 @@ class Manager(object):
|
|||
try:
|
||||
module = cls._import(name)
|
||||
module.register(cls)
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
@classmethod
|
||||
def get(cls, name=None, path=None):
|
||||
if name:
|
||||
|
@ -52,11 +53,11 @@ class Manager(object):
|
|||
try:
|
||||
module = cls._import(name)
|
||||
except ImportError:
|
||||
raise KeyError ('no matching format')
|
||||
raise KeyError("no matching format")
|
||||
return module.FormatParser()
|
||||
elif path:
|
||||
try:
|
||||
return cls.formats[os.path.splitext(path)[1][1:].lower()]
|
||||
except KeyError:
|
||||
pass
|
||||
raise KeyError('no matching parser')
|
||||
raise KeyError("no matching parser")
|
||||
|
|
|
@ -1,37 +1,39 @@
|
|||
from .parser import DTDParser as Parser
|
||||
from .serializer import DTDSerializer as Serializer
|
||||
|
||||
class FormatParser():
|
||||
name = 'dtd'
|
||||
desc = 'DTD reader/writer'
|
||||
extensions = ['dtd']
|
||||
encoding = 'utf_8' # allowed encoding
|
||||
fallback = ['utf_8_sig']
|
||||
|
||||
|
||||
class FormatParser:
|
||||
name = "dtd"
|
||||
desc = "DTD reader/writer"
|
||||
extensions = ["dtd"]
|
||||
encoding = "utf_8" # allowed encoding
|
||||
fallback = ["utf_8_sig"]
|
||||
|
||||
@classmethod
|
||||
def dump_structure (cls, l10nobject):
|
||||
def dump_structure(cls, l10nobject):
|
||||
text = Serializer.serialize(l10nobject)
|
||||
return text
|
||||
|
||||
@classmethod
|
||||
def dump_entitylist (cls, elist):
|
||||
def dump_entitylist(cls, elist):
|
||||
text = Serializer.dump_entitylist(elist)
|
||||
return text
|
||||
|
||||
@classmethod
|
||||
def get_idlist (cls, text):
|
||||
def get_idlist(cls, text):
|
||||
l10nobject = Parser.parse_to_idlist(text)
|
||||
return l10nobject
|
||||
|
||||
@classmethod
|
||||
def get_entitylist (cls, text):
|
||||
def get_entitylist(cls, text):
|
||||
l10nobject = Parser.parse_to_entitylist(text)
|
||||
return l10nobject
|
||||
|
||||
@classmethod
|
||||
def get_structure (cls, text):
|
||||
def get_structure(cls, text):
|
||||
l10nobject = Parser.parse(text)
|
||||
return l10nobject
|
||||
|
||||
|
||||
def register(Manager):
|
||||
Manager.register(FormatParser)
|
||||
|
|
|
@ -4,17 +4,22 @@ from silme.core.list import EntityList
|
|||
import re
|
||||
|
||||
|
||||
class DTDParser(object):
|
||||
name_start_char = u':A-Z_a-z\xC0-\xD6\xD8-\xF6\xF8-\u02FF' + \
|
||||
u'\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF'+\
|
||||
u'\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD'
|
||||
name_char = name_start_char + r'\-\.0-9' + u'\xB7\u0300-\u036F\u203F-\u2040'
|
||||
name = u'[' + name_start_char + u'][' + name_char + u']*'
|
||||
class DTDParser:
|
||||
name_start_char = (
|
||||
":A-Z_a-z\xC0-\xD6\xD8-\xF6\xF8-\u02FF"
|
||||
"\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF"
|
||||
"\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD"
|
||||
)
|
||||
name_char = name_start_char + r"\-\.0-9" + "\xB7\u0300-\u036F\u203F-\u2040"
|
||||
name = "[" + name_start_char + "][" + name_char + "]*"
|
||||
|
||||
patterns = {
|
||||
'id': re.compile(u'<!ENTITY\s+(' + name + u')[^>]*>', re.S | re.U),
|
||||
'entity': re.compile(u'<!ENTITY\s+(' + name + u')\s+((?:\"[^\"]*\")|(?:\'[^\']*\'))\s*>', re.S | re.U),
|
||||
'comment': re.compile(u'\<!\s*--(.*?)(?:--\s*\>)', re.M | re.S)
|
||||
"id": re.compile(r"<!ENTITY\s+(" + name + ")[^>]*>", re.S | re.U),
|
||||
"entity": re.compile(
|
||||
r"<!ENTITY\s+(" + name + r")\s+((?:\"[^\"]*\")|(?:'[^']*'))\s*>",
|
||||
re.S | re.U,
|
||||
),
|
||||
"comment": re.compile(r"\<!\s*--(.*?)(?:--\s*\>)", re.M | re.S),
|
||||
}
|
||||
|
||||
@classmethod
|
||||
|
@ -25,35 +30,36 @@ class DTDParser(object):
|
|||
|
||||
@classmethod
|
||||
def parse_to_idlist(cls, text):
|
||||
text = cls.patterns['comment'].sub('', text)
|
||||
ids = [m[0] for m in cls.patterns['id'].findall(text)]
|
||||
text = cls.patterns["comment"].sub("", text)
|
||||
ids = [m[0] for m in cls.patterns["id"].findall(text)]
|
||||
return ids
|
||||
|
||||
@classmethod
|
||||
def parse_to_entitylist(cls, text):
|
||||
elist = EntityList(id=None)
|
||||
text = cls.patterns['comment'].sub('', text)
|
||||
for match in cls.patterns['entity'].findall(text):
|
||||
text = cls.patterns["comment"].sub("", text)
|
||||
for match in cls.patterns["entity"].findall(text):
|
||||
elist.add(Entity(match[0], match[1][1:-1]))
|
||||
return elist
|
||||
|
||||
@classmethod
|
||||
def parse_entity(cls, text):
|
||||
match = cls.patterns['entity'].match(text)
|
||||
match = cls.patterns["entity"].match(text)
|
||||
if not match:
|
||||
raise Exception()
|
||||
entity = Entity(match.group(0))
|
||||
entity.set_value(match.group(1)[1:-1])
|
||||
return entity
|
||||
|
||||
|
||||
@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)
|
||||
|
||||
@classmethod
|
||||
def split_comments(cls, text, obj, code='default', pointer=0, end=None):
|
||||
pattern = cls.patterns['comment']
|
||||
def split_comments(cls, text, obj, code="default", pointer=0, end=None):
|
||||
pattern = cls.patterns["comment"]
|
||||
if end:
|
||||
match = pattern.search(text, pointer, end)
|
||||
else:
|
||||
|
@ -74,8 +80,8 @@ class DTDParser(object):
|
|||
cls.split_entities(text, obj, code=code, pointer=pointer)
|
||||
|
||||
@classmethod
|
||||
def split_entities(cls, text, obj, code='default', pointer=0, end=None):
|
||||
pattern = cls.patterns['entity']
|
||||
def split_entities(cls, text, obj, code="default", pointer=0, end=None):
|
||||
pattern = cls.patterns["entity"]
|
||||
if end:
|
||||
match = pattern.search(text, pointer, end)
|
||||
else:
|
||||
|
@ -87,8 +93,10 @@ class DTDParser(object):
|
|||
groups = match.groups()
|
||||
entity = Entity(groups[0])
|
||||
entity.set_value(groups[1][1:-1])
|
||||
entity.params['source'] = {
|
||||
'type': 'dtd', 'string': match.group(0), 'valpos': match.start(2)+1-st0
|
||||
entity.params["source"] = {
|
||||
"type": "dtd",
|
||||
"string": match.group(0),
|
||||
"valpos": match.start(2) + 1 - st0,
|
||||
}
|
||||
obj.append(entity)
|
||||
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 .structure import DTDStructure
|
||||
from .parser import DTDParser as Parser
|
||||
|
||||
class DTDSerializer():
|
||||
|
||||
class DTDSerializer:
|
||||
@classmethod
|
||||
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
|
||||
|
||||
@classmethod
|
||||
def dump_element (cls, element, fallback=None):
|
||||
def dump_element(cls, element, fallback=None):
|
||||
if is_entity(element):
|
||||
return cls.dump_entity(element, fallback=fallback)
|
||||
elif isinstance(element,Comment):
|
||||
elif isinstance(element, Comment):
|
||||
return cls.dump_comment(element)
|
||||
else:
|
||||
return element
|
||||
|
||||
@classmethod
|
||||
def dump_entity (cls, entity, fallback=None):
|
||||
if 'source' in entity.params and entity.params['source']['type']=='dtd':
|
||||
match = Parser.patterns['entity'].match(entity.params['source']['string'])
|
||||
def dump_entity(cls, entity, fallback=None):
|
||||
if "source" in entity.params and entity.params["source"]["type"] == "dtd":
|
||||
match = Parser.patterns["entity"].match(entity.params["source"]["string"])
|
||||
|
||||
middle = entity.params['source']['string'][match.end(1):match.start(2)+1]
|
||||
end = entity.params['source']['string'][match.end(2)-1:]
|
||||
middle = entity.params["source"]["string"][
|
||||
match.end(1) : match.start(2) + 1
|
||||
]
|
||||
end = entity.params["source"]["string"][match.end(2) - 1 :]
|
||||
|
||||
if middle.endswith('"') and '"' in entity.value:
|
||||
middle = middle.replace('"', "'")
|
||||
|
@ -33,24 +35,24 @@ class DTDSerializer():
|
|||
middle = middle.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 += middle
|
||||
string += entity.value
|
||||
string += end
|
||||
else:
|
||||
string = u'<!ENTITY '+entity.id+u' "'+entity.value+u'">'
|
||||
string = "<!ENTITY " + entity.id + ' "' + entity.value + '">'
|
||||
return string
|
||||
|
||||
@classmethod
|
||||
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
|
||||
|
||||
@classmethod
|
||||
def dump_comment (cls, comment):
|
||||
string = u'<!--'
|
||||
def dump_comment(cls, comment):
|
||||
string = "<!--"
|
||||
for element in comment:
|
||||
string += cls.dump_element(element)
|
||||
string += u'-->'
|
||||
string += "-->"
|
||||
return string
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
from silme.core import Entity, Structure, Comment
|
||||
from silme.core import Entity, Structure
|
||||
import re
|
||||
|
||||
|
||||
def process_entity(entity, subs):
|
||||
for code in entity._value.keys():
|
||||
entity._value[code] = re.sub('\&([^$]+)\;',
|
||||
lambda m:subs[m.group(1)],
|
||||
entity._value[code])
|
||||
entity._value[code] = re.sub(
|
||||
r"\&([^$]+)\;", lambda m: subs[m.group(1)], entity._value[code]
|
||||
)
|
||||
|
||||
|
||||
def process(self):
|
||||
if 'exents' not in self.params or \
|
||||
not self.params['exents']:
|
||||
if "exents" not in self.params or not self.params["exents"]:
|
||||
return
|
||||
for elem in self:
|
||||
if isinstance(elem, Entity):
|
||||
process_entity(elem, self.params['exents'])
|
||||
process_entity(elem, self.params["exents"])
|
||||
|
||||
|
||||
class DTDStructure(Structure):
|
||||
def __init__(self, id):
|
||||
|
|
|
@ -2,30 +2,30 @@ from .parser import IncParser as Parser
|
|||
from .serializer import IncSerializer as Serializer
|
||||
|
||||
|
||||
class FormatParser(object):
|
||||
name = 'inc'
|
||||
class FormatParser:
|
||||
name = "inc"
|
||||
desc = "INC reader/writer"
|
||||
extensions = ['inc']
|
||||
encoding = 'utf_8' # allowed encoding
|
||||
extensions = ["inc"]
|
||||
encoding = "utf_8" # allowed encoding
|
||||
fallback = None
|
||||
|
||||
@classmethod
|
||||
def dump_structure (cls, l10nobject):
|
||||
def dump_structure(cls, l10nobject):
|
||||
text = Serializer.serialize(l10nobject)
|
||||
return text
|
||||
|
||||
@classmethod
|
||||
def dump_entitylist (cls, elist):
|
||||
def dump_entitylist(cls, elist):
|
||||
text = Serializer.dump_entitylist(elist)
|
||||
return text
|
||||
|
||||
@classmethod
|
||||
def get_entitylist (cls, text):
|
||||
def get_entitylist(cls, text):
|
||||
l10nobject = Parser.parse_to_entitylist(text)
|
||||
return l10nobject
|
||||
|
||||
@classmethod
|
||||
def get_structure (cls, text):
|
||||
def get_structure(cls, text):
|
||||
l10nobject = Parser.parse(text)
|
||||
return l10nobject
|
||||
|
||||
|
|
|
@ -2,12 +2,14 @@ from ...core import EntityList, Entity, Comment
|
|||
from .structure import IncStructure
|
||||
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
|
||||
def parse(cls, text):
|
||||
|
@ -19,15 +21,15 @@ class IncParser():
|
|||
@classmethod
|
||||
def parse_to_entitylist(cls, text):
|
||||
entitylist = EntityList(id=None)
|
||||
text = cls.patterns['comment'].sub('', text)
|
||||
matchlist = cls.patterns['entity'].findall(text)
|
||||
text = cls.patterns["comment"].sub("", text)
|
||||
matchlist = cls.patterns["entity"].findall(text)
|
||||
for match in matchlist:
|
||||
entitylist.add(Entity(match[0], match[1]))
|
||||
return entitylist
|
||||
|
||||
@classmethod
|
||||
def parse_entity(cls, text):
|
||||
match = self.patterns['entity'].match(text)
|
||||
match = cls.patterns["entity"].match(text)
|
||||
if not match:
|
||||
raise Exception()
|
||||
entity = Entity(match.group(1))
|
||||
|
@ -35,12 +37,12 @@ class IncParser():
|
|||
return entity
|
||||
|
||||
@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)
|
||||
|
||||
@classmethod
|
||||
def split_comments(cls, text, object, pointer=0, end=None):
|
||||
pattern = cls.patterns['comment']
|
||||
pattern = cls.patterns["comment"]
|
||||
if end:
|
||||
match = pattern.search(text, pointer, end)
|
||||
else:
|
||||
|
@ -49,9 +51,8 @@ class IncParser():
|
|||
st0 = match.start(0)
|
||||
if st0 > pointer:
|
||||
cls.split_entities(text, object, pointer=pointer, end=st0)
|
||||
groups = match.groups()
|
||||
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)
|
||||
pointer = match.end(0)
|
||||
if end:
|
||||
|
@ -63,7 +64,7 @@ class IncParser():
|
|||
|
||||
@classmethod
|
||||
def split_entities(cls, text, object, pointer=0, end=None):
|
||||
pattern = cls.patterns['entity']
|
||||
pattern = cls.patterns["entity"]
|
||||
if end:
|
||||
match = pattern.search(text, pointer, end)
|
||||
else:
|
||||
|
@ -74,10 +75,12 @@ class IncParser():
|
|||
object.append(text[pointer:st0])
|
||||
groups = match.groups()
|
||||
entity = Entity(groups[0])
|
||||
entity.set_value(groups[1] or '')
|
||||
entity.params['source'] = {'type':'inc',
|
||||
'string':match.group(0),
|
||||
'valpos':match.start(2)-st0}
|
||||
entity.set_value(groups[1] or "")
|
||||
entity.params["source"] = {
|
||||
"type": "inc",
|
||||
"string": match.group(0),
|
||||
"valpos": match.start(2) - st0,
|
||||
}
|
||||
object.append(entity)
|
||||
pointer = match.end(0)
|
||||
if end:
|
||||
|
|
|
@ -1,52 +1,60 @@
|
|||
from ...core import EntityList, Entity, Comment
|
||||
from .structure import IncStructure
|
||||
from ...core import Entity, Comment
|
||||
from .parser import IncParser as Parser
|
||||
import re
|
||||
|
||||
class IncSerializer():
|
||||
|
||||
class IncSerializer:
|
||||
@classmethod
|
||||
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
|
||||
|
||||
@classmethod
|
||||
def dump_element(cls, element, fallback=None):
|
||||
if isinstance(element, Entity):
|
||||
return cls.dump_entity(element, fallback=fallback)
|
||||
elif isinstance(element,Comment):
|
||||
elif isinstance(element, Comment):
|
||||
return cls.dump_comment(element)
|
||||
else:
|
||||
return element
|
||||
|
||||
@classmethod
|
||||
def dump_entity (cls, entity, fallback=None):
|
||||
if 'source' in entity.params and entity.params['source']['type']=='properties':
|
||||
match = Parser.patterns['entity'].match(entity.params['source']['string'])
|
||||
string = entity.params['source']['string'][0:match.start(1)]
|
||||
def dump_entity(cls, entity, fallback=None):
|
||||
if (
|
||||
"source" in entity.params
|
||||
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.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.params['source']['string'][match.end(2):]
|
||||
string += entity.params["source"]["string"][match.end(2) :]
|
||||
else:
|
||||
string = u'#define %s %s' % (entity.id, entity.get_value(fallback))
|
||||
string = "#define {} {}".format(entity.id, entity.get_value(fallback))
|
||||
return string
|
||||
|
||||
@classmethod
|
||||
def dump_entitylist(cls, elist, fallback=None):
|
||||
if not 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
|
||||
|
||||
@classmethod
|
||||
def dump_comment (cls, comment):
|
||||
string = u''
|
||||
def dump_comment(cls, comment):
|
||||
string = ""
|
||||
for element in comment:
|
||||
string += cls.dump_element(element)
|
||||
if string:
|
||||
pattern = re.compile('\n')
|
||||
string = pattern.sub('\n# ', string)
|
||||
string = '# ' + string
|
||||
if string.endswith('# '):
|
||||
pattern = re.compile("\n")
|
||||
string = pattern.sub("\n# ", string)
|
||||
string = "# " + string
|
||||
if string.endswith("# "):
|
||||
string = string[:-2]
|
||||
return string
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from ...core.structure import Structure
|
||||
|
||||
|
||||
class IncStructure(Structure):
|
||||
pass
|
||||
|
|
|
@ -1,31 +1,31 @@
|
|||
from .parser import Parser
|
||||
from .structure import Structure
|
||||
from .serializer import Serializer
|
||||
|
||||
class FormatParser():
|
||||
name = 'ini'
|
||||
|
||||
class FormatParser:
|
||||
name = "ini"
|
||||
desc = "Ini reader/writer"
|
||||
extensions = ['ini']
|
||||
encoding = 'utf_8' # allowed encoding
|
||||
extensions = ["ini"]
|
||||
encoding = "utf_8" # allowed encoding
|
||||
fallback = None
|
||||
|
||||
@classmethod
|
||||
def dump_structure (cls, l10nobject):
|
||||
def dump_structure(cls, l10nobject):
|
||||
text = Serializer.serialize(l10nobject)
|
||||
return text
|
||||
|
||||
@classmethod
|
||||
def dump_entitylist (cls, elist):
|
||||
def dump_entitylist(cls, elist):
|
||||
text = Serializer.dump_entitylist(elist)
|
||||
return text
|
||||
|
||||
@classmethod
|
||||
def get_entitylist (cls, text):
|
||||
def get_entitylist(cls, text):
|
||||
l10nobject = Parser.parse_to_entitylist(text)
|
||||
return l10nobject
|
||||
|
||||
@classmethod
|
||||
def get_structure (cls, text):
|
||||
def get_structure(cls, text):
|
||||
l10nobject = Parser.parse(text)
|
||||
return l10nobject
|
||||
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
from ...core import EntityList, Entity, Comment
|
||||
from .structure import Structure, Section
|
||||
from silme.core.list import EntityList
|
||||
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
|
||||
def parse(cls, text):
|
||||
|
@ -20,15 +22,15 @@ class Parser():
|
|||
@classmethod
|
||||
def parse_to_entitylist(cls, text):
|
||||
entitylist = EntityList(id=None)
|
||||
text = cls.patterns['comment'].sub('', text)
|
||||
matchlist = cls.patterns['entity'].findall(text)
|
||||
text = cls.patterns["comment"].sub("", text)
|
||||
matchlist = cls.patterns["entity"].findall(text)
|
||||
for match in matchlist:
|
||||
entitylist.add(Entity(match[0], match[1]))
|
||||
return entitylist
|
||||
|
||||
@classmethod
|
||||
def parse_entity(cls, text):
|
||||
match = self.patterns['entity'].match(text)
|
||||
match = cls.patterns["entity"].match(text)
|
||||
if not match:
|
||||
raise Exception()
|
||||
entity = Entity(match.group(1))
|
||||
|
@ -36,13 +38,13 @@ class Parser():
|
|||
return entity
|
||||
|
||||
@classmethod
|
||||
def build_element_list (cls, text, object):
|
||||
def build_element_list(cls, text, object):
|
||||
cls.split_sections(text, object)
|
||||
|
||||
@classmethod
|
||||
def split_sections(cls, text, struct, pointer=0, end=None):
|
||||
root = struct
|
||||
pattern = cls.patterns['section']
|
||||
pattern = cls.patterns["section"]
|
||||
if end:
|
||||
match = pattern.search(text, pointer, end)
|
||||
else:
|
||||
|
@ -62,11 +64,9 @@ class Parser():
|
|||
if (not end or (end > pointer)) and len(text) > pointer:
|
||||
cls.split_comments(text, struct, pointer=pointer, end=end)
|
||||
|
||||
|
||||
|
||||
@classmethod
|
||||
def split_comments(cls, text, object, pointer=0, end=None):
|
||||
pattern = cls.patterns['comment']
|
||||
pattern = cls.patterns["comment"]
|
||||
if end:
|
||||
match = pattern.search(text, pointer, end)
|
||||
else:
|
||||
|
@ -76,7 +76,7 @@ class Parser():
|
|||
if st0 > pointer:
|
||||
cls.split_entities(text, object, pointer=pointer, end=st0)
|
||||
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)
|
||||
pointer = match.end(0)
|
||||
if end:
|
||||
|
@ -88,7 +88,7 @@ class Parser():
|
|||
|
||||
@classmethod
|
||||
def split_entities(cls, text, object, pointer=0, end=None):
|
||||
pattern = cls.patterns['entity']
|
||||
pattern = cls.patterns["entity"]
|
||||
if end:
|
||||
match = pattern.search(text, pointer, end)
|
||||
else:
|
||||
|
@ -100,9 +100,11 @@ class Parser():
|
|||
groups = match.groups()
|
||||
entity = Entity(groups[0])
|
||||
entity.set_value(groups[1])
|
||||
entity.params['source'] = {'type':'ini',
|
||||
'string':match.group(0),
|
||||
'valpos':match.start(2)-st0}
|
||||
entity.params["source"] = {
|
||||
"type": "ini",
|
||||
"string": match.group(0),
|
||||
"valpos": match.start(2) - st0,
|
||||
}
|
||||
object.append(entity)
|
||||
pointer = match.end(0)
|
||||
if end:
|
||||
|
|
|
@ -4,10 +4,11 @@ from .parser import Parser
|
|||
from silme.core.entity import is_entity
|
||||
import re
|
||||
|
||||
class Serializer():
|
||||
|
||||
class Serializer:
|
||||
@classmethod
|
||||
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
|
||||
|
||||
@classmethod
|
||||
|
@ -23,36 +24,36 @@ class Serializer():
|
|||
|
||||
@classmethod
|
||||
def dump_entity(cls, entity):
|
||||
if 'source' in entity.params and entity.params['source']['type']=='ini':
|
||||
match = Parser.patterns['entity'].match(entity.params['source']['string'])
|
||||
string = entity.params['source']['string'][0:match.start(1)]
|
||||
if "source" in entity.params and entity.params["source"]["type"] == "ini":
|
||||
match = Parser.patterns["entity"].match(entity.params["source"]["string"])
|
||||
string = entity.params["source"]["string"][0 : match.start(1)]
|
||||
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.params['source']['string'][match.end(2):]
|
||||
string += entity.params["source"]["string"][match.end(2) :]
|
||||
else:
|
||||
string = entity.id+'='+entity.value
|
||||
string = entity.id + "=" + entity.value
|
||||
return string
|
||||
|
||||
@classmethod
|
||||
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
|
||||
|
||||
@classmethod
|
||||
def dump_comment(cls, comment):
|
||||
string = ''
|
||||
string = ""
|
||||
for element in comment:
|
||||
string += cls.dump_element(element)
|
||||
if string:
|
||||
pattern = re.compile('\n')
|
||||
string = pattern.sub('\n#', string)
|
||||
string = '#' + string
|
||||
if string.endswith('#'):
|
||||
pattern = re.compile("\n")
|
||||
string = pattern.sub("\n#", string)
|
||||
string = "#" + string
|
||||
if string.endswith("#"):
|
||||
string = string[:-1]
|
||||
return string
|
||||
|
||||
@classmethod
|
||||
def dump_section(cls, section):
|
||||
string = '[%s]%s' % (section.id, cls.serialize(section))
|
||||
string = "[{}]{}".format(section.id, cls.serialize(section))
|
||||
return string
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
from silme.core.structure import Structure as BaseStructure, Comment
|
||||
from silme.core.entity import is_string, is_entity
|
||||
|
||||
|
||||
class Structure(BaseStructure):
|
||||
def __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):
|
||||
"""adds an element (string, entity or comment) to the Structure
|
||||
|
@ -25,16 +26,18 @@ class Structure(BaseStructure):
|
|||
elif item is None:
|
||||
return 0
|
||||
else:
|
||||
raise Exception('Cannot add element of type "' +
|
||||
type(item).__name__ +
|
||||
'" to the Structure')
|
||||
raise Exception(
|
||||
'Cannot add element of type "'
|
||||
+ type(item).__name__
|
||||
+ '" to the Structure'
|
||||
)
|
||||
|
||||
def add_section(self, section, pos=None):
|
||||
pos = self._get_pos(pos)
|
||||
if pos is None:
|
||||
self.first_section = len(self)
|
||||
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)
|
||||
return 1
|
||||
|
||||
|
@ -45,8 +48,9 @@ class Structure(BaseStructure):
|
|||
('before', 'entity.id'), ('after', 'entity.id')
|
||||
"""
|
||||
pos = self._get_pos(pos)
|
||||
if self.first_section is not False and \
|
||||
(pos is None or pos > self.first_section):
|
||||
if self.first_section is not False and (
|
||||
pos is None or pos > self.first_section
|
||||
):
|
||||
raise Exception("Cannot add entity after section")
|
||||
self.add_at_pos(entity, pos)
|
||||
return 1
|
||||
|
@ -65,8 +69,7 @@ class Structure(BaseStructure):
|
|||
raise KeyError("No such entity or section")
|
||||
|
||||
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:
|
||||
if is_entity(item) and item.id == id:
|
||||
return True
|
||||
|
@ -75,12 +78,11 @@ class Structure(BaseStructure):
|
|||
return False
|
||||
|
||||
def section(self, key):
|
||||
"""returns a section for a given id
|
||||
"""
|
||||
"""returns a section for a given id"""
|
||||
for item in self:
|
||||
if isinstance(item, Section) and item.id == key:
|
||||
return item
|
||||
raise KeyError('No such section')
|
||||
raise KeyError("No such section")
|
||||
|
||||
|
||||
class Section(Structure):
|
||||
|
@ -103,7 +105,8 @@ class Section(Structure):
|
|||
elif item is None:
|
||||
return 0
|
||||
else:
|
||||
raise Exception('Cannot add element of type "' +
|
||||
type(item).__name__ +
|
||||
'" to the Structure')
|
||||
|
||||
raise Exception(
|
||||
'Cannot add element of type "'
|
||||
+ type(item).__name__
|
||||
+ '" to the Structure'
|
||||
)
|
||||
|
|
|
@ -7,25 +7,25 @@ if sys.version_info[0] > 2:
|
|||
unichr = chr
|
||||
|
||||
|
||||
class FormatParser(object):
|
||||
name = 'properties'
|
||||
class FormatParser:
|
||||
name = "properties"
|
||||
desc = "Java Properties reader/writer"
|
||||
extensions = ['properties']
|
||||
encoding = 'utf_8' # allowed encoding
|
||||
fallback = ['utf_8_sig']
|
||||
extensions = ["properties"]
|
||||
encoding = "utf_8" # allowed encoding
|
||||
fallback = ["utf_8_sig"]
|
||||
|
||||
@classmethod
|
||||
def dump_structure (cls, l10nobject):
|
||||
def dump_structure(cls, l10nobject):
|
||||
text = Serializer.serialize(l10nobject)
|
||||
return text
|
||||
|
||||
@classmethod
|
||||
def dump_entitylist (cls, elist):
|
||||
def dump_entitylist(cls, elist):
|
||||
text = Serializer.dump_entitylist(elist)
|
||||
return text
|
||||
|
||||
@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
|
||||
if text and (text[0] == unichr(65279)):
|
||||
text = text[1:]
|
||||
|
@ -33,7 +33,7 @@ class FormatParser(object):
|
|||
return l10nobject
|
||||
|
||||
@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
|
||||
if text and (text[0] == unichr(65279)):
|
||||
text = text[1:]
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
from ...core import EntityList, Entity, Comment
|
||||
from .structure import PropertiesStructure
|
||||
from silme.core.list import EntityList
|
||||
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
|
||||
def parse(cls, text, code='default'):
|
||||
def parse(cls, text, code="default"):
|
||||
prop = PropertiesStructure(id=None)
|
||||
cls.build_element_list(text, prop, code=code)
|
||||
prop.fallback = code
|
||||
|
@ -20,15 +22,15 @@ class PropertiesParser():
|
|||
@classmethod
|
||||
def parse_to_entitylist(cls, text):
|
||||
entitylist = EntityList(None)
|
||||
text = cls.patterns['comment'].sub('', text)
|
||||
matchlist = cls.patterns['entity'].findall(text)
|
||||
text = cls.patterns["comment"].sub("", text)
|
||||
matchlist = cls.patterns["entity"].findall(text)
|
||||
for match in matchlist:
|
||||
entitylist.add(Entity(match[0], match[1]))
|
||||
return entitylist
|
||||
|
||||
@classmethod
|
||||
def parse_entity(cls, text, code='default'):
|
||||
match = self.patterns['entity'].match(text)
|
||||
def parse_entity(cls, text, code="default"):
|
||||
match = cls.patterns["entity"].match(text)
|
||||
if not match:
|
||||
raise Exception()
|
||||
entity = Entity(match.group(1))
|
||||
|
@ -36,12 +38,14 @@ class PropertiesParser():
|
|||
return entity
|
||||
|
||||
@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)
|
||||
|
||||
@classmethod
|
||||
def split_comments(cls, text, object, code='default', pointer=0, end=None):
|
||||
pattern = cls.patterns['comment']
|
||||
def split_comments(cls, text, object, code="default", pointer=0, end=None):
|
||||
pattern = cls.patterns["comment"]
|
||||
if end:
|
||||
match = pattern.search(text, pointer, end)
|
||||
else:
|
||||
|
@ -50,9 +54,8 @@ class PropertiesParser():
|
|||
st0 = match.start(0)
|
||||
if st0 > pointer:
|
||||
cls.split_entities(text, object, code=code, pointer=pointer, end=st0)
|
||||
groups = match.groups()
|
||||
comment = Comment()
|
||||
comment.add(match.group(0)[1:].replace('\n#', '\n'))
|
||||
comment.add(match.group(0)[1:].replace("\n#", "\n"))
|
||||
object.append(comment)
|
||||
pointer = match.end(0)
|
||||
if end:
|
||||
|
@ -63,8 +66,8 @@ class PropertiesParser():
|
|||
cls.split_entities(text, object, code=code, pointer=pointer)
|
||||
|
||||
@classmethod
|
||||
def split_entities(cls, text, object, code='default', pointer=0, end=None):
|
||||
pattern = cls.patterns['entity']
|
||||
def split_entities(cls, text, object, code="default", pointer=0, end=None):
|
||||
pattern = cls.patterns["entity"]
|
||||
if end:
|
||||
match = pattern.search(text, pointer, end)
|
||||
else:
|
||||
|
@ -76,9 +79,11 @@ class PropertiesParser():
|
|||
groups = match.groups()
|
||||
entity = Entity(groups[0])
|
||||
entity.set_value(groups[1])
|
||||
entity.params['source'] = {'type':'properties',
|
||||
'string':match.group(0),
|
||||
'valpos':match.start(2)-st0}
|
||||
entity.params["source"] = {
|
||||
"type": "properties",
|
||||
"string": match.group(0),
|
||||
"valpos": match.start(2) - st0,
|
||||
}
|
||||
object.append(entity)
|
||||
pointer = match.end(0)
|
||||
if end:
|
||||
|
|
|
@ -1,51 +1,54 @@
|
|||
from ...core import EntityList, Entity, Comment
|
||||
from ...core import Comment
|
||||
from silme.core.entity import is_entity
|
||||
from .structure import PropertiesStructure
|
||||
from .parser import PropertiesParser as Parser
|
||||
import re
|
||||
|
||||
class PropertiesSerializer():
|
||||
|
||||
class PropertiesSerializer:
|
||||
@classmethod
|
||||
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
|
||||
|
||||
@classmethod
|
||||
def dump_element(cls, element, fallback=None):
|
||||
if is_entity(element):
|
||||
return cls.dump_entity(element)
|
||||
elif isinstance(element,Comment):
|
||||
elif isinstance(element, Comment):
|
||||
return cls.dump_comment(element)
|
||||
else:
|
||||
return element
|
||||
|
||||
@classmethod
|
||||
def dump_entity (cls, entity):
|
||||
if 'source' in entity.params and entity.params['source']['type']=='properties':
|
||||
match = Parser.patterns['entity'].match(entity.params['source']['string'])
|
||||
string = entity.params['source']['string'][0:match.start(1)]
|
||||
def dump_entity(cls, entity):
|
||||
if (
|
||||
"source" in entity.params
|
||||
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.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.params['source']['string'][match.end(2):]
|
||||
string += entity.params["source"]["string"][match.end(2) :]
|
||||
else:
|
||||
string = entity.id+u' = '+entity.value
|
||||
string = entity.id + " = " + entity.value
|
||||
return string
|
||||
|
||||
@classmethod
|
||||
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
|
||||
|
||||
@classmethod
|
||||
def dump_comment (cls, comment):
|
||||
string = u''
|
||||
def dump_comment(cls, comment):
|
||||
string = ""
|
||||
for element in comment:
|
||||
string += cls.dump_element(element)
|
||||
if string:
|
||||
pattern = re.compile('\n')
|
||||
string = pattern.sub('\n#', string)
|
||||
string = '#' + string
|
||||
if string.endswith('#'):
|
||||
pattern = re.compile("\n")
|
||||
string = pattern.sub("\n#", string)
|
||||
string = "#" + string
|
||||
if string.endswith("#"):
|
||||
string = string[:-1]
|
||||
return string
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from ...core.structure import Structure
|
||||
|
||||
|
||||
class PropertiesStructure(Structure):
|
||||
pass
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
[build-system]
|
||||
requires = ["setuptools>=40.8.0", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[tool.black]
|
||||
line-length = 88
|
|
@ -0,0 +1,6 @@
|
|||
[flake8]
|
||||
max-line-length = 88
|
||||
ignore =
|
||||
E203,
|
||||
E731,
|
||||
W503,
|
42
setup.py
42
setup.py
|
@ -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.
|
||||
"""
|
||||
|
||||
docstrings = __doc__.split("\n")
|
||||
|
||||
from setuptools import setup, find_packages
|
||||
import sys
|
||||
import os.path
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'lib'))
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "lib"))
|
||||
|
||||
import silme
|
||||
import silme # noqa: E402
|
||||
|
||||
classifiers = """\
|
||||
Development Status :: 4 - Beta
|
||||
|
@ -27,17 +28,18 @@ Topic :: Software Development :: Libraries :: Python Modules
|
|||
Topic :: Software Development :: Localization
|
||||
"""
|
||||
|
||||
setup(name="silme",
|
||||
version=silme.get_short_version(),
|
||||
author="Zbigniew Braniecki",
|
||||
author_email="gandalf@mozilla.com",
|
||||
description=docstrings[0],
|
||||
long_description="\n".join(docstrings[2:]),
|
||||
license="MPL 1.1/GPL 2.0/LGPL 2.1",
|
||||
url="https://github.com/mathjazz/silme",
|
||||
classifiers=filter(None, classifiers.split("\n")),
|
||||
platforms=["any"],
|
||||
package_dir={'': 'lib'},
|
||||
packages=find_packages('lib'),
|
||||
keywords="localization, l10n"
|
||||
)
|
||||
setup(
|
||||
name="silme",
|
||||
version=silme.get_short_version(),
|
||||
author="Zbigniew Braniecki",
|
||||
author_email="gandalf@mozilla.com",
|
||||
description=docstrings[0],
|
||||
long_description="\n".join(docstrings[2:]),
|
||||
license="MPL 1.1/GPL 2.0/LGPL 2.1",
|
||||
url="https://github.com/mathjazz/silme",
|
||||
classifiers=filter(None, classifiers.split("\n")),
|
||||
platforms=["any"],
|
||||
package_dir={"": "lib"},
|
||||
packages=find_packages("lib"),
|
||||
keywords="localization, l10n",
|
||||
)
|
||||
|
|
|
@ -1,141 +1,140 @@
|
|||
import unittest
|
||||
import sys
|
||||
|
||||
from silme.core.entity import Entity, ComplexValue
|
||||
from silme.core.types import OrderedDict
|
||||
from collections import OrderedDict
|
||||
|
||||
|
||||
class EntityTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.entity = Entity('test')
|
||||
self.entity = Entity("test")
|
||||
|
||||
def test_id(self):
|
||||
self.assertEqual(self.entity.id, 'test')
|
||||
self.assertEqual(self.entity.id, "test")
|
||||
|
||||
def test_value1(self):
|
||||
self.entity.value = 'testvalue'
|
||||
self.assertEqual(self.entity.value, 'testvalue')
|
||||
self.entity.value = "testvalue"
|
||||
self.assertEqual(self.entity.value, "testvalue")
|
||||
self.assertEqual(self.entity.get_value(), self.entity.value)
|
||||
|
||||
def test_value3(self):
|
||||
self.entity = Entity('test', 'testvalue')
|
||||
self.assertEqual(self.entity.value, 'testvalue')
|
||||
self.entity = Entity("test", "testvalue")
|
||||
self.assertEqual(self.entity.value, "testvalue")
|
||||
self.assertEqual(self.entity.get_value(), self.entity.value)
|
||||
|
||||
def test_value5(self):
|
||||
self.assertEqual(self.entity.get_value(), None)
|
||||
|
||||
def test_value6(self):
|
||||
self.entity.value = 'foo'
|
||||
self.assertEqual(self.entity.value, 'foo')
|
||||
self.entity.value = "foo"
|
||||
self.assertEqual(self.entity.value, "foo")
|
||||
|
||||
def test_list1(self):
|
||||
self.entity.value = ['foo','foo2']
|
||||
self.assertEqual(self.entity.value, 'foo')
|
||||
self.entity.value = ["foo", "foo2"]
|
||||
self.assertEqual(self.entity.value, "foo")
|
||||
|
||||
def test_list2(self):
|
||||
self.entity.value = ['foo','foo2']
|
||||
self.assertEqual(self.entity[0], 'foo')
|
||||
self.assertEqual(self.entity[1], 'foo2')
|
||||
self.entity.value = ["foo", "foo2"]
|
||||
self.assertEqual(self.entity[0], "foo")
|
||||
self.assertEqual(self.entity[1], "foo2")
|
||||
|
||||
def test_list3(self):
|
||||
self.entity.value = ['foo','foo2']
|
||||
self.assertEqual(self.entity.get_value(0), 'foo')
|
||||
self.assertEqual(self.entity.get_value(1), 'foo2')
|
||||
self.entity.value = ["foo", "foo2"]
|
||||
self.assertEqual(self.entity.get_value(0), "foo")
|
||||
self.assertEqual(self.entity.get_value(1), "foo2")
|
||||
|
||||
def test_list4(self):
|
||||
self.entity = Entity('test', ['old','old2'])
|
||||
self.entity[0] = 'foo'
|
||||
self.entity[1] = 'foo2'
|
||||
self.assertEqual(self.entity.get_value(0), 'foo')
|
||||
self.assertEqual(self.entity.get_value(1), 'foo2')
|
||||
self.entity = Entity("test", ["old", "old2"])
|
||||
self.entity[0] = "foo"
|
||||
self.entity[1] = "foo2"
|
||||
self.assertEqual(self.entity.get_value(0), "foo")
|
||||
self.assertEqual(self.entity.get_value(1), "foo2")
|
||||
|
||||
def test_list5(self):
|
||||
self.entity.value = ['foo','foo2']
|
||||
self.entity.value = ["foo", "foo2"]
|
||||
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)
|
||||
|
||||
def test_dict1(self):
|
||||
self.entity = Entity('test', {'male':'Foo','female':'Foo2'})
|
||||
self.assertTrue(self.entity.value in ('Foo', 'Foo2'))
|
||||
self.entity = Entity("test", {"male": "Foo", "female": "Foo2"})
|
||||
self.assertTrue(self.entity.value in ("Foo", "Foo2"))
|
||||
|
||||
def test_dict2(self):
|
||||
self.entity.value = {'male':'Foo','female':'Foo2'}
|
||||
self.assertTrue(self.entity.value in ('Foo', 'Foo2'))
|
||||
self.entity.value = {"male": "Foo", "female": "Foo2"}
|
||||
self.assertTrue(self.entity.value in ("Foo", "Foo2"))
|
||||
|
||||
def test_dict3(self):
|
||||
self.entity.value = {'male':'Foo','female':'Foo2'}
|
||||
self.assertTrue(self.entity.get_value() in ('Foo', 'Foo2'))
|
||||
self.entity.value = {"male": "Foo", "female": "Foo2"}
|
||||
self.assertTrue(self.entity.get_value() in ("Foo", "Foo2"))
|
||||
|
||||
def test_dict4(self):
|
||||
self.entity.value = {'male':'Foo','female':'Foo2'}
|
||||
self.assertEqual(self.entity.get_value('male'), 'Foo')
|
||||
self.assertEqual(self.entity.get_value('female'), 'Foo2')
|
||||
self.entity.value = {"male": "Foo", "female": "Foo2"}
|
||||
self.assertEqual(self.entity.get_value("male"), "Foo")
|
||||
self.assertEqual(self.entity.get_value("female"), "Foo2")
|
||||
|
||||
def test_dict5(self):
|
||||
self.entity.value = {'male':'Foo','female':'Foo2'}
|
||||
self.assertEqual(self.entity['male'], 'Foo')
|
||||
self.assertEqual(self.entity['female'], 'Foo2')
|
||||
self.entity.value = {"male": "Foo", "female": "Foo2"}
|
||||
self.assertEqual(self.entity["male"], "Foo")
|
||||
self.assertEqual(self.entity["female"], "Foo2")
|
||||
|
||||
def test_dict6(self):
|
||||
self.entity.value = {'male':'Foo','female':'Foo2'}
|
||||
self.entity['male']='Foo3'
|
||||
self.assertEqual(self.entity['male'], 'Foo3')
|
||||
self.assertEqual(self.entity['female'], 'Foo2')
|
||||
self.entity.value = {"male": "Foo", "female": "Foo2"}
|
||||
self.entity["male"] = "Foo3"
|
||||
self.assertEqual(self.entity["male"], "Foo3")
|
||||
self.assertEqual(self.entity["female"], "Foo2")
|
||||
|
||||
def test_dict7(self):
|
||||
self.entity.value = {'male':'Foo','female':'Foo2'}
|
||||
del self.entity['male']
|
||||
self.assertEqual(self.entity['female'], 'Foo2')
|
||||
self.assertRaises(KeyError, self.entity.get_value, 'male')
|
||||
|
||||
self.entity.value = {"male": "Foo", "female": "Foo2"}
|
||||
del self.entity["male"]
|
||||
self.assertEqual(self.entity["female"], "Foo2")
|
||||
self.assertRaises(KeyError, self.entity.get_value, "male")
|
||||
|
||||
def test_complex5(self):
|
||||
self.entity.value = ComplexValue({'male':'Foo2','female':'Foo3'})
|
||||
self.assertEqual(self.entity['male'], 'Foo2')
|
||||
self.entity.value = ComplexValue({"male": "Foo2", "female": "Foo3"})
|
||||
self.assertEqual(self.entity["male"], "Foo2")
|
||||
|
||||
def test_complex6(self):
|
||||
self.entity.value = ComplexValue(['foo','foo4'])
|
||||
self.assertEqual(self.entity[1], 'foo4')
|
||||
self.entity.value = ComplexValue(["foo", "foo4"])
|
||||
self.assertEqual(self.entity[1], "foo4")
|
||||
|
||||
def test_complex7(self):
|
||||
self.entity.value = ComplexValue('Foo')
|
||||
self.entity.value = ComplexValue("Foo")
|
||||
self.assertRaises(TypeError, self.entity.__getitem__, 0)
|
||||
|
||||
def test_complex8(self):
|
||||
self.entity.value = ComplexValue('Foo')
|
||||
self.entity.value = ComplexValue("Foo")
|
||||
self.assertRaises(TypeError, self.entity.__getitem__, 0)
|
||||
self.entity.value = ComplexValue(['Foo3','Foo4'])
|
||||
self.assertEqual(self.entity[1], 'Foo4')
|
||||
self.entity.value = ComplexValue({'one':'Foo5','few':'Foo6','many':'Foo7'})
|
||||
self.assertEqual(self.entity['few'], 'Foo6')
|
||||
self.entity.value = ComplexValue(["Foo3", "Foo4"])
|
||||
self.assertEqual(self.entity[1], "Foo4")
|
||||
self.entity.value = ComplexValue({"one": "Foo5", "few": "Foo6", "many": "Foo7"})
|
||||
self.assertEqual(self.entity["few"], "Foo6")
|
||||
|
||||
def test_complex9(self):
|
||||
self.entity.value = ComplexValue('Foo')
|
||||
self.assertEqual(self.entity.value, 'Foo')
|
||||
self.entity.value = ComplexValue(['Foo3','Foo4'])
|
||||
self.assertEqual(self.entity.value, 'Foo3')
|
||||
self.entity.value = ComplexValue(OrderedDict((('one','Foo5'),('few','Foo6'),('many','Foo7'))))
|
||||
self.assertEqual(self.entity.value, 'Foo5')
|
||||
self.entity.value = ComplexValue("Foo")
|
||||
self.assertEqual(self.entity.value, "Foo")
|
||||
self.entity.value = ComplexValue(["Foo3", "Foo4"])
|
||||
self.assertEqual(self.entity.value, "Foo3")
|
||||
self.entity.value = ComplexValue(
|
||||
OrderedDict((("one", "Foo5"), ("few", "Foo6"), ("many", "Foo7")))
|
||||
)
|
||||
self.assertEqual(self.entity.value, "Foo5")
|
||||
|
||||
def test_custom1(self):
|
||||
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.value = ['Firefox', 'Firefoxes']
|
||||
self.assertEqual(self.entity.value, 'Firefox')
|
||||
self.assertEqual(self.entity.get_value(1), 'Firefox')
|
||||
self.assertEqual(self.entity.get_value(5), 'Firefoxes')
|
||||
self.entity.value = ["Firefox", "Firefoxes"]
|
||||
self.assertEqual(self.entity.value, "Firefox")
|
||||
self.assertEqual(self.entity.get_value(1), "Firefox")
|
||||
self.assertEqual(self.entity.get_value(5), "Firefoxes")
|
||||
|
||||
def test_values1(self):
|
||||
vals = ['foo', 'foo2']
|
||||
vals = ["foo", "foo2"]
|
||||
self.entity.value = vals
|
||||
vals.pop()
|
||||
self.assertNotEqual(self.entity.values, vals)
|
||||
#x = self.entity.values
|
||||
#x.pop()
|
||||
#self.assertEqual(x, vals)
|
||||
#self.assertNotEqual(self.entity.values, x)
|
||||
# x = self.entity.values
|
||||
# x.pop()
|
||||
# self.assertEqual(x, vals)
|
||||
# self.assertNotEqual(self.entity.values, x)
|
||||
|
|
|
@ -1,127 +1,125 @@
|
|||
import random
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
import silme.core
|
||||
|
||||
class EntityTestCase(unittest.TestCase):
|
||||
|
||||
class EntityTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.entity_list = silme.core.EntityList('test')
|
||||
self.entity_list = silme.core.EntityList("test")
|
||||
|
||||
def test_init1(self):
|
||||
self.assertEqual(self.entity_list.id, 'test')
|
||||
self.assertEqual(self.entity_list.id, "test")
|
||||
|
||||
def test_init2(self):
|
||||
self.assertRaises(AttributeError, silme.core.EntityList, 'test', 'foo')
|
||||
self.assertRaises(AttributeError, silme.core.EntityList, "test", "foo")
|
||||
|
||||
def test_init3(self):
|
||||
entity1 = silme.core.Entity('x')
|
||||
entity2 = silme.core.Entity('y')
|
||||
self.entity_list = silme.core.EntityList('test', entity1, entity2)
|
||||
self.assertEqual(self.entity_list['x'], entity1)
|
||||
self.assertEqual(self.entity_list['y'], entity2)
|
||||
entity1 = silme.core.Entity("x")
|
||||
entity2 = silme.core.Entity("y")
|
||||
self.entity_list = silme.core.EntityList("test", entity1, entity2)
|
||||
self.assertEqual(self.entity_list["x"], entity1)
|
||||
self.assertEqual(self.entity_list["y"], entity2)
|
||||
|
||||
def test_init4(self):
|
||||
entity1 = silme.core.Entity('x')
|
||||
entity2 = silme.core.Entity('y')
|
||||
entity_list = silme.core.EntityList('test', entity1, entity2)
|
||||
self.entity_list = silme.core.EntityList('id2', entity_list)
|
||||
self.assertEqual(self.entity_list['x'], entity1)
|
||||
self.assertEqual(self.entity_list['y'], entity2)
|
||||
|
||||
entity1 = silme.core.Entity("x")
|
||||
entity2 = silme.core.Entity("y")
|
||||
entity_list = silme.core.EntityList("test", entity1, entity2)
|
||||
self.entity_list = silme.core.EntityList("id2", entity_list)
|
||||
self.assertEqual(self.entity_list["x"], entity1)
|
||||
self.assertEqual(self.entity_list["y"], entity2)
|
||||
|
||||
def test_has_entity1(self):
|
||||
entity1 = silme.core.Entity('x')
|
||||
entity1 = silme.core.Entity("x")
|
||||
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):
|
||||
entity1 = silme.core.Entity('x')
|
||||
entity2 = silme.core.Entity('y')
|
||||
entity1 = silme.core.Entity("x")
|
||||
entity2 = silme.core.Entity("y")
|
||||
self.entity_list.add(entity1)
|
||||
self.entity_list.add(entity2)
|
||||
l = self.entity_list.entities()
|
||||
self.assertTrue(l[0].id in ('x', 'y'))
|
||||
self.assertTrue(l[1].id in ('x', 'y'))
|
||||
self.assertNotEqual(l[0].id, l[1].id)
|
||||
entities = self.entity_list.entities()
|
||||
self.assertTrue(entities[0].id in ("x", "y"))
|
||||
self.assertTrue(entities[1].id in ("x", "y"))
|
||||
self.assertNotEqual(entities[0].id, entities[1].id)
|
||||
|
||||
def test_iter_entities(self):
|
||||
entity1 = silme.core.Entity('x')
|
||||
entity2 = silme.core.Entity('y')
|
||||
entity3 = silme.core.Entity('z')
|
||||
entity1 = silme.core.Entity("x")
|
||||
entity2 = silme.core.Entity("y")
|
||||
entity3 = silme.core.Entity("z")
|
||||
self.entity_list.add(entity1)
|
||||
self.entity_list.add(entity2)
|
||||
self.entity_list.add(entity3)
|
||||
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):
|
||||
entity1 = silme.core.Entity('x')
|
||||
entity2 = silme.core.Entity('y')
|
||||
entity1 = silme.core.Entity("x")
|
||||
entity2 = silme.core.Entity("y")
|
||||
self.entity_list.add(entity1)
|
||||
self.entity_list.add(entity2)
|
||||
ids = self.entity_list.keys()
|
||||
self.assertEqual('x' in ids, True)
|
||||
self.assertEqual('y' in ids, True)
|
||||
|
||||
self.assertEqual("x" in ids, True)
|
||||
self.assertEqual("y" in ids, True)
|
||||
|
||||
def test_modify_entity1(self):
|
||||
entity1 = silme.core.Entity('x')
|
||||
entity1 = silme.core.Entity("x")
|
||||
self.entity_list.add(entity1)
|
||||
self.entity_list.modify('x', 'test2')
|
||||
self.assertEqual(self.entity_list['x'].value, 'test2')
|
||||
self.entity_list.modify("x", "test2")
|
||||
self.assertEqual(self.entity_list["x"].value, "test2")
|
||||
|
||||
def test_modify_entity2(self):
|
||||
entity1 = silme.core.Entity('x', 'foo')
|
||||
entity1.set_value('heh')
|
||||
entity1 = silme.core.Entity("x", "foo")
|
||||
entity1.set_value("heh")
|
||||
self.entity_list.add(entity1)
|
||||
self.entity_list.modify('x', 'test2')
|
||||
self.assertEqual(self.entity_list['x'].get_value(), 'test2')
|
||||
self.entity_list.modify("x", "test2")
|
||||
self.assertEqual(self.entity_list["x"].get_value(), "test2")
|
||||
|
||||
def test_entity1(self):
|
||||
entity1 = silme.core.Entity('x', 'foo')
|
||||
entity1 = silme.core.Entity("x", "foo")
|
||||
self.entity_list.add(entity1)
|
||||
self.assertEqual(self.entity_list['x'], entity1)
|
||||
self.assertEqual(self.entity_list["x"], entity1)
|
||||
|
||||
def test_get_value(self):
|
||||
entity1 = silme.core.Entity('x')
|
||||
entity1.set_value('test')
|
||||
entity1 = silme.core.Entity("x")
|
||||
entity1.set_value("test")
|
||||
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):
|
||||
self.entity_list = silme.core.EntityList('test', ordered=True)
|
||||
ids = ('id1', 'id2', 'id3')
|
||||
self.entity_list = silme.core.EntityList("test", ordered=True)
|
||||
ids = ("id1", "id2", "id3")
|
||||
for i in ids:
|
||||
self.entity_list.add(silme.core.Entity(i))
|
||||
n = 0
|
||||
for i in self.entity_list.keys():
|
||||
self.assertEqual(i, ids[n])
|
||||
n+=1
|
||||
n += 1
|
||||
n = 0
|
||||
for i in self.entity_list:
|
||||
self.assertEqual(i, ids[n])
|
||||
n+=1
|
||||
n += 1
|
||||
|
||||
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):
|
||||
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(self.entity_list._stubs, set('id1'))
|
||||
e = self.entity_list['id1']
|
||||
self.assertEqual(e.id, 'id1')
|
||||
self.assertEqual(e.value, 'Foo1')
|
||||
self.assertTrue(self.entity_list._stubs, set("id1"))
|
||||
e = self.entity_list["id1"]
|
||||
self.assertEqual(e.id, "id1")
|
||||
self.assertEqual(e.value, "Foo1")
|
||||
self.assertEqual(len(self.entity_list._stubs), 0)
|
||||
|
||||
def test_value_list1(self):
|
||||
vlist = silme.core.list.ValueList('test')
|
||||
vlist.add(silme.core.Entity('id1', 'Foo1'))
|
||||
self.assertEqual(vlist['id1'], 'Foo1')
|
||||
vlist = silme.core.list.ValueList("test")
|
||||
vlist.add(silme.core.Entity("id1", "Foo1"))
|
||||
self.assertEqual(vlist["id1"], "Foo1")
|
||||
|
||||
def test_value_list2(self):
|
||||
vlist = silme.core.list.ValueList('test')
|
||||
vlist.add(silme.core.Entity('id1', 'Foo1'))
|
||||
vlist = silme.core.list.ValueList("test")
|
||||
vlist.add(silme.core.Entity("id1", "Foo1"))
|
||||
self.assertRaises(TypeError, vlist.entities)
|
||||
|
|
|
@ -1,88 +1,89 @@
|
|||
import random
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
import silme.core
|
||||
|
||||
class EntityTestCase(unittest.TestCase):
|
||||
|
||||
class EntityTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.l10npackage = silme.core.Package('test')
|
||||
self.l10npackage = silme.core.Package("test")
|
||||
|
||||
def test_id(self):
|
||||
self.assertEqual(self.l10npackage.id, 'test')
|
||||
self.assertEqual(self.l10npackage.id, "test")
|
||||
|
||||
def test_add_structure(self):
|
||||
l10nobject = silme.core.Structure('foo')
|
||||
l10nobject = silme.core.Structure("foo")
|
||||
self.l10npackage.add_structure(l10nobject)
|
||||
self.assertEqual(len(self.l10npackage.structures()), 1)
|
||||
|
||||
def test_add_structure2(self):
|
||||
l10nobject = silme.core.Structure('foo')
|
||||
self.l10npackage.add_structure(l10nobject, 'test2/test3')
|
||||
l10nobject = silme.core.Structure("foo")
|
||||
self.l10npackage.add_structure(l10nobject, "test2/test3")
|
||||
self.assertEqual(len(self.l10npackage.packages()), 1)
|
||||
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].structure('foo').id, 'foo')
|
||||
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].structure("foo").id, "foo"
|
||||
)
|
||||
|
||||
def test_add_package(self):
|
||||
l10npack = silme.core.Package('foo')
|
||||
l10npack = silme.core.Package("foo")
|
||||
self.l10npackage.add_package(l10npack)
|
||||
self.assertEqual(len(self.l10npackage.packages()), 1)
|
||||
|
||||
def test_add_package2(self):
|
||||
l10npack = silme.core.Package('foo')
|
||||
self.l10npackage.add_package(l10npack, 'test2/test3')
|
||||
l10npack = silme.core.Package("foo")
|
||||
self.l10npackage.add_package(l10npack, "test2/test3")
|
||||
self.assertEqual(len(self.l10npackage.packages()), 1)
|
||||
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].package('foo').id, 'foo')
|
||||
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].package("foo").id, "foo"
|
||||
)
|
||||
|
||||
def test_get_objects(self):
|
||||
self.l10npackage.add_structure(silme.core.Structure('foo'))
|
||||
self.l10npackage.add_structure(silme.core.Structure('foo2'))
|
||||
self.l10npackage.add_structure(silme.core.Structure('foo3'))
|
||||
self.assertEqual(self.l10npackage.structures()[0].id, 'foo')
|
||||
self.assertEqual(self.l10npackage.structures()[1].id, 'foo2')
|
||||
self.assertEqual(self.l10npackage.structures()[2].id, 'foo3')
|
||||
self.l10npackage.add_structure(silme.core.Structure("foo"))
|
||||
self.l10npackage.add_structure(silme.core.Structure("foo2"))
|
||||
self.l10npackage.add_structure(silme.core.Structure("foo3"))
|
||||
self.assertEqual(self.l10npackage.structures()[0].id, "foo")
|
||||
self.assertEqual(self.l10npackage.structures()[1].id, "foo2")
|
||||
self.assertEqual(self.l10npackage.structures()[2].id, "foo3")
|
||||
|
||||
def test_get_objects2(self):
|
||||
self.l10npackage.add_structure(silme.core.Structure('foo'))
|
||||
self.l10npackage.add_structure(silme.core.Structure('foo2'))
|
||||
self.l10npackage.add_structure(silme.core.Structure('foo3'))
|
||||
self.assertEqual(self.l10npackage.structures(ids=True), ['foo', 'foo2', 'foo3'])
|
||||
|
||||
self.l10npackage.add_structure(silme.core.Structure("foo"))
|
||||
self.l10npackage.add_structure(silme.core.Structure("foo2"))
|
||||
self.l10npackage.add_structure(silme.core.Structure("foo3"))
|
||||
self.assertEqual(self.l10npackage.structures(ids=True), ["foo", "foo2", "foo3"])
|
||||
|
||||
def test_get_packages(self):
|
||||
self.l10npackage.add_package(silme.core.Package('foo'))
|
||||
self.l10npackage.add_package(silme.core.Package('foo2'))
|
||||
self.l10npackage.add_package(silme.core.Package('foo3'))
|
||||
self.assertEqual(self.l10npackage.packages()[0].id, 'foo')
|
||||
self.assertEqual(self.l10npackage.packages()[1].id, 'foo2')
|
||||
self.assertEqual(self.l10npackage.packages()[2].id, 'foo3')
|
||||
self.l10npackage.add_package(silme.core.Package("foo"))
|
||||
self.l10npackage.add_package(silme.core.Package("foo2"))
|
||||
self.l10npackage.add_package(silme.core.Package("foo3"))
|
||||
self.assertEqual(self.l10npackage.packages()[0].id, "foo")
|
||||
self.assertEqual(self.l10npackage.packages()[1].id, "foo2")
|
||||
self.assertEqual(self.l10npackage.packages()[2].id, "foo3")
|
||||
|
||||
def test_get_packages2(self):
|
||||
self.l10npackage.add_package(silme.core.Package('foo'))
|
||||
self.l10npackage.add_package(silme.core.Package('foo2'))
|
||||
self.l10npackage.add_package(silme.core.Package('foo3'))
|
||||
self.assertEqual(self.l10npackage.packages(ids=True), ['foo', 'foo2', 'foo3'])
|
||||
self.l10npackage.add_package(silme.core.Package("foo"))
|
||||
self.l10npackage.add_package(silme.core.Package("foo2"))
|
||||
self.l10npackage.add_package(silme.core.Package("foo3"))
|
||||
self.assertEqual(self.l10npackage.packages(ids=True), ["foo", "foo2", "foo3"])
|
||||
|
||||
def test_get_entities(self):
|
||||
l10nobject = silme.core.Structure('foo')
|
||||
l10nobject.add_entity(silme.core.Entity('entid'))
|
||||
l10nobject2 = silme.core.Structure('foo2')
|
||||
l10nobject2.add_entity(silme.core.Entity('entid2'))
|
||||
l10nobject = silme.core.Structure("foo")
|
||||
l10nobject.add_entity(silme.core.Entity("entid"))
|
||||
l10nobject2 = silme.core.Structure("foo2")
|
||||
l10nobject2.add_entity(silme.core.Entity("entid2"))
|
||||
self.l10npackage.add_structure(l10nobject)
|
||||
self.l10npackage.add_structure(l10nobject2)
|
||||
entities = self.l10npackage.entities()
|
||||
self.assertEqual(len(entities), 2)
|
||||
|
||||
def test_get_entities2(self):
|
||||
l10nobject = silme.core.Structure('foo')
|
||||
l10nobject.add_entity(silme.core.Entity('entid'))
|
||||
l10nobject2 = silme.core.Structure('foo2')
|
||||
l10nobject.add_entity(silme.core.Entity('entid2'))
|
||||
l10npack = silme.core.Package('test2')
|
||||
l10nobject = silme.core.Structure("foo")
|
||||
l10nobject.add_entity(silme.core.Entity("entid"))
|
||||
l10nobject2 = silme.core.Structure("foo2")
|
||||
l10nobject.add_entity(silme.core.Entity("entid2"))
|
||||
l10npack = silme.core.Package("test2")
|
||||
l10npack.add_structure(l10nobject)
|
||||
l10npack.add_structure(l10nobject2)
|
||||
self.l10npackage.add_package(l10npack)
|
||||
|
@ -92,53 +93,61 @@ class EntityTestCase(unittest.TestCase):
|
|||
self.assertEqual(len(entities), 0)
|
||||
|
||||
def test_get_entities_with_path(self):
|
||||
l10nobject = silme.core.Structure('foo')
|
||||
l10nobject.add_entity(silme.core.Entity('entid'))
|
||||
l10nobject2 = silme.core.Structure('foo2')
|
||||
l10nobject.add_entity(silme.core.Entity('entid2'))
|
||||
l10npack = silme.core.Package('test2')
|
||||
l10nobject = silme.core.Structure("foo")
|
||||
l10nobject.add_entity(silme.core.Entity("entid"))
|
||||
l10nobject2 = silme.core.Structure("foo2")
|
||||
l10nobject.add_entity(silme.core.Entity("entid2"))
|
||||
l10npack = silme.core.Package("test2")
|
||||
l10npack.add_structure(l10nobject)
|
||||
l10npack.add_structure(l10nobject2)
|
||||
self.l10npackage.add_package(l10npack)
|
||||
entities = self.l10npackage.entities(recursive=True, path=True)
|
||||
self.assertEqual(entities[0][1], 'test2/foo')
|
||||
entities = self.l10npackage.package('test2').entities(recursive=True, path=True)
|
||||
self.assertEqual(entities[0][1], 'foo')
|
||||
self.assertEqual(entities[0][1], "test2/foo")
|
||||
entities = self.l10npackage.package("test2").entities(recursive=True, path=True)
|
||||
self.assertEqual(entities[0][1], "foo")
|
||||
|
||||
def test_package_lazy_by_default(self):
|
||||
self.assertEqual(self.l10npackage.lazy, True)
|
||||
|
||||
def test_package__stub_exceptions_if_not_lazy(self):
|
||||
pack = silme.core.Package('id1', lazy=False)
|
||||
self.assertRaises(Exception, pack.add_package_stub,
|
||||
'id1',
|
||||
lambda x:silme.core.Package('test1'))
|
||||
self.assertRaises(Exception, pack.add_structure_stub,
|
||||
'id1',
|
||||
lambda x:silme.core.Structure('id1'))
|
||||
pack = silme.core.Package("id1", lazy=False)
|
||||
self.assertRaises(
|
||||
Exception,
|
||||
pack.add_package_stub,
|
||||
"id1",
|
||||
lambda x: silme.core.Package("test1"),
|
||||
)
|
||||
self.assertRaises(
|
||||
Exception,
|
||||
pack.add_structure_stub,
|
||||
"id1",
|
||||
lambda x: silme.core.Structure("id1"),
|
||||
)
|
||||
|
||||
def test_package_add_structure_stub(self):
|
||||
def resolver(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('id1' in pack, True)
|
||||
self.assertEqual("id1" in pack, True)
|
||||
self.assertEqual(len(pack.structures(ids=True)), 1)
|
||||
self.assertEqual(len(pack._structures._stubs), 1)
|
||||
self.assertEqual(pack.has_structure('id1'), True)
|
||||
self.assertEqual(pack.structure('id1').id, 'id1')
|
||||
self.assertEqual(pack.has_structure("id1"), True)
|
||||
self.assertEqual(pack.structure("id1").id, "id1")
|
||||
self.assertEqual(len(pack._structures._stubs), 0)
|
||||
|
||||
def test_package_add_package_stub(self):
|
||||
def resolver(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('id1' in pack, True)
|
||||
self.assertEqual("id1" in pack, True)
|
||||
self.assertEqual(len(pack.packages(ids=True)), 1)
|
||||
self.assertEqual(len(pack._packages._stubs), 1)
|
||||
self.assertEqual(pack.has_package('id1'), True)
|
||||
self.assertEqual(pack.package('id1').id, 'id1')
|
||||
self.assertEqual(pack.has_package("id1"), True)
|
||||
self.assertEqual(pack.package("id1").id, "id1")
|
||||
self.assertEqual(len(pack._packages._stubs), 0)
|
||||
|
|
|
@ -1,154 +1,153 @@
|
|||
import random
|
||||
import unittest
|
||||
import sys
|
||||
import re
|
||||
|
||||
import silme.core
|
||||
|
||||
class structureTestCase(unittest.TestCase):
|
||||
|
||||
class structureTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.structure = silme.core.Structure('id')
|
||||
self.structure = silme.core.Structure("id")
|
||||
|
||||
def test_id(self):
|
||||
self.structure.id = 'test'
|
||||
self.assertEqual(self.structure.id, 'test')
|
||||
self.structure.id = "test"
|
||||
self.assertEqual(self.structure.id, "test")
|
||||
|
||||
def test_add_element(self):
|
||||
entity = silme.core.Entity('entid')
|
||||
entity2 = silme.core.Entity('entid2')
|
||||
def test_add_at_pos(self):
|
||||
entity = silme.core.Entity("entid")
|
||||
entity2 = silme.core.Entity("entid2")
|
||||
self.structure.add_at_pos(entity, 0)
|
||||
self.structure.add_at_pos(entity2, 0)
|
||||
self.assertEqual(self.structure.get_entity_pos('entid'), 1)
|
||||
self.assertEqual(self.structure.get_entity_pos('entid2'), 0)
|
||||
self.assertEqual(self.structure.entity_pos("entid"), 1)
|
||||
self.assertEqual(self.structure.entity_pos("entid2"), 0)
|
||||
|
||||
def test_add_entity(self):
|
||||
entity = silme.core.Entity('entid')
|
||||
entity2 = silme.core.Entity('entid2')
|
||||
entity3 = silme.core.Entity('entid3')
|
||||
entity4 = silme.core.Entity('entid4')
|
||||
entity = silme.core.Entity("entid")
|
||||
entity2 = silme.core.Entity("entid2")
|
||||
entity3 = silme.core.Entity("entid3")
|
||||
entity4 = silme.core.Entity("entid4")
|
||||
# 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(entity3, 0)
|
||||
self.structure.add_entity(entity4, 1)
|
||||
self.assertEqual(self.structure.entity_pos('entid'), 2)
|
||||
self.assertEqual(self.structure.entity_pos('entid2'), 3)
|
||||
self.assertEqual(self.structure.entity_pos('entid3'), 0)
|
||||
self.assertEqual(self.structure.entity_pos('entid4'), 1)
|
||||
self.assertEqual(self.structure.entity_pos("entid"), 2)
|
||||
self.assertEqual(self.structure.entity_pos("entid2"), 3)
|
||||
self.assertEqual(self.structure.entity_pos("entid3"), 0)
|
||||
self.assertEqual(self.structure.entity_pos("entid4"), 1)
|
||||
|
||||
def test_get_value(self):
|
||||
entity = silme.core.Entity('entid')
|
||||
entity.set_value('foo')
|
||||
entity = silme.core.Entity("entid")
|
||||
entity.set_value("foo")
|
||||
self.structure.add_entity(entity)
|
||||
self.assertEqual(self.structure.value('entid'), 'foo')
|
||||
self.assertEqual(self.structure.value("entid"), "foo")
|
||||
|
||||
|
||||
def test_get_entity(self):
|
||||
self.structure.add_entity(silme.core.Entity('entid'))
|
||||
self.structure.add_entity(silme.core.Entity('entid2'))
|
||||
self.assertEqual(len(self.structure.get_entities()), 2)
|
||||
self.assertEqual(self.structure.get_entities()[0].id, 'entid')
|
||||
self.assertEqual(self.structure.get_entities()[1].id, 'entid2')
|
||||
def test_entities(self):
|
||||
self.structure.add_entity(silme.core.Entity("entid"))
|
||||
self.structure.add_entity(silme.core.Entity("entid2"))
|
||||
self.assertEqual(len(self.structure.entities()), 2)
|
||||
self.assertEqual(self.structure.entities()[0].id, "entid")
|
||||
self.assertEqual(self.structure.entities()[1].id, "entid2")
|
||||
|
||||
def test_get_entity_ids(self):
|
||||
self.structure.add_entity(silme.core.Entity('entid'))
|
||||
self.structure.add_entity(silme.core.Entity('entid2'))
|
||||
self.assertEqual(self.structure.ids(), ['entid', 'entid2'])
|
||||
self.structure.add_entity(silme.core.Entity("entid"))
|
||||
self.structure.add_entity(silme.core.Entity("entid2"))
|
||||
self.assertEqual(self.structure.ids(), ["entid", "entid2"])
|
||||
|
||||
def test_has_entity(self):
|
||||
self.structure.add_entity(silme.core.Entity('entid'))
|
||||
self.structure.add_entity(silme.core.Entity('entid2'))
|
||||
self.structure.add_entity(silme.core.Entity("entid"))
|
||||
self.structure.add_entity(silme.core.Entity("entid2"))
|
||||
self.assertEqual(len(self.structure.entities()), 2)
|
||||
self.assertEqual(self.structure.has_entity('entid'), True)
|
||||
self.assertEqual(self.structure.has_entity('entid3'), False)
|
||||
self.assertEqual(self.structure.has_entity("entid"), True)
|
||||
self.assertEqual(self.structure.has_entity("entid3"), False)
|
||||
|
||||
def test_modify_entity(self):
|
||||
entity = silme.core.Entity('entid')
|
||||
entity.set_value('testvalue')
|
||||
entity = silme.core.Entity("entid")
|
||||
entity.set_value("testvalue")
|
||||
self.structure.add_entity(entity)
|
||||
self.assertEqual(self.structure.modify_entity('entid', 'newvalue'), True)
|
||||
self.assertEqual(entity.get_value(), 'newvalue')
|
||||
self.assertEqual(self.structure.modify_entity("entid", "newvalue"), True)
|
||||
self.assertEqual(entity.get_value(), "newvalue")
|
||||
|
||||
def test_modify_entity2(self):
|
||||
entity = silme.core.Entity('entid')
|
||||
entity.set_value('testvalue')
|
||||
entity = silme.core.Entity("entid")
|
||||
entity.set_value("testvalue")
|
||||
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):
|
||||
entity = silme.core.Entity('entid')
|
||||
entity.default_code = 'pl'
|
||||
entity.set_value('testvalue')
|
||||
entity = silme.core.Entity("entid")
|
||||
entity.default_code = "pl"
|
||||
entity.set_value("testvalue")
|
||||
self.structure.add_entity(entity)
|
||||
self.structure.modify_entity('entid', 'newvalue')
|
||||
self.assertEqual(entity.get_value(), 'newvalue')
|
||||
|
||||
self.structure.modify_entity("entid", "newvalue")
|
||||
self.assertEqual(entity.get_value(), "newvalue")
|
||||
|
||||
def test_get_entity(self):
|
||||
entity = silme.core.Entity('entid')
|
||||
entity = silme.core.Entity("entid")
|
||||
self.structure.add_entity(entity)
|
||||
self.assertEqual(self.structure.entity('entid'), entity)
|
||||
self.assertRaises(KeyError, self.structure.entity, 'endid')
|
||||
self.assertEqual(self.structure.entity("entid"), entity)
|
||||
self.assertRaises(KeyError, self.structure.entity, "endid")
|
||||
|
||||
def test_get_entity_pos(self):
|
||||
entity = silme.core.Entity('entid')
|
||||
self.structure.add_string('foo')
|
||||
self.structure.add_entity(silme.core.Entity('entityid2'))
|
||||
self.structure.add_string('foo')
|
||||
entity = silme.core.Entity("entid")
|
||||
self.structure.add_string("foo")
|
||||
self.structure.add_entity(silme.core.Entity("entityid2"))
|
||||
self.structure.add_string("foo")
|
||||
self.structure.add_entity(entity)
|
||||
self.structure.add_string('foo')
|
||||
self.assertEqual(self.structure.entity_pos('entid'), 3)
|
||||
self.structure.add_string("foo")
|
||||
self.assertEqual(self.structure.entity_pos("entid"), 3)
|
||||
|
||||
def test_remove_entity(self):
|
||||
entity = silme.core.Entity('entid')
|
||||
self.structure.add_entity(silme.core.Entity('entityid3'))
|
||||
entity = silme.core.Entity("entid")
|
||||
self.structure.add_entity(silme.core.Entity("entityid3"))
|
||||
self.structure.add_entity(entity)
|
||||
self.structure.add_entity(silme.core.Entity('entityid2'))
|
||||
self.assertEqual(self.structure.remove_entity('entid'), True)
|
||||
self.assertRaises(KeyError, self.structure.entity, 'endid')
|
||||
|
||||
self.structure.add_entity(silme.core.Entity("entityid2"))
|
||||
self.assertEqual(self.structure.remove_entity("entid"), True)
|
||||
self.assertRaises(KeyError, self.structure.entity, "endid")
|
||||
|
||||
def test_add_element(self):
|
||||
entity = silme.core.Entity('entid')
|
||||
entity = silme.core.Entity("entid")
|
||||
comment = silme.core.Comment()
|
||||
comment.add('foo')
|
||||
str = 'foo'
|
||||
comment.add("foo")
|
||||
str = "foo"
|
||||
self.assertEqual(self.structure.add(entity), 1)
|
||||
self.assertEqual(self.structure.add(comment), 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):
|
||||
entity = silme.core.Entity('entid')
|
||||
entity = silme.core.Entity("entid")
|
||||
comment = silme.core.Comment()
|
||||
comment.add('foo')
|
||||
str = 'foo'
|
||||
comment.add("foo")
|
||||
str = "foo"
|
||||
list = [entity, comment, entity, str]
|
||||
self.assertEqual(self.structure.add_elements(list), 4)
|
||||
|
||||
def test_get_entitylist(self):
|
||||
self.structure.add_string('foo')
|
||||
self.structure.add_entity(silme.core.Entity('entid'))
|
||||
self.structure.add_string('foo')
|
||||
self.structure.add_entity(silme.core.Entity('entid2'))
|
||||
self.structure.add_string('foo')
|
||||
self.structure.add_string("foo")
|
||||
self.structure.add_entity(silme.core.Entity("entid"))
|
||||
self.structure.add_string("foo")
|
||||
self.structure.add_entity(silme.core.Entity("entid2"))
|
||||
self.structure.add_string("foo")
|
||||
entitylist = self.structure.entitylist()
|
||||
self.assertEqual(len(entitylist.entities()), 2)
|
||||
self.assertEqual(entitylist['entid'].id, 'entid')
|
||||
self.assertEqual(entitylist['entid2'].id, 'entid2')
|
||||
self.assertEqual(entitylist["entid"].id, "entid")
|
||||
self.assertEqual(entitylist["entid2"].id, "entid2")
|
||||
|
||||
def test_process(self):
|
||||
def process_entity(entity, subs):
|
||||
entity.value = re.sub(r'\&([^$]+)\;',
|
||||
lambda m:subs[m.group(1)],
|
||||
str(entity.value))
|
||||
entity.value = re.sub(
|
||||
r"\&([^$]+)\;", lambda m: subs[m.group(1)], str(entity.value)
|
||||
)
|
||||
|
||||
def process(self):
|
||||
for elem in self:
|
||||
if isinstance(elem, silme.core.Entity):
|
||||
process_entity(elem, self.params['exents'])
|
||||
process_entity(elem, self.params["exents"])
|
||||
|
||||
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['exents'] = {'varMe': 'Woo'}
|
||||
self.structure.params["exents"] = {"varMe": "Woo"}
|
||||
self.structure.add_entity(entity1)
|
||||
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 sys
|
||||
|
||||
from silme.core.types.lazydict import LazyDict
|
||||
|
||||
|
||||
class LazyDictTestCase(unittest.TestCase):
|
||||
def test_constructor(self):
|
||||
# calling built-in types without argument must return empty
|
||||
|
@ -18,65 +18,66 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
def test_keys(self):
|
||||
d = LazyDict()
|
||||
self.assertEqual(set(d.keys()), set())
|
||||
d = LazyDict({'a': 1, 'b': 2})
|
||||
d = LazyDict({"a": 1, "b": 2})
|
||||
k = d.keys()
|
||||
self.assertTrue('a' in d)
|
||||
self.assertTrue('b' in d)
|
||||
self.assertEqual(set(k), {'a','b'})
|
||||
self.assertTrue("a" in d)
|
||||
self.assertTrue("b" in d)
|
||||
self.assertEqual(set(k), {"a", "b"})
|
||||
|
||||
self.assertRaises(TypeError, d.keys, None)
|
||||
|
||||
def test_values(self):
|
||||
d = LazyDict()
|
||||
self.assertEqual(set(d.values()), set())
|
||||
d = LazyDict({1:2})
|
||||
d = LazyDict({1: 2})
|
||||
self.assertEqual(set(d.values()), {2})
|
||||
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):
|
||||
d = LazyDict()
|
||||
self.assertEqual(set(d.items()), set())
|
||||
|
||||
d = LazyDict({1:2})
|
||||
d = LazyDict({1: 2})
|
||||
self.assertEqual(set(d.items()), {(1, 2)})
|
||||
|
||||
self.assertRaises(TypeError, d.items, None)
|
||||
|
||||
def test_contains(self):
|
||||
d = LazyDict()
|
||||
self.assertNotIn('a', d)
|
||||
self.assertFalse('a' in d)
|
||||
self.assertTrue('a' not in d)
|
||||
d = LazyDict({'a': 1, 'b': 2})
|
||||
self.assertIn('a', d)
|
||||
self.assertIn('b', d)
|
||||
self.assertNotIn('c', d)
|
||||
self.assertNotIn("a", d)
|
||||
self.assertFalse("a" in d)
|
||||
self.assertTrue("a" not in d)
|
||||
d = LazyDict({"a": 1, "b": 2})
|
||||
self.assertIn("a", d)
|
||||
self.assertIn("b", d)
|
||||
self.assertNotIn("c", d)
|
||||
|
||||
self.assertRaises(TypeError, d.__contains__)
|
||||
|
||||
def test_len(self):
|
||||
d = LazyDict()
|
||||
self.assertEqual(len(d), 0)
|
||||
d = LazyDict({'a': 1, 'b': 2})
|
||||
d = LazyDict({"a": 1, "b": 2})
|
||||
self.assertEqual(len(d), 2)
|
||||
|
||||
def test_getitem(self):
|
||||
d = LazyDict({'a': 1, 'b': 2})
|
||||
self.assertEqual(d['a'], 1)
|
||||
self.assertEqual(d['b'], 2)
|
||||
d['c'] = 3
|
||||
d['a'] = 4
|
||||
self.assertEqual(d['c'], 3)
|
||||
self.assertEqual(d['a'], 4)
|
||||
del d['b']
|
||||
self.assertEqual(d, {'a': 4, 'c': 3})
|
||||
d = LazyDict({"a": 1, "b": 2})
|
||||
self.assertEqual(d["a"], 1)
|
||||
self.assertEqual(d["b"], 2)
|
||||
d["c"] = 3
|
||||
d["a"] = 4
|
||||
self.assertEqual(d["c"], 3)
|
||||
self.assertEqual(d["a"], 4)
|
||||
del d["b"]
|
||||
self.assertEqual(d, {"a": 4, "c": 3})
|
||||
|
||||
self.assertRaises(TypeError, d.__getitem__)
|
||||
|
||||
class BadEq(object):
|
||||
class BadEq:
|
||||
def __eq__(self, other):
|
||||
raise Exc()
|
||||
|
||||
def __hash__(self):
|
||||
return 24
|
||||
|
||||
|
@ -84,10 +85,12 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
d[BadEq()] = 42
|
||||
self.assertRaises(KeyError, d.__getitem__, 23)
|
||||
|
||||
class Exc(Exception): pass
|
||||
class Exc(Exception):
|
||||
pass
|
||||
|
||||
class BadHash(object):
|
||||
class BadHash:
|
||||
fail = False
|
||||
|
||||
def __hash__(self):
|
||||
if self.fail:
|
||||
raise Exc()
|
||||
|
@ -100,7 +103,7 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
self.assertRaises(Exc, d.__getitem__, x)
|
||||
|
||||
def test_clear(self):
|
||||
d = LazyDict({1:1, 2:2, 3:3})
|
||||
d = LazyDict({1: 1, 2: 2, 3: 3})
|
||||
d.clear()
|
||||
self.assertEqual(d, {})
|
||||
|
||||
|
@ -108,33 +111,39 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
|
||||
def test_update(self):
|
||||
d = LazyDict()
|
||||
d.update({1:100})
|
||||
d.update({2:20})
|
||||
d.update({1:1, 2:2, 3:3})
|
||||
self.assertEqual(d, {1:1, 2:2, 3:3})
|
||||
d.update({1: 100})
|
||||
d.update({2: 20})
|
||||
d.update({1: 1, 2: 2, 3: 3})
|
||||
self.assertEqual(d, {1: 1, 2: 2, 3: 3})
|
||||
|
||||
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)
|
||||
|
||||
class SimpleUserDict:
|
||||
def __init__(self):
|
||||
self.d = {1:1, 2:2, 3:3}
|
||||
self.d = {1: 1, 2: 2, 3: 3}
|
||||
|
||||
def keys(self):
|
||||
return self.d.keys()
|
||||
|
||||
def __getitem__(self, i):
|
||||
return self.d[i]
|
||||
|
||||
d.clear()
|
||||
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()
|
||||
|
||||
class FailingUserDict:
|
||||
def keys(self):
|
||||
raise Exc
|
||||
|
||||
self.assertRaises(Exc, d.update, FailingUserDict())
|
||||
|
||||
class FailingUserDict:
|
||||
|
@ -142,43 +151,57 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
class BogonIter:
|
||||
def __init__(self):
|
||||
self.i = 1
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
if self.i:
|
||||
self.i = 0
|
||||
return 'a'
|
||||
return "a"
|
||||
raise Exc
|
||||
|
||||
next = __next__
|
||||
|
||||
return BogonIter()
|
||||
|
||||
def __getitem__(self, key):
|
||||
return key
|
||||
|
||||
self.assertRaises(Exc, d.update, FailingUserDict())
|
||||
|
||||
class FailingUserDict:
|
||||
def keys(self):
|
||||
class BogonIter:
|
||||
def __init__(self):
|
||||
self.i = ord('a')
|
||||
self.i = ord("a")
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
if self.i <= ord('z'):
|
||||
if self.i <= ord("z"):
|
||||
rtn = chr(self.i)
|
||||
self.i += 1
|
||||
return rtn
|
||||
raise StopIteration
|
||||
|
||||
next = __next__
|
||||
|
||||
return BogonIter()
|
||||
|
||||
def __getitem__(self, key):
|
||||
raise Exc
|
||||
|
||||
self.assertRaises(Exc, d.update, FailingUserDict())
|
||||
|
||||
class badseq(object):
|
||||
class badseq:
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
raise Exc()
|
||||
|
||||
next = __next__
|
||||
|
||||
self.assertRaises(Exc, {}.update, badseq())
|
||||
|
@ -186,30 +209,38 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
self.assertRaises(ValueError, {}.update, [(1, 2, 3)])
|
||||
|
||||
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()
|
||||
self.assertIsNot(d.fromkeys('abc'), d)
|
||||
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.assertIsNot(d.fromkeys("abc"), d)
|
||||
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([]), LazyDict())
|
||||
|
||||
def g():
|
||||
yield 1
|
||||
self.assertEqual(d.fromkeys(g()), LazyDict({1:None}))
|
||||
|
||||
self.assertEqual(d.fromkeys(g()), LazyDict({1: None}))
|
||||
self.assertRaises(TypeError, {}.fromkeys, 3)
|
||||
class dictlike(LazyDict): pass
|
||||
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 dictlike(LazyDict):
|
||||
pass
|
||||
|
||||
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):
|
||||
def __new__(cls):
|
||||
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.assertRaises(TypeError, dict.fromkeys)
|
||||
|
||||
class Exc(Exception): pass
|
||||
class Exc(Exception):
|
||||
pass
|
||||
|
||||
class baddict1(LazyDict):
|
||||
def __init__(self):
|
||||
|
@ -225,42 +256,44 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
|
||||
# test fast path for dictionary inputs
|
||||
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):
|
||||
d = LazyDict({1:1, 2:2, 3:3})
|
||||
self.assertEqual(d.copy(), 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(LazyDict().copy(), LazyDict())
|
||||
self.assertRaises(TypeError, d.copy, None)
|
||||
|
||||
def test_get(self):
|
||||
d = LazyDict()
|
||||
self.assertIs(d.get('c'), None)
|
||||
self.assertEqual(d.get('c', 3), 3)
|
||||
d = LazyDict({'a': 1, 'b': 2})
|
||||
self.assertIs(d.get('c'), None)
|
||||
self.assertEqual(d.get('c', 3), 3)
|
||||
self.assertEqual(d.get('a'), 1)
|
||||
self.assertEqual(d.get('a', 3), 1)
|
||||
self.assertIs(d.get("c"), None)
|
||||
self.assertEqual(d.get("c", 3), 3)
|
||||
d = LazyDict({"a": 1, "b": 2})
|
||||
self.assertIs(d.get("c"), None)
|
||||
self.assertEqual(d.get("c", 3), 3)
|
||||
self.assertEqual(d.get("a"), 1)
|
||||
self.assertEqual(d.get("a", 3), 1)
|
||||
self.assertRaises(TypeError, d.get)
|
||||
self.assertRaises(TypeError, d.get, None, None, None)
|
||||
|
||||
def test_setdefault(self):
|
||||
# dict.setdefault()
|
||||
d = LazyDict()
|
||||
self.assertIs(d.setdefault('key0'), None)
|
||||
d.setdefault('key0', [])
|
||||
self.assertIs(d.setdefault('key0'), None)
|
||||
d.setdefault('key', []).append(3)
|
||||
self.assertEqual(d['key'][0], 3)
|
||||
d.setdefault('key', []).append(4)
|
||||
self.assertEqual(len(d['key']), 2)
|
||||
self.assertIs(d.setdefault("key0"), None)
|
||||
d.setdefault("key0", [])
|
||||
self.assertIs(d.setdefault("key0"), None)
|
||||
d.setdefault("key", []).append(3)
|
||||
self.assertEqual(d["key"][0], 3)
|
||||
d.setdefault("key", []).append(4)
|
||||
self.assertEqual(len(d["key"]), 2)
|
||||
self.assertRaises(TypeError, d.setdefault)
|
||||
|
||||
class Exc(Exception): pass
|
||||
class Exc(Exception):
|
||||
pass
|
||||
|
||||
class BadHash(object):
|
||||
class BadHash:
|
||||
fail = False
|
||||
|
||||
def __hash__(self):
|
||||
if self.fail:
|
||||
raise Exc()
|
||||
|
@ -278,7 +311,7 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
# -1: b has same structure as a
|
||||
# +1: b is a.copy()
|
||||
for log2size in range(12):
|
||||
size = 2**log2size
|
||||
size = 2 ** log2size
|
||||
a = LazyDict()
|
||||
b = LazyDict()
|
||||
for i in range(size):
|
||||
|
@ -302,9 +335,9 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
def test_pop(self):
|
||||
# Tests for pop with specified key
|
||||
d = LazyDict()
|
||||
k, v = 'abc', 'def'
|
||||
k, v = "abc", "def"
|
||||
d[k] = v
|
||||
self.assertRaises(KeyError, d.pop, 'ghi')
|
||||
self.assertRaises(KeyError, d.pop, "ghi")
|
||||
|
||||
self.assertEqual(d.pop(k), v)
|
||||
self.assertEqual(len(d), 0)
|
||||
|
@ -315,7 +348,7 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
# (for 64-bit archs). See SF bug #689659.
|
||||
x = 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(d.pop(k, v), v)
|
||||
|
@ -324,10 +357,12 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
|
||||
self.assertRaises(TypeError, d.pop)
|
||||
|
||||
class Exc(Exception): pass
|
||||
class Exc(Exception):
|
||||
pass
|
||||
|
||||
class BadHash(object):
|
||||
class BadHash:
|
||||
fail = False
|
||||
|
||||
def __hash__(self):
|
||||
if self.fail:
|
||||
raise Exc()
|
||||
|
@ -341,18 +376,18 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
|
||||
def test_mutatingiteration(self):
|
||||
# changing dict size during iteration
|
||||
#d = LazyDict()
|
||||
#d[1] = 1
|
||||
#with self.assertRaises(RuntimeError):
|
||||
# d = LazyDict()
|
||||
# d[1] = 1
|
||||
# with self.assertRaises(RuntimeError):
|
||||
# for i in d:
|
||||
# d[i+1] = 1
|
||||
pass
|
||||
|
||||
def test_repr(self):
|
||||
#d = LazyDict()
|
||||
#self.assertEqual(repr(d), 'LazyDict()')
|
||||
#d[1] = 2
|
||||
#self.assertEqual(repr(d), 'LazyDict(dict_keys([1]))')
|
||||
# d = LazyDict()
|
||||
# self.assertEqual(repr(d), 'LazyDict()')
|
||||
# d[1] = 2
|
||||
# self.assertEqual(repr(d), 'LazyDict(dict_keys([1]))')
|
||||
pass
|
||||
|
||||
def test_missing(self):
|
||||
|
@ -362,18 +397,22 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
# (E) subclass defines __missing__ method raising RuntimeError
|
||||
# (F) subclass sets __missing__ instance variable (no effect)
|
||||
# (G) subclass doesn't define __missing__ at a all
|
||||
|
||||
class D(dict):
|
||||
def __missing__(self, key):
|
||||
return 42
|
||||
|
||||
d = D({1: 2, 3: 4})
|
||||
self.assertEqual(d[1], 2)
|
||||
self.assertEqual(d[3], 4)
|
||||
self.assertTrue(2 not in d)
|
||||
self.assertTrue(2 not in d.keys())
|
||||
self.assertEqual(d[2], 42)
|
||||
|
||||
class E(dict):
|
||||
def __missing__(self, key):
|
||||
raise RuntimeError(key)
|
||||
|
||||
e = E()
|
||||
try:
|
||||
e[42]
|
||||
|
@ -381,10 +420,12 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
self.assertEqual(err.args, (42,))
|
||||
else:
|
||||
self.fail("e[42] didn't raise RuntimeError")
|
||||
|
||||
class F(dict):
|
||||
def __init__(self):
|
||||
# An instance variable __missing__ should have no effect
|
||||
self.__missing__ = lambda key: None
|
||||
|
||||
f = F()
|
||||
try:
|
||||
f[42]
|
||||
|
@ -392,8 +433,10 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
self.assertEqual(err.args, (42,))
|
||||
else:
|
||||
self.fail("f[42] didn't raise KeyError")
|
||||
|
||||
class G(dict):
|
||||
pass
|
||||
|
||||
g = G()
|
||||
try:
|
||||
g[42]
|
||||
|
@ -402,7 +445,6 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
else:
|
||||
self.fail("g[42] didn't raise KeyError")
|
||||
|
||||
|
||||
def test_tuple_keyerror(self):
|
||||
# SF #1576657
|
||||
d = LazyDict()
|
||||
|
@ -429,9 +471,9 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
|
||||
d = LazyDict()
|
||||
x1 = BadDictKey()
|
||||
x2 = BadDictKey()
|
||||
d[x1] = 1
|
||||
#for stmt in ['d[x2] = 2',
|
||||
# x2 = BadDictKey()
|
||||
# for stmt in ['d[x2] = 2',
|
||||
# 'z = d[x2]',
|
||||
# 'x2 in d',
|
||||
# 'x2 in d',
|
||||
|
@ -442,82 +484,84 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
# with self.assertRaises(CustomException):
|
||||
# exec stmt in locals()
|
||||
|
||||
##########
|
||||
##########
|
||||
|
||||
def test_lazy_keys(self):
|
||||
def resolver(id):
|
||||
p = {'b': 2, 'c': 3}
|
||||
p = {"b": 2, "c": 3}
|
||||
return p[id]
|
||||
d = LazyDict({'a': 1})
|
||||
d.set_stub('b', resolver)
|
||||
d.set_stub('c', resolver)
|
||||
d['d'] = 4
|
||||
|
||||
d = LazyDict({"a": 1})
|
||||
d.set_stub("b", resolver)
|
||||
d.set_stub("c", resolver)
|
||||
d["d"] = 4
|
||||
k = d.keys()
|
||||
self.assertTrue('a' in d)
|
||||
self.assertTrue('b' in d)
|
||||
self.assertTrue('c' in d)
|
||||
self.assertTrue('d' in d)
|
||||
self.assertEqual(set(k), {'a','b','c','d'})
|
||||
self.assertTrue("a" in d)
|
||||
self.assertTrue("b" in d)
|
||||
self.assertTrue("c" in d)
|
||||
self.assertTrue("d" in d)
|
||||
self.assertEqual(set(k), {"a", "b", "c", "d"})
|
||||
|
||||
def test_lazy_values(self):
|
||||
def resolver(id):
|
||||
p = {'c': 3}
|
||||
p = {"c": 3}
|
||||
return p[id]
|
||||
|
||||
d = LazyDict()
|
||||
self.assertEqual(set(d.values()), set())
|
||||
d = LazyDict({1:2})
|
||||
d.set_stub('c', resolver)
|
||||
d = LazyDict({1: 2})
|
||||
d.set_stub("c", resolver)
|
||||
v = d.values()
|
||||
self.assertEqual(set(v), {2,3})
|
||||
self.assertEqual(set(v), {2, 3})
|
||||
|
||||
self.assertRaises(TypeError, d.values, None)
|
||||
|
||||
def test_lazy_items(self):
|
||||
d = LazyDict()
|
||||
d.set_stub(1, lambda x:x)
|
||||
d.set_stub(1, lambda x: x)
|
||||
self.assertEqual(set(d.items()), {(1, 1)})
|
||||
|
||||
d = LazyDict({1:2})
|
||||
d.set_stub(2, lambda x:x)
|
||||
d = LazyDict({1: 2})
|
||||
d.set_stub(2, lambda x: x)
|
||||
self.assertEqual(set(d.items()), {(1, 2), (2, 2)})
|
||||
|
||||
def test_lazy_contains(self):
|
||||
d = LazyDict()
|
||||
self.assertNotIn('a', d)
|
||||
self.assertFalse('a' in d)
|
||||
self.assertTrue('a' not in d)
|
||||
d = LazyDict({'a': 1, 'b': 2})
|
||||
self.assertIn('a', d)
|
||||
self.assertIn('b', d)
|
||||
self.assertNotIn('c', d)
|
||||
self.assertNotIn("a", d)
|
||||
self.assertFalse("a" in d)
|
||||
self.assertTrue("a" not in d)
|
||||
d = LazyDict({"a": 1, "b": 2})
|
||||
self.assertIn("a", d)
|
||||
self.assertIn("b", d)
|
||||
self.assertNotIn("c", d)
|
||||
|
||||
self.assertRaises(TypeError, d.__contains__)
|
||||
|
||||
def test_lazy_len(self):
|
||||
d = LazyDict({'1':1})
|
||||
d = LazyDict({"1": 1})
|
||||
self.assertEqual(len(d), 1)
|
||||
d['2'] = 2
|
||||
d["2"] = 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)
|
||||
|
||||
|
||||
def test_lazy_getitem(self):
|
||||
d = LazyDict({'a': 1, 'b': 2})
|
||||
self.assertEqual(d['a'], 1)
|
||||
self.assertEqual(d['b'], 2)
|
||||
d['c'] = 3
|
||||
d['a'] = 4
|
||||
self.assertEqual(d['c'], 3)
|
||||
self.assertEqual(d['a'], 4)
|
||||
del d['b']
|
||||
self.assertEqual(d, {'a': 4, 'c': 3})
|
||||
d = LazyDict({"a": 1, "b": 2})
|
||||
self.assertEqual(d["a"], 1)
|
||||
self.assertEqual(d["b"], 2)
|
||||
d["c"] = 3
|
||||
d["a"] = 4
|
||||
self.assertEqual(d["c"], 3)
|
||||
self.assertEqual(d["a"], 4)
|
||||
del d["b"]
|
||||
self.assertEqual(d, {"a": 4, "c": 3})
|
||||
|
||||
self.assertRaises(TypeError, d.__getitem__)
|
||||
|
||||
class BadEq(object):
|
||||
class BadEq:
|
||||
def __eq__(self, other):
|
||||
raise Exc()
|
||||
|
||||
def __hash__(self):
|
||||
return 24
|
||||
|
||||
|
@ -525,10 +569,12 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
d[BadEq()] = 42
|
||||
self.assertRaises(KeyError, d.__getitem__, 23)
|
||||
|
||||
class Exc(Exception): pass
|
||||
class Exc(Exception):
|
||||
pass
|
||||
|
||||
class BadHash(object):
|
||||
class BadHash:
|
||||
fail = False
|
||||
|
||||
def __hash__(self):
|
||||
if self.fail:
|
||||
raise Exc()
|
||||
|
@ -541,8 +587,8 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
self.assertRaises(Exc, d.__getitem__, x)
|
||||
|
||||
def test_lazy_clear(self):
|
||||
d = LazyDict({1:1, 2:2, 3:3})
|
||||
d.set_stub(4, lambda x:x)
|
||||
d = LazyDict({1: 1, 2: 2, 3: 3})
|
||||
d.set_stub(4, lambda x: x)
|
||||
d.clear()
|
||||
self.assertEqual(d, {})
|
||||
self.assertEqual(set(d.keys()), set())
|
||||
|
@ -552,74 +598,79 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
|
||||
def test_lazy_update(self):
|
||||
d = LazyDict()
|
||||
d.set_stub(4, lambda x:x)
|
||||
d.update(LazyDict({1:100}))
|
||||
d.update(LazyDict({2:20}))
|
||||
d.update({4:5})
|
||||
d.update(LazyDict({1:1, 2:2, 3:3}))
|
||||
self.assertEqual(d, {1:1, 2:2, 3:3, 4:5})
|
||||
d.set_stub(4, lambda x: x)
|
||||
d.update(LazyDict({1: 100}))
|
||||
d.update(LazyDict({2: 20}))
|
||||
d.update({4: 5})
|
||||
d.update(LazyDict({1: 1, 2: 2, 3: 3}))
|
||||
self.assertEqual(d, {1: 1, 2: 2, 3: 3, 4: 5})
|
||||
|
||||
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)
|
||||
|
||||
class SimpleUserDict:
|
||||
def __init__(self):
|
||||
self.d = {1:1, 2:2, 3:3}
|
||||
self.d = {1: 1, 2: 2, 3: 3}
|
||||
|
||||
def keys(self):
|
||||
return self.d.keys()
|
||||
|
||||
def __getitem__(self, i):
|
||||
return self.d[i]
|
||||
|
||||
d.clear()
|
||||
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):
|
||||
d = LazyDict({'1':1})
|
||||
d['2'] = 2
|
||||
d = LazyDict({"1": 1})
|
||||
d["2"] = 2
|
||||
x = d.copy()
|
||||
self.assertEqual(len(x), 2)
|
||||
i = {'num': 0}
|
||||
i = {"num": 0}
|
||||
|
||||
def r(key, i):
|
||||
i['num'] += 1
|
||||
return i['num']
|
||||
d.set_stub('3', r, i)
|
||||
i["num"] += 1
|
||||
return i["num"]
|
||||
|
||||
d.set_stub("3", r, i)
|
||||
x = d.copy()
|
||||
self.assertEqual(d['3'], 1)
|
||||
self.assertEqual(d["3"], 1)
|
||||
self.assertEqual(len(d._stubs), 0)
|
||||
self.assertEqual(len(x._stubs), 1)
|
||||
self.assertEqual(x['3'], 2)
|
||||
self.assertEqual(x["3"], 2)
|
||||
self.assertEqual(len(x._stubs), 0)
|
||||
x = d.copy()
|
||||
self.assertEqual(d['3'], 1)
|
||||
self.assertEqual(x['3'], 1)
|
||||
self.assertEqual(d["3"], 1)
|
||||
self.assertEqual(x["3"], 1)
|
||||
|
||||
def test_lazy_get(self):
|
||||
d = LazyDict({'a': 1, 'b': 2})
|
||||
d.set_stub('d', lambda x:x)
|
||||
self.assertIs(d.get('c'), None)
|
||||
self.assertEqual(d.get('c', 3), 3)
|
||||
self.assertEqual(d.get('a'), 1)
|
||||
self.assertEqual(d.get('a', 3), 1)
|
||||
self.assertEqual(d.get('d'), 'd')
|
||||
self.assertEqual(d.get('d', 3), 'd')
|
||||
d = LazyDict({"a": 1, "b": 2})
|
||||
d.set_stub("d", lambda x: x)
|
||||
self.assertIs(d.get("c"), None)
|
||||
self.assertEqual(d.get("c", 3), 3)
|
||||
self.assertEqual(d.get("a"), 1)
|
||||
self.assertEqual(d.get("a", 3), 1)
|
||||
self.assertEqual(d.get("d"), "d")
|
||||
self.assertEqual(d.get("d", 3), "d")
|
||||
self.assertRaises(TypeError, d.get)
|
||||
self.assertRaises(TypeError, d.get, None, None, None)
|
||||
|
||||
def test_lazy_setdefault(self):
|
||||
d = LazyDict()
|
||||
self.assertIs(d.setdefault('key0'), None)
|
||||
d.set_stub('key0', lambda x:'value0')
|
||||
self.assertIs(d.setdefault('key0'), 'value0')
|
||||
d.set_stub('key0', lambda x:'value0')
|
||||
self.assertEqual(d.setdefault('key1', 'value1'), 'value1')
|
||||
self.assertEqual(d['key1'], 'value1')
|
||||
self.assertEqual(d.setdefault('key0', 'value2'), 'value0')
|
||||
self.assertIs(d.setdefault("key0"), None)
|
||||
d.set_stub("key0", lambda x: "value0")
|
||||
self.assertIs(d.setdefault("key0"), "value0")
|
||||
d.set_stub("key0", lambda x: "value0")
|
||||
self.assertEqual(d.setdefault("key1", "value1"), "value1")
|
||||
self.assertEqual(d["key1"], "value1")
|
||||
self.assertEqual(d.setdefault("key0", "value2"), "value0")
|
||||
|
||||
def test_lazy_popitem(self):
|
||||
d = LazyDict({1: 1})
|
||||
d.set_stub(2, lambda x:x)
|
||||
d.set_stub(2, lambda x: x)
|
||||
k, v = d.popitem()
|
||||
self.assertEqual(k, v)
|
||||
k, v = d.popitem()
|
||||
|
@ -630,9 +681,9 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
|
||||
def test_lazy_pop(self):
|
||||
d = LazyDict()
|
||||
k, v = ('abc', 'def')
|
||||
d.set_stub(k, lambda x:'def')
|
||||
self.assertRaises(KeyError, d.pop, 'ghi')
|
||||
k, v = ("abc", "def")
|
||||
d.set_stub(k, lambda x: "def")
|
||||
self.assertRaises(KeyError, d.pop, "ghi")
|
||||
|
||||
self.assertEqual(d.pop(k), v)
|
||||
self.assertEqual(len(d), 0)
|
||||
|
@ -640,25 +691,25 @@ class LazyDictTestCase(unittest.TestCase):
|
|||
self.assertRaises(KeyError, d.pop, k)
|
||||
|
||||
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.assertRaises(TypeError, d.pop)
|
||||
|
||||
def test_lazy_delitem(self):
|
||||
d = LazyDict()
|
||||
d['1'] = 1
|
||||
d['2'] = 2
|
||||
del d['1']
|
||||
d["1"] = 1
|
||||
d["2"] = 2
|
||||
del d["1"]
|
||||
self.assertEqual(len(d), 1)
|
||||
self.assertRaises(KeyError, d.__getitem__, '1')
|
||||
d.set_stub('1', lambda x:x)
|
||||
self.assertRaises(KeyError, d.__getitem__, "1")
|
||||
d.set_stub("1", lambda x: x)
|
||||
self.assertEqual(len(d), 2)
|
||||
del d['1']
|
||||
del d["1"]
|
||||
self.assertEqual(len(d), 1)
|
||||
self.assertRaises(KeyError, d.__getitem__, '1')
|
||||
d.set_stub('1', lambda x:x)
|
||||
self.assertEqual(d['1'], '1')
|
||||
del d['1']
|
||||
self.assertRaises(KeyError, d.__getitem__, "1")
|
||||
d.set_stub("1", lambda x: x)
|
||||
self.assertEqual(d["1"], "1")
|
||||
del d["1"]
|
||||
self.assertEqual(len(d), 1)
|
||||
self.assertRaises(KeyError, d.__getitem__, '1')
|
||||
self.assertRaises(KeyError, d.__getitem__, "1")
|
||||
|
|
Загрузка…
Ссылка в новой задаче