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

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

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

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

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

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

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

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

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

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

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

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

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

@ -2,7 +2,8 @@ from silme.core.list import is_entitylist
from silme.core.structure import Blob, Structure
from silme.core.types import LazyDict
class Package(object):
class Package:
"""
Package is a container that stores
set of data structures (Structures, EntityLists, Blobs) and sub-packages.
@ -16,6 +17,7 @@ class Package(object):
If you load a directory into memory and then serialize it back to disk,
the two directories should be identical minus any modifications you made.
"""
uri = None
def __init__(self, id, lazy=True):
@ -28,14 +30,12 @@ class Package(object):
return len(self._packages) + len(self._structures)
def __iter__(self):
for i in self._packages.items():
yield i
for i in self._structures.items():
yield i
yield from self._packages.items()
yield from self._structures.items()
raise StopIteration
def __repr__(self):
return '%s(%s)' % (self.__class__.__name__, self.id)
return f"{self.__class__.__name__}({self.id})"
def __contains__(self, id):
if id in self._packages.keys():
@ -84,14 +84,13 @@ class Package(object):
if not path:
self._structures[struct.id] = struct
else:
path = path.split('/')
path = path.split("/")
if path[0] in self._packages:
self._packages[path[0]].add_structure(struct,
'/'.join(path[1:]))
self._packages[path[0]].add_structure(struct, "/".join(path[1:]))
else:
sub_l10n_pack = Package(path[0])
self.add_package(sub_l10n_pack)
sub_l10n_pack.add_structure(struct, '/'.join(path[1:]))
sub_l10n_pack.add_structure(struct, "/".join(path[1:]))
def add_package(self, package, path=None):
"""
@ -107,14 +106,13 @@ class Package(object):
if not path:
self._packages[package.id] = package
else:
path = path.split('/')
path = path.split("/")
if path[0] in self._packages:
self._packages[path[0]].add_package(package,
'/'.join(path[1:]))
self._packages[path[0]].add_package(package, "/".join(path[1:]))
else:
sub_l10n_pack = Package(path[0])
self._packages[path[0]] = sub_l10n_pack
sub_l10n_pack.add_package(package, '/'.join(path[1:]))
sub_l10n_pack.add_package(package, "/".join(path[1:]))
def packages(self, ids=False):
"""
@ -127,24 +125,24 @@ class Package(object):
else:
return list(self._packages.values())
def structures(self, type='all', ids=False):
def structures(self, type="all", ids=False):
"""
Returns a list of structures inside Package.
If parameter ids is set to True list of
names is returned instead of structures.
"""
if type == 'all':
if type == "all":
if ids:
return list(self._structures.keys())
else:
return list(self._structures.values())
else:
l10n_structures = {}
if type == 'list':
if type == "list":
type = is_entitylist
elif type == 'structure':
elif type == "structure":
type = lambda x: isinstance(x, Structure)
elif type == 'blob':
elif type == "blob":
type = lambda x: isinstance(x, Blob)
for struct in self._structures:
if type(self._structures[struct]):
@ -163,20 +161,21 @@ class Package(object):
"""
entities = []
if path is True:
spath = ''
spath = ""
elif path is not False:
spath='%s/%s' % (path, self.id) if path else self.id
spath = f"{path}/{self.id}" if path else self.id
else:
spath = path
if recursive:
for pack in self._packages.values():
entities.extend(pack.entities(path=spath))
for i in self._structures:
if isinstance(self._structures[i], Structure) or is_entitylist(self._structures[i]):
if isinstance(self._structures[i], Structure) or is_entitylist(
self._structures[i]
):
elist = self._structures[i].entities()
spath2 = '%s/%s' % (spath, i) if spath else i
spath2 = f"{spath}/{i}" if spath else i
entities.extend([(e, spath2) for e in elist])
return entities
@ -190,13 +189,13 @@ class Package(object):
try:
return self._structures[id]
except KeyError:
raise KeyError('No such structure: %s' % id)
raise KeyError("No such structure: %s" % id)
def package(self, id):
try:
return self._packages[id]
except KeyError:
raise KeyError('No such package: %s' % id)
raise KeyError("No such package: %s" % id)
def element(self, path):
"""
@ -211,11 +210,11 @@ class Package(object):
"""
if not path:
return None
elems = path.split('/')
elems = path.split("/")
if len(elems) == 0:
return None
if len(elems) == 2 and elems[1] == '':
if len(elems) == 2 and elems[1] == "":
elems = elems[:-1]
if len(elems) == 1:
@ -230,7 +229,7 @@ class Package(object):
return None
else:
try:
return self._packages[elems[0]].element('/'.join(elems[1:]))
return self._packages[elems[0]].element("/".join(elems[1:]))
except KeyError:
raise

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

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

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

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

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

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

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

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

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

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

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

@ -1,7 +1,8 @@
import os
import sys
class Manager(object):
class Manager:
formats = {}
names = {}
path = []
@ -40,7 +41,7 @@ class Manager(object):
try:
module = cls._import(name)
module.register(cls)
except:
except Exception:
pass
@classmethod
@ -52,11 +53,11 @@ class Manager(object):
try:
module = cls._import(name)
except ImportError:
raise KeyError ('no matching format')
raise KeyError("no matching format")
return module.FormatParser()
elif path:
try:
return cls.formats[os.path.splitext(path)[1][1:].lower()]
except KeyError:
pass
raise KeyError('no matching parser')
raise KeyError("no matching parser")

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

@ -1,12 +1,13 @@
from .parser import DTDParser as Parser
from .serializer import DTDSerializer as Serializer
class FormatParser():
name = 'dtd'
desc = 'DTD reader/writer'
extensions = ['dtd']
encoding = 'utf_8' # allowed encoding
fallback = ['utf_8_sig']
class FormatParser:
name = "dtd"
desc = "DTD reader/writer"
extensions = ["dtd"]
encoding = "utf_8" # allowed encoding
fallback = ["utf_8_sig"]
@classmethod
def dump_structure(cls, l10nobject):
@ -33,5 +34,6 @@ class FormatParser():
l10nobject = Parser.parse(text)
return l10nobject
def register(Manager):
Manager.register(FormatParser)

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

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

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

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

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

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

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

@ -2,11 +2,11 @@ from .parser import IncParser as Parser
from .serializer import IncSerializer as Serializer
class FormatParser(object):
name = 'inc'
class FormatParser:
name = "inc"
desc = "INC reader/writer"
extensions = ['inc']
encoding = 'utf_8' # allowed encoding
extensions = ["inc"]
encoding = "utf_8" # allowed encoding
fallback = None
@classmethod

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

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

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

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

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

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

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

@ -1,12 +1,12 @@
from .parser import Parser
from .structure import Structure
from .serializer import Serializer
class FormatParser():
name = 'ini'
class FormatParser:
name = "ini"
desc = "Ini reader/writer"
extensions = ['ini']
encoding = 'utf_8' # allowed encoding
extensions = ["ini"]
encoding = "utf_8" # allowed encoding
fallback = None
@classmethod

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -1,3 +1,7 @@
from setuptools import setup, find_packages
import sys
import os.path
"""Python localization library
New library for localization written in Python.
@ -5,12 +9,9 @@ New library for localization written in Python.
docstrings = __doc__.split("\n")
from setuptools import setup, find_packages
import sys
import os.path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'lib'))
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "lib"))
import silme
import silme # noqa: E402
classifiers = """\
Development Status :: 4 - Beta
@ -27,7 +28,8 @@ Topic :: Software Development :: Libraries :: Python Modules
Topic :: Software Development :: Localization
"""
setup(name="silme",
setup(
name="silme",
version=silme.get_short_version(),
author="Zbigniew Braniecki",
author_email="gandalf@mozilla.com",
@ -37,7 +39,7 @@ setup(name="silme",
url="https://github.com/mathjazz/silme",
classifiers=filter(None, classifiers.split("\n")),
platforms=["any"],
package_dir={'': 'lib'},
packages=find_packages('lib'),
keywords="localization, l10n"
package_dir={"": "lib"},
packages=find_packages("lib"),
keywords="localization, l10n",
)

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

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

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

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

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

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

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

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

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

@ -1,8 +1,8 @@
import unittest
import sys
from silme.core.types.lazydict import LazyDict
class LazyDictTestCase(unittest.TestCase):
def test_constructor(self):
# calling built-in types without argument must return empty
@ -18,11 +18,11 @@ class LazyDictTestCase(unittest.TestCase):
def test_keys(self):
d = LazyDict()
self.assertEqual(set(d.keys()), set())
d = LazyDict({'a': 1, 'b': 2})
d = LazyDict({"a": 1, "b": 2})
k = d.keys()
self.assertTrue('a' in d)
self.assertTrue('b' in d)
self.assertEqual(set(k), {'a','b'})
self.assertTrue("a" in d)
self.assertTrue("b" in d)
self.assertEqual(set(k), {"a", "b"})
self.assertRaises(TypeError, d.keys, None)
@ -45,38 +45,39 @@ class LazyDictTestCase(unittest.TestCase):
def test_contains(self):
d = LazyDict()
self.assertNotIn('a', d)
self.assertFalse('a' in d)
self.assertTrue('a' not in d)
d = LazyDict({'a': 1, 'b': 2})
self.assertIn('a', d)
self.assertIn('b', d)
self.assertNotIn('c', d)
self.assertNotIn("a", d)
self.assertFalse("a" in d)
self.assertTrue("a" not in d)
d = LazyDict({"a": 1, "b": 2})
self.assertIn("a", d)
self.assertIn("b", d)
self.assertNotIn("c", d)
self.assertRaises(TypeError, d.__contains__)
def test_len(self):
d = LazyDict()
self.assertEqual(len(d), 0)
d = LazyDict({'a': 1, 'b': 2})
d = LazyDict({"a": 1, "b": 2})
self.assertEqual(len(d), 2)
def test_getitem(self):
d = LazyDict({'a': 1, 'b': 2})
self.assertEqual(d['a'], 1)
self.assertEqual(d['b'], 2)
d['c'] = 3
d['a'] = 4
self.assertEqual(d['c'], 3)
self.assertEqual(d['a'], 4)
del d['b']
self.assertEqual(d, {'a': 4, 'c': 3})
d = LazyDict({"a": 1, "b": 2})
self.assertEqual(d["a"], 1)
self.assertEqual(d["b"], 2)
d["c"] = 3
d["a"] = 4
self.assertEqual(d["c"], 3)
self.assertEqual(d["a"], 4)
del d["b"]
self.assertEqual(d, {"a": 4, "c": 3})
self.assertRaises(TypeError, d.__getitem__)
class BadEq(object):
class BadEq:
def __eq__(self, other):
raise Exc()
def __hash__(self):
return 24
@ -84,10 +85,12 @@ class LazyDictTestCase(unittest.TestCase):
d[BadEq()] = 42
self.assertRaises(KeyError, d.__getitem__, 23)
class Exc(Exception): pass
class Exc(Exception):
pass
class BadHash(object):
class BadHash:
fail = False
def __hash__(self):
if self.fail:
raise Exc()
@ -121,20 +124,26 @@ class LazyDictTestCase(unittest.TestCase):
class SimpleUserDict:
def __init__(self):
self.d = {1: 1, 2: 2, 3: 3}
def keys(self):
return self.d.keys()
def __getitem__(self, i):
return self.d[i]
d.clear()
d.update(SimpleUserDict())
self.assertEqual(d, {1: 1, 2: 2, 3: 3})
class Exc(Exception): pass
class Exc(Exception):
pass
d.clear()
class FailingUserDict:
def keys(self):
raise Exc
self.assertRaises(Exc, d.update, FailingUserDict())
class FailingUserDict:
@ -142,43 +151,57 @@ class LazyDictTestCase(unittest.TestCase):
class BogonIter:
def __init__(self):
self.i = 1
def __iter__(self):
return self
def __next__(self):
if self.i:
self.i = 0
return 'a'
return "a"
raise Exc
next = __next__
return BogonIter()
def __getitem__(self, key):
return key
self.assertRaises(Exc, d.update, FailingUserDict())
class FailingUserDict:
def keys(self):
class BogonIter:
def __init__(self):
self.i = ord('a')
self.i = ord("a")
def __iter__(self):
return self
def __next__(self):
if self.i <= ord('z'):
if self.i <= ord("z"):
rtn = chr(self.i)
self.i += 1
return rtn
raise StopIteration
next = __next__
return BogonIter()
def __getitem__(self, key):
raise Exc
self.assertRaises(Exc, d.update, FailingUserDict())
class badseq(object):
class badseq:
def __iter__(self):
return self
def __next__(self):
raise Exc()
next = __next__
self.assertRaises(Exc, {}.update, badseq())
@ -186,30 +209,38 @@ class LazyDictTestCase(unittest.TestCase):
self.assertRaises(ValueError, {}.update, [(1, 2, 3)])
def test_fromkeys(self):
self.assertEqual(LazyDict().fromkeys('abc'), {'a':None, 'b':None, 'c':None})
self.assertEqual(LazyDict().fromkeys("abc"), {"a": None, "b": None, "c": None})
d = LazyDict()
self.assertIsNot(d.fromkeys('abc'), d)
self.assertEqual(d.fromkeys('abc'), LazyDict({'a':None, 'b':None, 'c':None}))
self.assertIsNot(d.fromkeys("abc"), d)
self.assertEqual(d.fromkeys("abc"), LazyDict({"a": None, "b": None, "c": None}))
self.assertEqual(d.fromkeys((4, 5), 0), LazyDict({4: 0, 5: 0}))
self.assertEqual(d.fromkeys([]), LazyDict())
def g():
yield 1
self.assertEqual(d.fromkeys(g()), LazyDict({1: None}))
self.assertRaises(TypeError, {}.fromkeys, 3)
class dictlike(LazyDict): pass
self.assertEqual(dictlike.fromkeys('a'), LazyDict({'a':None}))
self.assertEqual(dictlike().fromkeys('a'), LazyDict({'a':None}))
self.assertTrue(type(dictlike.fromkeys('a')) is dictlike)
self.assertTrue(type(dictlike().fromkeys('a')) is dictlike)
class dictlike(LazyDict):
pass
self.assertEqual(dictlike.fromkeys("a"), LazyDict({"a": None}))
self.assertEqual(dictlike().fromkeys("a"), LazyDict({"a": None}))
self.assertTrue(type(dictlike.fromkeys("a")) is dictlike)
self.assertTrue(type(dictlike().fromkeys("a")) is dictlike)
class mydict(LazyDict):
def __new__(cls):
return LazyDict()
ud = mydict.fromkeys('ab')
self.assertEqual(ud, LazyDict({'a':None, 'b':None}))
ud = mydict.fromkeys("ab")
self.assertEqual(ud, LazyDict({"a": None, "b": None}))
self.assertTrue(isinstance(ud, LazyDict))
self.assertRaises(TypeError, dict.fromkeys)
class Exc(Exception): pass
class Exc(Exception):
pass
class baddict1(LazyDict):
def __init__(self):
@ -235,32 +266,34 @@ class LazyDictTestCase(unittest.TestCase):
def test_get(self):
d = LazyDict()
self.assertIs(d.get('c'), None)
self.assertEqual(d.get('c', 3), 3)
d = LazyDict({'a': 1, 'b': 2})
self.assertIs(d.get('c'), None)
self.assertEqual(d.get('c', 3), 3)
self.assertEqual(d.get('a'), 1)
self.assertEqual(d.get('a', 3), 1)
self.assertIs(d.get("c"), None)
self.assertEqual(d.get("c", 3), 3)
d = LazyDict({"a": 1, "b": 2})
self.assertIs(d.get("c"), None)
self.assertEqual(d.get("c", 3), 3)
self.assertEqual(d.get("a"), 1)
self.assertEqual(d.get("a", 3), 1)
self.assertRaises(TypeError, d.get)
self.assertRaises(TypeError, d.get, None, None, None)
def test_setdefault(self):
# dict.setdefault()
d = LazyDict()
self.assertIs(d.setdefault('key0'), None)
d.setdefault('key0', [])
self.assertIs(d.setdefault('key0'), None)
d.setdefault('key', []).append(3)
self.assertEqual(d['key'][0], 3)
d.setdefault('key', []).append(4)
self.assertEqual(len(d['key']), 2)
self.assertIs(d.setdefault("key0"), None)
d.setdefault("key0", [])
self.assertIs(d.setdefault("key0"), None)
d.setdefault("key", []).append(3)
self.assertEqual(d["key"][0], 3)
d.setdefault("key", []).append(4)
self.assertEqual(len(d["key"]), 2)
self.assertRaises(TypeError, d.setdefault)
class Exc(Exception): pass
class Exc(Exception):
pass
class BadHash(object):
class BadHash:
fail = False
def __hash__(self):
if self.fail:
raise Exc()
@ -302,9 +335,9 @@ class LazyDictTestCase(unittest.TestCase):
def test_pop(self):
# Tests for pop with specified key
d = LazyDict()
k, v = 'abc', 'def'
k, v = "abc", "def"
d[k] = v
self.assertRaises(KeyError, d.pop, 'ghi')
self.assertRaises(KeyError, d.pop, "ghi")
self.assertEqual(d.pop(k), v)
self.assertEqual(len(d), 0)
@ -315,7 +348,7 @@ class LazyDictTestCase(unittest.TestCase):
# (for 64-bit archs). See SF bug #689659.
x = 4503599627370496
y = 4503599627370496
h = LazyDict({x: 'anything', y: 'something else'})
h = LazyDict({x: "anything", y: "something else"})
self.assertEqual(h[x], h[y])
self.assertEqual(d.pop(k, v), v)
@ -324,10 +357,12 @@ class LazyDictTestCase(unittest.TestCase):
self.assertRaises(TypeError, d.pop)
class Exc(Exception): pass
class Exc(Exception):
pass
class BadHash(object):
class BadHash:
fail = False
def __hash__(self):
if self.fail:
raise Exc()
@ -362,18 +397,22 @@ class LazyDictTestCase(unittest.TestCase):
# (E) subclass defines __missing__ method raising RuntimeError
# (F) subclass sets __missing__ instance variable (no effect)
# (G) subclass doesn't define __missing__ at a all
class D(dict):
def __missing__(self, key):
return 42
d = D({1: 2, 3: 4})
self.assertEqual(d[1], 2)
self.assertEqual(d[3], 4)
self.assertTrue(2 not in d)
self.assertTrue(2 not in d.keys())
self.assertEqual(d[2], 42)
class E(dict):
def __missing__(self, key):
raise RuntimeError(key)
e = E()
try:
e[42]
@ -381,10 +420,12 @@ class LazyDictTestCase(unittest.TestCase):
self.assertEqual(err.args, (42,))
else:
self.fail("e[42] didn't raise RuntimeError")
class F(dict):
def __init__(self):
# An instance variable __missing__ should have no effect
self.__missing__ = lambda key: None
f = F()
try:
f[42]
@ -392,8 +433,10 @@ class LazyDictTestCase(unittest.TestCase):
self.assertEqual(err.args, (42,))
else:
self.fail("f[42] didn't raise KeyError")
class G(dict):
pass
g = G()
try:
g[42]
@ -402,7 +445,6 @@ class LazyDictTestCase(unittest.TestCase):
else:
self.fail("g[42] didn't raise KeyError")
def test_tuple_keyerror(self):
# SF #1576657
d = LazyDict()
@ -429,8 +471,8 @@ class LazyDictTestCase(unittest.TestCase):
d = LazyDict()
x1 = BadDictKey()
x2 = BadDictKey()
d[x1] = 1
# x2 = BadDictKey()
# for stmt in ['d[x2] = 2',
# 'z = d[x2]',
# 'x2 in d',
@ -446,27 +488,29 @@ class LazyDictTestCase(unittest.TestCase):
def test_lazy_keys(self):
def resolver(id):
p = {'b': 2, 'c': 3}
p = {"b": 2, "c": 3}
return p[id]
d = LazyDict({'a': 1})
d.set_stub('b', resolver)
d.set_stub('c', resolver)
d['d'] = 4
d = LazyDict({"a": 1})
d.set_stub("b", resolver)
d.set_stub("c", resolver)
d["d"] = 4
k = d.keys()
self.assertTrue('a' in d)
self.assertTrue('b' in d)
self.assertTrue('c' in d)
self.assertTrue('d' in d)
self.assertEqual(set(k), {'a','b','c','d'})
self.assertTrue("a" in d)
self.assertTrue("b" in d)
self.assertTrue("c" in d)
self.assertTrue("d" in d)
self.assertEqual(set(k), {"a", "b", "c", "d"})
def test_lazy_values(self):
def resolver(id):
p = {'c': 3}
p = {"c": 3}
return p[id]
d = LazyDict()
self.assertEqual(set(d.values()), set())
d = LazyDict({1: 2})
d.set_stub('c', resolver)
d.set_stub("c", resolver)
v = d.values()
self.assertEqual(set(v), {2, 3})
@ -483,41 +527,41 @@ class LazyDictTestCase(unittest.TestCase):
def test_lazy_contains(self):
d = LazyDict()
self.assertNotIn('a', d)
self.assertFalse('a' in d)
self.assertTrue('a' not in d)
d = LazyDict({'a': 1, 'b': 2})
self.assertIn('a', d)
self.assertIn('b', d)
self.assertNotIn('c', d)
self.assertNotIn("a", d)
self.assertFalse("a" in d)
self.assertTrue("a" not in d)
d = LazyDict({"a": 1, "b": 2})
self.assertIn("a", d)
self.assertIn("b", d)
self.assertNotIn("c", d)
self.assertRaises(TypeError, d.__contains__)
def test_lazy_len(self):
d = LazyDict({'1':1})
d = LazyDict({"1": 1})
self.assertEqual(len(d), 1)
d['2'] = 2
d["2"] = 2
self.assertEqual(len(d), 2)
d.set_stub('3', lambda x: x)
d.set_stub("3", lambda x: x)
self.assertEqual(len(d), 3)
def test_lazy_getitem(self):
d = LazyDict({'a': 1, 'b': 2})
self.assertEqual(d['a'], 1)
self.assertEqual(d['b'], 2)
d['c'] = 3
d['a'] = 4
self.assertEqual(d['c'], 3)
self.assertEqual(d['a'], 4)
del d['b']
self.assertEqual(d, {'a': 4, 'c': 3})
d = LazyDict({"a": 1, "b": 2})
self.assertEqual(d["a"], 1)
self.assertEqual(d["b"], 2)
d["c"] = 3
d["a"] = 4
self.assertEqual(d["c"], 3)
self.assertEqual(d["a"], 4)
del d["b"]
self.assertEqual(d, {"a": 4, "c": 3})
self.assertRaises(TypeError, d.__getitem__)
class BadEq(object):
class BadEq:
def __eq__(self, other):
raise Exc()
def __hash__(self):
return 24
@ -525,10 +569,12 @@ class LazyDictTestCase(unittest.TestCase):
d[BadEq()] = 42
self.assertRaises(KeyError, d.__getitem__, 23)
class Exc(Exception): pass
class Exc(Exception):
pass
class BadHash(object):
class BadHash:
fail = False
def __hash__(self):
if self.fail:
raise Exc()
@ -567,55 +613,60 @@ class LazyDictTestCase(unittest.TestCase):
class SimpleUserDict:
def __init__(self):
self.d = {1: 1, 2: 2, 3: 3}
def keys(self):
return self.d.keys()
def __getitem__(self, i):
return self.d[i]
d.clear()
d.update(SimpleUserDict())
self.assertEqual(d, {1: 1, 2: 2, 3: 3})
def test_lazy_copy(self):
d = LazyDict({'1':1})
d['2'] = 2
d = LazyDict({"1": 1})
d["2"] = 2
x = d.copy()
self.assertEqual(len(x), 2)
i = {'num': 0}
i = {"num": 0}
def r(key, i):
i['num'] += 1
return i['num']
d.set_stub('3', r, i)
i["num"] += 1
return i["num"]
d.set_stub("3", r, i)
x = d.copy()
self.assertEqual(d['3'], 1)
self.assertEqual(d["3"], 1)
self.assertEqual(len(d._stubs), 0)
self.assertEqual(len(x._stubs), 1)
self.assertEqual(x['3'], 2)
self.assertEqual(x["3"], 2)
self.assertEqual(len(x._stubs), 0)
x = d.copy()
self.assertEqual(d['3'], 1)
self.assertEqual(x['3'], 1)
self.assertEqual(d["3"], 1)
self.assertEqual(x["3"], 1)
def test_lazy_get(self):
d = LazyDict({'a': 1, 'b': 2})
d.set_stub('d', lambda x:x)
self.assertIs(d.get('c'), None)
self.assertEqual(d.get('c', 3), 3)
self.assertEqual(d.get('a'), 1)
self.assertEqual(d.get('a', 3), 1)
self.assertEqual(d.get('d'), 'd')
self.assertEqual(d.get('d', 3), 'd')
d = LazyDict({"a": 1, "b": 2})
d.set_stub("d", lambda x: x)
self.assertIs(d.get("c"), None)
self.assertEqual(d.get("c", 3), 3)
self.assertEqual(d.get("a"), 1)
self.assertEqual(d.get("a", 3), 1)
self.assertEqual(d.get("d"), "d")
self.assertEqual(d.get("d", 3), "d")
self.assertRaises(TypeError, d.get)
self.assertRaises(TypeError, d.get, None, None, None)
def test_lazy_setdefault(self):
d = LazyDict()
self.assertIs(d.setdefault('key0'), None)
d.set_stub('key0', lambda x:'value0')
self.assertIs(d.setdefault('key0'), 'value0')
d.set_stub('key0', lambda x:'value0')
self.assertEqual(d.setdefault('key1', 'value1'), 'value1')
self.assertEqual(d['key1'], 'value1')
self.assertEqual(d.setdefault('key0', 'value2'), 'value0')
self.assertIs(d.setdefault("key0"), None)
d.set_stub("key0", lambda x: "value0")
self.assertIs(d.setdefault("key0"), "value0")
d.set_stub("key0", lambda x: "value0")
self.assertEqual(d.setdefault("key1", "value1"), "value1")
self.assertEqual(d["key1"], "value1")
self.assertEqual(d.setdefault("key0", "value2"), "value0")
def test_lazy_popitem(self):
d = LazyDict({1: 1})
@ -630,9 +681,9 @@ class LazyDictTestCase(unittest.TestCase):
def test_lazy_pop(self):
d = LazyDict()
k, v = ('abc', 'def')
d.set_stub(k, lambda x:'def')
self.assertRaises(KeyError, d.pop, 'ghi')
k, v = ("abc", "def")
d.set_stub(k, lambda x: "def")
self.assertRaises(KeyError, d.pop, "ghi")
self.assertEqual(d.pop(k), v)
self.assertEqual(len(d), 0)
@ -647,18 +698,18 @@ class LazyDictTestCase(unittest.TestCase):
def test_lazy_delitem(self):
d = LazyDict()
d['1'] = 1
d['2'] = 2
del d['1']
d["1"] = 1
d["2"] = 2
del d["1"]
self.assertEqual(len(d), 1)
self.assertRaises(KeyError, d.__getitem__, '1')
d.set_stub('1', lambda x:x)
self.assertRaises(KeyError, d.__getitem__, "1")
d.set_stub("1", lambda x: x)
self.assertEqual(len(d), 2)
del d['1']
del d["1"]
self.assertEqual(len(d), 1)
self.assertRaises(KeyError, d.__getitem__, '1')
d.set_stub('1', lambda x:x)
self.assertEqual(d['1'], '1')
del d['1']
self.assertRaises(KeyError, d.__getitem__, "1")
d.set_stub("1", lambda x: x)
self.assertEqual(d["1"], "1")
del d["1"]
self.assertEqual(len(d), 1)
self.assertRaises(KeyError, d.__getitem__, '1')
self.assertRaises(KeyError, d.__getitem__, "1")