Is there ar preferable way to create type aliases for compound types with Python's typing module?What's the canonical way to check for type in Python?What is the best (idiomatic) way to check the type of a Python variable?Is arr.__len__() the preferred way to get the length of an array in Python?Way to create multiline comments in Python?Pythonic way to create a long multi-line stringGet Mypy to accept unpacked dictMypy throws errors when using __new__how to explain domain specific constraints to mypyLooking for a working example of `SupportsRound`Type annotations for __floor__ and `__ceil__
Do sudoku answers always have a single minimal clue set?
Why does the numerical solution of an ODE move away from an unstable equilibrium?
How would a order of Monks that renounce their names communicate effectively?
Do I have to roll to maintain concentration if a target other than me who is affected by my concentration spell takes damage?
How to modify the uneven space between separate loop cuts, while they are already cut?
Dold-Kan correspondence in the category of symmetric spectra
Difference between 'demás' and 'otros'?
Why is a blank required between "[[" and "-e xxx" in ksh?
Going to get married soon, should I do it on Dec 31 or Jan 1?
How hard is it to sell a home which is currently mortgaged?
Does anycast addressing add additional latency in any way?
Dual statement category theory
How to convert object fill in to fine lines?
How can I check type T is among parameter pack Ts... in C++?
Three column layout
When is it ok to add filler to a story?
Symbol for "not absolutely continuous" in Latex
Is adding a new player (or players) a DM decision, or a group decision?
Could Sauron have read Tom Bombadil's mind if Tom had held the Palantir?
How should I behave to assure my friends that I am not after their money?
Why is Madam Hooch not a professor?
Analog is Obtuse!
Set vertical spacing between two particular items
SPI Waveform on Raspberry Pi Not clean and I'm wondering why
Is there ar preferable way to create type aliases for compound types with Python's typing module?
What's the canonical way to check for type in Python?What is the best (idiomatic) way to check the type of a Python variable?Is arr.__len__() the preferred way to get the length of an array in Python?Way to create multiline comments in Python?Pythonic way to create a long multi-line stringGet Mypy to accept unpacked dictMypy throws errors when using __new__how to explain domain specific constraints to mypyLooking for a working example of `SupportsRound`Type annotations for __floor__ and `__ceil__
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I have a function with one parameter, which should take an int
or a None
as argument. There are several ways to create a type alias for such a compound type:
# test.py
import typing
IntOrNone_1 = typing.TypeVar('IntOrNone_1', int, None)
IntOrNone_2 = typing.Union[int, None]
def my_func1(xyz: IntOrNone_1):
return xyz
def my_func2(xyz: IntOrNone_2):
return xyz
my_func1(12)
my_func1(None)
my_func1(13.7)
my_func1('str')
my_func2(12)
my_func2(None)
my_func2(13.7)
my_func2('str')
Both methods do what I expect them to do, however, the correspondig mypy
erros differ slightly, but basically have the same meaning.
test.py:14: error: Value of type variable "IntOrNone_1" of "my_func1"
cannot be "float"
test.py:15: error: Value of type variable "IntOrNone_1" of "my_func1"
cannot be "str"
test.py:19: error: Argument 1 to "my_func2" has incompatible type
"float"; expected "Optional[int]"
test.py:20: error: Argument 1 to "my_func2" has incompatible type
"str"; expected "Optional[int]"
I tend to use the second approach, since it additionally reports which argument caused the error.
Are both methods indeed equivalent, as I suppose, or is one of them to be preferred?
python typing typechecking
add a comment |
I have a function with one parameter, which should take an int
or a None
as argument. There are several ways to create a type alias for such a compound type:
# test.py
import typing
IntOrNone_1 = typing.TypeVar('IntOrNone_1', int, None)
IntOrNone_2 = typing.Union[int, None]
def my_func1(xyz: IntOrNone_1):
return xyz
def my_func2(xyz: IntOrNone_2):
return xyz
my_func1(12)
my_func1(None)
my_func1(13.7)
my_func1('str')
my_func2(12)
my_func2(None)
my_func2(13.7)
my_func2('str')
Both methods do what I expect them to do, however, the correspondig mypy
erros differ slightly, but basically have the same meaning.
test.py:14: error: Value of type variable "IntOrNone_1" of "my_func1"
cannot be "float"
test.py:15: error: Value of type variable "IntOrNone_1" of "my_func1"
cannot be "str"
test.py:19: error: Argument 1 to "my_func2" has incompatible type
"float"; expected "Optional[int]"
test.py:20: error: Argument 1 to "my_func2" has incompatible type
"str"; expected "Optional[int]"
I tend to use the second approach, since it additionally reports which argument caused the error.
Are both methods indeed equivalent, as I suppose, or is one of them to be preferred?
python typing typechecking
add a comment |
I have a function with one parameter, which should take an int
or a None
as argument. There are several ways to create a type alias for such a compound type:
# test.py
import typing
IntOrNone_1 = typing.TypeVar('IntOrNone_1', int, None)
IntOrNone_2 = typing.Union[int, None]
def my_func1(xyz: IntOrNone_1):
return xyz
def my_func2(xyz: IntOrNone_2):
return xyz
my_func1(12)
my_func1(None)
my_func1(13.7)
my_func1('str')
my_func2(12)
my_func2(None)
my_func2(13.7)
my_func2('str')
Both methods do what I expect them to do, however, the correspondig mypy
erros differ slightly, but basically have the same meaning.
test.py:14: error: Value of type variable "IntOrNone_1" of "my_func1"
cannot be "float"
test.py:15: error: Value of type variable "IntOrNone_1" of "my_func1"
cannot be "str"
test.py:19: error: Argument 1 to "my_func2" has incompatible type
"float"; expected "Optional[int]"
test.py:20: error: Argument 1 to "my_func2" has incompatible type
"str"; expected "Optional[int]"
I tend to use the second approach, since it additionally reports which argument caused the error.
Are both methods indeed equivalent, as I suppose, or is one of them to be preferred?
python typing typechecking
I have a function with one parameter, which should take an int
or a None
as argument. There are several ways to create a type alias for such a compound type:
# test.py
import typing
IntOrNone_1 = typing.TypeVar('IntOrNone_1', int, None)
IntOrNone_2 = typing.Union[int, None]
def my_func1(xyz: IntOrNone_1):
return xyz
def my_func2(xyz: IntOrNone_2):
return xyz
my_func1(12)
my_func1(None)
my_func1(13.7)
my_func1('str')
my_func2(12)
my_func2(None)
my_func2(13.7)
my_func2('str')
Both methods do what I expect them to do, however, the correspondig mypy
erros differ slightly, but basically have the same meaning.
test.py:14: error: Value of type variable "IntOrNone_1" of "my_func1"
cannot be "float"
test.py:15: error: Value of type variable "IntOrNone_1" of "my_func1"
cannot be "str"
test.py:19: error: Argument 1 to "my_func2" has incompatible type
"float"; expected "Optional[int]"
test.py:20: error: Argument 1 to "my_func2" has incompatible type
"str"; expected "Optional[int]"
I tend to use the second approach, since it additionally reports which argument caused the error.
Are both methods indeed equivalent, as I suppose, or is one of them to be preferred?
python typing typechecking
python typing typechecking
asked Mar 25 at 11:21
MaxPowersMaxPowers
2,56423 silver badges49 bronze badges
2,56423 silver badges49 bronze badges
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
The two methods are very far from being equivalent. You should avoid thinking of TypeVars as being mere aliases -- rather, they're more special forms that you use when you want to make your functions generic.
It's easiest to explain what a "generic function" is with an example. Suppose you want to write a function that accepts some object (any object!) and return another object of the exact same type. How would you do this?
One method we could do is to try using object
:
def identity(x: object) -> object:
return x
This gets us close, since our identity
function can at least accept literally anything (since all types inherit from object
in Python). However, this solution is flawed: if we pass in an int, we get back out object
, which isn't what we want.
Rather, what we need is a way for the type checker to understand that there's a "relationship" between these two types. This is exactly where TypeVar
comes in handy:
T = TypeVar('T')
def identity(x: T) -> T:
return x
Our TypeVar 'T' in this case is acting as a "placeholder" that can be bound to any type we want. So if we do identity(3)
, the T
will be bound to int
-- so the type checker will therefore understand the return type must also be int
!
And if we use T
multiple times within our parameter type hints, the type checker will make sure that the types are the same each time.
So, what is the expression below doing?
IntOrNone_1 = typing.TypeVar('IntOrNone_1', int, None)
Well, it turns out that it can sometimes be useful to add constraints to our special placeholder type. For example, you've constrained IntOrNone_1
so that it can be bound to only int
or None
, and no other types.
And finally, to answer your last question: in the examples you've given, you should absolutely be using Union, not TypeVars.
Whether you use a Union or a type alias to a Union is really a matter of personal taste, but if you don't need this "placeholder" or "generic" behavior, you shouldn't be using TypeVars.
The mypy docs has a section on generics if you'd like to learn more about how to use TypeVars. It covers several things I skipped, including how to make generic classes (not just generic functions).
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55336690%2fis-there-ar-preferable-way-to-create-type-aliases-for-compound-types-with-python%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The two methods are very far from being equivalent. You should avoid thinking of TypeVars as being mere aliases -- rather, they're more special forms that you use when you want to make your functions generic.
It's easiest to explain what a "generic function" is with an example. Suppose you want to write a function that accepts some object (any object!) and return another object of the exact same type. How would you do this?
One method we could do is to try using object
:
def identity(x: object) -> object:
return x
This gets us close, since our identity
function can at least accept literally anything (since all types inherit from object
in Python). However, this solution is flawed: if we pass in an int, we get back out object
, which isn't what we want.
Rather, what we need is a way for the type checker to understand that there's a "relationship" between these two types. This is exactly where TypeVar
comes in handy:
T = TypeVar('T')
def identity(x: T) -> T:
return x
Our TypeVar 'T' in this case is acting as a "placeholder" that can be bound to any type we want. So if we do identity(3)
, the T
will be bound to int
-- so the type checker will therefore understand the return type must also be int
!
And if we use T
multiple times within our parameter type hints, the type checker will make sure that the types are the same each time.
So, what is the expression below doing?
IntOrNone_1 = typing.TypeVar('IntOrNone_1', int, None)
Well, it turns out that it can sometimes be useful to add constraints to our special placeholder type. For example, you've constrained IntOrNone_1
so that it can be bound to only int
or None
, and no other types.
And finally, to answer your last question: in the examples you've given, you should absolutely be using Union, not TypeVars.
Whether you use a Union or a type alias to a Union is really a matter of personal taste, but if you don't need this "placeholder" or "generic" behavior, you shouldn't be using TypeVars.
The mypy docs has a section on generics if you'd like to learn more about how to use TypeVars. It covers several things I skipped, including how to make generic classes (not just generic functions).
add a comment |
The two methods are very far from being equivalent. You should avoid thinking of TypeVars as being mere aliases -- rather, they're more special forms that you use when you want to make your functions generic.
It's easiest to explain what a "generic function" is with an example. Suppose you want to write a function that accepts some object (any object!) and return another object of the exact same type. How would you do this?
One method we could do is to try using object
:
def identity(x: object) -> object:
return x
This gets us close, since our identity
function can at least accept literally anything (since all types inherit from object
in Python). However, this solution is flawed: if we pass in an int, we get back out object
, which isn't what we want.
Rather, what we need is a way for the type checker to understand that there's a "relationship" between these two types. This is exactly where TypeVar
comes in handy:
T = TypeVar('T')
def identity(x: T) -> T:
return x
Our TypeVar 'T' in this case is acting as a "placeholder" that can be bound to any type we want. So if we do identity(3)
, the T
will be bound to int
-- so the type checker will therefore understand the return type must also be int
!
And if we use T
multiple times within our parameter type hints, the type checker will make sure that the types are the same each time.
So, what is the expression below doing?
IntOrNone_1 = typing.TypeVar('IntOrNone_1', int, None)
Well, it turns out that it can sometimes be useful to add constraints to our special placeholder type. For example, you've constrained IntOrNone_1
so that it can be bound to only int
or None
, and no other types.
And finally, to answer your last question: in the examples you've given, you should absolutely be using Union, not TypeVars.
Whether you use a Union or a type alias to a Union is really a matter of personal taste, but if you don't need this "placeholder" or "generic" behavior, you shouldn't be using TypeVars.
The mypy docs has a section on generics if you'd like to learn more about how to use TypeVars. It covers several things I skipped, including how to make generic classes (not just generic functions).
add a comment |
The two methods are very far from being equivalent. You should avoid thinking of TypeVars as being mere aliases -- rather, they're more special forms that you use when you want to make your functions generic.
It's easiest to explain what a "generic function" is with an example. Suppose you want to write a function that accepts some object (any object!) and return another object of the exact same type. How would you do this?
One method we could do is to try using object
:
def identity(x: object) -> object:
return x
This gets us close, since our identity
function can at least accept literally anything (since all types inherit from object
in Python). However, this solution is flawed: if we pass in an int, we get back out object
, which isn't what we want.
Rather, what we need is a way for the type checker to understand that there's a "relationship" between these two types. This is exactly where TypeVar
comes in handy:
T = TypeVar('T')
def identity(x: T) -> T:
return x
Our TypeVar 'T' in this case is acting as a "placeholder" that can be bound to any type we want. So if we do identity(3)
, the T
will be bound to int
-- so the type checker will therefore understand the return type must also be int
!
And if we use T
multiple times within our parameter type hints, the type checker will make sure that the types are the same each time.
So, what is the expression below doing?
IntOrNone_1 = typing.TypeVar('IntOrNone_1', int, None)
Well, it turns out that it can sometimes be useful to add constraints to our special placeholder type. For example, you've constrained IntOrNone_1
so that it can be bound to only int
or None
, and no other types.
And finally, to answer your last question: in the examples you've given, you should absolutely be using Union, not TypeVars.
Whether you use a Union or a type alias to a Union is really a matter of personal taste, but if you don't need this "placeholder" or "generic" behavior, you shouldn't be using TypeVars.
The mypy docs has a section on generics if you'd like to learn more about how to use TypeVars. It covers several things I skipped, including how to make generic classes (not just generic functions).
The two methods are very far from being equivalent. You should avoid thinking of TypeVars as being mere aliases -- rather, they're more special forms that you use when you want to make your functions generic.
It's easiest to explain what a "generic function" is with an example. Suppose you want to write a function that accepts some object (any object!) and return another object of the exact same type. How would you do this?
One method we could do is to try using object
:
def identity(x: object) -> object:
return x
This gets us close, since our identity
function can at least accept literally anything (since all types inherit from object
in Python). However, this solution is flawed: if we pass in an int, we get back out object
, which isn't what we want.
Rather, what we need is a way for the type checker to understand that there's a "relationship" between these two types. This is exactly where TypeVar
comes in handy:
T = TypeVar('T')
def identity(x: T) -> T:
return x
Our TypeVar 'T' in this case is acting as a "placeholder" that can be bound to any type we want. So if we do identity(3)
, the T
will be bound to int
-- so the type checker will therefore understand the return type must also be int
!
And if we use T
multiple times within our parameter type hints, the type checker will make sure that the types are the same each time.
So, what is the expression below doing?
IntOrNone_1 = typing.TypeVar('IntOrNone_1', int, None)
Well, it turns out that it can sometimes be useful to add constraints to our special placeholder type. For example, you've constrained IntOrNone_1
so that it can be bound to only int
or None
, and no other types.
And finally, to answer your last question: in the examples you've given, you should absolutely be using Union, not TypeVars.
Whether you use a Union or a type alias to a Union is really a matter of personal taste, but if you don't need this "placeholder" or "generic" behavior, you shouldn't be using TypeVars.
The mypy docs has a section on generics if you'd like to learn more about how to use TypeVars. It covers several things I skipped, including how to make generic classes (not just generic functions).
answered Mar 25 at 19:06
Michael0x2aMichael0x2a
24.9k16 gold badges80 silver badges134 bronze badges
24.9k16 gold badges80 silver badges134 bronze badges
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55336690%2fis-there-ar-preferable-way-to-create-type-aliases-for-compound-types-with-python%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown