inspect.signature with PEP 563












4














The following code:



import inspect
from typing import NamedTuple

class Example(NamedTuple):
a: str

if __name__== "__main__":
signature: inspect.Signature = inspect.signature(Example)
print(signature)


outputs:



(a: str)


However when enabling PEP 563 – Postponed Evaluation of Annotations:



from __future__ import annotations
import inspect
from typing import NamedTuple

class Example(NamedTuple):
a: str

if __name__== "__main__":
signature: inspect.Signature = inspect.signature(Example)
print(signature)


The output is:



(a: 'str')


How can I get the exact same object of type inspect.Signature with PEP 563 like without it?










share|improve this question
























  • The whole point of that PEP is to not get the same object... You'll have to evaluate the string using exec or the like.
    – Bakuriu
    Nov 22 at 22:59
















4














The following code:



import inspect
from typing import NamedTuple

class Example(NamedTuple):
a: str

if __name__== "__main__":
signature: inspect.Signature = inspect.signature(Example)
print(signature)


outputs:



(a: str)


However when enabling PEP 563 – Postponed Evaluation of Annotations:



from __future__ import annotations
import inspect
from typing import NamedTuple

class Example(NamedTuple):
a: str

if __name__== "__main__":
signature: inspect.Signature = inspect.signature(Example)
print(signature)


The output is:



(a: 'str')


How can I get the exact same object of type inspect.Signature with PEP 563 like without it?










share|improve this question
























  • The whole point of that PEP is to not get the same object... You'll have to evaluate the string using exec or the like.
    – Bakuriu
    Nov 22 at 22:59














4












4








4







The following code:



import inspect
from typing import NamedTuple

class Example(NamedTuple):
a: str

if __name__== "__main__":
signature: inspect.Signature = inspect.signature(Example)
print(signature)


outputs:



(a: str)


However when enabling PEP 563 – Postponed Evaluation of Annotations:



from __future__ import annotations
import inspect
from typing import NamedTuple

class Example(NamedTuple):
a: str

if __name__== "__main__":
signature: inspect.Signature = inspect.signature(Example)
print(signature)


The output is:



(a: 'str')


How can I get the exact same object of type inspect.Signature with PEP 563 like without it?










share|improve this question















The following code:



import inspect
from typing import NamedTuple

class Example(NamedTuple):
a: str

if __name__== "__main__":
signature: inspect.Signature = inspect.signature(Example)
print(signature)


outputs:



(a: str)


However when enabling PEP 563 – Postponed Evaluation of Annotations:



from __future__ import annotations
import inspect
from typing import NamedTuple

class Example(NamedTuple):
a: str

if __name__== "__main__":
signature: inspect.Signature = inspect.signature(Example)
print(signature)


The output is:



(a: 'str')


How can I get the exact same object of type inspect.Signature with PEP 563 like without it?







python python-3.x types python-3.7 static-typing






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 20 at 10:46









usr2564301

17.6k73270




17.6k73270










asked Nov 20 at 10:29









Tobias Hermann

2,81612149




2,81612149












  • The whole point of that PEP is to not get the same object... You'll have to evaluate the string using exec or the like.
    – Bakuriu
    Nov 22 at 22:59


















  • The whole point of that PEP is to not get the same object... You'll have to evaluate the string using exec or the like.
    – Bakuriu
    Nov 22 at 22:59
















The whole point of that PEP is to not get the same object... You'll have to evaluate the string using exec or the like.
– Bakuriu
Nov 22 at 22:59




The whole point of that PEP is to not get the same object... You'll have to evaluate the string using exec or the like.
– Bakuriu
Nov 22 at 22:59












2 Answers
2






active

oldest

votes


















3





+100









The point of using PEP 536 is to not evaluate the annotations unless needed. The signature merely reports on the annotations.



If for your purposes you need to have the annotations resolved, you have to do so yourself. PEP 536 tells documents how you do this:




For code that uses type hints, the typing.get_type_hints(obj, globalns=None, localns=None) function correctly evaluates expressions back from its string form.



[...]



For code which uses annotations for other purposes, a regular eval(ann, globals, locals) call is enough to resolve the annotation.




