mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-08-14 10:36:57 -07:00
Bump cherrypy from 18.6.1 to 18.8.0 (#1796)
* Bump cherrypy from 18.6.1 to 18.8.0 Bumps [cherrypy](https://github.com/cherrypy/cherrypy) from 18.6.1 to 18.8.0. - [Release notes](https://github.com/cherrypy/cherrypy/releases) - [Changelog](https://github.com/cherrypy/cherrypy/blob/main/CHANGES.rst) - [Commits](https://github.com/cherrypy/cherrypy/compare/v18.6.1...v18.8.0) --- updated-dependencies: - dependency-name: cherrypy dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Update cherrypy==18.8.0 Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com>
This commit is contained in:
parent
e79da07973
commit
76cc56a215
75 changed files with 19150 additions and 1339 deletions
|
@ -143,7 +143,7 @@ class classproperty:
|
|||
return super().__setattr__(key, value)
|
||||
|
||||
def __init__(self, fget, fset=None):
|
||||
self.fget = self._fix_function(fget)
|
||||
self.fget = self._ensure_method(fget)
|
||||
self.fset = fset
|
||||
fset and self.setter(fset)
|
||||
|
||||
|
@ -158,14 +158,13 @@ class classproperty:
|
|||
return self.fset.__get__(None, owner)(value)
|
||||
|
||||
def setter(self, fset):
|
||||
self.fset = self._fix_function(fset)
|
||||
self.fset = self._ensure_method(fset)
|
||||
return self
|
||||
|
||||
@classmethod
|
||||
def _fix_function(cls, fn):
|
||||
def _ensure_method(cls, fn):
|
||||
"""
|
||||
Ensure fn is a classmethod or staticmethod.
|
||||
"""
|
||||
if not isinstance(fn, (classmethod, staticmethod)):
|
||||
return classmethod(fn)
|
||||
return fn
|
||||
needs_method = not isinstance(fn, (classmethod, staticmethod))
|
||||
return classmethod(fn) if needs_method else fn
|
||||
|
|
|
@ -63,7 +63,7 @@ class Projection(collections.abc.Mapping):
|
|||
return len(tuple(iter(self)))
|
||||
|
||||
|
||||
class DictFilter(object):
|
||||
class DictFilter(collections.abc.Mapping):
|
||||
"""
|
||||
Takes a dict, and simulates a sub-dict based on the keys.
|
||||
|
||||
|
@ -92,15 +92,21 @@ class DictFilter(object):
|
|||
...
|
||||
KeyError: 'e'
|
||||
|
||||
>>> 'e' in filtered
|
||||
False
|
||||
|
||||
Pattern is useful for excluding keys with a prefix.
|
||||
|
||||
>>> filtered = DictFilter(sample, include_pattern=r'(?![ace])')
|
||||
>>> dict(filtered)
|
||||
{'b': 2, 'd': 4}
|
||||
|
||||
Also note that DictFilter keeps a reference to the original dict, so
|
||||
if you modify the original dict, that could modify the filtered dict.
|
||||
|
||||
>>> del sample['d']
|
||||
>>> del sample['a']
|
||||
>>> filtered == {'b': 2, 'c': 3}
|
||||
True
|
||||
>>> filtered != {'b': 2, 'c': 3}
|
||||
False
|
||||
>>> dict(filtered)
|
||||
{'b': 2}
|
||||
"""
|
||||
|
||||
def __init__(self, dict, include_keys=[], include_pattern=None):
|
||||
|
@ -120,29 +126,18 @@ class DictFilter(object):
|
|||
|
||||
@property
|
||||
def include_keys(self):
|
||||
return self.specified_keys.union(self.pattern_keys)
|
||||
|
||||
def keys(self):
|
||||
return self.include_keys.intersection(self.dict.keys())
|
||||
|
||||
def values(self):
|
||||
return map(self.dict.get, self.keys())
|
||||
return self.specified_keys | self.pattern_keys
|
||||
|
||||
def __getitem__(self, i):
|
||||
if i not in self.include_keys:
|
||||
raise KeyError(i)
|
||||
return self.dict[i]
|
||||
|
||||
def items(self):
|
||||
keys = self.keys()
|
||||
values = map(self.dict.get, keys)
|
||||
return zip(keys, values)
|
||||
def __iter__(self):
|
||||
return filter(self.include_keys.__contains__, self.dict.keys())
|
||||
|
||||
def __eq__(self, other):
|
||||
return dict(self) == other
|
||||
|
||||
def __ne__(self, other):
|
||||
return dict(self) != other
|
||||
def __len__(self):
|
||||
return len(list(self))
|
||||
|
||||
|
||||
def dict_map(function, dictionary):
|
||||
|
@ -167,7 +162,7 @@ class RangeMap(dict):
|
|||
the sorted list of keys.
|
||||
|
||||
One may supply keyword parameters to be passed to the sort function used
|
||||
to sort keys (i.e. cmp [python 2 only], keys, reverse) as sort_params.
|
||||
to sort keys (i.e. key, reverse) as sort_params.
|
||||
|
||||
Let's create a map that maps 1-3 -> 'a', 4-6 -> 'b'
|
||||
|
||||
|
@ -220,6 +215,23 @@ class RangeMap(dict):
|
|||
|
||||
>>> r.get(7, 'not found')
|
||||
'not found'
|
||||
|
||||
One often wishes to define the ranges by their left-most values,
|
||||
which requires use of sort params and a key_match_comparator.
|
||||
|
||||
>>> r = RangeMap({1: 'a', 4: 'b'},
|
||||
... sort_params=dict(reverse=True),
|
||||
... key_match_comparator=operator.ge)
|
||||
>>> r[1], r[2], r[3], r[4], r[5], r[6]
|
||||
('a', 'a', 'a', 'b', 'b', 'b')
|
||||
|
||||
That wasn't nearly as easy as before, so an alternate constructor
|
||||
is provided:
|
||||
|
||||
>>> r = RangeMap.left({1: 'a', 4: 'b', 7: RangeMap.undefined_value})
|
||||
>>> r[1], r[2], r[3], r[4], r[5], r[6]
|
||||
('a', 'a', 'a', 'b', 'b', 'b')
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, source, sort_params={}, key_match_comparator=operator.le):
|
||||
|
@ -227,6 +239,12 @@ class RangeMap(dict):
|
|||
self.sort_params = sort_params
|
||||
self.match = key_match_comparator
|
||||
|
||||
@classmethod
|
||||
def left(cls, source):
|
||||
return cls(
|
||||
source, sort_params=dict(reverse=True), key_match_comparator=operator.ge
|
||||
)
|
||||
|
||||
def __getitem__(self, item):
|
||||
sorted_keys = sorted(self.keys(), **self.sort_params)
|
||||
if isinstance(item, RangeMap.Item):
|
||||
|
@ -261,7 +279,7 @@ class RangeMap(dict):
|
|||
return (sorted_keys[RangeMap.first_item], sorted_keys[RangeMap.last_item])
|
||||
|
||||
# some special values for the RangeMap
|
||||
undefined_value = type(str('RangeValueUndefined'), (object,), {})()
|
||||
undefined_value = type(str('RangeValueUndefined'), (), {})()
|
||||
|
||||
class Item(int):
|
||||
"RangeMap Item"
|
||||
|
@ -370,7 +388,7 @@ class FoldedCaseKeyedDict(KeyTransformingDict):
|
|||
True
|
||||
>>> 'HELLO' in d
|
||||
True
|
||||
>>> print(repr(FoldedCaseKeyedDict({'heLlo': 'world'})).replace("u'", "'"))
|
||||
>>> print(repr(FoldedCaseKeyedDict({'heLlo': 'world'})))
|
||||
{'heLlo': 'world'}
|
||||
>>> d = FoldedCaseKeyedDict({'heLlo': 'world'})
|
||||
>>> print(d['hello'])
|
||||
|
@ -433,7 +451,7 @@ class FoldedCaseKeyedDict(KeyTransformingDict):
|
|||
return jaraco.text.FoldedCase(key)
|
||||
|
||||
|
||||
class DictAdapter(object):
|
||||
class DictAdapter:
|
||||
"""
|
||||
Provide a getitem interface for attributes of an object.
|
||||
|
||||
|
@ -452,7 +470,7 @@ class DictAdapter(object):
|
|||
return getattr(self.object, name)
|
||||
|
||||
|
||||
class ItemsAsAttributes(object):
|
||||
class ItemsAsAttributes:
|
||||
"""
|
||||
Mix-in class to enable a mapping object to provide items as
|
||||
attributes.
|
||||
|
@ -561,7 +579,7 @@ class IdentityOverrideMap(dict):
|
|||
return key
|
||||
|
||||
|
||||
class DictStack(list, collections.abc.Mapping):
|
||||
class DictStack(list, collections.abc.MutableMapping):
|
||||
"""
|
||||
A stack of dictionaries that behaves as a view on those dictionaries,
|
||||
giving preference to the last.
|
||||
|
@ -578,11 +596,12 @@ class DictStack(list, collections.abc.Mapping):
|
|||
>>> stack.push(dict(a=3))
|
||||
>>> stack['a']
|
||||
3
|
||||
>>> stack['a'] = 4
|
||||
>>> set(stack.keys()) == set(['a', 'b', 'c'])
|
||||
True
|
||||
>>> set(stack.items()) == set([('a', 3), ('b', 2), ('c', 2)])
|
||||
>>> set(stack.items()) == set([('a', 4), ('b', 2), ('c', 2)])
|
||||
True
|
||||
>>> dict(**stack) == dict(stack) == dict(a=3, c=2, b=2)
|
||||
>>> dict(**stack) == dict(stack) == dict(a=4, c=2, b=2)
|
||||
True
|
||||
>>> d = stack.pop()
|
||||
>>> stack['a']
|
||||
|
@ -593,6 +612,9 @@ class DictStack(list, collections.abc.Mapping):
|
|||
>>> stack.get('b', None)
|
||||
>>> 'c' in stack
|
||||
True
|
||||
>>> del stack['c']
|
||||
>>> dict(stack)
|
||||
{'a': 1}
|
||||
"""
|
||||
|
||||
def __iter__(self):
|
||||
|
@ -613,6 +635,18 @@ class DictStack(list, collections.abc.Mapping):
|
|||
def __len__(self):
|
||||
return len(list(iter(self)))
|
||||
|
||||
def __setitem__(self, key, item):
|
||||
last = list.__getitem__(self, -1)
|
||||
return last.__setitem__(key, item)
|
||||
|
||||
def __delitem__(self, key):
|
||||
last = list.__getitem__(self, -1)
|
||||
return last.__delitem__(key)
|
||||
|
||||
# workaround for mypy confusion
|
||||
def pop(self, *args, **kwargs):
|
||||
return list.pop(self, *args, **kwargs)
|
||||
|
||||
|
||||
class BijectiveMap(dict):
|
||||
"""
|
||||
|
@ -855,7 +889,7 @@ class Enumeration(ItemsAsAttributes, BijectiveMap):
|
|||
return (self[name] for name in self.names)
|
||||
|
||||
|
||||
class Everything(object):
|
||||
class Everything:
|
||||
"""
|
||||
A collection "containing" every possible thing.
|
||||
|
||||
|
@ -896,7 +930,7 @@ class InstrumentedDict(collections.UserDict): # type: ignore # buggy mypy
|
|||
self.data = data
|
||||
|
||||
|
||||
class Least(object):
|
||||
class Least:
|
||||
"""
|
||||
A value that is always lesser than any other
|
||||
|
||||
|
@ -928,7 +962,7 @@ class Least(object):
|
|||
__gt__ = __ge__
|
||||
|
||||
|
||||
class Greatest(object):
|
||||
class Greatest:
|
||||
"""
|
||||
A value that is always greater than any other
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ class FoldedCase(str):
|
|||
>>> s in ["Hello World"]
|
||||
True
|
||||
|
||||
You may test for set inclusion, but candidate and elements
|
||||
Allows testing for set inclusion, but candidate and elements
|
||||
must both be folded.
|
||||
|
||||
>>> FoldedCase("Hello World") in {s}
|
||||
|
@ -92,37 +92,40 @@ class FoldedCase(str):
|
|||
|
||||
>>> FoldedCase('hello') > FoldedCase('Hello')
|
||||
False
|
||||
|
||||
>>> FoldedCase('ß') == FoldedCase('ss')
|
||||
True
|
||||
"""
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.lower() < other.lower()
|
||||
return self.casefold() < other.casefold()
|
||||
|
||||
def __gt__(self, other):
|
||||
return self.lower() > other.lower()
|
||||
return self.casefold() > other.casefold()
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.lower() == other.lower()
|
||||
return self.casefold() == other.casefold()
|
||||
|
||||
def __ne__(self, other):
|
||||
return self.lower() != other.lower()
|
||||
return self.casefold() != other.casefold()
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.lower())
|
||||
return hash(self.casefold())
|
||||
|
||||
def __contains__(self, other):
|
||||
return super().lower().__contains__(other.lower())
|
||||
return super().casefold().__contains__(other.casefold())
|
||||
|
||||
def in_(self, other):
|
||||
"Does self appear in other?"
|
||||
return self in FoldedCase(other)
|
||||
|
||||
# cache lower since it's likely to be called frequently.
|
||||
# cache casefold since it's likely to be called frequently.
|
||||
@method_cache
|
||||
def lower(self):
|
||||
return super().lower()
|
||||
def casefold(self):
|
||||
return super().casefold()
|
||||
|
||||
def index(self, sub):
|
||||
return self.lower().index(sub.lower())
|
||||
return self.casefold().index(sub.casefold())
|
||||
|
||||
def split(self, splitter=' ', maxsplit=0):
|
||||
pattern = re.compile(re.escape(splitter), re.I)
|
||||
|
@ -277,7 +280,7 @@ class WordSet(tuple):
|
|||
>>> WordSet.parse("myABCClass")
|
||||
('my', 'ABC', 'Class')
|
||||
|
||||
The result is a WordSet, so you can get the form you need.
|
||||
The result is a WordSet, providing access to other forms.
|
||||
|
||||
>>> WordSet.parse("myABCClass").underscore_separated()
|
||||
'my_ABC_Class'
|
||||
|
@ -598,3 +601,22 @@ def join_continuation(lines):
|
|||
except StopIteration:
|
||||
return
|
||||
yield item
|
||||
|
||||
|
||||
def read_newlines(filename, limit=1024):
|
||||
r"""
|
||||
>>> tmp_path = getfixture('tmp_path')
|
||||
>>> filename = tmp_path / 'out.txt'
|
||||
>>> _ = filename.write_text('foo\n', newline='')
|
||||
>>> read_newlines(filename)
|
||||
'\n'
|
||||
>>> _ = filename.write_text('foo\r\n', newline='')
|
||||
>>> read_newlines(filename)
|
||||
'\r\n'
|
||||
>>> _ = filename.write_text('foo\r\nbar\nbing\r', newline='')
|
||||
>>> read_newlines(filename)
|
||||
('\r', '\n', '\r\n')
|
||||
"""
|
||||
with open(filename) as fp:
|
||||
fp.read(limit)
|
||||
return fp.newlines
|
||||
|
|
25
lib/jaraco/text/layouts.py
Normal file
25
lib/jaraco/text/layouts.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
qwerty = "-=qwertyuiop[]asdfghjkl;'zxcvbnm,./_+QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>?"
|
||||
dvorak = "[]',.pyfgcrl/=aoeuidhtns-;qjkxbmwvz{}\"<>PYFGCRL?+AOEUIDHTNS_:QJKXBMWVZ"
|
||||
|
||||
|
||||
to_dvorak = str.maketrans(qwerty, dvorak)
|
||||
to_qwerty = str.maketrans(dvorak, qwerty)
|
||||
|
||||
|
||||
def translate(input, translation):
|
||||
"""
|
||||
>>> translate('dvorak', to_dvorak)
|
||||
'ekrpat'
|
||||
>>> translate('qwerty', to_qwerty)
|
||||
'x,dokt'
|
||||
"""
|
||||
return input.translate(translation)
|
||||
|
||||
|
||||
def _translate_stream(stream, translation):
|
||||
"""
|
||||
>>> import io
|
||||
>>> _translate_stream(io.StringIO('foo'), to_dvorak)
|
||||
urr
|
||||
"""
|
||||
print(translate(stream.read(), translation))
|
33
lib/jaraco/text/show-newlines.py
Normal file
33
lib/jaraco/text/show-newlines.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
import autocommand
|
||||
import inflect
|
||||
|
||||
from more_itertools import always_iterable
|
||||
|
||||
import jaraco.text
|
||||
|
||||
|
||||
def report_newlines(filename):
|
||||
r"""
|
||||
Report the newlines in the indicated file.
|
||||
|
||||
>>> tmp_path = getfixture('tmp_path')
|
||||
>>> filename = tmp_path / 'out.txt'
|
||||
>>> _ = filename.write_text('foo\nbar\n', newline='')
|
||||
>>> report_newlines(filename)
|
||||
newline is '\n'
|
||||
>>> filename = tmp_path / 'out.txt'
|
||||
>>> _ = filename.write_text('foo\nbar\r\n', newline='')
|
||||
>>> report_newlines(filename)
|
||||
newlines are ('\n', '\r\n')
|
||||
"""
|
||||
newlines = jaraco.text.read_newlines(filename)
|
||||
count = len(tuple(always_iterable(newlines)))
|
||||
engine = inflect.engine()
|
||||
print(
|
||||
engine.plural_noun("newline", count),
|
||||
engine.plural_verb("is", count),
|
||||
repr(newlines),
|
||||
)
|
||||
|
||||
|
||||
autocommand.autocommand(__name__)(report_newlines)
|
6
lib/jaraco/text/to-dvorak.py
Normal file
6
lib/jaraco/text/to-dvorak.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
import sys
|
||||
|
||||
from . import layouts
|
||||
|
||||
|
||||
__name__ == '__main__' and layouts._translate_stream(sys.stdin, layouts.to_dvorak)
|
6
lib/jaraco/text/to-qwerty.py
Normal file
6
lib/jaraco/text/to-qwerty.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
import sys
|
||||
|
||||
from . import layouts
|
||||
|
||||
|
||||
__name__ == '__main__' and layouts._translate_stream(sys.stdin, layouts.to_qwerty)
|
Loading…
Add table
Add a link
Reference in a new issue