124 lines
3.6 KiB
Plaintext
124 lines
3.6 KiB
Plaintext
This rule raises an issue when an item operation is performed on an object which doesn't have the corresponding method.
|
|
|
|
== Why is this an issue?
|
|
|
|
:link-with-uscores1: https://docs.python.org/3/reference/datamodel.html#object.__getitem__
|
|
:link-with-uscores2: https://docs.python.org/3/reference/datamodel.html#object.__class_getitem__
|
|
:link-with-uscores3: https://docs.python.org/3/reference/datamodel.html#object.__setitem__
|
|
:link-with-uscores4: https://docs.python.org/3/reference/datamodel.html#object.__delitem__
|
|
|
|
Getting, setting and deleting items using square brackets requires the accessed object to have special methods:
|
|
|
|
* Getting items such as ``++my_variable[key]++`` requires ``++my_variable++`` to have the {link-with-uscores1}[``++__getitem__++``] method, or the {link-with-uscores2}[``++__class_getitem__++``] method if ``++my_variable++`` is a class.
|
|
* Setting items such as ``++my_variable[key] = 42++`` requires ``++my_variable++`` to have the {link-with-uscores3}[``++__setitem__++``] method.
|
|
* Deleting items such as ``++del my_variable[key]++`` requires ``++my_variable++`` to have the {link-with-uscores4}[``++__delitem__++``] method.
|
|
|
|
Performing these operations on an object that doesn't have the corresponding method will result in a `TypeError`.
|
|
|
|
To fix this issue, make sure that the class for which you are trying to perform item operations implements the required methods.
|
|
|
|
=== Code examples
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,python]
|
|
----
|
|
del (1, 2)[0] # Noncompliant: tuples are immutable
|
|
(1, 2)[0] = 42 # Noncompliant
|
|
(1, 2)[0]
|
|
|
|
class A:
|
|
def __init__(self, values):
|
|
self._values = values
|
|
|
|
a = A([0,1,2])
|
|
|
|
a[0] # Noncompliant
|
|
del a[0] # Noncompliant
|
|
a[0] = 42 # Noncompliant
|
|
|
|
class B:
|
|
pass
|
|
|
|
B[0] # Noncompliant
|
|
----
|
|
|
|
|
|
==== Compliant solution
|
|
|
|
[source,python]
|
|
----
|
|
del [1, 2][0] # Lists are mutable
|
|
[1, 2][0] = 42
|
|
[1, 2][0]
|
|
|
|
class A:
|
|
def __init__(self, values):
|
|
self._values = values
|
|
|
|
def __getitem__(self, key):
|
|
return self._values[key]
|
|
|
|
def __setitem__(self, key, value):
|
|
self._values[key] = value
|
|
|
|
def __delitem__(self, key):
|
|
del self._values[key]
|
|
|
|
a = A([0,1,2])
|
|
|
|
a[0]
|
|
del a[0]
|
|
a[0] = 42
|
|
|
|
class B:
|
|
def __class_getitem__(cls, key):
|
|
return [0, 1, 2, 3][key]
|
|
|
|
B[0]
|
|
----
|
|
|
|
|
|
:link-with-uscores1: https://docs.python.org/3/reference/datamodel.html#object.__getitem__
|
|
:link-with-uscores2: https://docs.python.org/3/reference/datamodel.html#object.__setitem__
|
|
:link-with-uscores3: https://docs.python.org/3/reference/datamodel.html#object.__delitem__
|
|
:link-with-uscores4: https://docs.python.org/3/reference/datamodel.html#object.__class_getitem__
|
|
|
|
== Resources
|
|
|
|
=== Documentation
|
|
|
|
* {link-with-uscores1}[Python documentation - ++__getitem__++ method]
|
|
* {link-with-uscores2}[Python documentation - ++__setitem__++ method]
|
|
* {link-with-uscores3}[Python documentation - ++__delitem__++ method]
|
|
* {link-with-uscores4}[Python documentation - ++__class_getitem__++ method]
|
|
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
|
|
'''
|
|
== Implementation Specification
|
|
(visible only on this page)
|
|
|
|
=== Message
|
|
|
|
* Fix this code; "X" does not have a "__getitem__" method.
|
|
* Fix this code; "X" does not have a "__setitem__" method.
|
|
* Fix this code; "X" does not have a "__delitem__" method.
|
|
* Fix this code; class "Y" does not have a "__class_getitem__" method.
|
|
|
|
|
|
=== Highlighting
|
|
|
|
Primary: The variable before the "["
|
|
|
|
* Secondary 1 (if the call is made on a variable)
|
|
** location: The last value assigned.
|
|
** message: "Assigned value."
|
|
* Secondary 2
|
|
** location: The class/function/... definition
|
|
** message: 'Definition of \"``++X++``".'
|
|
|
|
|
|
endif::env-github,rspecator-view[]
|