code: def _get_getter_fun(object_type,           # type: Type
                      parameter,             # type: Parameter
                      private_property_name  # type: str
                      ):
      
  
      property_name = parameter.name
  
      # -- check overridden getter for this property name
      overridden_getters = getmembers(object_type, predicate=_has_annotation(__GETTER_OVERRIDE_ANNOTATION, property_name))
  
      if len(overridden_getters) > 0:
          if len(overridden_getters) > 1:
              raise DuplicateOverrideError('Getter is overridden more than once for attribute name : ' + property_name)
  
          # --use the overridden getter
          getter_fun = overridden_getters[0][1]
  
          # --check its signature
          s = signature(getter_fun)
          if not ('self' in s.parameters.keys() and len(s.parameters.keys()) == 1):
              raise IllegalGetterSignatureException('overridden getter must only have a self parameter, found ' +
                                                    str(len(s.parameters.items()) - 1) + ' for function ' + str(
                  getter_fun.__qualname__))
  
          # --use the overridden getter ?
          property_obj = property(getter_fun)
      else:
          # -- generate the getter :
          def autoprops_generated_getter(self):
              return getattr(self, private_property_name)
  
          # -- use the generated getter
          getter_fun = autoprops_generated_getter
  
          try:
              annotations = getter_fun.__annotations__
          except AttributeError:
              # python 2
              pass
          else:
              annotations['return'] = parameter.annotation  # add type hint to output declaration
  
      return getter_fun
docs: Utility method to find the overridden getter function for a given property, or generate a new one
  
      :param object_type:
      :param property_name:
      :param private_property_name:
      :return: