Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-keyring for openSUSE:Factory 
checked in at 2022-09-18 17:31:58
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-keyring (Old)
 and      /work/SRC/openSUSE:Factory/.python-keyring.new.2083 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-keyring"

Sun Sep 18 17:31:58 2022 rev:47 rq:1004358 version:23.9.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-keyring/python-keyring.changes    
2022-08-30 14:48:11.567921185 +0200
+++ /work/SRC/openSUSE:Factory/.python-keyring.new.2083/python-keyring.changes  
2022-09-18 17:32:00.049732091 +0200
@@ -1,0 +2,21 @@
+Sat Sep 17 08:34:37 UTC 2022 - Dirk M??ller <dmuel...@suse.com>
+
+- update to 23.9.1:
+  * #593: Restore ``keyring.util.properties`` with deprecation warning for
+    backward compatibility.
+  * #588: Project now depends on ``jaraco.classes`` for class property support.
+  * #581: Corrected regression in ``libsecret`` tests (``.collection`` 
property).
+  * #587: Fix regression in ``libsecret``.
+  * #448: ``SecretService`` and ``libsecret`` backends now support a
+    new ``SelectableScheme``, allowing the keys for "username" and
+    "service" to be overridden for compatibility with other schemes
+    such as KeePassXC.
+  * Introduced a new ``.with_properties`` method on backends to
+    produce a new keyring with different properties. Use for example
+    to get a keyring with a different ``keychain`` (macOS) or
+    ``scheme`` (SecretService/libsecret). e.g.::
+      keypass = keyring.get_keyring().with_properties(scheme='KeePassXC')
+  * ``.with_keychain`` method on macOS is superseded by ``.with_properties``
+    and so is now deprecated.
+
+-------------------------------------------------------------------

Old:
----
  keyring-23.7.0.tar.gz

New:
----
  keyring-23.9.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-keyring.spec ++++++
--- /var/tmp/diff_new_pack.8xCEx2/_old  2022-09-18 17:32:00.621733760 +0200
+++ /var/tmp/diff_new_pack.8xCEx2/_new  2022-09-18 17:32:00.629733783 +0200
@@ -27,7 +27,7 @@
 %bcond_with test
 %endif
 Name:           python-keyring%{psuffix}
-Version:        23.7.0
+Version:        23.9.1
 Release:        0
 Summary:        System keyring service access from Python
 License:        MIT AND Python-2.0

++++++ keyring-23.7.0.tar.gz -> keyring-23.9.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyring-23.7.0/.github/workflows/main.yml 
new/keyring-23.9.1/.github/workflows/main.yml
--- old/keyring-23.7.0/.github/workflows/main.yml       2022-07-14 
08:38:54.000000000 +0200
+++ new/keyring-23.9.1/.github/workflows/main.yml       2022-09-05 
01:30:36.000000000 +0200
@@ -7,11 +7,9 @@
     strategy:
       matrix:
         python:
-        # Build on pre-releases until stable, then stable releases.
-        # actions/setup-python#213
-        - ~3.7.0-0
-        - ~3.10.0-0
-        - ~3.11.0-0
+        - 3.7
+        - '3.10'
+        - '3.11'
         platform:
         - ubuntu-latest
         - macos-latest
@@ -20,9 +18,9 @@
     steps:
       - uses: actions/checkout@v3
       - name: Setup Python
-        uses: actions/setup-python@v3
+        uses: actions/setup-python@v4
         with:
-          python-version: ${{ matrix.python }}
+          python-version: ${{ matrix.python }}-dev
       - name: Install tox
         run: |
           python -m pip install tox
@@ -52,9 +50,9 @@
     steps:
       - uses: actions/checkout@v3
       - name: Setup Python
-        uses: actions/setup-python@v3
+        uses: actions/setup-python@v4
         with:
-          python-version: "3.10"
+          python-version: "3.11-dev"
       - name: Install tox
         run: |
           python -m pip install tox
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyring-23.7.0/CHANGES.rst 
new/keyring-23.9.1/CHANGES.rst
--- old/keyring-23.7.0/CHANGES.rst      2022-07-14 08:38:54.000000000 +0200
+++ new/keyring-23.9.1/CHANGES.rst      2022-09-05 01:30:36.000000000 +0200
@@ -1,3 +1,42 @@
+v23.9.1
+-------
+
+* #593: Restore ``keyring.util.properties`` with deprecation warning for
+  backward compatibility.
+
+v23.9.0
+-------
+
+* #588: Project now depends on ``jaraco.classes`` for class property support.
+
+v23.8.2
+-------
+
+* #581: Corrected regression in ``libsecret`` tests (``.collection`` property).
+
+v23.8.1
+-------
+
+* #587: Fix regression in ``libsecret``.
+
+v23.8.0
+-------
+
+* #448: ``SecretService`` and ``libsecret`` backends now support a
+  new ``SelectableScheme``, allowing the keys for "username" and
+  "service" to be overridden for compatibility with other schemes
+  such as KeePassXC.
+
+* Introduced a new ``.with_properties`` method on backends to
+  produce a new keyring with different properties. Use for example
+  to get a keyring with a different ``keychain`` (macOS) or
+  ``scheme`` (SecretService/libsecret). e.g.::
+
+    keypass = keyring.get_keyring().with_properties(scheme='KeePassXC')
+
+* ``.with_keychain`` method on macOS is superseded by ``.with_properties``
+  and so is now deprecated.
+
 v23.7.0
 -------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyring-23.7.0/PKG-INFO new/keyring-23.9.1/PKG-INFO
