2023-07-31 14:18:28 +02:00
This rule raises an issue when operators ``++in++`` and ``++not in++`` are called with a right operand not supporting membership protocol.
2023-05-03 11:06:20 +02:00
== Why is this an issue?
2023-07-31 14:18:28 +02:00
Operators ``++in++`` and ``++not in++``, also called https://docs.python.org/3/reference/expressions.html#membership-test-operations["membership test operators"], require that the right operand supports the membership protocol.
2021-04-28 16:49:39 +02:00
2023-07-31 14:18:28 +02:00
In order to support the membership protocol, a user-defined class should implement at least one of the following methods: ``++__contains__++``, ``++__iter__++``, ``++__getitem__++``.
2021-04-28 16:49:39 +02:00
2023-07-31 14:18:28 +02:00
If none of these methods is implemented, a `TypeError` will be raised when performing a membership test.
2021-04-28 16:49:39 +02:00
2023-07-31 14:18:28 +02:00
== How to fix it
2021-04-28 16:49:39 +02:00
2023-07-31 14:18:28 +02:00
== Code examples
2021-04-28 18:08:03 +02:00
2023-05-03 11:06:20 +02:00
=== Noncompliant code example
2021-04-28 16:49:39 +02:00
2022-02-04 17:28:24 +01:00
[source,python]
2021-04-28 16:49:39 +02:00
----
myint = 42
2023-07-31 14:18:28 +02:00
if 42 in myint: # Noncompliant: integers don't support membership protocol
...
2021-04-28 16:49:39 +02:00
class A:
def __init__(self, values):
self._values = values
2023-07-31 14:18:28 +02:00
if "mystring" in A(["mystring"]): # Noncompliant: class A doesn't support membership protocol
...
2021-04-28 16:49:39 +02:00
----
2021-04-28 18:08:03 +02:00
2023-05-03 11:06:20 +02:00
=== Compliant solution
2021-04-28 16:49:39 +02:00
2022-02-04 17:28:24 +01:00
[source,python]
2021-04-28 16:49:39 +02:00
----
mylist = [42]
if 42 in mylist:
2023-07-31 14:18:28 +02:00
...
2021-04-28 16:49:39 +02:00
class MyContains:
def __init__(self, values):
self._values = values
def __contains__(self, value):
return value in self._values
2023-07-31 14:18:28 +02:00
if "mystring" in MyContains(["mystring"]):
...
2021-04-28 16:49:39 +02:00
# OR
class MyIterable:
def __init__(self, values):
self._values = values
def __iter__(self):
return iter(self._values)
2023-07-31 14:18:28 +02:00
if "mystring" in MyIterable(["mystring"]):
...
2021-04-28 16:49:39 +02:00
# OR
class MyGetItem:
def __init__(self, values):
self._values = values
def __getitem__(self, key):
return self._values[key]
2023-07-31 14:18:28 +02:00
if "mystring" in MyGetItem(["mystring"]):
...
2021-04-28 16:49:39 +02:00
----
2021-04-28 18:08:03 +02:00
2023-05-03 11:06:20 +02:00
== Resources
2021-04-28 16:49:39 +02:00
2023-07-31 14:18:28 +02:00
=== Documentation
* Python Documentation - https://docs.python.org/3/reference/expressions.html#membership-test-operations[Membership test operations]
2021-04-28 18:08:03 +02:00
2021-09-20 15:38:42 +02:00
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
2023-05-25 14:18:12 +02:00
=== Message
Change the type of X; type Y does not support membership protocol.
For an expression like "a in X" where X has type Y
=== Highlighting
Primary: The "in" or "not in" operator
Secondary: The operator's right operand
2021-09-20 15:38:42 +02:00
endif::env-github,rspecator-view[]