mirror of https://github.com/jab/bidict.git
improve namedbidict
- raise TypeError if base_type is not a frozenbidict subclass - rewrite the code to be clearer
This commit is contained in:
parent
5a8ab033e8
commit
f1749540cb
|
@ -79,8 +79,19 @@ Breaking API Changes
|
||||||
(So it is no longer possible to create an infinite chain like
|
(So it is no longer possible to create an infinite chain like
|
||||||
``DuplicationPolicy.RAISE.RAISE.RAISE...``.)
|
``DuplicationPolicy.RAISE.RAISE.RAISE...``.)
|
||||||
|
|
||||||
- Pickling bidicts on Python 2 now requires the latest version of the
|
- :func:`~bidict.namedbidict` now raises :class:`TypeError` if the provided
|
||||||
pickle protocol (specified via -1), e.g. ``pickle.dumps(mybidict, -1)``
|
``base_type`` is not a subclass of :class:`~bidict.frozenbidict`.
|
||||||
|
|
||||||
|
- Pickling ordered bidicts now requires
|
||||||
|
at least version 2 of the pickle protocol.
|
||||||
|
If you are using Python 3,
|
||||||
|
:attr:`pickle.DEFAULT_PROTOCOL` is 3 anyway,
|
||||||
|
so this will not affect you.
|
||||||
|
However if you are using in Python 2,
|
||||||
|
:attr:`~pickle.DEFAULT_PROTOCOL` is 0,
|
||||||
|
so you must now explicitly specify the version
|
||||||
|
in your :func:`pickle.dumps` calls,
|
||||||
|
e.g. ``pickle.dumps(ob, 2)``.
|
||||||
|
|
||||||
|
|
||||||
0.14.2 (2017-12-06)
|
0.14.2 (2017-12-06)
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from ._frozen import frozenbidict
|
||||||
from ._bidict import bidict
|
from ._bidict import bidict
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,36 +23,42 @@ def namedbidict(typename, keyname, valname, base_type=bidict):
|
||||||
|
|
||||||
Analagous to :func:`collections.namedtuple`.
|
Analagous to :func:`collections.namedtuple`.
|
||||||
"""
|
"""
|
||||||
|
if not issubclass(base_type, frozenbidict):
|
||||||
|
raise TypeError('base_type must be a subclass of frozenbidict')
|
||||||
|
|
||||||
for name in typename, keyname, valname:
|
for name in typename, keyname, valname:
|
||||||
if not _LEGALNAMERE.match(name):
|
if not _LEGALNAMERE.match(name):
|
||||||
raise ValueError('"%s" does not match pattern %s' %
|
raise ValueError('%r does not match pattern %s' % (name, _LEGALNAMEPAT))
|
||||||
(name, _LEGALNAMEPAT))
|
|
||||||
|
|
||||||
getfwd = lambda self: self.inv if self._isinv else self # pylint: disable=protected-access
|
class _Named(base_type):
|
||||||
getfwd.__name__ = valname + '_for'
|
|
||||||
getfwd.__doc__ = u'%s forward %s: %s → %s' % (typename, base_type.__name__, keyname, valname)
|
|
||||||
|
|
||||||
getinv = lambda self: self if self._isinv else self.inv # pylint: disable=protected-access
|
__slots__ = ()
|
||||||
getinv.__name__ = keyname + '_for'
|
|
||||||
getinv.__doc__ = u'%s inverse %s: %s → %s' % (typename, base_type.__name__, valname, keyname)
|
|
||||||
|
|
||||||
__reduce__ = lambda self: (
|
def _getfwd(self):
|
||||||
_make_empty, (typename, keyname, valname, base_type), self.__getstate__())
|
return self.inv if self._isinv else self # pylint: disable=protected-access
|
||||||
__reduce__.__name__ = '__reduce__'
|
|
||||||
__reduce__.__doc__ = 'helper for pickle'
|
|
||||||
|
|
||||||
__dict__ = {
|
def _getinv(self):
|
||||||
getfwd.__name__: property(getfwd),
|
return self if self._isinv else self.inv # pylint: disable=protected-access
|
||||||
getinv.__name__: property(getinv),
|
|
||||||
'__reduce__': __reduce__,
|
def __reduce__(self):
|
||||||
}
|
return (_make_empty, (typename, keyname, valname, base_type), self.__getstate__())
|
||||||
return type(typename, (base_type,), __dict__)
|
|
||||||
|
|
||||||
|
bname = base_type.__name__
|
||||||
|
fname = valname + '_for'
|
||||||
|
iname = keyname + '_for'
|
||||||
|
names = dict(typename=typename, bname=bname, keyname=keyname, valname=valname)
|
||||||
|
fdoc = u'{typename} forward {bname}: {keyname} → {valname}'.format(**names)
|
||||||
|
idoc = u'{typename} inverse {bname}: {valname} → {keyname}'.format(**names)
|
||||||
|
setattr(_Named, fname, property(_Named._getfwd, doc=fdoc))
|
||||||
|
setattr(_Named, iname, property(_Named._getinv, doc=idoc))
|
||||||
|
|
||||||
|
_Named.__name__ = typename
|
||||||
|
return _Named
|
||||||
|
|
||||||
|
|
||||||
def _make_empty(typename, keyname, valname, base_type):
|
def _make_empty(typename, keyname, valname, base_type):
|
||||||
"""
|
"""Create a named bidict with the indicated arguments and return an empty instance.
|
||||||
Create a named bidict with the indicated arguments and return an empty instance.
|
|
||||||
|
|
||||||
Used to make :func:`bidict.namedbidict` instances picklable.
|
Used to make :func:`bidict.namedbidict` instances picklable.
|
||||||
"""
|
"""
|
||||||
cls = namedbidict(typename, keyname, valname, base_type=base_type)
|
cls = namedbidict(typename, keyname, valname, base_type=base_type)
|
||||||
|
|
Loading…
Reference in New Issue