--- old/keyring-23.7.0/PKG-INFO 2022-07-14 08:39:16.994262000 +0200
+++ new/keyring-23.9.1/PKG-INFO 2022-09-05 01:31:07.461742000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: keyring
-Version: 23.7.0
+Version: 23.9.1
 Summary: Store and access your passwords safely.
 Home-page: https://github.com/jaraco/keyring
 Author: Kang Zhang
@@ -77,7 +77,7 @@
 Compatibility - macOS
 =====================
 
-macOS keychain support macOS 11 (Big Sur) and later requires Python 3.8.7
+macOS keychain supports macOS 11 (Big Sur) and later requires Python 3.8.7
 or later with the "universal2" binary. See
 `#525 <https://github.com/jaraco/keyring/issues/525>`_ for details.
 
@@ -98,7 +98,7 @@
 Keyring supplies a ``keyring`` command which is installed with the
 package. After installing keyring in most environments, the
 command should be available for setting, getting, and deleting
-passwords. For more information on usage, invoke with no arguments
+passwords. For more usage information, invoke with no arguments
 or with ``--help`` as so::
 
     $ keyring --help
@@ -163,7 +163,7 @@
 In addition to the backends provided by the core keyring package for
 the most common and secure use cases, there
 are additional keyring backend implementations available for other
-use-cases. Simply install them to make them available:
+use cases. Simply install them to make them available:
 
 - `keyrings.cryptfile <https://pypi.org/project/keyrings.cryptfile>`_
   - Encrypted text file storage.
@@ -183,7 +183,7 @@
   backend which uses the ssh agent protocol's signature operation to
   derive the cipher key.
 - `keyrings.osx_keychain_keys 
<https://pypi.org/project/keyrings.osx-keychain-keys>`_
-  - OSX keychain key-management, for private, public and symmetric keys.
+  - OSX keychain key-management, for private, public, and symmetric keys.
 
 
 Write your own keyring backend
@@ -203,7 +203,7 @@
 in the ``keyrings`` namespace, in a manner modeled by the `keyrings.alt
 package <https://github.com/jaraco/keyrings.alt>`_. See the
 ``setup.cfg`` file
-in that project for a hints on how to create the requisite entry points.
+in that project for hints on how to create the requisite entry points.
 Backends that prove essential may be considered for inclusion in the core
 library, although the ease of installing these third-party packages should
 mean that extensions may be readily available.
@@ -224,7 +224,7 @@
     import keyring.backend
 
     class TestKeyring(keyring.backend.KeyringBackend):
-        """A test keyring which always outputs same password
+        """A test keyring which always outputs the same password
         """
         priority = 1
 
@@ -265,7 +265,7 @@
 - Uninstall keyring. Most applications are tolerant to keyring
   not being installed. Uninstalling keyring should cause those
   applications to fall back to the behavior without keyring.
-  This approach affects that Python environment where keyring
+  This approach affects the Python environment where keyring
   would otherwise have been installed.
 
 - Configure the Null keyring in the environment. Set
@@ -336,7 +336,7 @@
 
   When that command is started, enter a password into stdin and
   press Ctrl+D (end of data). After that, the daemon will fork into
-  background (use ``--foreground`` option to block).
+  the background (use ``--foreground`` option to block).
 * Now you can use the SecretService backend of Keyring. Remember to
   run your application in the same D-Bus session as the daemon.
 
@@ -397,11 +397,11 @@
 Exceptions
 ----------
 
-The keyring lib raises following exceptions:
+The keyring lib raises the following exceptions:
 
 * ``keyring.errors.KeyringError``: Base Error class for all exceptions in 
keyring lib.
 * ``keyring.errors.InitError``: Raised when the keyring cannot be initialized.
-* ``keyring.errors.PasswordSetError``: Raised when password cannot be set in 
the keyring.
+* ``keyring.errors.PasswordSetError``: Raised when the password cannot be set 
in the keyring.
 * ``keyring.errors.PasswordDeleteError``: Raised when the password cannot be 
deleted in the keyring.
 
 Get Involved
@@ -433,7 +433,7 @@
 Security Considerations
 =======================
 
-Each builtin backend may have security considerations to understand
+Each built-in backend may have security considerations to understand
 before using this library. Authors of tools or libraries utilizing
 ``keyring`` are encouraged to consider these concerns.
 
@@ -461,7 +461,7 @@
 Making Releases
 ===============
 
-This project makes use of automated releases continuous
+This project makes use of automated releases and continuous
 integration. The
 simple workflow is to tag a commit and push it to Github. If it
 passes tests in CI, it will be automatically deployed to PyPI.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyring-23.7.0/README.rst 
new/keyring-23.9.1/README.rst
--- old/keyring-23.7.0/README.rst       2022-07-14 08:38:54.000000000 +0200
+++ new/keyring-23.9.1/README.rst       2022-09-05 01:30:36.000000000 +0200
@@ -57,7 +57,7 @@
 Compatibility - macOS
 =====================
 
-macOS keychain support macOS 11 (Big Sur) and later requires Python 3.8.7
+macOS keychain supports macOS 11 (Big Sur) and later requires Python 3.8.7
 or later with the "universal2" binary. See
 `#525 <https://github.com/jaraco/keyring/issues/525>`_ for details.
 
@@ -78,7 +78,7 @@
 Keyring supplies a ``keyring`` command which is installed with the
 package. After installing keyring in most environments, the
 command should be available for setting, getting, and deleting
-passwords. For more information on usage, invoke with no arguments
+passwords. For more usage information, invoke with no arguments
 or with ``--help`` as so::
 
     $ keyring --help
@@ -143,7 +143,7 @@
 In addition to the backends provided by the core keyring package for
 the most common and secure use cases, there
 are additional keyring backend implementations available for other
-use-cases. Simply install them to make them available:
+use cases. Simply install them to make them available:
 
 - `keyrings.cryptfile <https://pypi.org/project/keyrings.cryptfile>`_
   - Encrypted text file storage.
@@ -163,7 +163,7 @@
   backend which uses the ssh agent protocol's signature operation to
   derive the cipher key.
 - `keyrings.osx_keychain_keys 
<https://pypi.org/project/keyrings.osx-keychain-keys>`_
-  - OSX keychain key-management, for private, public and symmetric keys.
+  - OSX keychain key-management, for private, public, and symmetric keys.
 
 
 Write your own keyring backend
@@ -183,7 +183,7 @@
 in the ``keyrings`` namespace, in a manner modeled by the `keyrings.alt
 package <https://github.com/jaraco/keyrings.alt>`_. See the
 ``setup.cfg`` file
-in that project for a hints on how to create the requisite entry points.
+in that project for hints on how to create the requisite entry points.
 Backends that prove essential may be considered for inclusion in the core
 library, although the ease of installing these third-party packages should
 mean that extensions may be readily available.
@@ -204,7 +204,7 @@
     import keyring.backend
 
     class TestKeyring(keyring.backend.KeyringBackend):
-        """A test keyring which always outputs same password
+        """A test keyring which always outputs the same password
         """
         priority = 1
 
