Skip to content

func-returns-value check is overly restrictive and prevents legitimate None-returning functions #19555

@kesha1225

Description

@kesha1225

MyPy's func-returns-value check is overly restrictive and breaks legitimate use cases

Problem

MyPy's func-returns-value error is being triggered for functions that legitimately need to return None explicitly, even when the return type annotation is correctly set to None. This check seems to assume that any assignment from a function call expects a meaningful value, which is not always the case.

Example

class TestObject:
    def get_none(self) -> None:
        return None

# This triggers: error: "get_none" of "TestObject" does not return a value (it only ever returns None)
none_value = obj.get_none()

Why This Check Is Problematic

  1. Legitimate use cases exist: Functions that return None are valid and necessary in many scenarios:

    • Factory methods that may fail and return None
    • Optional operations that may not produce a result
    • Functions that perform side effects and explicitly return None
    • API consistency where some methods in a family return values and others return None
  2. Type annotations are explicit: When I write -> None, I'm being explicit about the return type. The type checker should respect this annotation rather than second-guessing my design decisions.

  3. Assignment is still meaningful: Assigning the result of a None-returning function to a variable is valid Python and can be useful for:

    • Consistency in API usage patterns
    • Future refactoring flexibility
    • Explicit documentation of intent
    • Testing and debugging
  4. Forces unnecessary workarounds: This check forces developers to either:

    • Use # type: ignore comments (defeating the purpose of type checking)
    • Restructure valid code to appease the linter
    • Avoid explicit None returns where they would be clearer

Proposed Solution

The func-returns-value check should be removed or made significantly less aggressive. If a function is annotated with -> None and explicitly returns None, that should be considered valid and the assignment should not trigger an error.

Type checkers should focus on actual type safety issues, not on making assumptions about developer intent when the code is already properly typed.

Current Workaround

Currently, I have to litter my code with # type: ignore comments, which defeats the purpose of having a type checker in the first place:

none_value = obj.get_none()  # type: ignore

This is not a sustainable solution and reduces confidence in the type checking system overall.

Metadata

Metadata

Assignees

No one assigned

    Labels

    pendingIssues that may be closed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions