You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
(🎁) Flag to make default return type None instead of Any #9413
Most other languages(Kotlin, Rust, Swift etc) have a void(or equivalent) return type by default. Can an option be added to have an implicit None return type.
deffoo(): # implicit Noneprint("hi")
🆕 Update
Basedmypy 1.3 supports this functionality with the --default-return flag.
I think that this could be a useful feature, but perhaps only when --check-untyped-defs or --disallow-untyped-defs is enabled, as otherwise def foo(): would be ambiguous -- it's unclear if we should type check the body.
There is a problem when using --check-untyped-defs, as we should only give def foo(): an implicit None return type if there is no return statement with an explicit value in the body. This would be a bit dangerous however, as any return statement with a value would turn the return type into Any. So maybe this should only be allowed with --disallow-untyped-defs?
Unit tests, in particular, could benefit from this, since there tend to be a lot of functions like def test_foo(...) -> None.
Additionally, maybe an explicit None return type should be an error in this mode, as otherwise it could look confusing (or at least inconsistent). We could give this error a dedicated error code so that it would be possible to disable the message, however.
Maybe name the flag --default-none-return and if enabled then def foo(): would then be considered a typed def and should be checked regardless of whether --check-untyped-defs is selected.
I would think an explicit none return type in this mode should be a warning.
I don't know. Maybe I'm just too spoiled by the fact that return None, return and implicit return do exactly the same thing, but it feels just wrong to add -> None to a function that doesn't actually have a return None statement. For me it feels natural that functions that don't have a return type annotation should be considered as retuning None, because that's what happens if a function doesn't have a return statement.
Reacted by Matthew Gamble, Bogdan Opanchuk, Diddi Oskarsson, Oboleninov Anton, Eternal Sorrow, John Hennig, Jack McIvor, Lionel Peer, peter-goldstein, buster-blue and 5 more
I would not want it to be inferred. I would like this to give me an error:
but why?
Because it may not be obvious to a human reader what the expected return type is. It's one thing to have mypy infer the return type by looking at what's being returned, it's a completely different thing for a human to do the same. In the example of returning a single integer that's easy enough of course, but chained function calls or objects are less obvious.
By being explicit with what you want to return you are also reducing risk for bugs and it makes refactoring and team work much easier. And yes I do consider not writing a return type to be just as explicit as writing -> None. It makes sense that when you look at a function that doesn't have a return type it's because it doesn't return anything.
I am very much in favor of having a flag that enables this behavior as I find myself writing -> None a lot in unit tests etc. which will never return anything. It just feels redundant to have it there.
Reacted by Bogdan Opanchuk, Eternal Sorrow, Matthew Gamble, Sean Löfgren, John Hennig, Doug Hoskisson, Matt Richards, buster-blue and kikones34
changed the title [-]Flag to make default return type None instead of Any[/-][+]Flag to make default return type `None` instead of `Any`[/+]on Oct 5, 2022
I'll bring a counterproposal from my (closed as duplicate) issue #14180, which I'll copy here for convenience.
I seem to understand that all arguments against the proposal have to do with it potentially being unexpected as a default behaviour (and it would definitely be something of a breaking change for anyone who already adopts mypy and doesn't enable disallow_untyped_defs). My proposal includes the behaviour only behind a flag, which would make the feature opt-in and thus not a problem for current adopters anymore. Please see the full proposal below:
Feature
Behind a config flag like untyped_return_type_is_none = true, Mypy assumes that a function with no return type, e.g.:
defmy_func(i_am_annotated: str): # Note: no "-> int" annotationreturn5
Returns None, instead of accepting any return type at face value.
Additionally, while untyped_return_type_is_none is true, disallow_untyped_defs allows functions to have no return annotation if their return type is None.
Pitch
Adoption for the disallow_untyped_defs is difficult, because it requires None to be explicitly annotated. This makes code more wordy in many places where the annotation adds zero value (think of all test functions/methods for extremely popular frameworks like pytest or unittest). This is especially overwhelming for maintainers of large codebases with many tests and existing functions.
Having the flag would give users an option to leave -> None functions unannotated.
Current behaviour would be unchanged if the new flag were not activated, but activating the flag would force users to annotate those functions that do return a value, providing a large but progressive step towards disallow_untyped_defs, reducing the essentially meaningless menial work of adding -> None everywhere.
Reacted by Doug Hoskisson, Diddi Oskarsson, Thomas M Kehrenberg, Martin Bernstorff, duncathan salt, John Hennig, Markus Törnqvist and kikones34
@AlexWaygood This is not about inference.
The return type would not be inferred.
With this option turned on, the return type for any function without a return type annotation would be None.
Nothing is inferred.
deffoo():
return3
With this option turned on, this would be considered an annotated function, and it would report an error because I'm not allowed to return 3 when the return type is None.
Reacted by Matthew Gamble, Arthur Woimbée, Martin Bernstorff, Eternal Sorrow, duncathan salt, John Hennig, Franck Charras, Jack McIvor, Markus Törnqvist, kikones34 and 1 more
Strongly in favor of this! The major blocker for out team in adopting disallow_untyped_defs is requiring -> None in plenty of functions where it is obvious.
Reacted by Mon, Matthew Gamble, michaelCTS, Franck Charras, Fabian Keller, Charvak Kondapalli, Markus Törnqvist, kikones34, Evgeny Filatov and abel1502
Note you could use a complementary tool like https://github.com/JelleZijlstra/autotyping to automatically add -> None (edit from later: or ruff check . --select ANN2 --fix)
@hauntsaninja Yes, but -> None is a visual garbage that makes function definitions longer (they are already long because of the arguments annotations). And it doesn't add anything in terms of code readability.
Reacted by Doug Hoskisson, Mon, Matthew Gamble, Changbin Liu, KotlinIsland, Franck Charras, Fabian Keller, Markus Törnqvist, John Hennig, kikones34 and 3 more
changed the title [-]Flag to make default return type `None` instead of `Any`[/-][+](🎁) Flag to make default return type `None` instead of `Any`[/+]on Oct 12, 2023
Came here looking for this feature - to default the return type to None if one wasn't specified, and give me an error if the function is returning something.
Reacted by Doug Hoskisson, Adrien P., Alon Sirota, Fabian Keller and Markus Törnqvist
This is fine and all for what it is, but it's not super useful, because mypy foo.py will complain, and the editor's LSP integration will still light up.
Activity
gvanrossum commentedon Sep 4, 2020
Already exists: ‘ --check-untyped-defs’.
KotlinIsland commentedon Sep 4, 2020
@gvanrossum I don't think you understand my feature request, in Kotlin
is a valid function, that returns an implicit
Unit(essentiallyVoid) and is fully typed.Swift and Rust(and others I assume) also have this feature and I think it's a good one.
The
--check-untyped-defsflag isn't what I'm asking for.Thanks for the quick response.
KotlinIsland commentedon Sep 4, 2020
Go also supports this.
KotlinIsland commentedon Sep 4, 2020
Currently returns
Anygvanrossum commentedon Sep 4, 2020
Whoops.
JukkaL commentedon Sep 4, 2020
I think that this could be a useful feature, but perhaps only when
--check-untyped-defsor--disallow-untyped-defsis enabled, as otherwisedef foo():would be ambiguous -- it's unclear if we should type check the body.There is a problem when using
--check-untyped-defs, as we should only givedef foo():an implicitNonereturn type if there is no return statement with an explicit value in the body. This would be a bit dangerous however, as any return statement with a value would turn the return type intoAny. So maybe this should only be allowed with--disallow-untyped-defs?Unit tests, in particular, could benefit from this, since there tend to be a lot of functions like
def test_foo(...) -> None.Additionally, maybe an explicit
Nonereturn type should be an error in this mode, as otherwise it could look confusing (or at least inconsistent). We could give this error a dedicated error code so that it would be possible to disable the message, however.KotlinIsland commentedon Sep 4, 2020
Maybe name the flag
--default-none-returnand if enabled thendef foo():would then be considered a typed def and should be checked regardless of whether--check-untyped-defsis selected.I would think an explicit none return type in this mode should be a warning.
eternal-sorrow commentedon Jan 27, 2022
Or it would rather be an alternative to these 2 options.
This case should be considered an error.
gvanrossum commentedon Jan 27, 2022
I feel this feature request is misguided. It creates an incompatible variant language. Just write ‘-> None’ already!
eternal-sorrow commentedon Jan 27, 2022
I don't know. Maybe I'm just too spoiled by the fact that
return None,returnand implicit return do exactly the same thing, but it feels just wrong to add-> Noneto a function that doesn't actually have areturn Nonestatement. For me it feels natural that functions that don't have a return type annotation should be considered as retuningNone, because that's what happens if a function doesn't have a return statement.JelleZijlstra commentedon Jan 27, 2022
This feels like a special case of #4409.
5 remaining items
djmattyg007 commentedon May 2, 2022
but why?
eternal-sorrow commentedon May 2, 2022
There is a perfect explanation of that in the post you replied to.
diddi- commentedon Oct 4, 2022
Because it may not be obvious to a human reader what the expected return type is. It's one thing to have mypy infer the return type by looking at what's being returned, it's a completely different thing for a human to do the same. In the example of returning a single integer that's easy enough of course, but chained function calls or objects are less obvious.
By being explicit with what you want to return you are also reducing risk for bugs and it makes refactoring and team work much easier. And yes I do consider not writing a return type to be just as explicit as writing
-> None. It makes sense that when you look at a function that doesn't have a return type it's because it doesn't return anything.I am very much in favor of having a flag that enables this behavior as I find myself writing
-> Nonea lot in unit tests etc. which will never return anything. It just feels redundant to have it there.[-]Flag to make default return type None instead of Any[/-][+]Flag to make default return type `None` instead of `Any`[/+]berzi commentedon Nov 24, 2022
I'll bring a counterproposal from my (closed as duplicate) issue #14180, which I'll copy here for convenience.
I seem to understand that all arguments against the proposal have to do with it potentially being unexpected as a default behaviour (and it would definitely be something of a breaking change for anyone who already adopts mypy and doesn't enable
disallow_untyped_defs). My proposal includes the behaviour only behind a flag, which would make the feature opt-in and thus not a problem for current adopters anymore. Please see the full proposal below:beauxq commentedon Nov 24, 2022
@AlexWaygood This is not about inference.
The return type would not be inferred.
With this option turned on, the return type for any function without a return type annotation would be
None.Nothing is inferred.
With this option turned on, this would be considered an annotated function, and it would report an error because I'm not allowed to return
3when the return type isNone.MartinBernstorff commentedon Mar 9, 2023
Strongly in favor of this! The major blocker for out team in adopting
disallow_untyped_defsis requiring-> Nonein plenty of functions where it is obvious.hauntsaninja commentedon Mar 9, 2023
Note you could use a complementary tool like https://github.com/JelleZijlstra/autotyping to automatically add
-> None(edit from later: orruff check . --select ANN2 --fix)eternal-sorrow commentedon Mar 9, 2023
@hauntsaninja Yes, but
-> Noneis a visual garbage that makes function definitions longer (they are already long because of the arguments annotations). And it doesn't add anything in terms of code readability.MartinBernstorff commentedon Mar 9, 2023
As a workaround,
ruffsupportsflake8-annotationswhich tests for this, andflake8-annotationshas the requested setting![-]Flag to make default return type `None` instead of `Any`[/-][+](🎁) Flag to make default return type `None` instead of `Any`[/+]ronpsmith commentedon Oct 19, 2023
Came here looking for this feature - to default the return type to None if one wasn't specified, and give me an error if the function is returning something.
mjtorn commentedon Jul 24, 2025
This is fine and all for what it is, but it's not super useful, because
mypy foo.pywill complain, and the editor's LSP integration will still light up.