@@ -245,7 +245,7 @@
 - Uninstall keyring. Most applications are tolerant to keyring
   not being installed. Uninstalling keyring should cause those
   applications to fall back to the behavior without keyring.
-  This approach affects that Python environment where keyring
+  This approach affects the Python environment where keyring
   would otherwise have been installed.
 
 - Configure the Null keyring in the environment. Set
@@ -316,7 +316,7 @@
 
   When that command is started, enter a password into stdin and
   press Ctrl+D (end of data). After that, the daemon will fork into
-  background (use ``--foreground`` option to block).
+  the background (use ``--foreground`` option to block).
 * Now you can use the SecretService backend of Keyring. Remember to
   run your application in the same D-Bus session as the daemon.
 
@@ -377,11 +377,11 @@
 Exceptions
 ----------
 
-The keyring lib raises following exceptions:
+The keyring lib raises the following exceptions:
 
 * ``keyring.errors.KeyringError``: Base Error class for all exceptions in 
keyring lib.
 * ``keyring.errors.InitError``: Raised when the keyring cannot be initialized.
-* ``keyring.errors.PasswordSetError``: Raised when password cannot be set in 
the keyring.
+* ``keyring.errors.PasswordSetError``: Raised when the password cannot be set 
in the keyring.
 * ``keyring.errors.PasswordDeleteError``: Raised when the password cannot be 
deleted in the keyring.
 
 Get Involved
@@ -413,7 +413,7 @@
 Security Considerations
 =======================
 
-Each builtin backend may have security considerations to understand
+Each built-in backend may have security considerations to understand
 before using this library. Authors of tools or libraries utilizing
 ``keyring`` are encouraged to consider these concerns.
 
@@ -441,7 +441,7 @@
 Making Releases
 ===============
 
-This project makes use of automated releases continuous
+This project makes use of automated releases and continuous
 integration. The
 simple workflow is to tag a commit and push it to Github. If it
 passes tests in CI, it will be automatically deployed to PyPI.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyring-23.7.0/keyring/_compat.py 
