docs: def has_role(self, principal, role, object=None):
          """True if `principal` has `role` (either globally, if `object` is
          None, or on the specific `object`).
  
          :param:role: can be a list or tuple of strings or a :class:`Role`
              instance
  
          `object` can be an :class:`Entity`, a string, or `None`.
  
          Note: we're using a cache for efficiency here. TODO: check that we're not
          over-caching.
  
          Note2: caching could also be moved upfront to when the user is loaded.
          """
          if not principal:
              return False
  
          principal = unwrap(principal)
          if not self.running:
              return True
  
          if isinstance(role, (Role, (str,))):
              role = (role,)
  
          # admin & manager always have role
          valid_roles = frozenset((Admin, Manager) + tuple(role))
  
          if AnonymousRole in valid_roles:
              # everybody has the role 'Anonymous'
              return True
  
          if (
              Authenticated in valid_roles
              and isinstance(principal, User)
              and not principal.is_anonymous
          ):
              return True
  
          if principal is AnonymousRole or (
              hasattr(principal, "is_anonymous") and principal.is_anonymous
          ):
              # anonymous user, and anonymous role isn't in valid_roles
              return False
  
          # root always have any role
          if isinstance(principal, User) and principal.id == 0:
              return True
  
          if object:
              assert isinstance(object, Entity)
              object_key = "{}:{}".format(object.object_type, str(object.id))
              if Creator in role:
                  if object.creator == principal:
                      return True
              if Owner in role:
                  if object.owner == principal:
                      return True
  
          else:
              object_key = None
  
          all_roles = (
              self._fill_role_cache(principal)
              if self.app_state.use_cache
              else self._all_roles(principal)
          )
          roles = set()
          roles |= all_roles.get(None, set())
          roles |= all_roles.get(object_key, set())
          return len(valid_roles & roles) > 0