:link-with-uscores1: https://docs.python.org/3/reference/datamodel.html#object.__len__

The {link-with-uscores1}[``++__len__++``] special method enables to define the length of an object. As such it should always return an integer greater than or equal to 0. When the ``++len(...)++`` builtin is called on an object, any other return type will raise a ``++TypeError++`` and a negative integer will raise a ``++ValueError++``.


This rule raises an issue when a ``++__len__++`` method returns an expression which is not an integer greater than or equal to 0.


== Noncompliant Code Example

----
class A:
    def __len__(self):
        return 2.0  # Noncompliant

len(A())  # This will raise "TypeError: 'float' object cannot be interpreted as an integer"

class B:
    def __len__(self):
        return -2  # Noncompliant

len(B())  # This will raise "ValueError: __len__() should return >= 0"
----


== Compliant Solution

----
class A:
    def __len__(self):
        return 2

len(A())  # This will return 2
----


:link-with-uscores1: https://docs.python.org/3/reference/datamodel.html#object.__index__

== Exceptions

This rule raises no issue when the type returned by ``++__len__++`` is a class implementing the {link-with-uscores1}[``++__index__++``] special method.


----
class Ind:
    def __index__(self):
        return 3

class A:
    def __len__(self):
        return Ind()

len(A())  # This will return 3
----

ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

include::message.adoc[]

include::highlighting.adoc[]

endif::env-github,rspecator-view[]
