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;








2















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?










share|improve this question




























    2















    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?










    share|improve this question
























      2












      2








      2








      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?










      share|improve this question














      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






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Mar 25 at 11:21









      MaxPowersMaxPowers

      2,56423 silver badges49 bronze badges




      2,56423 silver badges49 bronze badges






















          1 Answer
          1






          active

          oldest

          votes


















          3














          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).






          share|improve this answer

























            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
            );



            );













            draft saved

            draft discarded


















            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









            3














            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).






            share|improve this answer



























              3














              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).






              share|improve this answer

























                3












                3








                3







                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).






                share|improve this answer













                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).







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Mar 25 at 19:06









                Michael0x2aMichael0x2a

                24.9k16 gold badges80 silver badges134 bronze badges




                24.9k16 gold badges80 silver badges134 bronze badges





























                    draft saved

                    draft discarded
















































                    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.




                    draft saved


                    draft discarded














                    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





















































                    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







                    Popular posts from this blog

                    Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

                    Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

                    Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript