|
@ -34,6 +34,7 @@ import datetime |
|
|
from email.utils import parsedate_to_datetime |
|
|
from email.utils import parsedate_to_datetime |
|
|
import functools |
|
|
import functools |
|
|
from inspect import isawaitable as _isawaitable |
|
|
from inspect import isawaitable as _isawaitable |
|
|
|
|
|
from operator import attrgetter |
|
|
import json |
|
|
import json |
|
|
import re |
|
|
import re |
|
|
import warnings |
|
|
import warnings |
|
@ -247,19 +248,28 @@ def get(iterable, **attrs): |
|
|
Keyword arguments that denote attributes to search with. |
|
|
Keyword arguments that denote attributes to search with. |
|
|
""" |
|
|
""" |
|
|
|
|
|
|
|
|
def predicate(elem): |
|
|
# global -> local |
|
|
for attr, val in attrs.items(): |
|
|
_all = all |
|
|
nested = attr.split('__') |
|
|
attrget = attrgetter |
|
|
obj = elem |
|
|
|
|
|
for attribute in nested: |
|
|
# Special case the single element call |
|
|
obj = getattr(obj, attribute) |
|
|
if len(attrs) == 1: |
|
|
|
|
|
k, v = attrs.popitem() |
|
|
if obj != val: |
|
|
pred = attrget(k.replace('__', '.')) |
|
|
return False |
|
|
for elem in iterable: |
|
|
return True |
|
|
if pred(elem) == v: |
|
|
|
|
|
return elem |
|
|
|
|
|
return None |
|
|
|
|
|
|
|
|
return find(predicate, iterable) |
|
|
converted = [ |
|
|
|
|
|
(attrget(attr.replace('__', '.')), value) |
|
|
|
|
|
for attr, value in attrs.items() |
|
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
|
|
for elem in iterable: |
|
|
|
|
|
if _all(pred(elem) == value for pred, value in converted): |
|
|
|
|
|
return elem |
|
|
|
|
|
return None |
|
|
|
|
|
|
|
|
def _unique(iterable): |
|
|
def _unique(iterable): |
|
|
seen = set() |
|
|
seen = set() |
|
|