Skip to content

0.990 reports error for function with body that is just ellipsis #14048

Closed

Description

@haxtibal

mypy 0.990 (python 3.8) reports an error for the following source code

def foo() -> int:
    ...
$ mypy foo.py 
/tmp/foo.py:1: error: Missing return statement  [empty-body]
Found 1 error in 1 file (checked 1 source file)

mypy 0.981 would let the same code pass. Was that an intended change in between, or a regression?

From mypy CLI documentation

By default, mypy will generate errors when a function is missing return statements in some execution paths. The only exceptions are when:

  • The function has a None or Any return type
  • The function has an empty body or a body that is just ellipsis (...). Empty functions are often used for abstract methods.

I'd expect Success for the given example, because the 2nd exception ("body that is just ellipsis") applies.

Activity

  1. changed the title [-]0.990 reports [/-] [+]0.990 reports error for function with body that is just ellipsis[/+] on Nov 9, 2022
  2. JukkaL commented on Nov 9, 2022

    @JukkaL
    Collaborator

    This was an intentional change in 0.990 and the special casing for ... bodies was mostly removed (#13729). The documentation seems to be now out of date.

  3. JukkaL commented on Nov 9, 2022

    @JukkaL
    Collaborator
  4. ilevkivskyi commented on Nov 9, 2022

    @ilevkivskyi
    Member

    Yep, I will update the docs. Now you need --allow-empty-bodies if you want old behavior (or disable empty-body error code in your mypy config)

  5. haxtibal commented on Nov 9, 2022

    @haxtibal
    Author

    Thank's for clarifying.

    Now you need --allow-empty-bodies if you want old behavior

    I'm unsure if I want the old behavior🤔 Actually I was ever in doubt if the way I used such ... stubs was good practice. If you have a minute left, would you consider this pseudo code:

    class FooStub:
        # Serves as means to check calls to use_generated_foo() with mypy
    
        def bar() -> int:
            ...
    
    class GeneratedFoo(RuntimeAttrGen, FooStub):
        # Attributes made available at runtime, according to external spec.
        # I control the spec and therefore know what methods and attributes will be available,    
        # but can't hardcode implementations here.
        pass
    
    
    def use_generated_foo(x: FooStub)
        x.bar()

    Would you recommend another approach for type checking such runtime-determined types? E.g., I'd rather avoid deriving from FooStub in favor of structural subtyping. But then I don't know how to associate GeneratedFoo with attributes and methods as in FooStub.

  6. ilevkivskyi commented on Nov 9, 2022

    @ilevkivskyi
    Member

    IIUC the situation, my personal preference would be to replace ... with raise AttributeNotGeneratedError. This way if empty stub is used accidentally, you will know immediately, instead of discovering random None somewhere down the call stack.

  7. ilevkivskyi commented on Nov 9, 2022

    @ilevkivskyi
    Member

    To clarify, mypy will also not complain about this.

  8. added
    pendingIssues that may be closed
    and removed
    pendingIssues that may be closed
    on Nov 10, 2022
  9. added a commit that references this issue on Nov 11, 2022
    70e544b
  10. added a commit that references this issue on Nov 11, 2022
    1650ae0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions