googleapis / python-datastore

Apache License 2.0
80 stars 44 forks source link

Remove warnings in sample code snippets related to using using `filter` positional args instead of keyword argument #504

Open parthea opened 12 months ago

parthea commented 12 months ago

https://github.com/googleapis/python-datastore/blob/a1051f289460221539e10713f03ddb5736a7d973/samples/snippets/snippets.py#L340

_____________ TestDatastoreSnippets.test_avg_query_property_filter _____________

self = 
capsys = <_pytest.capture.CaptureFixture object at 0x7fede0934e80>
client = 

    @backoff.on_exception(backoff.expo, AssertionError, max_time=240)
    def test_avg_query_property_filter(self, capsys, client):
>       tasks = snippets.avg_query_property_filter(client)

snippets_test.py:191: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
snippets.py:340: in avg_query_property_filter
    completed_tasks = client.query(kind="Task").add_filter("done", "=", True)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = 
property_name = 'done', operator = '=', value = True

    def add_filter(
        self,
        property_name=None,
        operator=None,
        value=None,
        *,
        filter=None,
    ):
        """Filter the query based on a property name, operator and a value.

        Expressions take the form of::

          .add_filter(
            filter=PropertyFilter('', '', )
          )

        where property is a property stored on the entity in the datastore
        and operator is one of ``OPERATORS``
        (ie, ``=``, ``<``, ``<=``, ``>``, ``>=``, ``!=``, ``IN``, ``NOT_IN``):

        Both AND and OR operations are supported by passing in a `CompositeFilter` object to the `filter` parameter::

           .add_filter(
               filter=And(
                   [
                       PropertyFilter('', '', ),
                       PropertyFilter('', '', )

                   ]
               )
           )

           .add_filter(
               filter=Or(
                   [
                       PropertyFilter('', '', ),
                       PropertyFilter('', '', )
                   ]
               )
           )

        .. testsetup:: query-filter

            import uuid

            from google.cloud import datastore
            from google.cloud.datastore.query import PropertyFilter

            client = datastore.Client()

        .. doctest:: query-filter

            >>> query = client.query(kind='Person')
            >>> query = query.add_filter(filter=PropertyFilter('name', '=', 'James'))
            >>> query = query.add_filter(filter=PropertyFilter('age', '>', 50))

        :type property_name: str
        :param property_name: A property name.

        :type operator: str
        :param operator: One of ``=``, ``<``, ``<=``, ``>``, ``>=``, ``!=``, ``IN``, ``NOT_IN``.

        :type value: :class:`int`, :class:`str`, :class:`bool`,
                     :class:`float`, :class:`NoneType`,
                     :class:`datetime.datetime`,
                     :class:`google.cloud.datastore.key.Key`
        :param value: The value to filter on.

        :type filter: :class:`CompositeFilter`, :class:`PropertyFiler`
        :param filter: A instance of a `BaseFilter`, either a `CompositeFilter` or `PropertyFilter`.

        :rtype: :class:`~google.cloud.datastore.query.Query`
        :returns: A query object.

        :raises: :class:`ValueError` if ``operation`` is not one of the
                 specified values, or if a filter names ``'__key__'`` but
                 passes an invalid value (a key is required).
        """
        if isinstance(property_name, PropertyFilter):
            raise ValueError(
                "PropertyFilter object must be passed using keyword argument 'filter'"
            )
        if isinstance(property_name, BaseCompositeFilter):
            raise ValueError(
                "'Or' and 'And' objects must be passed using keyword argument 'filter'"
            )

        if property_name is not None and operator is not None:
            if filter is not None:
                raise ValueError(
                    "Can't pass in both the positional arguments and 'filter' at the same time"
                )

            if property_name == KEY_PROPERTY_NAME and not isinstance(value, Key):
                raise ValueError('Invalid key: "%s"' % value)

            if self.OPERATORS.get(operator) is None:
                error_message = 'Invalid expression: "%s"' % (operator,)
                choices_message = "Please use one of: =, <, <=, >, >=, !=, IN, NOT_IN."
                raise ValueError(error_message, choices_message)

>           warnings.warn(
                "Detected filter using positional arguments. Prefer using the 'filter' keyword argument instead.",
                UserWarning,
                stacklevel=2,
            )
E           UserWarning: Detected filter using positional arguments. Prefer using the 'filter' keyword argument instead.

../../google/cloud/datastore/query.py:430: UserWarning
dhimmel commented 8 months ago

Noting related issues from firestore:

Based on those issues, it's not clear whether the warning is intentional due to a planned deprecation. Examples of the proposed solution to the warning would be helpful.