def fetch_samples(proj, selector_attribute=None, selector_include=None, selector_exclude=None):
if selector_attribute is None or (not selector_include and not selector_exclude):<EOL><INDENT>return list(proj.samples)<EOL><DEDENT>if proj.samples and not any([hasattr(i, selector_attribute) for i in proj.samples]):<EOL><INDENT>raise AttributeError("<STR_LIT>"<EOL>.format(attr=selector_attribute))<EOL><DEDENT>if selector_include and selector_exclude:<EOL><INDENT>raise TypeError("<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>def make_set(items):<EOL><INDENT>if isinstance(items, str):<EOL><INDENT>items = [items]<EOL><DEDENT>return items<EOL><DEDENT>if not selector_include:<EOL><INDENT>def keep(s):<EOL><INDENT>return not hasattr(s, selector_attribute) orgetattr(s, selector_attribute) not in make_set(selector_exclude)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>def keep(s):<EOL><INDENT>return hasattr(s, selector_attribute) andgetattr(s, selector_attribute) in make_set(selector_include)<EOL><DEDENT><DEDENT>return list(filter(keep, proj.samples))<EOL>
Collect samples of particular protocol(s).

Protocols can't be both positively selected for and negatively
selected against. That is, it makes no sense and is not allowed to
specify both selector_include and selector_exclude protocols. On the other hand, if
neither is provided, all of the Project's Samples are returned.
If selector_include is specified, Samples without a protocol will be excluded,
but if selector_exclude is specified, protocol-less Samples will be included.

:param Project proj: the Project with Samples to fetch
:param Project str: the sample selector_attribute to select for
:param Iterable[str] | str selector_include: protocol(s) of interest;
    if specified, a Sample must
:param Iterable[str] | str selector_exclude: protocol(s) to include
:return list[Sample]: Collection of this Project's samples with
    protocol that either matches one of those in selector_include, or either
    lacks a protocol or does not match one of those in selector_exclude
:raise TypeError: if both selector_include and selector_exclude protocols are
    specified; TypeError since it's basically providing two arguments
    when only one is accepted, so remain consistent with vanilla Python2