*Currently, the `in` operator (also known as `__contains__`) always uses the rightmost argument's implementation.*
*For example,* > * status = obj in "xylophone" * > *Is similar to:* * status = "xylophone".__contains__( obj )* *The current implementation of `__contains__` is similar to the way that `+` used to only look to the leftmost argument for implementation. * * total = 4 + obj* > > * total = int.__add__(4, obj)* > *However, these days, `__radd__` gives us the following:* * try:* > * total = type(4).__add__(4, obj)* > * except NotImplementedError:* > > * total = type(obj).__radd__(obj, 4) * > *We propose something similar for `__contains__`: That a new dunder/magic method `__lcontains__` be created and that the `in` operator be implemented similarly to the following:* * # IMPLEMENTATION OF* > > * # status = obj in "xylophone"`* > * try:* > * status = "xylophone".__contains__(obj)* > * except NotImplementedError:* > > * status = False * > > > > > > > > > > > > > > > > * if not status: try: status = > obj.__lcontains__(“xylophone”) except AttributeError: # type(obj) > does not have an `__lcontains__` method with io.StringIO() as > string_stream: print( "unsupported operand > type(s) for `in`:", repr(type(4).__name__), > "and", repr(type(obj).__name__), > file=string_stream ) msg = string_stream.getvalue() > raise TypeError(msg) from None* > *The proposed enhancement would be backwards compatible except in the event that a user already wrote a class having an `__lcontains__` method.* * With our running example of the string “xylophone”, writers of user-defined classes would be able to decide whether their objects are elements of “xylophone” or not. Programmer would do this by writing an `__lcontains__` method.* *As an example application, one might develope a tree in which each node represents a string (the strings being unique within the tree). A property of the tree might be that node `n` is a descendant of node `m` if and only if `n` is a sub-string of `m`. For example the string "yell" is a descendant of "yellow." We might want the root node of the tree to be a special object, `root` such that every string is in `root` and that `root` is in no string. That is, the code `root in "yellow"` should return `False`. If ` __lcontains__ ` were implemented, then we could implement the node as follows:* > > > *class RootNode(Node): * > > * def __contains__(container, element):* > > > * return True * > > * def __lcontains__(element, container):* > > * return False* >
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/X2VCWCBJZABPWJH5LNMYPODZKNM7UZML/ Code of Conduct: http://python.org/psf/codeofconduct/