Translation of UI (german and english)
Bugfix for feeds
- removed categories related and up
- load new books now working
- category random now working
login page is free of non accessible elements
boolean custom column is vivible in UI
books with only with certain languages can be shown
book shelfs can be deleted from UI
Anonymous user view is more resticted
Added browse of series in sidebar
Dependencys in vendor folder are updated to newer versions (licencs files are now present)
Bugfix editing Authors names
Made upload on windows working
This commit is contained in:
Vendored
+242
@@ -0,0 +1,242 @@
|
||||
Metadata-Version: 1.1
|
||||
Name: singledispatch
|
||||
Version: 3.4.0.3
|
||||
Summary: This library brings functools.singledispatch from Python 3.4 to Python 2.6-3.3.
|
||||
Home-page: http://docs.python.org/3/library/functools.html#functools.singledispatch
|
||||
Author: Łukasz Langa
|
||||
Author-email: lukasz@langa.pl
|
||||
License: MIT
|
||||
Description: ==============
|
||||
singledispatch
|
||||
==============
|
||||
|
||||
`PEP 443 <http://www.python.org/dev/peps/pep-0443/>`_ proposed to expose
|
||||
a mechanism in the ``functools`` standard library module in Python 3.4
|
||||
that provides a simple form of generic programming known as
|
||||
single-dispatch generic functions.
|
||||
|
||||
This library is a backport of this functionality to Python 2.6 - 3.3.
|
||||
|
||||
To define a generic function, decorate it with the ``@singledispatch``
|
||||
decorator. Note that the dispatch happens on the type of the first
|
||||
argument, create your function accordingly::
|
||||
|
||||
>>> from singledispatch import singledispatch
|
||||
>>> @singledispatch
|
||||
... def fun(arg, verbose=False):
|
||||
... if verbose:
|
||||
... print("Let me just say,", end=" ")
|
||||
... print(arg)
|
||||
|
||||
To add overloaded implementations to the function, use the
|
||||
``register()`` attribute of the generic function. It is a decorator,
|
||||
taking a type parameter and decorating a function implementing the
|
||||
operation for that type::
|
||||
|
||||
>>> @fun.register(int)
|
||||
... def _(arg, verbose=False):
|
||||
... if verbose:
|
||||
... print("Strength in numbers, eh?", end=" ")
|
||||
... print(arg)
|
||||
...
|
||||
>>> @fun.register(list)
|
||||
... def _(arg, verbose=False):
|
||||
... if verbose:
|
||||
... print("Enumerate this:")
|
||||
... for i, elem in enumerate(arg):
|
||||
... print(i, elem)
|
||||
|
||||
To enable registering lambdas and pre-existing functions, the
|
||||
``register()`` attribute can be used in a functional form::
|
||||
|
||||
>>> def nothing(arg, verbose=False):
|
||||
... print("Nothing.")
|
||||
...
|
||||
>>> fun.register(type(None), nothing)
|
||||
|
||||
The ``register()`` attribute returns the undecorated function which
|
||||
enables decorator stacking, pickling, as well as creating unit tests for
|
||||
each variant independently::
|
||||
|
||||
>>> @fun.register(float)
|
||||
... @fun.register(Decimal)
|
||||
... def fun_num(arg, verbose=False):
|
||||
... if verbose:
|
||||
... print("Half of your number:", end=" ")
|
||||
... print(arg / 2)
|
||||
...
|
||||
>>> fun_num is fun
|
||||
False
|
||||
|
||||
When called, the generic function dispatches on the type of the first
|
||||
argument::
|
||||
|
||||
>>> fun("Hello, world.")
|
||||
Hello, world.
|
||||
>>> fun("test.", verbose=True)
|
||||
Let me just say, test.
|
||||
>>> fun(42, verbose=True)
|
||||
Strength in numbers, eh? 42
|
||||
>>> fun(['spam', 'spam', 'eggs', 'spam'], verbose=True)
|
||||
Enumerate this:
|
||||
0 spam
|
||||
1 spam
|
||||
2 eggs
|
||||
3 spam
|
||||
>>> fun(None)
|
||||
Nothing.
|
||||
>>> fun(1.23)
|
||||
0.615
|
||||
|
||||
Where there is no registered implementation for a specific type, its
|
||||
method resolution order is used to find a more generic implementation.
|
||||
The original function decorated with ``@singledispatch`` is registered
|
||||
for the base ``object`` type, which means it is used if no better
|
||||
implementation is found.
|
||||
|
||||
To check which implementation will the generic function choose for
|
||||
a given type, use the ``dispatch()`` attribute::
|
||||
|
||||
>>> fun.dispatch(float)
|
||||
<function fun_num at 0x1035a2840>
|
||||
>>> fun.dispatch(dict) # note: default implementation
|
||||
<function fun at 0x103fe0000>
|
||||
|
||||
To access all registered implementations, use the read-only ``registry``
|
||||
attribute::
|
||||
|
||||
>>> fun.registry.keys()
|
||||
dict_keys([<class 'NoneType'>, <class 'int'>, <class 'object'>,
|
||||
<class 'decimal.Decimal'>, <class 'list'>,
|
||||
<class 'float'>])
|
||||
>>> fun.registry[float]
|
||||
<function fun_num at 0x1035a2840>
|
||||
>>> fun.registry[object]
|
||||
<function fun at 0x103fe0000>
|
||||
|
||||
The vanilla documentation is available at
|
||||
http://docs.python.org/3/library/functools.html#functools.singledispatch.
|
||||
|
||||
|
||||
Versioning
|
||||
----------
|
||||
|
||||
This backport is intended to keep 100% compatibility with the vanilla
|
||||
release in Python 3.4+. To help maintaining a version you want and
|
||||
expect, a versioning scheme is used where:
|
||||
|
||||
* the first three numbers indicate the version of Python 3.x from which the
|
||||
backport is done
|
||||
|
||||
* a backport release number is provided after the last dot
|
||||
|
||||
For example, ``3.4.0.0`` is the **first** release of ``singledispatch``
|
||||
compatible with the library found in Python **3.4.0**.
|
||||
|
||||
A single exception from the 100% compatibility principle is that bugs
|
||||
fixed before releasing another minor Python 3.x.y version **will be
|
||||
included** in the backport releases done in the mean time. This rule
|
||||
applies to bugs only.
|
||||
|
||||
|
||||
Maintenance
|
||||
-----------
|
||||
|
||||
This backport is maintained on BitBucket by Łukasz Langa, one of the
|
||||
members of the core CPython team:
|
||||
|
||||
* `singledispatch Mercurial repository <https://bitbucket.org/ambv/singledispatch>`_
|
||||
|
||||
* `singledispatch issue tracker <https://bitbucket.org/ambv/singledispatch/issues>`_
|
||||
|
||||
|
||||
Change Log
|
||||
----------
|
||||
|
||||
3.4.0.3
|
||||
~~~~~~~
|
||||
|
||||
Should now install flawlessly on PyPy as well. Thanks to Ryan Petrello
|
||||
for finding and fixing the ``setup.py`` issue.
|
||||
|
||||
3.4.0.2
|
||||
~~~~~~~
|
||||
|
||||
Updated to the reference implementation as of 02-July-2013.
|
||||
|
||||
* more predictable dispatch order when abstract base classes are in use:
|
||||
abstract base classes are now inserted into the MRO of the argument's
|
||||
class where their functionality is introduced, i.e. issubclass(cls,
|
||||
abc) returns True for the class itself but returns False for all its
|
||||
direct base classes. Implicit ABCs for a given class (either
|
||||
registered or inferred from the presence of a special method like
|
||||
__len__) are inserted directly after the last ABC explicitly listed in
|
||||
the MRO of said class. This also means there are less "ambiguous
|
||||
dispatch" exceptions raised.
|
||||
|
||||
* better test coverage and improved docstrings
|
||||
|
||||
3.4.0.1
|
||||
~~~~~~~
|
||||
|
||||
Updated to the reference implementation as of 31-May-2013.
|
||||
|
||||
* better performance
|
||||
|
||||
* fixed a corner case with PEP 435 enums
|
||||
|
||||
* calls to `dispatch()` also cached
|
||||
|
||||
* dispatching algorithm now now a module-level routine called `_find_impl()`
|
||||
with a simplified implementation and proper documentation
|
||||
|
||||
* `dispatch()` now handles all caching-related activities
|
||||
|
||||
* terminology more consistent: "overload" -> "implementation"
|
||||
|
||||
3.4.0.0
|
||||
~~~~~~~
|
||||
|
||||
* the first public release compatible with 3.4.0
|
||||
|
||||
|
||||
Conversion Process
|
||||
------------------
|
||||
|
||||
This section is technical and should bother you only if you are
|
||||
wondering how this backport is produced. If the implementation details
|
||||
of this backport are not important for you, feel free to ignore the
|
||||
following content.
|
||||
|
||||
``singledispatch`` is converted using `six
|
||||
<http://pypi.python.org/pypi/six>`_ so that a single codebase can be
|
||||
used for all compatible Python versions. Because a fully automatic
|
||||
conversion was not doable, I took the following branching approach:
|
||||
|
||||
* the ``upstream`` branch holds unchanged files synchronized from the
|
||||
upstream CPython repository. The synchronization is currently done by
|
||||
manually copying the required code parts and stating from which
|
||||
CPython changeset they come from. The tests should pass on Python 3.4
|
||||
on this branch.
|
||||
|
||||
* the ``default`` branch holds the manually translated version and this
|
||||
is where all tests are run for all supported Python versions using
|
||||
Tox.
|
||||
|
||||
Keywords: single dispatch generic functions singledispatch genericfunctions decorator backport
|
||||
Platform: any
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: MIT License
|
||||
Classifier: Natural Language :: English
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 2
|
||||
Classifier: Programming Language :: Python :: 2.6
|
||||
Classifier: Programming Language :: Python :: 2.7
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3.2
|
||||
Classifier: Programming Language :: Python :: 3.3
|
||||
Classifier: Programming Language :: Python :: 3.4
|
||||
Classifier: Topic :: Software Development :: Libraries
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||
+219
@@ -0,0 +1,219 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
__all__ = ['singledispatch']
|
||||
|
||||
from functools import update_wrapper
|
||||
from weakref import WeakKeyDictionary
|
||||
from singledispatch_helpers import MappingProxyType, get_cache_token
|
||||
|
||||
################################################################################
|
||||
### singledispatch() - single-dispatch generic function decorator
|
||||
################################################################################
|
||||
|
||||
def _c3_merge(sequences):
|
||||
"""Merges MROs in *sequences* to a single MRO using the C3 algorithm.
|
||||
|
||||
Adapted from http://www.python.org/download/releases/2.3/mro/.
|
||||
|
||||
"""
|
||||
result = []
|
||||
while True:
|
||||
sequences = [s for s in sequences if s] # purge empty sequences
|
||||
if not sequences:
|
||||
return result
|
||||
for s1 in sequences: # find merge candidates among seq heads
|
||||
candidate = s1[0]
|
||||
for s2 in sequences:
|
||||
if candidate in s2[1:]:
|
||||
candidate = None
|
||||
break # reject the current head, it appears later
|
||||
else:
|
||||
break
|
||||
if not candidate:
|
||||
raise RuntimeError("Inconsistent hierarchy")
|
||||
result.append(candidate)
|
||||
# remove the chosen candidate
|
||||
for seq in sequences:
|
||||
if seq[0] == candidate:
|
||||
del seq[0]
|
||||
|
||||
def _c3_mro(cls, abcs=None):
|
||||
"""Computes the method resolution order using extended C3 linearization.
|
||||
|
||||
If no *abcs* are given, the algorithm works exactly like the built-in C3
|
||||
linearization used for method resolution.
|
||||
|
||||
If given, *abcs* is a list of abstract base classes that should be inserted
|
||||
into the resulting MRO. Unrelated ABCs are ignored and don't end up in the
|
||||
result. The algorithm inserts ABCs where their functionality is introduced,
|
||||
i.e. issubclass(cls, abc) returns True for the class itself but returns
|
||||
False for all its direct base classes. Implicit ABCs for a given class
|
||||
(either registered or inferred from the presence of a special method like
|
||||
__len__) are inserted directly after the last ABC explicitly listed in the
|
||||
MRO of said class. If two implicit ABCs end up next to each other in the
|
||||
resulting MRO, their ordering depends on the order of types in *abcs*.
|
||||
|
||||
"""
|
||||
for i, base in enumerate(reversed(cls.__bases__)):
|
||||
if hasattr(base, '__abstractmethods__'):
|
||||
boundary = len(cls.__bases__) - i
|
||||
break # Bases up to the last explicit ABC are considered first.
|
||||
else:
|
||||
boundary = 0
|
||||
abcs = list(abcs) if abcs else []
|
||||
explicit_bases = list(cls.__bases__[:boundary])
|
||||
abstract_bases = []
|
||||
other_bases = list(cls.__bases__[boundary:])
|
||||
for base in abcs:
|
||||
if issubclass(cls, base) and not any(
|
||||
issubclass(b, base) for b in cls.__bases__
|
||||
):
|
||||
# If *cls* is the class that introduces behaviour described by
|
||||
# an ABC *base*, insert said ABC to its MRO.
|
||||
abstract_bases.append(base)
|
||||
for base in abstract_bases:
|
||||
abcs.remove(base)
|
||||
explicit_c3_mros = [_c3_mro(base, abcs=abcs) for base in explicit_bases]
|
||||
abstract_c3_mros = [_c3_mro(base, abcs=abcs) for base in abstract_bases]
|
||||
other_c3_mros = [_c3_mro(base, abcs=abcs) for base in other_bases]
|
||||
return _c3_merge(
|
||||
[[cls]] +
|
||||
explicit_c3_mros + abstract_c3_mros + other_c3_mros +
|
||||
[explicit_bases] + [abstract_bases] + [other_bases]
|
||||
)
|
||||
|
||||
def _compose_mro(cls, types):
|
||||
"""Calculates the method resolution order for a given class *cls*.
|
||||
|
||||
Includes relevant abstract base classes (with their respective bases) from
|
||||
the *types* iterable. Uses a modified C3 linearization algorithm.
|
||||
|
||||
"""
|
||||
bases = set(cls.__mro__)
|
||||
# Remove entries which are already present in the __mro__ or unrelated.
|
||||
def is_related(typ):
|
||||
return (typ not in bases and hasattr(typ, '__mro__')
|
||||
and issubclass(cls, typ))
|
||||
types = [n for n in types if is_related(n)]
|
||||
# Remove entries which are strict bases of other entries (they will end up
|
||||
# in the MRO anyway.
|
||||
def is_strict_base(typ):
|
||||
for other in types:
|
||||
if typ != other and typ in other.__mro__:
|
||||
return True
|
||||
return False
|
||||
types = [n for n in types if not is_strict_base(n)]
|
||||
# Subclasses of the ABCs in *types* which are also implemented by
|
||||
# *cls* can be used to stabilize ABC ordering.
|
||||
type_set = set(types)
|
||||
mro = []
|
||||
for typ in types:
|
||||
found = []
|
||||
for sub in typ.__subclasses__():
|
||||
if sub not in bases and issubclass(cls, sub):
|
||||
found.append([s for s in sub.__mro__ if s in type_set])
|
||||
if not found:
|
||||
mro.append(typ)
|
||||
continue
|
||||
# Favor subclasses with the biggest number of useful bases
|
||||
found.sort(key=len, reverse=True)
|
||||
for sub in found:
|
||||
for subcls in sub:
|
||||
if subcls not in mro:
|
||||
mro.append(subcls)
|
||||
return _c3_mro(cls, abcs=mro)
|
||||
|
||||
def _find_impl(cls, registry):
|
||||
"""Returns the best matching implementation from *registry* for type *cls*.
|
||||
|
||||
Where there is no registered implementation for a specific type, its method
|
||||
resolution order is used to find a more generic implementation.
|
||||
|
||||
Note: if *registry* does not contain an implementation for the base
|
||||
*object* type, this function may return None.
|
||||
|
||||
"""
|
||||
mro = _compose_mro(cls, registry.keys())
|
||||
match = None
|
||||
for t in mro:
|
||||
if match is not None:
|
||||
# If *match* is an implicit ABC but there is another unrelated,
|
||||
# equally matching implicit ABC, refuse the temptation to guess.
|
||||
if (t in registry and t not in cls.__mro__
|
||||
and match not in cls.__mro__
|
||||
and not issubclass(match, t)):
|
||||
raise RuntimeError("Ambiguous dispatch: {0} or {1}".format(
|
||||
match, t))
|
||||
break
|
||||
if t in registry:
|
||||
match = t
|
||||
return registry.get(match)
|
||||
|
||||
def singledispatch(func):
|
||||
"""Single-dispatch generic function decorator.
|
||||
|
||||
Transforms a function into a generic function, which can have different
|
||||
behaviours depending upon the type of its first argument. The decorated
|
||||
function acts as the default implementation, and additional
|
||||
implementations can be registered using the register() attribute of the
|
||||
generic function.
|
||||
|
||||
"""
|
||||
registry = {}
|
||||
dispatch_cache = WeakKeyDictionary()
|
||||
def ns(): pass
|
||||
ns.cache_token = None
|
||||
|
||||
def dispatch(cls):
|
||||
"""generic_func.dispatch(cls) -> <function implementation>
|
||||
|
||||
Runs the dispatch algorithm to return the best available implementation
|
||||
for the given *cls* registered on *generic_func*.
|
||||
|
||||
"""
|
||||
if ns.cache_token is not None:
|
||||
current_token = get_cache_token()
|
||||
if ns.cache_token != current_token:
|
||||
dispatch_cache.clear()
|
||||
ns.cache_token = current_token
|
||||
try:
|
||||
impl = dispatch_cache[cls]
|
||||
except KeyError:
|
||||
try:
|
||||
impl = registry[cls]
|
||||
except KeyError:
|
||||
impl = _find_impl(cls, registry)
|
||||
dispatch_cache[cls] = impl
|
||||
return impl
|
||||
|
||||
def register(cls, func=None):
|
||||
"""generic_func.register(cls, func) -> func
|
||||
|
||||
Registers a new implementation for the given *cls* on a *generic_func*.
|
||||
|
||||
"""
|
||||
if func is None:
|
||||
return lambda f: register(cls, f)
|
||||
registry[cls] = func
|
||||
if ns.cache_token is None and hasattr(cls, '__abstractmethods__'):
|
||||
ns.cache_token = get_cache_token()
|
||||
dispatch_cache.clear()
|
||||
return func
|
||||
|
||||
def wrapper(*args, **kw):
|
||||
return dispatch(args[0].__class__)(*args, **kw)
|
||||
|
||||
registry[object] = func
|
||||
wrapper.register = register
|
||||
wrapper.dispatch = dispatch
|
||||
wrapper.registry = MappingProxyType(registry)
|
||||
wrapper._clear_cache = dispatch_cache.clear
|
||||
update_wrapper(wrapper, func)
|
||||
return wrapper
|
||||
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from abc import ABCMeta
|
||||
from collections import MutableMapping
|
||||
import sys
|
||||
try:
|
||||
from collections import UserDict
|
||||
except ImportError:
|
||||
from UserDict import UserDict
|
||||
try:
|
||||
from collections import OrderedDict
|
||||
except ImportError:
|
||||
from ordereddict import OrderedDict
|
||||
try:
|
||||
from thread import get_ident
|
||||
except ImportError:
|
||||
try:
|
||||
from _thread import get_ident
|
||||
except ImportError:
|
||||
from _dummy_thread import get_ident
|
||||
|
||||
|
||||
def recursive_repr(fillvalue='...'):
|
||||
'Decorator to make a repr function return fillvalue for a recursive call'
|
||||
|
||||
def decorating_function(user_function):
|
||||
repr_running = set()
|
||||
|
||||
def wrapper(self):
|
||||
key = id(self), get_ident()
|
||||
if key in repr_running:
|
||||
return fillvalue
|
||||
repr_running.add(key)
|
||||
try:
|
||||
result = user_function(self)
|
||||
finally:
|
||||
repr_running.discard(key)
|
||||
return result
|
||||
|
||||
# Can't use functools.wraps() here because of bootstrap issues
|
||||
wrapper.__module__ = getattr(user_function, '__module__')
|
||||
wrapper.__doc__ = getattr(user_function, '__doc__')
|
||||
wrapper.__name__ = getattr(user_function, '__name__')
|
||||
wrapper.__annotations__ = getattr(user_function, '__annotations__', {})
|
||||
return wrapper
|
||||
|
||||
return decorating_function
|
||||
|
||||
|
||||
class ChainMap(MutableMapping):
|
||||
''' A ChainMap groups multiple dicts (or other mappings) together
|
||||
to create a single, updateable view.
|
||||
|
||||
The underlying mappings are stored in a list. That list is public and can
|
||||
accessed or updated using the *maps* attribute. There is no other state.
|
||||
|
||||
Lookups search the underlying mappings successively until a key is found.
|
||||
In contrast, writes, updates, and deletions only operate on the first
|
||||
mapping.
|
||||
|
||||
'''
|
||||
|
||||
def __init__(self, *maps):
|
||||
'''Initialize a ChainMap by setting *maps* to the given mappings.
|
||||
If no mappings are provided, a single empty dictionary is used.
|
||||
|
||||
'''
|
||||
self.maps = list(maps) or [{}] # always at least one map
|
||||
|
||||
def __missing__(self, key):
|
||||
raise KeyError(key)
|
||||
|
||||
def __getitem__(self, key):
|
||||
for mapping in self.maps:
|
||||
try:
|
||||
return mapping[key] # can't use 'key in mapping' with defaultdict
|
||||
except KeyError:
|
||||
pass
|
||||
return self.__missing__(key) # support subclasses that define __missing__
|
||||
|
||||
def get(self, key, default=None):
|
||||
return self[key] if key in self else default
|
||||
|
||||
def __len__(self):
|
||||
return len(set().union(*self.maps)) # reuses stored hash values if possible
|
||||
|
||||
def __iter__(self):
|
||||
return iter(set().union(*self.maps))
|
||||
|
||||
def __contains__(self, key):
|
||||
return any(key in m for m in self.maps)
|
||||
|
||||
@recursive_repr()
|
||||
def __repr__(self):
|
||||
return '{0.__class__.__name__}({1})'.format(
|
||||
self, ', '.join(map(repr, self.maps)))
|
||||
|
||||
@classmethod
|
||||
def fromkeys(cls, iterable, *args):
|
||||
'Create a ChainMap with a single dict created from the iterable.'
|
||||
return cls(dict.fromkeys(iterable, *args))
|
||||
|
||||
def copy(self):
|
||||
'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]'
|
||||
return self.__class__(self.maps[0].copy(), *self.maps[1:])
|
||||
|
||||
__copy__ = copy
|
||||
|
||||
def new_child(self): # like Django's Context.push()
|
||||
'New ChainMap with a new dict followed by all previous maps.'
|
||||
return self.__class__({}, *self.maps)
|
||||
|
||||
@property
|
||||
def parents(self): # like Django's Context.pop()
|
||||
'New ChainMap from maps[1:].'
|
||||
return self.__class__(*self.maps[1:])
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
self.maps[0][key] = value
|
||||
|
||||
def __delitem__(self, key):
|
||||
try:
|
||||
del self.maps[0][key]
|
||||
except KeyError:
|
||||
raise KeyError('Key not found in the first mapping: {!r}'.format(key))
|
||||
|
||||
def popitem(self):
|
||||
'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.'
|
||||
try:
|
||||
return self.maps[0].popitem()
|
||||
except KeyError:
|
||||
raise KeyError('No keys found in the first mapping.')
|
||||
|
||||
def pop(self, key, *args):
|
||||
'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].'
|
||||
try:
|
||||
return self.maps[0].pop(key, *args)
|
||||
except KeyError:
|
||||
raise KeyError('Key not found in the first mapping: {!r}'.format(key))
|
||||
|
||||
def clear(self):
|
||||
'Clear maps[0], leaving maps[1:] intact.'
|
||||
self.maps[0].clear()
|
||||
|
||||
|
||||
class MappingProxyType(UserDict):
|
||||
def __init__(self, data):
|
||||
UserDict.__init__(self)
|
||||
self.data = data
|
||||
|
||||
|
||||
def get_cache_token():
|
||||
return ABCMeta._abc_invalidation_counter
|
||||
|
||||
|
||||
|
||||
class Support(object):
|
||||
def dummy(self):
|
||||
pass
|
||||
|
||||
def cpython_only(self, func):
|
||||
if 'PyPy' in sys.version:
|
||||
return self.dummy
|
||||
return func
|
||||
Reference in New Issue
Block a user