MCPcopy Index your code
hub / github.com/python/mypy / AnnotationPrinter

Class AnnotationPrinter

mypy/stubutil.py:227–323  ·  view source on GitHub ↗

Visitor used to print existing annotations in a file. The main difference from TypeStrVisitor is a better treatment of unbound types. Notes: * This visitor doesn't add imports necessary for annotations, this is done separately by ImportTracker. * It can print all kinds of

Source from the content-addressed store, hash-verified

225
226
227class AnnotationPrinter(TypeStrVisitor):
228 """Visitor used to print existing annotations in a file.
229
230 The main difference from TypeStrVisitor is a better treatment of
231 unbound types.
232
233 Notes:
234 * This visitor doesn't add imports necessary for annotations, this is done separately
235 by ImportTracker.
236 * It can print all kinds of types, but the generated strings may not be valid (notably
237 callable types) since it prints the same string that reveal_type() does.
238 * For Instance types it prints the fully qualified names.
239 """
240
241 # TODO: Generate valid string representation for callable types.
242 # TODO: Use short names for Instances.
243 def __init__(
244 self,
245 stubgen: BaseStubGenerator,
246 known_modules: list[str] | None = None,
247 local_modules: list[str] | None = None,
248 ) -> None:
249 super().__init__(options=mypy.options.Options())
250 self.stubgen = stubgen
251 self.known_modules = known_modules
252 self.local_modules = local_modules or ["builtins"]
253
254 def visit_any(self, t: AnyType) -> str:
255 s = super().visit_any(t)
256 self.stubgen.import_tracker.require_name(s)
257 return s
258
259 def visit_unbound_type(self, t: UnboundType) -> str:
260 s = t.name
261 fullname = self.stubgen.resolve_name(s)
262 if fullname == "typing.Union":
263 return " | ".join([item.accept(self) for item in t.args])
264 if fullname == "typing.Optional":
265 if len(t.args) == 1:
266 return f"{t.args[0].accept(self)} | None"
267 return self.stubgen.add_name("_typeshed.Incomplete")
268 if fullname in TYPING_BUILTIN_REPLACEMENTS:
269 s = self.stubgen.add_name(TYPING_BUILTIN_REPLACEMENTS[fullname], require=True)
270 if self.known_modules is not None and "." in s:
271 # see if this object is from any of the modules that we're currently processing.
272 # reverse sort so that subpackages come before parents: e.g. "foo.bar" before "foo".
273 for module_name in self.local_modules + sorted(self.known_modules, reverse=True):
274 if s.startswith(module_name + "."):
275 if module_name in self.local_modules:
276 s = s[len(module_name) + 1 :]
277 arg_module = module_name
278 break
279 else:
280 arg_module = s[: s.rindex(".")]
281 if arg_module not in self.local_modules:
282 self.stubgen.import_tracker.add_import(arg_module, require=True)
283 elif s == "NoneType":
284 # when called without analysis all types are unbound, so this won't hit

Callers 2

format_type_argsMethod · 0.85
print_annotationMethod · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…