class_docstr: Writes a single pyi file
class_docstr_tok: ["Writes","a","single","pyi","file"]
docstr: generic_container
    if set, type the field with generic interfaces. Eg.
    - Iterable[int] rather than RepeatedScalarFieldContainer[int]
    - Mapping[k, v] rather than MessageMap[k, v]
    Can be useful for input types (eg constructor)
docstr_tok: ["generic_container","if","set",",","type","the","field","with","generic","interfaces",".","Eg",".","-","Iterable","[","int","]","rather","than","RepeatedScalarFieldContainer","[","int","]","-","Mapping","[","k",",","v","]","rather","than","MessageMap","[","k",",","v","]","Can","be","useful","for","input","types","(","eg","constructor",")"]
code: def python_type(
      self,
      field: d.FieldDescriptorProto,
      generic_container: bool = False,
  ) -> str:
      """
      generic_container
        if set, type the field with generic interfaces. Eg.
        - Iterable[int] rather than RepeatedScalarFieldContainer[int]
        - Mapping[k, v] rather than MessageMap[k, v]
        Can be useful for input types (eg constructor)
      """
      oldstyle_casttype = field.options.Extensions[
          extensions_pb2.casttype
      ]
      if oldstyle_casttype:
          print(
              f"Warning: Field {field.name}: (mypy_protobuf.casttype) is deprecated. Prefer (mypy_protobuf.options).casttype",
              file=sys.stderr,
          )
      casttype = (
          field.options.Extensions[extensions_pb2.options].casttype
          or oldstyle_casttype
      )
      if casttype:
          return self._import_casttype(casttype)
  
      mapping: Dict[
          d.FieldDescriptorProto.Type.V, Callable[[], str]
      ] = {
          d.FieldDescriptorProto.TYPE_DOUBLE: lambda: self._builtin(
              "float"
          ),
          d.FieldDescriptorProto.TYPE_FLOAT: lambda: self._builtin(
              "float"
          ),
          d.FieldDescriptorProto.TYPE_INT64: lambda: self._builtin(
              "int"
          ),
          d.FieldDescriptorProto.TYPE_UINT64: lambda: self._builtin(
              "int"
          ),
          d.FieldDescriptorProto.TYPE_FIXED64: lambda: self._builtin(
              "int"
          ),
          d.FieldDescriptorProto.TYPE_SFIXED64: lambda: self._builtin(
              "int"
          ),
          d.FieldDescriptorProto.TYPE_SINT64: lambda: self._builtin(
              "int"
          ),
          d.FieldDescriptorProto.TYPE_INT32: lambda: self._builtin(
              "int"
          ),
          d.FieldDescriptorProto.TYPE_UINT32: lambda: self._builtin(
              "int"
          ),
          d.FieldDescriptorProto.TYPE_FIXED32: lambda: self._builtin(
              "int"
          ),
          d.FieldDescriptorProto.TYPE_SFIXED32: lambda: self._builtin(
              "int"
          ),
          d.FieldDescriptorProto.TYPE_SINT32: lambda: self._builtin(
              "int"
          ),
          d.FieldDescriptorProto.TYPE_BOOL: lambda: self._builtin(
              "bool"
          ),
          d.FieldDescriptorProto.TYPE_STRING: lambda: self._builtin(
              "str"
          ),
          d.FieldDescriptorProto.TYPE_BYTES: lambda: self._builtin(
              "bytes"
          ),
          d.FieldDescriptorProto.TYPE_ENUM: lambda: self._import_message(
              field.type_name + ".ValueType"
          ),
          d.FieldDescriptorProto.TYPE_MESSAGE: lambda: self._import_message(
              field.type_name
          ),
          d.FieldDescriptorProto.TYPE_GROUP: lambda: self._import_message(
              field.type_name
          ),
      }
  
      assert field.type in mapping, "Unrecognized type: " + repr(
          field.type
      )
      field_type = mapping[field.type]()
  
      # For non-repeated fields, we're done!
      if field.label != d.FieldDescriptorProto.LABEL_REPEATED:
          return field_type
  
      # Scalar repeated fields go in RepeatedScalarFieldContainer
      if is_scalar(field):
          container = (
              self._import("collections.abc", "Iterable")
              if generic_container
              else self._import(
                  "google.protobuf.internal.containers",
                  "RepeatedScalarFieldContainer",
              )
          )
          return f"{container}[{field_type}]"
  
      # non-scalar repeated map fields go in ScalarMap/MessageMap
      msg = self.descriptors.messages[field.type_name]
      if msg.options.map_entry:
          # map generates a special Entry wrapper message
          if generic_container:
              container = self._import("collections.abc", "Mapping")
          elif is_scalar(msg.field[1]):
              container = self._import(
                  "google.protobuf.internal.containers", "ScalarMap"
              )
          else:
              container = self._import(
                  "google.protobuf.internal.containers", "MessageMap"
              )
          ktype, vtype = self._map_key_value_types(
              field, msg.field[0], msg.field[1]
          )
          return f"{container}[{ktype}, {vtype}]"
  
      # non-scalar repetated fields go in RepeatedCompositeFieldContainer
      container = (
          self._import("collections.abc", "Iterable")
          if generic_container
          else self._import(
              "google.protobuf.internal.containers",
              "RepeatedCompositeFieldContainer",
          )
      )
      return f"{container}[{field_type}]"
  
imports: from __future__ import annotations
  import sys
  from collections import defaultdict
  from contextlib import contextmanager
  from typing import Any, Callable, Dict, Iterable, Iterator, List, Optional, Set, Sequence, Tuple
  import google.protobuf.descriptor_pb2
  from google.protobuf.compiler import plugin_pb2
  from google.protobuf.internal.containers import RepeatedCompositeFieldContainer
  from google.protobuf.internal.well_known_types import WKTBASES
  from .None import extensions_pb2
label_desc: Use image node_id 26 for calling the PkgWriter obj's underlying member method code with example usage: obj.python_type(field, generic_container) and returns: container, str, field_type, str, self, field_type, container, str, field_type, str, container, str, ktype, str, vtype, str