Package: anys
GitHub|PyPI|Issues|Changeloganysprovides matchers forpytest-style assertions.  What’s a “matcher,”
you say?  Well, say you’re writing a unit test and you want to assert that a
given object contains the correct values.  Normally, you’d just write:assertfoo=={"widgets":42,"name":"Alice","subfoo":{"created_at":"2021-06-24T18:41:59Z","name":"Bob","widgets":23,}}But wait!  What if the value offoo["subfoo"]["created_at"]can’t be
determined in advance, but you still need to check that it’s a valid timestamp?
You’d have to compare everything infooother than that one field to the
expected values and then separately check the timestamp field for validity.
This is where matchers come in: they’re magic objects that compare equal to any
& all values that meet given criteria.  For the case above,anysallows you
to just write:fromanysimportANY_DATETIME_STRassertfoo=={"widgets":42,"name":"Alice","subfoo":{"created_at":ANY_DATETIME_STR,"name":"Bob","widgets":23,}}and the assertion will do what you mean.Installationanysrequires Python 3.7 or higher.  Just usepipfor Python 3 (You have pip, right?) to install it:python3 -m pip install anysAPIanysprovides the following classes & constants for matching against values
meeting certain criteria.  Matching is performed by comparing a value against
ananysmatcher with==, either directly or as a result of comparing
two larger structures with==.If a comparison raises aTypeErrororValueError(say, because you
evaluated42 ==AnyMatch(r'\d+'), which tries to match a regex against an
integer), the exception is suppressed, and the comparison evaluates toFalse; all other exceptions are propagated out.anysmatchers can be combined using the&operator to produce new
matchers that require both operands to succeed; for example,AnyGT(23) & AnyLT(42)will match any number between 23 and 42, exclusive, and nothing
else.anysmatchers can be combined using the|operator to produce new
matchers that require at least one of the operands to succeed; for example,ANY_INT | ANY_STRwill match any value that is anintor astr.ClassesNote that, unless stated otherwise,anysclass constructors cannot takeanysmatchers as arguments.AnyContains(key:Any,/)A matcher that matches any value for whichkey in valueis true.  Ifkeyis ananysmatcher,value == AnyContains(key)will instead be
evaluated by iterating through the elements ofvalueand checking whether
any matchkey.AnyFullmatch(pattern:Union[AnyStr,re.Pattern[AnyStr]],/)A matcher that matches any stringsfor whichre.fullmatch(pattern, s)succeedsAnyFunc(func:Callable,/)A matcher that matches any valuexfor whichfunc(x)is true.  Iffunc(x)raises aTypeErrororValueError, it will be suppressed,
andx == AnyFunc(func)will evaluate toFalse.  All other exceptions
are propagated out.AnyGE(bound:Any,/)A matcher that matches any value greater than or equal toboundAnyGT(bound:Any,/)A matcher that matches any value greater thanboundAnyIn(iterable:Iterable,/)A matcher that matches any value that equals or matches an element ofiterable(which may containanysmatchers).  Note that, ifiterableis a string, only individual characters in the string will match; to match
substrings, useAnySubstr()instead.AnyInstance(classinfo,/)A matcher that matches any value that is an instance ofclassinfo.classinfocan be either a type or a tuple of types (or, starting in Python
3.10, aUnionof types).A number of pre-composedAnyInstance()values are provided as constants for
your convenience; see “Constants” below.AnyLE(bound:Any,/)A matcher that matches any value less than or equal toboundAnyLT(bound:Any,/)A matcher that matches any value less thanboundAnyMatch(pattern:Union[AnyStr,re.Pattern[AnyStr]],/)A matcher that matches any stringsfor whichre.match(pattern, s)succeedsAnySearch(pattern:Union[AnyStr,re.Pattern[AnyStr]],/)A matcher that matches any stringsfor whichre.search(pattern, s)succeedsAnySubstr(s:AnyStr,/)A matcher that matches any substring ofsAnyWithAttrs(mapping:Mapping,/)A matcher that matches any objectobjsuch thatgetattr(obj, k) == vfor allk,vinmapping.items().The values (but not the keys) ofmappingcan beanysmatchers.AnyWithEntries(mapping:Mapping,/)A matcher that matches any objectobjsuch thatobj[k] == vfor allk,vinmapping.items().The values (but not the keys) ofmappingcan beanysmatchers.Maybe(arg:Any,/)A matcher that matchesNoneand any value that equals or matchesarg(which can be ananysmatcher)Not(arg:Any,/)A matcher that matches anything that does not equal or matcharg(which can
be ananysmatcher)ConstantsThe following constants match values of the given type:ANY_BOOLANY_BYTESANY_COMPLEXANY_DATE— Matchesdateinstances.  You may not be aware, butdatetimeis a subclass ofdate, and so this also matchesdatetimes.  If you only want to match actualdates, useANY_STRICT_DATE.ANY_DATETIMEANY_DICTANY_FLOATANY_INTANY_ITERABLEANY_ITERATORANY_LISTANY_MAPPINGANY_NUMBERANY_SEQUENCEANY_SETANY_STRANY_STRICT_DATE— Matches any instance ofdatethat is not an
instance ofdatetimeANY_TUPLEThe following constants matchaware or naïvedatetimeortimevalues:ANY_AWARE_DATETIMEANY_AWARE_TIMEANY_NAIVE_DATETIMEANY_NAIVE_TIMEThe following constants match ISO 8601-style date, time, & datetime strings.
“Aware” matchers require timezone information, while “naïve” matchers forbid
it.ANY_AWARE_DATETIME_STRANY_AWARE_TIME_STRANY_DATETIME_STRANY_DATE_STRANY_NAIVE_DATETIME_STRANY_NAIVE_TIME_STRANY_TIME_STROther constants:ANY_FALSY— Matches anything considered falseANY_TRUTHY— Matches anything considered trueNote: If you’re after a matcher that matches absolutely everything, Python
already provides that as theunittest.mock.ANYconstant.Caveat: Custom ClassesWhen a well-behaved class defines an__eq__method, it will only test
against values of the same class, returningNotImplementedfor other types,[1]which signals Python to evaluatex == yby instead callingy’s__eq__method.  Thus, when comparing ananysmatcher against an
instance of a well-behaved class, the matcher can be on either the left or the
right of the==.  All of the classes in the Python standard library are
well-behaved, as are classes that don’t define__eq__methods, but some
custom classes in third-party code are not well-behaved.  In order to
successfully compare ananysmatcher against an ill-behaved class, the
matcher must be on theleftside of the==operator; if it is on the
right, only the custom class’s__eq__method will be consulted, which
usually means that the comparison will always evaluate to false.[1]In order to work their magic,anysmatchers do not follow this rule,
and so they are not well-behaved.  “Do as I say, not as I do,” as they
say.