140140
141141
142142import abc
143+ from annotationlib import Format
143144from annotationlib import get_annotations # re-exported
144145import ast
145146import dis
@@ -1319,7 +1320,9 @@ def getargvalues(frame):
13191320 args , varargs , varkw = getargs (frame .f_code )
13201321 return ArgInfo (args , varargs , varkw , frame .f_locals )
13211322
1322- def formatannotation (annotation , base_module = None ):
1323+ def formatannotation (annotation , base_module = None , * , quote_annotation_strings = True ):
1324+ if not quote_annotation_strings and isinstance (annotation , str ):
1325+ return annotation
13231326 if getattr (annotation , '__module__' , None ) == 'typing' :
13241327 def repl (match ):
13251328 text = match .group ()
@@ -2270,7 +2273,8 @@ def _signature_from_builtin(cls, func, skip_bound_arg=True):
22702273
22712274
22722275def _signature_from_function (cls , func , skip_bound_arg = True ,
2273- globals = None , locals = None , eval_str = False ):
2276+ globals = None , locals = None , eval_str = False ,
2277+ * , annotation_format = Format .VALUE ):
22742278 """Private helper: constructs Signature for the given python function."""
22752279
22762280 is_duck_function = False
@@ -2296,7 +2300,8 @@ def _signature_from_function(cls, func, skip_bound_arg=True,
22962300 positional = arg_names [:pos_count ]
22972301 keyword_only_count = func_code .co_kwonlyargcount
22982302 keyword_only = arg_names [pos_count :pos_count + keyword_only_count ]
2299- annotations = get_annotations (func , globals = globals , locals = locals , eval_str = eval_str )
2303+ annotations = get_annotations (func , globals = globals , locals = locals , eval_str = eval_str ,
2304+ format = annotation_format )
23002305 defaults = func .__defaults__
23012306 kwdefaults = func .__kwdefaults__
23022307
@@ -2379,7 +2384,8 @@ def _signature_from_callable(obj, *,
23792384 globals = None ,
23802385 locals = None ,
23812386 eval_str = False ,
2382- sigcls ):
2387+ sigcls ,
2388+ annotation_format = Format .VALUE ):
23832389
23842390 """Private helper function to get signature for arbitrary
23852391 callable objects.
@@ -2391,7 +2397,8 @@ def _signature_from_callable(obj, *,
23912397 globals = globals ,
23922398 locals = locals ,
23932399 sigcls = sigcls ,
2394- eval_str = eval_str )
2400+ eval_str = eval_str ,
2401+ annotation_format = annotation_format )
23952402
23962403 if not callable (obj ):
23972404 raise TypeError ('{!r} is not a callable object' .format (obj ))
@@ -2472,7 +2479,8 @@ def _signature_from_callable(obj, *,
24722479 # of a Python function (Cython functions, for instance), then:
24732480 return _signature_from_function (sigcls , obj ,
24742481 skip_bound_arg = skip_bound_arg ,
2475- globals = globals , locals = locals , eval_str = eval_str )
2482+ globals = globals , locals = locals , eval_str = eval_str ,
2483+ annotation_format = annotation_format )
24762484
24772485 if _signature_is_builtin (obj ):
24782486 return _signature_from_builtin (sigcls , obj ,
@@ -2707,13 +2715,17 @@ def replace(self, *, name=_void, kind=_void,
27072715 return type (self )(name , kind , default = default , annotation = annotation )
27082716
27092717 def __str__ (self ):
2718+ return self ._format ()
2719+
2720+ def _format (self , * , quote_annotation_strings = True ):
27102721 kind = self .kind
27112722 formatted = self ._name
27122723
27132724 # Add annotation and default value
27142725 if self ._annotation is not _empty :
2715- formatted = '{}: {}' .format (formatted ,
2716- formatannotation (self ._annotation ))
2726+ annotation = formatannotation (self ._annotation ,
2727+ quote_annotation_strings = quote_annotation_strings )
2728+ formatted = '{}: {}' .format (formatted , annotation )
27172729
27182730 if self ._default is not _empty :
27192731 if self ._annotation is not _empty :
@@ -2961,11 +2973,13 @@ def __init__(self, parameters=None, *, return_annotation=_empty,
29612973
29622974 @classmethod
29632975 def from_callable (cls , obj , * ,
2964- follow_wrapped = True , globals = None , locals = None , eval_str = False ):
2976+ follow_wrapped = True , globals = None , locals = None , eval_str = False ,
2977+ annotation_format = Format .VALUE ):
29652978 """Constructs Signature for the given callable object."""
29662979 return _signature_from_callable (obj , sigcls = cls ,
29672980 follow_wrapper_chains = follow_wrapped ,
2968- globals = globals , locals = locals , eval_str = eval_str )
2981+ globals = globals , locals = locals , eval_str = eval_str ,
2982+ annotation_format = annotation_format )
29692983
29702984 @property
29712985 def parameters (self ):
@@ -3180,19 +3194,24 @@ def __repr__(self):
31803194 def __str__ (self ):
31813195 return self .format ()
31823196
3183- def format (self , * , max_width = None ):
3197+ def format (self , * , max_width = None , quote_annotation_strings = True ):
31843198 """Create a string representation of the Signature object.
31853199
31863200 If *max_width* integer is passed,
31873201 signature will try to fit into the *max_width*.
31883202 If signature is longer than *max_width*,
31893203 all parameters will be on separate lines.
3204+
3205+ If *quote_annotation_strings* is False, annotations
3206+ in the signature are displayed without opening and closing quotation
3207+ marks. This is useful when the signature was created with the
3208+ STRING format or when ``from __future__ import annotations`` was used.
31903209 """
31913210 result = []
31923211 render_pos_only_separator = False
31933212 render_kw_only_separator = True
31943213 for param in self .parameters .values ():
3195- formatted = str ( param )
3214+ formatted = param . _format ( quote_annotation_strings = quote_annotation_strings )
31963215
31973216 kind = param .kind
31983217
@@ -3229,16 +3248,19 @@ def format(self, *, max_width=None):
32293248 rendered = '(\n {}\n )' .format (',\n ' .join (result ))
32303249
32313250 if self .return_annotation is not _empty :
3232- anno = formatannotation (self .return_annotation )
3251+ anno = formatannotation (self .return_annotation ,
3252+ quote_annotation_strings = quote_annotation_strings )
32333253 rendered += ' -> {}' .format (anno )
32343254
32353255 return rendered
32363256
32373257
3238- def signature (obj , * , follow_wrapped = True , globals = None , locals = None , eval_str = False ):
3258+ def signature (obj , * , follow_wrapped = True , globals = None , locals = None , eval_str = False ,
3259+ annotation_format = Format .VALUE ):
32393260 """Get a signature object for the passed callable."""
32403261 return Signature .from_callable (obj , follow_wrapped = follow_wrapped ,
3241- globals = globals , locals = locals , eval_str = eval_str )
3262+ globals = globals , locals = locals , eval_str = eval_str ,
3263+ annotation_format = annotation_format )
32423264
32433265
32443266class BufferFlags (enum .IntFlag ):
0 commit comments