rspec/rules/S5886/python/rule.adoc
2023-08-03 10:58:37 +02:00

81 lines
2.5 KiB
Plaintext

This rule raises an issue when a function or method returns a value that contradicts its type hint.
== Why is this an issue?
Developers can use type hints to specify which type a function is expected to return. Doing so improves maintainability since it clarifies the contract of the function, making it easier to use and understand.
When annotating a function with a specific type hint, it is expected that the returned value matches the type specified in the hint.
If the type hint specifies a class or a named type, then the value returned should be an instance of that class or type. If the type hint specifies a structural type, then the value returned should have the same structure as the type hint.
In the following example, while `Bucket` does not directly inherit from `Iterable`, it does implement the `Iterable` protocol thanks to its ``++__iter__++`` method and can therefore be used as a valid `Iterable` return type.
[source,python]
----
from collections.abc import Iterator, Iterable
class Bucket: # Note: no base classes
...
def __len__(self) -> int: ...
def __iter__(self) -> Iterator[int]: ...
def collect() -> Iterable: return Bucket()
----
Since type annotations are not enforced at runtime, returning a completely different type might not fail. It is however likely to be unintended and will lead to maintainability issues, if not bugs.
== How to fix it
=== Code examples
To fix this issue, make sure that the returned value of your function is compatible with its type hint.
==== Noncompliant code example
[source,python,diff-id=1,diff-type=noncompliant]
----
def hello() -> str:
return 42 # Noncompliant: Function's type hint asks for a string return value
----
==== Compliant solution
[source,python,diff-id=1,diff-type=compliant]
----
def hello() -> str:
return "Hello"
----
== Resources
=== Documentation
* Python documentation - https://docs.python.org/3/library/typing.html[Support for type hints]
* PEP 544 - https://peps.python.org/pep-0544/[Protocols: Structural subtyping (static duck typing)]
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
=== Message
*Return a "XXX" instead of a "YYY" or update function "ZZZ" type hint.
=== Highlighting
* If the function returns the wrong type:
** Primary: The return statement
** Secondaries: 1. the function name, 2. The type hint
* If the function might terminate without reaching a return statement:
** Primary Location: The function name
** Secondary: the type hint
endif::env-github,rspecator-view[]