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'