diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index d2eac20..cc177e6 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -60,7 +60,7 @@ jobs: - name: Lint if: ${{ matrix.lint == 'true' }} run: | - #pylint msal_extensions + pylint msal_extensions # stop the build if there are Python syntax errors or undefined names #flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide diff --git a/.pylintrc b/.pylintrc index bd618db..101e3ed 100644 --- a/.pylintrc +++ b/.pylintrc @@ -2,5 +2,7 @@ good-names= logger disable= + super-with-arguments, # For Python 2.x + raise-missing-from, # For Python 2.x trailing-newlines, useless-object-inheritance diff --git a/msal_extensions/cache_lock.py b/msal_extensions/cache_lock.py index 67ada29..f5033f1 100644 --- a/msal_extensions/cache_lock.py +++ b/msal_extensions/cache_lock.py @@ -4,11 +4,13 @@ import errno import time import logging - -logger = logging.getLogger(__name__) +from distutils.version import LooseVersion +import warnings import portalocker -from distutils.version import LooseVersion + + +logger = logging.getLogger(__name__) class CrossPlatLock(object): @@ -19,7 +21,8 @@ class CrossPlatLock(object): def __init__(self, lockfile_path): self._lockpath = lockfile_path # Support for passing through arguments to the open syscall was added in v1.4.0 - open_kwargs = {'buffering': 0} if LooseVersion(portalocker.__version__) >= LooseVersion("1.4.0") else {} + open_kwargs = ({'buffering': 0} + if LooseVersion(portalocker.__version__) >= LooseVersion("1.4.0") else {}) self._lock = portalocker.Lock( lockfile_path, mode='wb+', @@ -31,6 +34,11 @@ def __init__(self, lockfile_path): **open_kwargs) def try_to_create_lock_file(self): + """Do not call this. It will be removed in next release""" + warnings.warn("try_to_create_lock_file() will be removed", DeprecationWarning) + return self._try_to_create_lock_file() + + def _try_to_create_lock_file(self): timeout = 5 check_interval = 0.25 current_time = getattr(time, "monotonic", time.time) @@ -48,7 +56,7 @@ def try_to_create_lock_file(self): return False def __enter__(self): - if not self.try_to_create_lock_file(): + if not self._try_to_create_lock_file(): logger.warning("Failed to create lock file") file_handle = self._lock.__enter__() file_handle.write('{} {}'.format(os.getpid(), sys.argv[0]).encode('utf-8')) diff --git a/msal_extensions/libsecret.py b/msal_extensions/libsecret.py index 9f624e7..64fd5f1 100644 --- a/msal_extensions/libsecret.py +++ b/msal_extensions/libsecret.py @@ -18,7 +18,7 @@ logger = logging.getLogger(__name__) try: - import gi # https://github.com/AzureAD/microsoft-authentication-extensions-for-python/wiki/Encryption-on-Linux + import gi # https://github.com/AzureAD/microsoft-authentication-extensions-for-python/wiki/Encryption-on-Linux # pylint: disable=line-too-long except ImportError: logger.exception( """Runtime dependency of PyGObject is missing. @@ -51,7 +51,7 @@ def __init__( # pylint: disable=too-many-arguments label="", # Helpful when visualizing secrets by other viewers attribute_types=None, # {name: SchemaAttributeType, ...} collection=None, # None means default collection - ): # pylint: disable=bad-continuation + ): """This agent is built on top of lower level libsecret API. Content stored via libsecret is associated with a bunch of attributes. @@ -126,7 +126,8 @@ def trial_run(): agent.save(payload) # It would fail when running inside an SSH session assert agent.load() == payload # This line is probably not reachable agent.clear() - except (gi.repository.GLib.Error, AssertionError): + except (gi.repository.GLib.Error, AssertionError): # pylint: disable=no-member + # https://pygobject.readthedocs.io/en/latest/guide/api/error_handling.html#examples message = """libsecret did not perform properly. * If you encountered error "Remote error from secret service: org.freedesktop.DBus.Error.ServiceUnknown", diff --git a/msal_extensions/osx.py b/msal_extensions/osx.py index 33f85e9..ef1a2cc 100644 --- a/msal_extensions/osx.py +++ b/msal_extensions/osx.py @@ -5,7 +5,7 @@ import os import ctypes as _ctypes -OS_RESULT = _ctypes.c_int32 +OS_RESULT = _ctypes.c_int32 # pylint: disable=invalid-name class KeychainError(OSError): diff --git a/msal_extensions/persistence.py b/msal_extensions/persistence.py index 5a87877..0c6c6d3 100644 --- a/msal_extensions/persistence.py +++ b/msal_extensions/persistence.py @@ -13,7 +13,7 @@ import sys try: from pathlib import Path # Built-in in Python 3 -except: +except ImportError: from pathlib2 import Path # An extra lib for Python 2 @@ -59,10 +59,12 @@ class PersistenceNotFound(IOError): # Use IOError rather than OSError as base, # https://github.com/AzureAD/microsoft-authentication-extensions-for-python/blob/0.2.2/msal_extensions/token_cache.py#L38 # Now we want to maintain backward compatibility even when using Python 2.x # It makes no difference in Python 3.3+ where IOError is an alias of OSError. - def __init__( - self, - err_no=errno.ENOENT, message="Persistence not found", location=None): - super(PersistenceNotFound, self).__init__(err_no, message, location) + """This happens when attempting BasePersistence.load() on a non-existent persistence instance""" + def __init__(self, err_no=None, message=None, location=None): + super(PersistenceNotFound, self).__init__( + err_no or errno.ENOENT, + message or "Persistence not found", + location) class BasePersistence(ABC): @@ -220,7 +222,7 @@ def load(self): try: return locker.get_generic_password( self._service_name, self._account_name) - except self._KeychainError as ex: + except self._KeychainError as ex: # pylint: disable=invalid-name if ex.exit_status == self._KeychainError.ITEM_NOT_FOUND: # This happens when a load() is called before a save(). # We map it into cross-platform error for unified catching.