new/keyring-23.9.1/keyring/_compat.py
--- old/keyring-23.7.0/keyring/_compat.py       1970-01-01 01:00:00.000000000 
+0100
+++ new/keyring-23.9.1/keyring/_compat.py       2022-09-05 01:30:36.000000000 
+0200
@@ -0,0 +1,7 @@
+__all__ = ['properties']
+
+
+try:
+    from jaraco.compat import properties  # pragma: no-cover
+except ImportError:
+    from . import _properties_compat as properties  # pragma: no-cover
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyring-23.7.0/keyring/_properties_compat.py 
new/keyring-23.9.1/keyring/_properties_compat.py
--- old/keyring-23.7.0/keyring/_properties_compat.py    1970-01-01 
01:00:00.000000000 +0100
+++ new/keyring-23.9.1/keyring/_properties_compat.py    2022-09-05 
01:30:36.000000000 +0200
@@ -0,0 +1,169 @@
+# from jaraco.classes 3.2.2
+
+
+class NonDataProperty:
+    """Much like the property builtin, but only implements __get__,
+    making it a non-data property, and can be subsequently reset.
+
+    See http://users.rcn.com/python/download/Descriptor.htm for more
+    information.
+
+    >>> class X(object):
+    ...   @NonDataProperty
+    ...   def foo(self):
+    ...     return 3
+    >>> x = X()
+    >>> x.foo
+    3
+    >>> x.foo = 4
+    >>> x.foo
+    4
+    """
+
+    def __init__(self, fget):
+        assert fget is not None, "fget cannot be none"
+        assert callable(fget), "fget must be callable"
+        self.fget = fget
+
+    def __get__(self, obj, objtype=None):
+        if obj is None:
+            return self
+        return self.fget(obj)
+
+
+class classproperty:
+    """
+    Like @property but applies at the class level.
+
+
+    >>> class X(metaclass=classproperty.Meta):
+    ...   val = None
+    ...   @classproperty
+    ...   def foo(cls):
+    ...     return cls.val
+    ...   @foo.setter
+    ...   def foo(cls, val):
+    ...     cls.val = val
+    >>> X.foo
+    >>> X.foo = 3
+    >>> X.foo
+    3
+    >>> x = X()
+    >>> x.foo
+    3
+    >>> X.foo = 4
+    >>> x.foo
+    4
+
+    Setting the property on an instance affects the class.
+
+    >>> x.foo = 5
+    >>> x.foo
+    5
+    >>> X.foo
+    5
+    >>> vars(x)
+    {}
+    >>> X().foo
+    5
+
+    Attempting to set an attribute where no setter was defined
+    results in an AttributeError:
+
+    >>> class GetOnly(metaclass=classproperty.Meta):
+    ...   @classproperty
+    ...   def foo(cls):
+    ...     return 'bar'
+    >>> GetOnly.foo = 3
+    Traceback (most recent call last):
+    ...
+    AttributeError: can't set attribute
+
+    It is also possible to wrap a classmethod or staticmethod in
+    a classproperty.
+
+    >>> class Static(metaclass=classproperty.Meta):
+    ...   @classproperty
+    ...   @classmethod
+    ...   def foo(cls):
+    ...     return 'foo'
+    ...   @classproperty
+    ...   @staticmethod
+    ...   def bar():
+    ...     return 'bar'
+    >>> Static.foo
+    'foo'
+    >>> Static.bar
+    'bar'
+
+    *Legacy*
+
+    For compatibility, if the metaclass isn't specified, the
+    legacy behavior will be invoked.
+
+    >>> class X:
+    ...   val = None
+    ...   @classproperty
+    ...   def foo(cls):
+    ...     return cls.val
+    ...   @foo.setter
+    ...   def foo(cls, val):
+    ...     cls.val = val
+    >>> X.foo
+    >>> X.foo = 3
+    >>> X.foo
+    3
+    >>> x = X()
+    >>> x.foo
+    3
+    >>> X.foo = 4
+    >>> x.foo
+    4
+
+    Note, because the metaclass was not specified, setting
+    a value on an instance does not have the intended effect.
+
+    >>> x.foo = 5
+    >>> x.foo
+    5
+    >>> X.foo  # should be 5
+    4
+    >>> vars(x)  # should be empty
+    {'foo': 5}
+    >>> X().foo  # should be 5
+    4
+    """
+
+    class Meta(type):
+        def __setattr__(self, key, value):
+            obj = self.__dict__.get(key, None)
+            if type(obj) is classproperty:
+                return obj.__set__(self, value)
+            return super().__setattr__(key, value)
+
+    def __init__(self, fget, fset=None):
+        self.fget = self._ensure_method(fget)
+        self.fset = fset
+        fset and self.setter(fset)
+
+    def __get__(self, instance, owner=None):
+        return self.fget.__get__(None, owner)()
+
+    def __set__(self, owner, value):
+        if not self.fset:
+            raise AttributeError("can't set attribute")
+        if type(owner) is not classproperty.Meta:
+            owner = type(owner)
+        return self.fset.__get__(None, owner)(value)
+
+    def setter(self, fset):
+        self.fset = self._ensure_method(fset)
+        return self
+
+    @classmethod
+    def _ensure_method(cls, fn):
+        """
+        Ensure fn is a classmethod or staticmethod.
+        """
+        needs_method = not isinstance(fn, (classmethod, staticmethod))
+        return classmethod(fn) if needs_method else fn
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyring-23.7.0/keyring/backend.py 
new/keyring-23.9.1/keyring/backend.py
--- old/keyring-23.7.0/keyring/backend.py       2022-07-14 08:38:54.000000000 
+0200
+++ new/keyring-23.9.1/keyring/backend.py       2022-09-05 01:30:36.000000000 
+0200
@@ -6,12 +6,13 @@
 import abc
 import logging
 import operator
+import copy
 
 from typing import Optional
 
 from .py310compat import metadata
 from . import credentials, errors, util
-from .util import properties
+from ._compat import properties
 
 log = logging.getLogger(__name__)
 
@@ -60,8 +61,7 @@
         suitable, but a priority of one or greater is recommended.
         """
 
-    @properties.ClassProperty
-    @classmethod
+    @properties.classproperty
     def viable(cls):
         with errors.ExceptionRaisedContext() as exc:
             cls.priority
@@ -74,8 +74,7 @@
         """
         return filter(operator.attrgetter('viable'), cls._classes)
 