You could even use the typing.get_type_hints() function to assign back to __annotations__ before getting the signature:



import typing

Example.__new__.__annotations__ = typing.get_type_hints(Example.__new__)
signature: inspect.Signature = inspect.signature(Example)


Doing this is safe even if from __future__ import annotations had not been used.






share|improve this answer





















  • Perfect. Thanks. I'll award the bounty tomorrow, because for some reason stackoverflow does not allow me to do so right now without waiting 3 hours. :rolleyes:
    – Tobias Hermann
    Nov 23 at 17:51



















1














First, let's run a different example:



signature: inspect.Signature = inspect.signature(Example)
print(signature)
print(Example.__annotations__)


This prints:



(a: str)
OrderedDict([('a', <class 'str'>)])


So far so good, we have or Signature and our __anotations__ as we expected.



Now let's do the same for the second example, it prints:



(a: 'str')
OrderedDict([('a', ForwardRef('str'))])


So you're not getting the same Signature here. One gives you the actual class and the other a typing.ForwardRef to the class.






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%2f53390985%2finspect-signature-with-pep-563%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3





    +100









    The point of using PEP 536 is to not evaluate the annotations unless needed. The signature merely reports on the annotations.



    If for your purposes you need to have the annotations resolved, you have to do so yourself. PEP 536 tells documents how you do this:




    For code that uses type hints, the typing.get_type_hints(obj, globalns=None, localns=None) function correctly evaluates expressions back from its string form.



    [...]



    For code which uses annotations for other purposes, a regular eval(ann, globals, locals) call is enough to resolve the annotation.




    You could even use the typing.get_type_hints() function to assign back to __annotations__ before getting the signature:



    import typing

    Example.__new__.__annotations__ = typing.get_type_hints(Example.__new__)
    signature: inspect.Signature = inspect.signature(Example)


    Doing this is safe even if from __future__ import annotations had not been used.






    share|improve this answer





















    • Perfect. Thanks. I'll award the bounty tomorrow, because for some reason stackoverflow does not allow me to do so right now without waiting 3 hours. :rolleyes:
      – Tobias Hermann
      Nov 23 at 17:51
















    3





    +100









    The point of using PEP 536 is to not evaluate the annotations unless needed. The signature merely reports on the annotations.



    If for your purposes you need to have the annotations resolved, you have to do so yourself. PEP 536 tells documents how you do this:




    For code that uses type hints, the typing.get_type_hints(obj, globalns=None, localns=None) function correctly evaluates expressions back from its string form.



    [...]



    For code which uses annotations for other purposes, a regular eval(ann, globals, locals) call is enough to resolve the annotation.




    You could even use the typing.get_type_hints() function to assign back to __annotations__ before getting the signature:



    import typing

    Example.__new__.__annotations__ = typing.get_type_hints(Example.__new__)
    signature: inspect.Signature = inspect.signature(Example)


    Doing this is safe even if from __future__ import annotations had not been used.






    share|improve this answer





















    • Perfect. Thanks. I'll award the bounty tomorrow, because for some reason stackoverflow does not allow me to do so right now without waiting 3 hours. :rolleyes:
      – Tobias Hermann
      Nov 23 at 17:51














    3





    +100







    3





    +100



    3




    +100




    The point of using PEP 536 is to not evaluate the annotations unless needed. The signature merely reports on the annotations.



    If for your purposes you need to have the annotations resolved, you have to do so yourself. PEP 536 tells documents how you do this:




    For code that uses type hints, the typing.get_type_hints(obj, globalns=None, localns=None) function correctly evaluates expressions back from its string form.



    [...]



    For code which uses annotations for other purposes, a regular eval(ann, globals, locals) call is enough to resolve the annotation.




    You could even use the typing.get_type_hints() function to assign back to __annotations__ before getting the signature:



    import typing

    Example.__new__.__annotations__ = typing.get_type_hints(Example.__new__)
    signature: inspect.Signature = inspect.signature(Example)


    Doing this is safe even if from __future__ import annotations had not been used.






    share|improve this answer












    The point of using PEP 536 is to not evaluate the annotations unless needed. The signature merely reports on the annotations.



    If for your purposes you need to have the annotations resolved, you have to do so yourself. PEP 536 tells documents how you do this:




    For code that uses type hints, the typing.get_type_hints(obj, globalns=None, localns=None) function correctly evaluates expressions back from its string form.



    [...]



    For code which uses annotations for other purposes, a regular eval(ann, globals, locals) call is enough to resolve the annotation.




    You could even use the typing.get_type_hints() function to assign back to __annotations__ before getting the signature:



    import typing

    Example.__new__.__annotations__ = typing.get_type_hints(Example.__new__)
    signature: inspect.Signature = inspect.signature(Example)


    Doing this is safe even if from __future__ import annotations had not been used.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 22 at 23:38









    Martijn Pieters

    698k12924122252




    698k12924122252












    • Perfect. Thanks. I'll award the bounty tomorrow, because for some reason stackoverflow does not allow me to do so right now without waiting 3 hours. :rolleyes:
      – Tobias Hermann
      Nov 23 at 17:51


















    • Perfect. Thanks. I'll award the bounty tomorrow, because for some reason stackoverflow does not allow me to do so right now without waiting 3 hours. :rolleyes:
      – Tobias Hermann
      Nov 23 at 17:51
















    Perfect. Thanks. I'll award the bounty tomorrow, because for some reason stackoverflow does not allow me to do so right now without waiting 3 hours. :rolleyes:
    – Tobias Hermann
    Nov 23 at 17:51




    Perfect. Thanks. I'll award the bounty tomorrow, because for some reason stackoverflow does not allow me to do so right now without waiting 3 hours. :rolleyes:
    – Tobias Hermann
    Nov 23 at 17:51













    1














    First, let's run a different example:



    signature: inspect.Signature = inspect.signature(Example)
    print(signature)
    print(Example.__annotations__)


    This prints:



    (a: str)
    OrderedDict([('a', <class 'str'>)])


    So far so good, we have or Signature and our __anotations__ as we expected.



    Now let's do the same for the second example, it prints:



    (a: 'str')
    OrderedDict([('a', ForwardRef('str'))])


    So you're not getting the same Signature here. One gives you the actual class and the other a typing.ForwardRef to the class.






    share|improve this answer


























      1














      First, let's run a different example:



      signature: inspect.Signature = inspect.signature(Example)
      print(signature)
      print(Example.__annotations__)


      This prints:



      (a: str)
      OrderedDict([('a', <class 'str'>)])


      So far so good, we have or Signature and our __anotations__ as we expected.



      Now let's do the same for the second example, it prints:



      (a: 'str')
      OrderedDict([('a', ForwardRef('str'))])


      So you're not getting the same Signature here. One gives you the actual class and the other a typing.ForwardRef to the class.






      share|improve this answer
























        1












        1








        1






        First, let's run a different example:



        signature: inspect.Signature = inspect.signature(Example)
        print(signature)
        print(Example.__annotations__)


        This prints:



        (a: str)
        OrderedDict([('a', <class 'str'>)])


        So far so good, we have or Signature and our __anotations__ as we expected.



        Now let's do the same for the second example, it prints:



        (a: 'str')
        OrderedDict([('a', ForwardRef('str'))])


        So you're not getting the same Signature here. One gives you the actual class and the other a typing.ForwardRef to the class.






        share|improve this answer












        First, let's run a different example:



        signature: inspect.Signature = inspect.signature(Example)
        print(signature)
        print(Example.__annotations__)


        This prints:



        (a: str)
        OrderedDict([('a', <class 'str'>)])


        So far so good, we have or Signature and our __anotations__ as we expected.



        Now let's do the same for the second example, it prints:



        (a: 'str')
        OrderedDict([('a', ForwardRef('str'))])


        So you're not getting the same Signature here. One gives you the actual class and the other a typing.ForwardRef to the class.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 22 at 22:53









        yorodm

        2,015617




        2,015617






























            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.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • 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%2f53390985%2finspect-signature-with-pep-563%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

            A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

            Calculate evaluation metrics using cross_val_predict sklearn

            Insert data from modal to MySQL (multiple modal on website)