140
140
141
141
142
142
import abc
143
+ from annotationlib import Format
143
144
from annotationlib import get_annotations # re-exported
144
145
import ast
145
146
import dis
@@ -1319,7 +1320,9 @@ def getargvalues(frame):
1319
1320
args , varargs , varkw = getargs (frame .f_code )
1320
1321
return ArgInfo (args , varargs , varkw , frame .f_locals )
1321
1322
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
1323
1326
if getattr (annotation , '__module__' , None ) == 'typing' :
1324
1327
def repl (match ):
1325
1328
text = match .group ()
@@ -2270,7 +2273,8 @@ def _signature_from_builtin(cls, func, skip_bound_arg=True):
2270
2273
2271
2274
2272
2275
def _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 ):
2274
2278
"""Private helper: constructs Signature for the given python function."""
2275
2279
2276
2280
is_duck_function = False
@@ -2296,7 +2300,8 @@ def _signature_from_function(cls, func, skip_bound_arg=True,
2296
2300
positional = arg_names [:pos_count ]
2297
2301
keyword_only_count = func_code .co_kwonlyargcount
2298
2302
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 )
2300
2305
defaults = func .__defaults__
2301
2306
kwdefaults = func .__kwdefaults__
2302
2307
@@ -2379,7 +2384,8 @@ def _signature_from_callable(obj, *,
2379
2384
globals = None ,
2380
2385
locals = None ,
2381
2386
eval_str = False ,
2382
- sigcls ):
2387
+ sigcls ,
2388
+ annotation_format = Format .VALUE ):
2383
2389
2384
2390
"""Private helper function to get signature for arbitrary
2385
2391
callable objects.
@@ -2391,7 +2397,8 @@ def _signature_from_callable(obj, *,
2391
2397
globals = globals ,
2392
2398
locals = locals ,
2393
2399
sigcls = sigcls ,
2394
- eval_str = eval_str )
2400
+ eval_str = eval_str ,
2401
+ annotation_format = annotation_format )
2395
2402
2396
2403
if not callable (obj ):
2397
2404
raise TypeError ('{!r} is not a callable object' .format (obj ))
@@ -2472,7 +2479,8 @@ def _signature_from_callable(obj, *,
2472
2479
# of a Python function (Cython functions, for instance), then:
2473
2480
return _signature_from_function (sigcls , obj ,
2474
2481
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 )
2476
2484
2477
2485
if _signature_is_builtin (obj ):
2478
2486
return _signature_from_builtin (sigcls , obj ,
@@ -2707,13 +2715,17 @@ def replace(self, *, name=_void, kind=_void,
2707
2715
return type (self )(name , kind , default = default , annotation = annotation )
2708
2716
2709
2717
def __str__ (self ):
2718
+ return self ._format ()
2719
+
2720
+ def _format (self , * , quote_annotation_strings = True ):
2710
2721
kind = self .kind
2711
2722
formatted = self ._name
2712
2723
2713
2724
# Add annotation and default value
2714
2725
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 )
2717
2729
2718
2730
if self ._default is not _empty :
2719
2731
if self ._annotation is not _empty :
@@ -2961,11 +2973,13 @@ def __init__(self, parameters=None, *, return_annotation=_empty,
2961
2973
2962
2974
@classmethod
2963
2975
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 ):
2965
2978
"""Constructs Signature for the given callable object."""
2966
2979
return _signature_from_callable (obj , sigcls = cls ,
2967
2980
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 )
2969
2983
2970
2984
@property
2971
2985
def parameters (self ):
@@ -3180,19 +3194,24 @@ def __repr__(self):
3180
3194
def __str__ (self ):
3181
3195
return self .format ()
3182
3196
3183
- def format (self , * , max_width = None ):
3197
+ def format (self , * , max_width = None , quote_annotation_strings = True ):
3184
3198
"""Create a string representation of the Signature object.
3185
3199
3186
3200
If *max_width* integer is passed,
3187
3201
signature will try to fit into the *max_width*.
3188
3202
If signature is longer than *max_width*,
3189
3203
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.
3190
3209
"""
3191
3210
result = []
3192
3211
render_pos_only_separator = False
3193
3212
render_kw_only_separator = True
3194
3213
for param in self .parameters .values ():
3195
- formatted = str ( param )
3214
+ formatted = param . _format ( quote_annotation_strings = quote_annotation_strings )
3196
3215
3197
3216
kind = param .kind
3198
3217
@@ -3229,16 +3248,19 @@ def format(self, *, max_width=None):
3229
3248
rendered = '(\n {}\n )' .format (',\n ' .join (result ))
3230
3249
3231
3250
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 )
3233
3253
rendered += ' -> {}' .format (anno )
3234
3254
3235
3255
return rendered
3236
3256
3237
3257
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 ):
3239
3260
"""Get a signature object for the passed callable."""
3240
3261
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 )
3242
3264
3243
3265
3244
3266
class BufferFlags (enum .IntFlag ):
0 commit comments