-    @properties.ClassProperty
-    @classmethod
+    @properties.classproperty
     def name(cls):
         """
         The keyring name, suitable for display.
@@ -151,6 +150,11 @@
         for name, value in props:
             setattr(self, name, value)
 
+    def with_properties(self, **kwargs):
+        alt = copy.copy(self)
+        vars(alt).update(kwargs)
+        return alt
+
 
 class Crypter:
     """Base class providing encryption and decryption"""
@@ -212,3 +216,41 @@
     viable_classes = KeyringBackend.get_viable_backends()
     rings = util.suppress_exceptions(viable_classes, exceptions=TypeError)
     return list(rings)
+
+
+class SchemeSelectable:
+    """
+    Allow a backend to select different "schemes" for the
+    username and service.
+
+    >>> backend = SchemeSelectable()
+    >>> backend._query('contoso', 'alice')
+    {'username': 'alice', 'service': 'contoso'}
+    >>> backend._query('contoso')
+    {'service': 'contoso'}
+    >>> backend.scheme = 'KeePassXC'
+    >>> backend._query('contoso', 'alice')
+    {'UserName': 'alice', 'Title': 'contoso'}
+    >>> backend._query('contoso', 'alice', foo='bar')
+    {'UserName': 'alice', 'Title': 'contoso', 'foo': 'bar'}
+    """
+
+    scheme = 'default'
+    schemes = dict(
+        default=dict(username='username', service='service'),
+        KeePassXC=dict(username='UserName', service='Title'),
+    )
+
+    def _query(self, service, username=None, **base):
+        scheme = self.schemes[self.scheme]
+        return dict(
+            {
+                scheme['username']: username,
+                scheme['service']: service,
+            }
+            if username is not None
+            else {
+                scheme['service']: service,
+            },
+            **base,
+        )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyring-23.7.0/keyring/backends/SecretService.py 
new/keyring-23.9.1/keyring/backends/SecretService.py
--- old/keyring-23.7.0/keyring/backends/SecretService.py        2022-07-14 
08:38:54.000000000 +0200
+++ new/keyring-23.9.1/keyring/backends/SecretService.py        2022-09-05 
01:30:36.000000000 +0200
@@ -1,7 +1,8 @@
 from contextlib import closing
 import logging
 
-from ..util import properties
+from .. import backend
+from .._compat import properties
 from ..backend import KeyringBackend
 from ..credentials import SimpleCredential
 from ..errors import (
@@ -23,13 +24,12 @@
 log = logging.getLogger(__name__)
 
 
-class Keyring(KeyringBackend):
+class Keyring(backend.SchemeSelectable, KeyringBackend):
     """Secret Service Keyring"""
 
     appid = 'Python keyring library'
 
-    @properties.ClassProperty
-    @classmethod
+    @properties.classproperty
     def priority(cls):
         with ExceptionRaisedContext() as exc:
             secretstorage.__name__
@@ -77,7 +77,7 @@
         """Get password of the username for the service"""
         collection = self.get_preferred_collection()
         with closing(collection.connection):
-            items = collection.search_items({"username": username, "service": 
service})
+            items = collection.search_items(self._query(service, username))
             for item in items:
                 self.unlock(item)
                 return item.get_secret().decode('utf-8')
@@ -85,11 +85,7 @@
     def set_password(self, service, username, password):
         """Set password for the username of the service"""
         collection = self.get_preferred_collection()
-        attributes = {
-            "application": self.appid,
-            "service": service,
-            "username": username,
-        }
+        attributes = self._query(service, username, application=self.appid)
         label = "Password for '{}' on '{}'".format(username, service)
         with closing(collection.connection):
             collection.create_item(label, attributes, password, replace=True)
@@ -98,7 +94,7 @@
         """Delete the stored password (only the first one)"""
         collection = self.get_preferred_collection()
         with closing(collection.connection):
-            items = collection.search_items({"username": username, "service": 
service})
+            items = collection.search_items(self._query(service, username))
             for item in items:
                 return item.delete()
         raise PasswordDeleteError("No such password!")
@@ -111,16 +107,13 @@
         and return a SimpleCredential containing  the username and password
         Otherwise, it will return the first username and password combo that 
it finds.
         """
-
-        query = {"service": service}
-        if username:
-            query["username"] = username
-
+        scheme = self.schemes[self.scheme]
+        query = self._query(service, username)
         collection = self.get_preferred_collection()
 
         with closing(collection.connection):
             items = collection.search_items(query)
             for item in items:
                 self.unlock(item)
-                username = item.get_attributes().get("username")
+                username = item.get_attributes().get(scheme['username'])
                 return SimpleCredential(username, 
item.get_secret().decode('utf-8'))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyring-23.7.0/keyring/backends/Windows.py 
new/keyring-23.9.1/keyring/backends/Windows.py
--- old/keyring-23.7.0/keyring/backends/Windows.py      2022-07-14 
08:38:54.000000000 +0200
+++ new/keyring-23.9.1/keyring/backends/Windows.py      2022-09-05 
01:30:36.000000000 +0200
@@ -1,6 +1,6 @@
 import logging
 
-from ..util import properties
+from .._compat import properties
 from ..backend import KeyringBackend
 from ..credentials import SimpleCredential
 from ..errors import PasswordDeleteError, ExceptionRaisedContext
@@ -80,8 +80,7 @@
 
     persist = Persistence()
 
-    @properties.ClassProperty
-    @classmethod
+    @properties.classproperty
     def priority(cls):
         """
         If available, the preferred backend on Windows.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyring-23.7.0/keyring/backends/chainer.py 
new/keyring-23.9.1/keyring/backends/chainer.py
--- old/keyring-23.7.0/keyring/backends/chainer.py      2022-07-14 
08:38:54.000000000 +0200
+++ new/keyring-23.9.1/keyring/backends/chainer.py      2022-09-05 
01:30:36.000000000 +0200
@@ -4,7 +4,7 @@
 """
 
 from .. import backend
-from ..util import properties
+from .._compat import properties
 from . import fail
 
 
@@ -18,8 +18,7 @@
     # until other backends have been constructed
     viable = True
 
-    @properties.ClassProperty
-    @classmethod
+    @properties.classproperty
     def priority(cls):
         """
         If there are backends to chain, high priority
@@ -28,8 +27,7 @@
         """
         return 10 if len(cls.backends) > 1 else (fail.Keyring.priority - 1)
 
