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