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 '18 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 '18 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 '18 at 10:46









usr2564301

17.8k73370




17.8k73370










asked Nov 20 '18 at 10:29









Tobias HermannTobias Hermann

2,96022151




2,96022151













  • 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 at 23:38









    Martijn PietersMartijn Pieters

    714k13724952307




    714k13724952307













    • 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 '18 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 '18 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 '18 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 '18 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 '18 at 22:53









        yorodmyorodm

        2,247717




        2,247717






























            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%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







            這個網誌中的熱門文章

            Xamarin.form Move up view when keyboard appear

            Post-Redirect-Get with Spring WebFlux and Thymeleaf

            Anylogic : not able to use stopDelay()