-    @properties.ClassProperty
-    @classmethod
+    @properties.classproperty
     def backends(cls):
         """
         Discover all keyrings for chaining.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyring-23.7.0/keyring/backends/kwallet.py 
new/keyring-23.9.1/keyring/backends/kwallet.py
--- old/keyring-23.7.0/keyring/backends/kwallet.py      2022-07-14 
08:38:54.000000000 +0200
+++ new/keyring-23.9.1/keyring/backends/kwallet.py      2022-09-05 
01:30:36.000000000 +0200
@@ -6,7 +6,7 @@
 from ..credentials import SimpleCredential
 from ..errors import PasswordDeleteError
 from ..errors import PasswordSetError, InitError, KeyringLocked
-from ..util import properties
+from .._compat import properties
 
 try:
     import dbus
@@ -37,8 +37,7 @@
     bus_name = 'org.kde.kwalletd5'
     object_path = '/modules/kwalletd5'
 
-    @properties.ClassProperty
-    @classmethod
+    @properties.classproperty
     def priority(cls):
         if 'dbus' not in globals():
             raise RuntimeError('python-dbus not installed')
@@ -161,7 +160,6 @@
     bus_name = 'org.kde.kwalletd'
     object_path = '/modules/kwalletd'
 
-    @properties.ClassProperty
-    @classmethod
+    @properties.classproperty
     def priority(cls):
         return super().priority - 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyring-23.7.0/keyring/backends/libsecret.py 
new/keyring-23.9.1/keyring/backends/libsecret.py
--- old/keyring-23.7.0/keyring/backends/libsecret.py    2022-07-14 
08:38:54.000000000 +0200
+++ new/keyring-23.9.1/keyring/backends/libsecret.py    2022-09-05 
01:30:36.000000000 +0200
@@ -1,6 +1,7 @@
 import logging
 
-from ..util import properties
+from .. import backend
+from .._compat import properties
 from ..backend import KeyringBackend
 from ..credentials import SimpleCredential
 from ..errors import (
@@ -26,24 +27,28 @@
 log = logging.getLogger(__name__)
 
 
-class Keyring(KeyringBackend):
+class Keyring(backend.SchemeSelectable, KeyringBackend):
     """libsecret Keyring"""
 
     appid = 'Python keyring library'
-    if available:
-        schema = Secret.Schema.new(
+
+    @property
+    def schema(self):
+        return Secret.Schema.new(
             "org.freedesktop.Secret.Generic",
             Secret.SchemaFlags.NONE,
-            {
-                "application": Secret.SchemaAttributeType.STRING,
-                "service": Secret.SchemaAttributeType.STRING,
-                "username": Secret.SchemaAttributeType.STRING,
-            },
+            self._query(
+                Secret.SchemaAttributeType.STRING,
+                Secret.SchemaAttributeType.STRING,
+                application=Secret.SchemaAttributeType.STRING,
+            ),
         )
-        collection = Secret.COLLECTION_DEFAULT
 
-    @properties.ClassProperty
-    @classmethod
+    @properties.NonDataProperty
+    def collection(self):
+        return Secret.COLLECTION_DEFAULT
+
+    @properties.classproperty
     def priority(cls):
         with ExceptionRaisedContext() as exc:
             Secret.__name__
@@ -53,11 +58,7 @@
 
     def get_password(self, service, username):
         """Get password of the username for the service"""
-        attributes = {
-            "application": self.appid,
-            "service": service,
-            "username": username,
-        }
+        attributes = self._query(service, username, application=self.appid)
         try:
             items = Secret.password_search_sync(
                 self.schema, attributes, Secret.SearchFlags.UNLOCK, None
@@ -78,11 +79,7 @@
 
     def set_password(self, service, username, password):
         """Set password for the username of the service"""
-        attributes = {
-            "application": self.appid,
-            "service": service,
-            "username": username,
-        }
+        attributes = self._query(service, username, application=self.appid)
         label = "Password for '{}' on '{}'".format(username, service)
         try:
             stored = Secret.password_store_sync(
@@ -101,11 +98,7 @@
 
     def delete_password(self, service, username):
         """Delete the stored password (only the first one)"""
-        attributes = {
-            "application": self.appid,
-            "service": service,
-            "username": username,
-        }
+        attributes = self._query(service, username, application=self.appid)
         try:
             items = Secret.password_search_sync(
                 self.schema, attributes, Secret.SearchFlags.UNLOCK, None
@@ -136,9 +129,7 @@
         and return a SimpleCredential containing  the username and password
         Otherwise, it will return the first username and password combo that 
it finds.
         """
