Copilot commented on code in PR #11026:
URL: https://github.com/apache/gravitino/pull/11026#discussion_r3216676725


##########
clients/client-python/gravitino/api/authorization/privileges.py:
##########
@@ -169,6 +171,21 @@ class Name(Enum):
         RUN_JOB = (0, 1 << 27)
         """The privilege to run a job."""
 
+        CREATE_VIEW = (0, 1 << 28)
+        """The privilege to create a view."""
+
+        SELECT_VIEW = (0, 1 << 29)
+        """The privilege to select data from a view."""

Review Comment:
   For backward compatibility with existing Gravitino deployments/clients, 
consider supporting deprecated legacy privilege names that exist in the 
server/Java API (e.g., CREATE_MODEL and CREATE_MODEL_VERSION) by adding them as 
aliases in Privilege.Name (sharing the same bit values) and mapping them in 
Privileges.allow()/deny(). Without this, Privileges.allow("CREATE_MODEL") will 
raise IllegalArgumentException even though the privilege name may still appear 
in older policies or user code.



##########
clients/client-python/gravitino/api/metadata_object.py:
##########
@@ -56,6 +56,9 @@ class Type(Enum):
         MySQL, etc.
         """
 
+        VIEW = "view"
+        """A view is mapped to the view of relational data sources like Apache 
Hive, MySQL, etc."""
+

Review Comment:
   Adding MetadataObject.Type.VIEW/FUNCTION here makes them part of the public 
type system, but MetadataObjects.of()/parse() and MetadataObjects.parent() 
currently don't recognize VIEW/FUNCTION (e.g., name-length/type validation and 
parent resolution). This will raise IllegalArgumentException when callers try 
to construct securable objects for view/function privileges. Please update 
MetadataObjects to support VIEW/FUNCTION (including parent type = SCHEMA and 
3-part names) and extend existing unit tests accordingly.



##########
clients/client-python/gravitino/api/authorization/privileges.py:
##########
@@ -218,6 +235,1454 @@ class Condition(Enum):
         DENY = "DENY"
 
 
-class Privileges:
-    # TODO Implement the Privileges class.
-    pass
+class GenericPrivilege(Privilege):
+    """Abstract class representing a generic privilege."""
+
+    def __init__(
+        self,
+        condition: Privilege.Condition,
+        name: Privilege.Name,
+    ) -> None:
+        self._condition = condition
+        self._name = name
+
+    def name(self) -> Privilege.Name:
+        return self._name
+
+    def condition(self) -> Privilege.Condition:
+        return self._condition
+
+    def simple_string(self) -> str:
+        return f"{self._condition.name} {self._name.name.lower().replace('_', 
' ')}"
+
+    def __hash__(self) -> int:
+        return hash((self._condition, self._name))
+
+    def __eq__(self, value: object) -> bool:
+        if not isinstance(value, GenericPrivilege):
+            return False
+        return self._condition == value._condition and self._name == 
value._name
+
+
+class CreateCatalog(GenericPrivilege):
+    """The privilege to create a catalog."""
+
+    _ALLOW_INSTANCE: Optional[CreateCatalog] = None
+    _DENY_INSTANCE: Optional[CreateCatalog] = None
+
+    @staticmethod
+    def allow() -> Privilege:
+        """
+        Retrieve the instance with allow condition of the privilege.
+
+        Returns:
+            Privilege: The privilege with allow condition.
+        """
+        if CreateCatalog._ALLOW_INSTANCE is None:
+            CreateCatalog._ALLOW_INSTANCE = CreateCatalog(
+                Privilege.Condition.ALLOW, Privilege.Name.CREATE_CATALOG
+            )
+        return CreateCatalog._ALLOW_INSTANCE
+
+    @staticmethod
+    def deny() -> Privilege:
+        """
+        Retrieve the instance with deny condition of the privilege.
+
+        Returns:
+            Privilege: The instance with deny condition of the privilege.
+        """
+        if CreateCatalog._DENY_INSTANCE is None:
+            CreateCatalog._DENY_INSTANCE = CreateCatalog(
+                Privilege.Condition.DENY, Privilege.Name.CREATE_CATALOG
+            )
+        return CreateCatalog._DENY_INSTANCE
+
+    def can_bind_to(self, obj_type: MetadataObject.Type) -> bool:
+        return obj_type == MetadataObject.Type.METALAKE
+
+
+class UseCatalog(GenericPrivilege):
+    """The privilege to use a catalog."""
+
+    _ALLOW_INSTANCE: Optional[UseCatalog] = None
+    _DENY_INSTANCE: Optional[UseCatalog] = None
+
+    @staticmethod
+    def allow() -> Privilege:
+        """
+        Retrieve the instance with allow condition of the privilege.
+
+        Returns:
+            Privilege: The instance with allow condition of the privilege.
+        """
+        if UseCatalog._ALLOW_INSTANCE is None:
+            UseCatalog._ALLOW_INSTANCE = UseCatalog(
+                Privilege.Condition.ALLOW, Privilege.Name.USE_CATALOG
+            )
+
+        return UseCatalog._ALLOW_INSTANCE
+
+    @staticmethod
+    def deny() -> Privilege:
+        """
+        Retrieve the instance with deny condition of the privilege.
+
+        Returns:
+            Privilege: The instance with deny condition of the privilege.
+        """
+        if UseCatalog._DENY_INSTANCE is None:
+            UseCatalog._DENY_INSTANCE = UseCatalog(
+                Privilege.Condition.DENY, Privilege.Name.USE_CATALOG
+            )
+
+        return UseCatalog._DENY_INSTANCE
+
+    def can_bind_to(self, obj_type: MetadataObject.Type) -> bool:
+        return obj_type in [MetadataObject.Type.METALAKE, 
MetadataObject.Type.CATALOG]
+
+
+class UseSchema(GenericPrivilege):
+    """The privilege to use a schema."""
+
+    _ALLOW_INSTANCE: Optional[UseSchema] = None
+    _DENY_INSTANCE: Optional[UseSchema] = None
+
+    @staticmethod
+    def allow() -> Privilege:
+        """
+        Retrieve the instance with allow condition of the privilege.
+
+        Returns:
+            Privilege: The instance with allow condition of the privilege.
+        """
+        if UseSchema._ALLOW_INSTANCE is None:
+            UseSchema._ALLOW_INSTANCE = UseSchema(
+                Privilege.Condition.ALLOW, Privilege.Name.USE_SCHEMA
+            )
+
+        return UseSchema._ALLOW_INSTANCE
+
+    @staticmethod
+    def deny() -> Privilege:
+        """
+        Retrieve the instance with deny condition of the privilege.
+
+        Returns:
+            Privilege: The instance with deny condition of the privilege.
+        """
+        if UseSchema._DENY_INSTANCE is None:
+            UseSchema._DENY_INSTANCE = UseSchema(
+                Privilege.Condition.DENY, Privilege.Name.USE_SCHEMA
+            )
+
+        return UseSchema._DENY_INSTANCE
+
+    def can_bind_to(self, obj_type: MetadataObject.Type) -> bool:
+        return obj_type in Privileges.SCHEMA_SUPPORTED_TYPES
+
+
+class CreateSchema(GenericPrivilege):
+    """Privilege to create a schema."""
+
+    _ALLOW_INSTANCE: Optional[CreateSchema] = None
+    _DENY_INSTANCE: Optional[CreateSchema] = None
+
+    @staticmethod
+    def allow() -> Privilege:
+        """
+        Retrieve the instance with allow condition of the privilege.
+
+        Returns:
+            Privilege: The instance with allow condition of the privilege.
+        """
+        if CreateSchema._ALLOW_INSTANCE is None:
+            CreateSchema._ALLOW_INSTANCE = CreateSchema(
+                Privilege.Condition.ALLOW, Privilege.Name.CREATE_SCHEMA
+            )
+
+        return CreateSchema._ALLOW_INSTANCE
+
+    @staticmethod
+    def deny() -> Privilege:
+        """
+        Retrieve the instance with deny condition of the privilege.
+
+        Returns:
+            Privilege: The instance with deny condition of the privilege.
+        """
+        if CreateSchema._DENY_INSTANCE is None:
+            CreateSchema._DENY_INSTANCE = CreateSchema(
+                Privilege.Condition.DENY, Privilege.Name.CREATE_SCHEMA
+            )
+
+        return CreateSchema._DENY_INSTANCE
+
+    def can_bind_to(self, obj_type: MetadataObject.Type) -> bool:
+        return obj_type in [MetadataObject.Type.METALAKE, 
MetadataObject.Type.CATALOG]
+
+
+class CreateTable(GenericPrivilege):
+    """The privilege to create a table."""
+
+    _ALLOW_INSTANCE: Optional[CreateTable] = None
+    _DENY_INSTANCE: Optional[CreateTable] = None
+
+    @staticmethod
+    def allow() -> Privilege:
+        """
+        Retrieve the instance with allow condition of the privilege.
+
+        Returns:
+            Privilege: The instance with allow condition of the privilege.
+        """
+        if CreateTable._ALLOW_INSTANCE is None:
+            CreateTable._ALLOW_INSTANCE = CreateTable(
+                Privilege.Condition.ALLOW, Privilege.Name.CREATE_TABLE
+            )
+
+        return CreateTable._ALLOW_INSTANCE
+
+    @staticmethod
+    def deny() -> Privilege:
+        """
+        Retrieve the instance with deny condition of the privilege.
+
+        Returns:
+            Privilege: The instance with deny condition of the privilege.
+        """
+        if CreateTable._DENY_INSTANCE is None:
+            CreateTable._DENY_INSTANCE = CreateTable(
+                Privilege.Condition.DENY, Privilege.Name.CREATE_TABLE
+            )
+
+        return CreateTable._DENY_INSTANCE
+
+    def can_bind_to(self, obj_type: MetadataObject.Type) -> bool:
+        return obj_type in Privileges.SCHEMA_SUPPORTED_TYPES
+
+
+class SelectTable(GenericPrivilege):
+    """
+    Privilege to select table.
+    """
+
+    _ALLOW_INSTANCE: Optional[SelectTable] = None
+    _DENY_INSTANCE: Optional[SelectTable] = None
+
+    @staticmethod
+    def allow() -> Privilege:
+        """
+        Retrieve the instance with allow condition of the privilege.
+
+        Returns:
+            Privilege: The instance with allow condition of the privilege.
+        """
+        if SelectTable._ALLOW_INSTANCE is None:
+            SelectTable._ALLOW_INSTANCE = SelectTable(
+                Privilege.Condition.ALLOW, Privilege.Name.SELECT_TABLE
+            )
+
+        return SelectTable._ALLOW_INSTANCE
+
+    @staticmethod
+    def deny() -> Privilege:
+        """
+        Retrieve the instance with deny condition of the privilege.
+
+        Returns:
+            Privilege: The instance with deny condition of the privilege.
+        """
+        if SelectTable._DENY_INSTANCE is None:
+            SelectTable._DENY_INSTANCE = SelectTable(
+                Privilege.Condition.DENY, Privilege.Name.SELECT_TABLE
+            )
+
+        return SelectTable._DENY_INSTANCE
+
+    def can_bind_to(self, obj_type: MetadataObject.Type) -> bool:
+        return obj_type in Privileges.TABLE_SUPPORTED_TYPES
+
+
+class ModifyTable(GenericPrivilege):
+    """The privilege to write data to a table or modify the table schema."""
+
+    _ALLOW_INSTANCE: Optional[ModifyTable] = None
+    _DENY_INSTANCE: Optional[ModifyTable] = None
+
+    @staticmethod
+    def allow() -> Privilege:
+        """
+        Retrieve the instance with allow condition of the privilege.
+
+        Returns:
+            Privilege: The instance with allow condition of the privilege.
+        """
+        if ModifyTable._ALLOW_INSTANCE is None:
+            ModifyTable._ALLOW_INSTANCE = ModifyTable(
+                Privilege.Condition.ALLOW, Privilege.Name.MODIFY_TABLE
+            )
+
+        return ModifyTable._ALLOW_INSTANCE
+
+    @staticmethod
+    def deny() -> Privilege:
+        """
+        Retrieve the instance with deny condition of the privilege.
+
+        Returns:
+            Privilege: The instance with deny condition of the privilege.
+        """
+        if ModifyTable._DENY_INSTANCE is None:
+            ModifyTable._DENY_INSTANCE = ModifyTable(
+                Privilege.Condition.DENY, Privilege.Name.MODIFY_TABLE
+            )
+
+        return ModifyTable._DENY_INSTANCE
+
+    def can_bind_to(self, obj_type: MetadataObject.Type) -> bool:
+        return obj_type in Privileges.TABLE_SUPPORTED_TYPES
+
+
+class CreateFileset(GenericPrivilege):
+    """The privilege to create a fileset."""
+
+    _ALLOW_INSTANCE: Optional[CreateFileset] = None
+    _DENY_INSTANCE: Optional[CreateFileset] = None
+
+    @staticmethod
+    def allow() -> Privilege:
+        """
+        Retrieve the instance with allow condition of the privilege.
+
+        Returns:
+            Privilege: The instance with allow condition of the privilege.
+        """
+        if CreateFileset._ALLOW_INSTANCE is None:
+            CreateFileset._ALLOW_INSTANCE = CreateFileset(
+                Privilege.Condition.ALLOW, Privilege.Name.CREATE_FILESET
+            )
+
+        return CreateFileset._ALLOW_INSTANCE
+
+    @staticmethod
+    def deny() -> Privilege:
+        """
+        Retrieve the instance with deny condition of the privilege.
+
+        Returns:
+            Privilege: The instance with deny condition of the privilege.
+        """
+        if CreateFileset._DENY_INSTANCE is None:
+            CreateFileset._DENY_INSTANCE = CreateFileset(
+                Privilege.Condition.DENY, Privilege.Name.CREATE_FILESET
+            )
+
+        return CreateFileset._DENY_INSTANCE
+
+    def can_bind_to(self, obj_type: MetadataObject.Type) -> bool:
+        return obj_type in Privileges.SCHEMA_SUPPORTED_TYPES
+
+
+class ReadFileset(GenericPrivilege):
+    """
+    Privilege to read fileset.
+    """
+
+    _ALLOW_INSTANCE: Optional[ReadFileset] = None
+    _DENY_INSTANCE: Optional[ReadFileset] = None
+
+    @staticmethod
+    def allow() -> Privilege:
+        """
+        Retrieve the instance with allow condition of the privilege.
+
+        Returns:
+            Privilege: The instance with allow condition of the privilege.
+        """
+        if ReadFileset._ALLOW_INSTANCE is None:
+            ReadFileset._ALLOW_INSTANCE = ReadFileset(
+                Privilege.Condition.ALLOW, Privilege.Name.READ_FILESET
+            )
+
+        return ReadFileset._ALLOW_INSTANCE
+
+    @staticmethod
+    def deny() -> Privilege:
+        """
+        Retrieve the instance with deny condition of the privilege.
+
+        Returns:
+            Privilege: The instance with deny condition of the privilege.
+        """
+        if ReadFileset._DENY_INSTANCE is None:
+            ReadFileset._DENY_INSTANCE = ReadFileset(
+                Privilege.Condition.DENY, Privilege.Name.READ_FILESET
+            )
+
+        return ReadFileset._DENY_INSTANCE
+
+    def can_bind_to(self, obj_type: MetadataObject.Type) -> bool:
+        return obj_type in Privileges.FILESET_SUPPORTED_TYPES
+
+
+class WriteFileset(GenericPrivilege):
+    """
+    Privilege to write fileset.
+    """
+
+    _ALLOW_INSTANCE: Optional[WriteFileset] = None
+    _DENY_INSTANCE: Optional[WriteFileset] = None
+
+    @staticmethod
+    def allow() -> Privilege:
+        """
+        Retrieve the instance with allow condition of the privilege.
+
+        Returns:
+            Privilege: The instance with allow condition of the privilege.
+        """
+        if WriteFileset._ALLOW_INSTANCE is None:
+            WriteFileset._ALLOW_INSTANCE = WriteFileset(
+                Privilege.Condition.ALLOW, Privilege.Name.WRITE_FILESET
+            )
+
+        return WriteFileset._ALLOW_INSTANCE
+
+    @staticmethod
+    def deny() -> Privilege:
+        """
+        Retrieve the instance with deny condition of the privilege.
+
+        Returns:
+            Privilege: The instance with deny condition of the privilege.
+
+        """
+        if WriteFileset._DENY_INSTANCE is None:
+            WriteFileset._DENY_INSTANCE = WriteFileset(
+                Privilege.Condition.DENY, Privilege.Name.WRITE_FILESET
+            )
+
+        return WriteFileset._DENY_INSTANCE
+
+    def can_bind_to(self, obj_type: MetadataObject.Type) -> bool:
+        return obj_type in Privileges.FILESET_SUPPORTED_TYPES
+
+
+class CreateTopic(GenericPrivilege):
+    """The privilege to create a topic."""
+
+    _ALLOW_INSTANCE: Optional[CreateTopic] = None
+    _DENY_INSTANCE: Optional[CreateTopic] = None
+
+    @staticmethod
+    def allow() -> Privilege:
+        """
+        Retrieve the instance with allow condition of the privilege.
+
+        Returns:
+            Privilege: The instance with allow condition of the privilege.
+
+        """
+        if CreateTopic._ALLOW_INSTANCE is None:
+            CreateTopic._ALLOW_INSTANCE = CreateTopic(
+                Privilege.Condition.ALLOW, Privilege.Name.CREATE_TOPIC
+            )
+
+        return CreateTopic._ALLOW_INSTANCE
+
+    @staticmethod
+    def deny() -> Privilege:
+        """
+        Retrieve the instance with deny condition of the privilege.
+
+        Returns:
+            Privilege: The instance with deny condition of the privilege.
+
+        """
+        if CreateTopic._DENY_INSTANCE is None:
+            CreateTopic._DENY_INSTANCE = CreateTopic(
+                Privilege.Condition.DENY, Privilege.Name.CREATE_TOPIC
+            )
+
+        return CreateTopic._DENY_INSTANCE
+
+    def can_bind_to(self, obj_type: MetadataObject.Type) -> bool:
+        return obj_type in Privileges.SCHEMA_SUPPORTED_TYPES
+
+
+class ConsumeTopic(GenericPrivilege):
+    """
+    Privilege for consuming a topic.
+    """
+
+    _ALLOW_INSTANCE: Optional[ConsumeTopic] = None
+    _DENY_INSTANCE: Optional[ConsumeTopic] = None
+
+    @staticmethod
+    def allow() -> Privilege:
+        """
+        Retrieve the instance with allow condition of the privilege.
+
+        Returns:
+            Privilege: The instance with allow condition of the privilege.
+
+        """
+        if ConsumeTopic._ALLOW_INSTANCE is None:
+            ConsumeTopic._ALLOW_INSTANCE = ConsumeTopic(
+                Privilege.Condition.ALLOW, Privilege.Name.CONSUME_TOPIC
+            )
+
+        return ConsumeTopic._ALLOW_INSTANCE
+
+    @staticmethod
+    def deny() -> Privilege:
+        """
+        Retrieve the instance with deny condition of the privilege.
+
+        Returns:
+            Privilege: The instance with deny condition of the privilege.
+
+        """
+        if ConsumeTopic._DENY_INSTANCE is None:
+            ConsumeTopic._DENY_INSTANCE = ConsumeTopic(
+                Privilege.Condition.DENY, Privilege.Name.CONSUME_TOPIC
+            )
+
+        return ConsumeTopic._DENY_INSTANCE
+
+    def can_bind_to(self, obj_type: MetadataObject.Type) -> bool:
+        return obj_type in Privileges.TOPIC_SUPPORTED_TYPES
+
+
+class ProduceTopic(GenericPrivilege):
+    """The privilege to produce to a topic."""
+
+    _ALLOW_INSTANCE: Optional[ProduceTopic] = None
+    _DENY_INSTANCE: Optional[ProduceTopic] = None
+
+    @staticmethod
+    def allow() -> Privilege:
+        """
+        Retrieve the instance with allow condition of the privilege.
+
+        Returns:
+            Privilege: The instance with allow condition of the privilege.
+
+        """
+        if ProduceTopic._ALLOW_INSTANCE is None:
+            ProduceTopic._ALLOW_INSTANCE = ProduceTopic(
+                Privilege.Condition.ALLOW, Privilege.Name.PRODUCE_TOPIC
+            )
+
+        return ProduceTopic._ALLOW_INSTANCE
+
+    @staticmethod
+    def deny() -> Privilege:
+        """
+        Retrieve the instance with deny condition of the privilege.
+
+        Returns:
+            Privilege: The instance with deny condition of the privilege.
+
+        """
+        if ProduceTopic._DENY_INSTANCE is None:
+            ProduceTopic._DENY_INSTANCE = ProduceTopic(
+                Privilege.Condition.DENY, Privilege.Name.PRODUCE_TOPIC
+            )
+
+        return ProduceTopic._DENY_INSTANCE
+
+    def can_bind_to(self, obj_type: MetadataObject.Type) -> bool:
+        return obj_type in Privileges.TOPIC_SUPPORTED_TYPES
+
+
+class ManageUsers(GenericPrivilege):
+    """The privilege to manage users."""
+
+    _ALLOW_INSTANCE: Optional[ManageUsers] = None
+    _DENY_INSTANCE: Optional[ManageUsers] = None
+
+    @staticmethod
+    def allow() -> Privilege:
+        """
+        Retrieve the instance with allow condition of the privilege.
+
+        Returns:
+            Privilege: The instance with allow condition of the privilege.
+
+        """
+        if ManageUsers._ALLOW_INSTANCE is None:
+            ManageUsers._ALLOW_INSTANCE = ManageUsers(
+                Privilege.Condition.ALLOW, Privilege.Name.MANAGE_USERS
+            )
+        return ManageUsers._ALLOW_INSTANCE
+
+    @staticmethod
+    def deny() -> Privilege:
+        """
+        Retrieve the instance with deny condition of the privilege.
+
+        Returns:
+            Privilege: The instance with deny condition of the privilege.
+
+        """
+        if ManageUsers._DENY_INSTANCE is None:
+            ManageUsers._DENY_INSTANCE = ManageUsers(
+                Privilege.Condition.DENY, Privilege.Name.MANAGE_USERS
+            )
+        return ManageUsers._DENY_INSTANCE
+
+    def can_bind_to(self, obj_type: MetadataObject.Type) -> bool:
+        return obj_type == MetadataObject.Type.METALAKE
+
+
+class ManageGroups(GenericPrivilege):
+    """The privilege to manage groups."""
+
+    _ALLOW_INSTANCE: Optional[ManageGroups] = None
+    _DENY_INSTANCE: Optional[ManageGroups] = None
+
+    @staticmethod
+    def allow() -> Privilege:
+        """
+        Retrieve the instance with allow condition of the privilege.
+
+        Returns:
+            Privilege: The instance with allow condition of the privilege.
+
+        """
+        if ManageGroups._ALLOW_INSTANCE is None:
+            ManageGroups._ALLOW_INSTANCE = ManageGroups(
+                Privilege.Condition.ALLOW, Privilege.Name.MANAGE_GROUPS
+            )
+
+        return ManageGroups._ALLOW_INSTANCE
+
+    @staticmethod
+    def deny() -> Privilege:
+        """
+        Retrieve the instance with deny condition of the privilege.
+
+        Returns:
+            Privilege: The instance with deny condition of the privilege.
+
+        """
+        if ManageGroups._DENY_INSTANCE is None:
+            ManageGroups._DENY_INSTANCE = ManageGroups(
+                Privilege.Condition.DENY, Privilege.Name.MANAGE_GROUPS
+            )
+
+        return ManageGroups._DENY_INSTANCE
+
+    def can_bind_to(self, obj_type: MetadataObject.Type) -> bool:
+        return obj_type == MetadataObject.Type.METALAKE
+
+
+class CreateRole(GenericPrivilege):
+    """The privilege to create a role."""
+
+    _ALLOW_INSTANCE: Optional[CreateRole] = None
+    _DENY_INSTANCE: Optional[CreateRole] = None
+
+    @staticmethod
+    def allow() -> Privilege:
+        """
+        Retrieve the instance with allow condition of the privilege.
+
+        Returns:
+            Privilege: The instance with allow condition of the privilege.
+
+        """
+        if CreateRole._ALLOW_INSTANCE is None:
+            CreateRole._ALLOW_INSTANCE = CreateRole(
+                Privilege.Condition.ALLOW, Privilege.Name.CREATE_ROLE
+            )
+
+        return CreateRole._ALLOW_INSTANCE
+
+    @staticmethod
+    def deny() -> Privilege:
+        """
+        Retrieve the instance with deny condition of the privilege.
+
+        Returns:
+            Privilege: The instance with deny condition of the privilege.
+
+        """
+        if CreateRole._DENY_INSTANCE is None:
+            CreateRole._DENY_INSTANCE = CreateRole(
+                Privilege.Condition.DENY, Privilege.Name.CREATE_ROLE
+            )
+
+        return CreateRole._DENY_INSTANCE
+
+    def can_bind_to(self, obj_type: MetadataObject.Type) -> bool:
+        return obj_type == MetadataObject.Type.METALAKE
+
+
+class ManageGrants(GenericPrivilege):
+    """
+    The privilege to grant or revoke privileges on securable objects. If bound 
on the metalake,
+    we can grant or revoke the role for users or groups.Unlike most privileges,
+    this can be bound at any level of the object hierarchy — METALAKE,
+    CATALOG, SCHEMA, TABLE, VIEW, TOPIC, FILESET, or MODEL.

Review Comment:
   ManageGrants docstring is out of sync with the actual supported binding 
types: Privileges.MANAGE_GRANTS_SUPPORTED_TYPES includes FUNCTION, but the 
docstring list ends at MODEL. Also, "groups.Unlike" is missing a space. Please 
update the docstring to include FUNCTION and fix the spacing/grammar so the 
documentation matches behavior.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to