-        query = {"service": service}
-        if username:
-            query["username"] = username
+        query = self._query(service, username)
         try:
             items = Secret.password_search_sync(
                 self.schema, query, Secret.SearchFlags.UNLOCK, None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyring-23.7.0/keyring/backends/macOS/__init__.py 
new/keyring-23.9.1/keyring/backends/macOS/__init__.py
--- old/keyring-23.7.0/keyring/backends/macOS/__init__.py       2022-07-14 
08:38:54.000000000 +0200
+++ new/keyring-23.9.1/keyring/backends/macOS/__init__.py       2022-09-05 
01:30:36.000000000 +0200
@@ -1,12 +1,13 @@
 import platform
 import os
+import warnings
 
 from ...backend import KeyringBackend
 from ...errors import PasswordSetError
 from ...errors import PasswordDeleteError
 from ...errors import KeyringLocked
 from ...errors import KeyringError
-from ...util import properties
+from ..._compat import properties
 
 try:
     from . import api
@@ -20,8 +21,7 @@
     keychain = os.environ.get('KEYCHAIN_PATH')
     "Path to keychain file, overriding default"
 
-    @properties.ClassProperty
-    @classmethod
+    @properties.classproperty
     def priority(cls):
         """
         Preferred for all macOS environments.
@@ -68,6 +68,9 @@
             )
 
     def with_keychain(self, keychain):
-        alt = Keyring()
-        alt.keychain = keychain
-        return alt
+        warnings.warn(
+            "macOS.Keyring.with_keychain is deprecated. Use with_properties 
instead.",
+            DeprecationWarning,
+            stacklevel=2,
+        )
+        return self.with_properties(keychain=keychain)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyring-23.7.0/keyring/testing/backend.py 
new/keyring-23.9.1/keyring/testing/backend.py
--- old/keyring-23.7.0/keyring/testing/backend.py       2022-07-14 
08:38:54.000000000 +0200
+++ new/keyring-23.9.1/keyring/testing/backend.py       2022-09-05 
01:30:36.000000000 +0200
@@ -163,3 +163,10 @@
         monkeypatch.setattr(os, 'environ', env)
         self.keyring.set_properties_from_env()
         assert self.keyring.foo_bar == 'fizz buzz'
+
+    def test_new_with_properties(self):
+        alt = self.keyring.with_properties(foo='bar')
+        assert alt is not self.keyring
+        assert alt.foo == 'bar'
+        with pytest.raises(AttributeError):
+            self.keyring.foo
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyring-23.7.0/keyring/util/properties.py 
new/keyring-23.9.1/keyring/util/properties.py
--- old/keyring-23.7.0/keyring/util/properties.py       2022-07-14 
08:38:54.000000000 +0200
+++ new/keyring-23.9.1/keyring/util/properties.py       2022-09-05 
01:30:36.000000000 +0200
@@ -1,57 +1,18 @@
-from collections import abc
+"""
+Backward compat shim
+"""
 
+import warnings
 
-class ClassProperty(property):
-    """
-    An implementation of a property callable on a class. Used to decorate a
-    classmethod but to then treat it like a property.
-
-    Example:
-
-    >>> class MyClass:
-    ...    @ClassProperty
-    ...    @classmethod
-    ...    def skillz(cls):
-    ...        return cls.__name__.startswith('My')
-    >>> MyClass.skillz
-    True
-    >>> class YourClass(MyClass): pass
-    >>> YourClass.skillz
-    False
-    """
-
-    def __get__(self, cls, owner):
-        return self.fget.__get__(None, owner)()
-
-
-# borrowed from jaraco.util.dictlib
-
-
-class NonDataProperty:
-    """Much like the property builtin, but only implements __get__,
-    making it a non-data property, and can be subsequently reset.
-
-    See http://users.rcn.com/python/download/Descriptor.htm for more
-    information.
-
-    >>> class X:
-    ...   @NonDataProperty
-    ...   def foo(self):
-    ...     return 3
-    >>> x = X()
-    >>> x.foo
-    3
-    >>> x.foo = 4
-    >>> x.foo
-    4
-    """
-
-    def __init__(self, fget):
-        assert fget is not None, "fget cannot be none"
-        assert isinstance(fget, abc.Callable), "fget must be callable"
-        self.fget = fget
-
-    def __get__(self, obj, objtype=None):
-        if obj is None:
-            return self
-        return self.fget(obj)
+from .._compat import properties
+
+
+NonDataProperty = properties.NonDataProperty
+ClassProperty = properties.classproperty
+
+
+warnings.warn(
+    "Properties from keyring.util are no longer supported. "
+    "Use jaraco.classes.properties instead.",
+    DeprecationWarning,
+)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyring-23.7.0/keyring.egg-info/PKG-INFO 
new/keyring-23.9.1/keyring.egg-info/PKG-INFO
--- old/keyring-23.7.0/keyring.egg-info/PKG-INFO        2022-07-14 
08:39:16.000000000 +0200
+++ new/keyring-23.9.1/keyring.egg-info/PKG-INFO        2022-09-05 
01:31:07.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: keyring
-Version: 23.7.0
+Version: 23.9.1
 Summary: Store and access your passwords safely.
 Home-page: https://github.com/jaraco/keyring
 Author: Kang Zhang
@@ -77,7 +77,7 @@
 Compatibility - macOS
 =====================
 
-macOS keychain support macOS 11 (Big Sur) and later requires Python 3.8.7
+macOS keychain supports macOS 11 (Big Sur) and later requires Python 3.8.7
 or later with the "universal2" binary. See
 `#525 <https://github.com/jaraco/keyring/issues/525>`_ for details.
 
@@ -98,7 +98,7 @@
 Keyring supplies a ``keyring`` command which is installed with the
 package. After installing keyring in most environments, the
 command should be available for setting, getting, and deleting
-passwords. For more information on usage, invoke with no arguments
+passwords. For more usage information, invoke with no arguments
 or with ``--help`` as so::
 
     $ keyring --help
@@ -163,7 +163,7 @@
 In addition to the backends provided by the core keyring package for
 the most common and secure use cases, there
 are additional keyring backend implementations available for other
-use-cases. Simply install them to make them available:
+use cases. Simply install them to make them available:
 
 - `keyrings.cryptfile <https://pypi.org/project/keyrings.cryptfile>`_
   - Encrypted text file storage.
@@ -183,7 +183,7 @@
   backend which uses the ssh agent protocol's signature operation to
   derive the cipher key.
 - `keyrings.osx_keychain_keys 
<https://pypi.org/project/keyrings.osx-keychain-keys>`_
-  - OSX keychain key-management, for private, public and symmetric keys.
+  - OSX keychain key-management, for private, public, and symmetric keys.
 
 
 Write your own keyring backend
@@ -203,7 +203,7 @@
 in the ``keyrings`` namespace, in a manner modeled by the `keyrings.alt
 package <https://github.com/jaraco/keyrings.alt>`_. See the
 ``setup.cfg`` file
-in that project for a hints on how to create the requisite entry points.
+in that project for hints on how to create the requisite entry points.
 Backends that prove essential may be considered for inclusion in the core
 library, although the ease of installing these third-party packages should
 mean that extensions may be readily available.
@@ -224,7 +224,7 @@
     import keyring.backend
 
     class TestKeyring(keyring.backend.KeyringBackend):
-        """A test keyring which always outputs same password
+        """A test keyring which always outputs the same password
         """
         priority = 1
 
@@ -265,7 +265,7 @@
 - Uninstall keyring. Most applications are tolerant to keyring
   not being installed. Uninstalling keyring should cause those
   applications to fall back to the behavior without keyring.
-  This approach affects that Python environment where keyring
+  This approach affects the Python environment where keyring
   would otherwise have been installed.
 
 - Configure the Null keyring in the environment. Set
@@ -336,7 +336,7 @@
 
   When that command is started, enter a password into stdin and
   press Ctrl+D (end of data). After that, the daemon will fork into
-  background (use ``--foreground`` option to block).
+  the background (use ``--foreground`` option to block).
 * Now you can use the SecretService backend of Keyring. Remember to
   run your application in the same D-Bus session as the daemon.
 
@@ -397,11 +397,11 @@
 Exceptions
 ----------
 
-The keyring lib raises following exceptions:
+The keyring lib raises the following exceptions:
 
 * ``keyring.errors.KeyringError``: Base Error class for all exceptions in 
keyring lib.
 * ``keyring.errors.InitError``: Raised when the keyring cannot be initialized.
-* ``keyring.errors.PasswordSetError``: Raised when password cannot be set in 
the keyring.
+* ``keyring.errors.PasswordSetError``: Raised when the password cannot be set 
in the keyring.
 * ``keyring.errors.PasswordDeleteError``: Raised when the password cannot be 
deleted in the keyring.
 
 Get Involved
@@ -433,7 +433,7 @@
 Security Considerations
 =======================
 
-Each builtin backend may have security considerations to understand
+Each built-in backend may have security considerations to understand
 before using this library. Authors of tools or libraries utilizing
 ``keyring`` are encouraged to consider these concerns.
 
@@ -461,7 +461,7 @@
 Making Releases
 ===============
 
-This project makes use of automated releases continuous
+This project makes use of automated releases and continuous
 integration. The
 simple workflow is to tag a commit and push it to Github. If it
 passes tests in CI, it will be automatically deployed to PyPI.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyring-23.7.0/keyring.egg-info/SOURCES.txt 
new/keyring-23.9.1/keyring.egg-info/SOURCES.txt
--- old/keyring-23.7.0/keyring.egg-info/SOURCES.txt     2022-07-14 
08:39:16.000000000 +0200
+++ new/keyring-23.9.1/keyring.egg-info/SOURCES.txt     2022-09-05 
01:31:07.000000000 +0200
@@ -26,6 +26,8 @@
 docs/troubleshooting config.md
 keyring/__init__.py
 keyring/__main__.py
+keyring/_compat.py
+keyring/_properties_compat.py
 keyring/backend.py
 keyring/cli.py
 keyring/core.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyring-23.7.0/keyring.egg-info/requires.txt 
new/keyring-23.9.1/keyring.egg-info/requires.txt
--- old/keyring-23.7.0/keyring.egg-info/requires.txt    2022-07-14 
08:39:16.000000000 +0200
+++ new/keyring-23.9.1/keyring.egg-info/requires.txt    2022-09-05 
01:31:07.000000000 +0200
@@ -1,3 +1,4 @@
+jaraco.classes
 
 [:python_version < "3.10"]
 importlib_metadata>=3.6
@@ -19,6 +20,7 @@
 pytest>=6
 pytest-checkdocs>=2.4
 pytest-flake8
+flake8<5
 pytest-cov
 pytest-enabler>=1.3
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyring-23.7.0/pytest.ini 
new/keyring-23.9.1/pytest.ini
--- old/keyring-23.7.0/pytest.ini       2022-07-14 08:38:54.000000000 +0200
+++ new/keyring-23.9.1/pytest.ini       2022-09-05 01:30:36.000000000 +0200
@@ -17,3 +17,4 @@
        ignore:Flake8Item is an Item subclass and should not be a 
collector:pytest.PytestWarning
 
        ignore:OS_X module is deprecated
+       ignore:Properties from keyring.util
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyring-23.7.0/setup.cfg new/keyring-23.9.1/setup.cfg
--- old/keyring-23.7.0/setup.cfg        2022-07-14 08:39:16.994262000 +0200
+++ new/keyring-23.9.1/setup.cfg        2022-09-05 01:31:07.461742000 +0200
@@ -24,6 +24,7 @@
        SecretStorage>=3.2; sys_platform=="linux"
        jeepney>=0.4.2; sys_platform=="linux"
        importlib_metadata >= 3.6; python_version < "3.10"
+       jaraco.classes
 
 [options.packages.find]
 exclude = 
@@ -37,6 +38,7 @@
        pytest >= 6
        pytest-checkdocs >= 2.4
        pytest-flake8
+       flake8 < 5
        pytest-black >= 0.3.7; \
        python_implementation != "PyPy"
        pytest-cov
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/keyring-23.7.0/tests/backends/test_macOS.py 
new/keyring-23.9.1/tests/backends/test_macOS.py
--- old/keyring-23.7.0/tests/backends/test_macOS.py     2022-07-14 
08:38:54.000000000 +0200
+++ new/keyring-23.9.1/tests/backends/test_macOS.py     2022-09-05 
01:30:36.000000000 +0200
@@ -12,8 +12,3 @@
 class Test_macOSKeychain(BackendBasicTests):
     def init_keyring(self):
         return macOS.Keyring()
-
-    def test_alternate_keychain(self):
-        alt = self.keyring.with_keychain('abcd')
-        assert alt.keychain == 'abcd'
-        assert self.keyring.keychain != 'abcd'

Reply via email to