Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-msal-extensions for 
openSUSE:Factory checked in at 2022-01-04 19:37:43
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-msal-extensions (Old)
 and      /work/SRC/openSUSE:Factory/.python-msal-extensions.new.1896 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-msal-extensions"

Tue Jan  4 19:37:43 2022 rev:4 rq:943621 version:0.3.1

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-msal-extensions/python-msal-extensions.changes
    2020-12-09 22:21:26.487676601 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-msal-extensions.new.1896/python-msal-extensions.changes
  2022-01-04 19:37:55.977964862 +0100
@@ -1,0 +2,13 @@
+Mon Jan  3 15:05:19 UTC 2022 - John Paul Adrian Glaubitz 
<adrian.glaub...@suse.com>
+
+- Update to version 0.3.1
+  + Enhancement: Better concurrency (#61, #63, #100)
+  + Bugfix: Now supports user home dir in drive root on Windows (#83, #84)
+  + Enhancement: This package can now be run inside container
+  + Enhancement: Improvement compatibility with PyInstaller 3.5 on Python 2.7 
(#85, #91)
+  + Enhancement: Catchable exception when persistence is unavailable (#92, #93)
+  + Enhancement: Support dependency portalocker 2.0+ (#94, #97)
+  + Enhancement: Improve documentation (#77, #102)
+  + Including license in release package (#76)
+
+-------------------------------------------------------------------

Old:
----
  msal-extensions-0.3.0.tar.gz

New:
----
  msal-extensions-0.3.1.tar.gz

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

Other differences:
------------------
++++++ python-msal-extensions.spec ++++++
--- /var/tmp/diff_new_pack.ULuwOM/_old  2022-01-04 19:37:56.457965490 +0100
+++ /var/tmp/diff_new_pack.ULuwOM/_new  2022-01-04 19:37:56.465965501 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-msal-extensions
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -21,7 +21,7 @@
 %define skip_python2 1
 %endif
 Name:           python-msal-extensions
-Version:        0.3.0
+Version:        0.3.1
 Release:        0
 Summary:        Microsoft Authentication Library (MSAL) for Python Extensions
 License:        MIT

++++++ msal-extensions-0.3.0.tar.gz -> msal-extensions-0.3.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msal-extensions-0.3.0/LICENSE 
new/msal-extensions-0.3.1/LICENSE
--- old/msal-extensions-0.3.0/LICENSE   1970-01-01 01:00:00.000000000 +0100
+++ new/msal-extensions-0.3.1/LICENSE   2021-12-13 05:46:45.000000000 +0100
@@ -0,0 +1,21 @@
+    MIT License
+
+    Copyright (c) Microsoft Corporation. All rights reserved.
+
+    Permission is hereby granted, free of charge, to any person obtaining a 
copy
+    of this software and associated documentation files (the "Software"), to 
deal
+    in the Software without restriction, including without limitation the 
rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included in 
all
+    copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+    SOFTWARE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msal-extensions-0.3.0/PKG-INFO 
new/msal-extensions-0.3.1/PKG-INFO
--- old/msal-extensions-0.3.0/PKG-INFO  2020-09-01 22:43:13.000000000 +0200
+++ new/msal-extensions-0.3.1/PKG-INFO  2021-12-13 05:46:55.792970000 +0100
@@ -1,104 +1,109 @@
 Metadata-Version: 2.1
 Name: msal-extensions
-Version: 0.3.0
+Version: 0.3.1
 Summary: UNKNOWN
 Home-page: UNKNOWN
-License: UNKNOWN
-Description: 
-        # Microsoft Authentication Extensions for Python
-        
-        The Microsoft Authentication Extensions for Python offers secure 
mechanisms for client applications to perform cross-platform token cache 
serialization and persistence. It gives additional support to the [Microsoft 
Authentication Library for Python 
(MSAL)](https://github.com/AzureAD/microsoft-authentication-library-for-python).
 
-        
-        MSAL Python supports an in-memory cache by default and provides the 
[SerializableTokenCache](https://msal-python.readthedocs.io/en/latest/#msal.SerializableTokenCache)
 to perform cache serialization. You can read more about this in the MSAL 
Python 
[documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-python-token-cache-serialization).
 Developers are required to implement their own cache persistance across 
multiple platforms and Microsoft Authentication Extensions makes this simpler.
-        
-        The supported platforms are Windows, Mac and Linux. 
-        - Windows - 
[DPAPI](https://docs.microsoft.com/en-us/dotnet/standard/security/how-to-use-data-protection)
 is used for encryption.
-        - MAC - The MAC KeyChain is used.
-        - Linux - [LibSecret](https://wiki.gnome.org/Projects/Libsecret) is 
used for encryption.
-        
-        > Note: It is recommended to use this library for cache persistance 
support for Public client applications such as Desktop apps only. In web 
applications, this may lead to scale and performance issues. Web applications 
are recommended to persist the cache in session. Take a look at this [webapp 
sample](https://github.com/Azure-Samples/ms-identity-python-webapp).
-        
-        ## Installation
-        
-        You can find Microsoft Authentication Extensions for Python on 
[Pypi](https://pypi.org/project/msal-extensions/).
-        1. If you haven't already, [install and/or upgrade the 
pip](https://pip.pypa.io/en/stable/installing/)
-           of your Python environment to a recent version. We tested with pip 
18.1.
-        2. Run `pip install msal-extensions`.
-        
-        ## Versions
-        
-        This library follows [Semantic Versioning](http://semver.org/).
-        
-        You can find the changes for each version under
-        
[Releases](https://github.com/AzureAD/microsoft-authentication-extensions-for-python/releases).
-        
-        ## Usage
-        
-        The Microsoft Authentication Extensions library provides the 
`PersistedTokenCache` which accepts a platform-dependent persistence instance. 
This token cache can then be used to instantiate the `PublicClientApplication` 
in MSAL Python. 
-        
-        The token cache includes a file lock, and auto-reload behavior under 
the hood.
-        
-        
-        
-        Here is an example of this pattern for multiple platforms (taken from 
the complete [sample 
here](https://github.com/AzureAD/microsoft-authentication-extensions-for-python/blob/dev/sample/token_cache_sample.py)):
-        
-        ```python
-        def build_persistence(location, fallback_to_plaintext=False):
-            """Build a suitable persistence instance based your current OS"""
-            if sys.platform.startswith('win'):
-                return FilePersistenceWithDataProtection(location)
-            if sys.platform.startswith('darwin'):
-                return KeychainPersistence(location, "my_service_name", 
"my_account_name")
-            if sys.platform.startswith('linux'):
-                try:
-                    return LibsecretPersistence(
-                        location,
-                        schema_name="my_schema_name",
-                        attributes={"my_attr1": "foo", "my_attr2": "bar"},
-                        )
-                except:  # pylint: disable=bare-except
-                    if not fallback_to_plaintext:
-                        raise
-                    logging.exception("Encryption unavailable. Opting in to 
plain text.")
-            return FilePersistence(location)
-        
-        persistence = build_persistence("token_cache.bin")
-        print("Is this persistence encrypted?", persistence.is_encrypted)
-        
-        cache = PersistedTokenCache(persistence)
-        ```
-        Now you can use it in an MSAL application like this:
-        ```python
-        app = msal.PublicClientApplication("my_client_id", token_cache=cache)
-        ```
-        
-        ## Community Help and Support
-        
-        We leverage Stack Overflow to work with the community on supporting 
Azure Active Directory and its SDKs, including this one!
-        We highly recommend you ask your questions on Stack Overflow (we're 
all on there!).
-        Also browse existing issues to see if someone has had your question 
before.
-        
-        We recommend you use the "msal" tag so we can see it!
-        Here is the latest Q&A on Stack Overflow for MSAL:
-        
[http://stackoverflow.com/questions/tagged/msal](http://stackoverflow.com/questions/tagged/msal)
-        
-        
-        ## Contributing
-        
-        All code is licensed under the MIT license and we triage actively on 
GitHub.
-        
-        This project welcomes contributions and suggestions.  Most 
contributions require you to agree to a
-        Contributor License Agreement (CLA) declaring that you have the right 
to, and actually do, grant us
-        the rights to use your contribution. For details, visit 
https://cla.microsoft.com.
-        
-        When you submit a pull request, a CLA-bot will automatically determine 
whether you need to provide
-        a CLA and decorate the PR appropriately (e.g., label, comment). Simply 
follow the instructions
-        provided by the bot. You will only need to do this once across all 
repos using our CLA.
-        
-        
-        ## We value and adhere to the Microsoft Open Source Code of Conduct
-        
-        This project has adopted the [Microsoft Open Source Code of 
Conduct](https://opensource.microsoft.com/codeofconduct/). For more information 
see the [Code of Conduct 
FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact 
[openc...@microsoft.com](mailto:openc...@microsoft.com) with any additional 
questions or comments.
+License: MIT
+Project-URL: Changelog, 
https://github.com/AzureAD/microsoft-authentication-extensions-for-python/releases
 Platform: UNKNOWN
-Classifier: Development Status :: 2 - Pre-Alpha
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Development Status :: 4 - Beta
 Description-Content-Type: text/markdown
+License-File: LICENSE
+
+
+# Microsoft Authentication Extensions for Python
+
+The Microsoft Authentication Extensions for Python offers secure mechanisms 
for client applications to perform cross-platform token cache serialization and 
persistence. It gives additional support to the [Microsoft Authentication 
Library for Python 
(MSAL)](https://github.com/AzureAD/microsoft-authentication-library-for-python).
 
+
+MSAL Python supports an in-memory cache by default and provides the 
[SerializableTokenCache](https://msal-python.readthedocs.io/en/latest/#msal.SerializableTokenCache)
 to perform cache serialization. You can read more about this in the MSAL 
Python 
[documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-python-token-cache-serialization).
 Developers are required to implement their own cache persistance across 
multiple platforms and Microsoft Authentication Extensions makes this simpler.
+
+The supported platforms are Windows, Mac and Linux. 
+- Windows - 
[DPAPI](https://docs.microsoft.com/en-us/dotnet/standard/security/how-to-use-data-protection)
 is used for encryption.
+- MAC - The MAC KeyChain is used.
+- Linux - [LibSecret](https://wiki.gnome.org/Projects/Libsecret) is used for 
encryption.
+
+> Note: It is recommended to use this library for cache persistance support 
for Public client applications such as Desktop apps only. In web applications, 
this may lead to scale and performance issues. Web applications are recommended 
to persist the cache in session. Take a look at this [webapp 
sample](https://github.com/Azure-Samples/ms-identity-python-webapp).
+
+## Installation
+
+You can find Microsoft Authentication Extensions for Python on 
[Pypi](https://pypi.org/project/msal-extensions/).
+1. If you haven't already, [install and/or upgrade the 
pip](https://pip.pypa.io/en/stable/installing/)
+   of your Python environment to a recent version. We tested with pip 18.1.
+2. Run `pip install msal-extensions`.
+
+## Versions
+
+This library follows [Semantic Versioning](http://semver.org/).
+
+You can find the changes for each version under
+[Releases](https://github.com/AzureAD/microsoft-authentication-extensions-for-python/releases).
+
+## Usage
+
+The Microsoft Authentication Extensions library provides the 
`PersistedTokenCache` which accepts a platform-dependent persistence instance. 
This token cache can then be used to instantiate the `PublicClientApplication` 
in MSAL Python. 
+
+The token cache includes a file lock, and auto-reload behavior under the hood.
+
+
+
+Here is an example of this pattern for multiple platforms (taken from the 
complete [sample 
here](https://github.com/AzureAD/microsoft-authentication-extensions-for-python/blob/dev/sample/token_cache_sample.py)):
+
+```python
+def build_persistence(location, fallback_to_plaintext=False):
+    """Build a suitable persistence instance based your current OS"""
+    if sys.platform.startswith('win'):
+        return FilePersistenceWithDataProtection(location)
+    if sys.platform.startswith('darwin'):
+        return KeychainPersistence(location, "my_service_name", 
"my_account_name")
+    if sys.platform.startswith('linux'):
+        try:
+            return LibsecretPersistence(
+                location,
+                schema_name="my_schema_name",
+                attributes={"my_attr1": "foo", "my_attr2": "bar"},
+                )
+        except:  # pylint: disable=bare-except
+            if not fallback_to_plaintext:
+                raise
+            logging.exception("Encryption unavailable. Opting in to plain 
text.")
+    return FilePersistence(location)
+
+persistence = build_persistence("token_cache.bin")
+print("Is this persistence encrypted?", persistence.is_encrypted)
+
+cache = PersistedTokenCache(persistence)
+```
+Now you can use it in an MSAL application like this:
+```python
+app = msal.PublicClientApplication("my_client_id", token_cache=cache)
+```
+
+## Community Help and Support
+
+We leverage Stack Overflow to work with the community on supporting Azure 
Active Directory and its SDKs, including this one!
+We highly recommend you ask your questions on Stack Overflow (we're all on 
there!).
+Also browse existing issues to see if someone has had your question before.
+
+We recommend you use the "msal" tag so we can see it!
+Here is the latest Q&A on Stack Overflow for MSAL:
+[http://stackoverflow.com/questions/tagged/msal](http://stackoverflow.com/questions/tagged/msal)
+
+
+## Contributing
+
+All code is licensed under the MIT license and we triage actively on GitHub.
+
+This project welcomes contributions and suggestions.  Most contributions 
require you to agree to a
+Contributor License Agreement (CLA) declaring that you have the right to, and 
actually do, grant us
+the rights to use your contribution. For details, visit 
https://cla.microsoft.com.
+
+When you submit a pull request, a CLA-bot will automatically determine whether 
you need to provide
+a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow 
the instructions
+provided by the bot. You will only need to do this once across all repos using 
our CLA.
+
+
+## We value and adhere to the Microsoft Open Source Code of Conduct
+
+This project has adopted the [Microsoft Open Source Code of 
Conduct](https://opensource.microsoft.com/codeofconduct/). For more information 
see the [Code of Conduct 
FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact 
[openc...@microsoft.com](mailto:openc...@microsoft.com) with any additional 
questions or comments.
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msal-extensions-0.3.0/msal_extensions/__init__.py 
new/msal-extensions-0.3.1/msal_extensions/__init__.py
--- old/msal-extensions-0.3.0/msal_extensions/__init__.py       2020-09-01 
22:42:14.000000000 +0200
+++ new/msal-extensions-0.3.1/msal_extensions/__init__.py       2021-12-13 
05:46:45.000000000 +0100
@@ -1,5 +1,5 @@
 """Provides auxiliary functionality to the `msal` package."""
-__version__ = "0.3.0"
+__version__ = "0.3.1"
 
 import sys
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msal-extensions-0.3.0/msal_extensions/cache_lock.py 
new/msal-extensions-0.3.1/msal_extensions/cache_lock.py
--- old/msal-extensions-0.3.0/msal_extensions/cache_lock.py     2020-09-01 
22:42:14.000000000 +0200
+++ new/msal-extensions-0.3.1/msal_extensions/cache_lock.py     2021-12-13 
05:46:45.000000000 +0100
@@ -2,9 +2,15 @@
 import os
 import sys
 import errno
-import portalocker
+import time
+import logging
 from distutils.version import LooseVersion
 
+import portalocker
+
+
+logger = logging.getLogger(__name__)
+
 
 class CrossPlatLock(object):
     """Offers a mechanism for waiting until another process is finished 
interacting with a shared
@@ -14,7 +20,8 @@
     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+',
@@ -25,9 +32,32 @@
             flags=portalocker.LOCK_EX | portalocker.LOCK_NB,
             **open_kwargs)
 
+    def _try_to_create_lock_file(self):
+        timeout = 5
+        check_interval = 0.25
+        current_time = getattr(time, "monotonic", time.time)
+        timeout_end = current_time() + timeout
+        pid = os.getpid()
+        while timeout_end > current_time():
+            try:
+                with open(self._lockpath, 'x'):  # pylint: 
disable=unspecified-encoding
+                    return True
+            except ValueError:  # This needs to be the first clause, for 
Python 2 to hit it
+                logger.warning("Python 2 does not support atomic creation of 
file")
+                return False
+            except FileExistsError:  # Only Python 3 will reach this clause
+                logger.debug(
+                    "Process %d found existing lock file, will retry after %f 
second",
+                    pid, check_interval)
+                time.sleep(check_interval)
+        return False
+
     def __enter__(self):
+        pid = os.getpid()
+        if not self._try_to_create_lock_file():
+            logger.warning("Process %d failed to create lock file", pid)
         file_handle = self._lock.__enter__()
-        file_handle.write('{} {}'.format(os.getpid(), 
sys.argv[0]).encode('utf-8'))
+        file_handle.write('{} {}'.format(pid, sys.argv[0]).encode('utf-8'))  # 
pylint: disable=consider-using-f-string
         return file_handle
 
     def __exit__(self, *args):
@@ -38,5 +68,5 @@
             # file for itself.
             os.remove(self._lockpath)
         except OSError as ex:  # pylint: disable=invalid-name
-            if ex.errno != errno.ENOENT and ex.errno != errno.EACCES:
+            if ex.errno not in (errno.ENOENT, errno.EACCES):
                 raise
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msal-extensions-0.3.0/msal_extensions/libsecret.py 
new/msal-extensions-0.3.1/msal_extensions/libsecret.py
--- old/msal-extensions-0.3.0/msal_extensions/libsecret.py      2020-09-01 
22:42:14.000000000 +0200
+++ new/msal-extensions-0.3.1/msal_extensions/libsecret.py      2021-12-13 
05:46:45.000000000 +0100
@@ -13,33 +13,29 @@
     pip install wheel
     PYGOBJECT_WITHOUT_PYCAIRO=1 pip install --no-build-isolation pygobject
 """
-import logging
-
-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.
+    raise ImportError("""Unable to import module 'gi'
+Runtime dependency of PyGObject is missing.
 Depends on your Linux distro, you could install it system-wide by something 
like:
     sudo apt install python3-gi python3-gi-cairo gir1.2-secret-1
 If necessary, please refer to PyGObject's doc:
 https://pygobject.readthedocs.io/en/latest/getting_started.html
-""")
-    raise
+""")  # Message via exception rather than log
 
 try:
     # pylint: disable=no-name-in-module
     gi.require_version("Secret", "1")  # Would require a package 
gir1.2-secret-1
     # pylint: disable=wrong-import-position
     from gi.repository import Secret  # Would require a package gir1.2-secret-1
-except (ValueError, ImportError):
-    logger.exception(
+except (ValueError, ImportError) as ex:
+    raise type(ex)(
         """Require a package "gir1.2-secret-1" which could be installed by:
         sudo apt install gir1.2-secret-1
-        """)
-    raise
+        """)  # Message via exception rather than log
+
 
 class LibSecretAgent(object):
     """A loader/saver built on top of low-level libsecret"""
@@ -51,7 +47,7 @@
             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,14 +122,13 @@
         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",
   you may need to install gnome-keyring package.
 * Headless mode (such as in an ssh session) is not supported.
 """
-        logger.exception(message)  # This log contains trace stack for 
debugging
-        logger.warning(message)  # This is visible by default
-        raise
+        raise RuntimeError(message)  # Message via exception rather than log
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msal-extensions-0.3.0/msal_extensions/osx.py 
new/msal-extensions-0.3.1/msal_extensions/osx.py
--- old/msal-extensions-0.3.0/msal_extensions/osx.py    2020-09-01 
22:42:14.000000000 +0200
+++ new/msal-extensions-0.3.1/msal_extensions/osx.py    2021-12-13 
05:46:45.000000000 +0100
@@ -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):
@@ -21,10 +21,9 @@
         self.exit_status = exit_status
         # TODO: pylint: disable=fixme
         #  use SecCopyErrorMessageString to fetch the appropriate message here.
-        self.message = \
-            '{} ' \
-            'see 
https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/MacErrors.h'\
-                .format(self.exit_status)
+        self.message = (
+            '{} see 
https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/MacErrors.h'
  # pylint: disable=consider-using-f-string,line-too-long
+            .format(self.exit_status))
 
 def _get_native_location(name):
     # type: (str) -> str
@@ -33,7 +32,7 @@
     :param name: The name of the library to be loaded.
     :return: The location of the library on a MacOS filesystem.
     """
-    return '/System/Library/Frameworks/{0}.framework/{0}'.format(name)
+    return '/System/Library/Frameworks/{0}.framework/{0}'.format(name)  # 
pylint: disable=consider-using-f-string
 
 
 # Load native MacOS libraries
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msal-extensions-0.3.0/msal_extensions/persistence.py 
new/msal-extensions-0.3.1/msal_extensions/persistence.py
--- old/msal-extensions-0.3.0/msal_extensions/persistence.py    2020-09-01 
22:42:14.000000000 +0200
+++ new/msal-extensions-0.3.1/msal_extensions/persistence.py    2021-12-13 
05:46:45.000000000 +0100
@@ -10,9 +10,10 @@
 import os
 import errno
 import logging
+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
 
 
@@ -28,14 +29,19 @@
 def _mkdir_p(path):
     """Creates a directory, and any necessary parents.
 
-    This implementation based on a Stack Overflow question that can be found 
here:
-    https://stackoverflow.com/questions/600268/mkdir-p-functionality-in-python
-
     If the path provided is an existing file, this function raises an 
exception.
     :param path: The directory name that should be created.
     """
     if not path:
         return  # NO-OP
+
+    if sys.version_info >= (3, 2):
+        os.makedirs(path, exist_ok=True)
+        return
+
+    # This fallback implementation is based on a Stack Overflow question:
+    # 
https://stackoverflow.com/questions/600268/mkdir-p-functionality-in-python
+    # Known issue: it won't work when the path is a root folder like "C:\\"
     try:
         os.makedirs(path)
     except OSError as exp:
@@ -53,10 +59,12 @@
         # 
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):
@@ -105,14 +113,14 @@
     def save(self, content):
         # type: (str) -> None
         """Save the content into this persistence"""
-        with open(self._location, 'w+') as handle:
+        with open(self._location, 'w+') as handle:  # pylint: 
disable=unspecified-encoding
             handle.write(content)
 
     def load(self):
         # type: () -> str
         """Load content from this persistence"""
         try:
-            with open(self._location, 'r') as handle:
+            with open(self._location, 'r') as handle:  # pylint: 
disable=unspecified-encoding
                 return handle.read()
         except EnvironmentError as exp:  # EnvironmentError in Py 2.7 works 
across platform
             if exp.errno == errno.ENOENT:
@@ -214,12 +222,12 @@
             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.
                     raise PersistenceNotFound(
-                        location="Service:{} Account:{}".format(
+                        location="Service:{} Account:{}".format(  # pylint: 
disable=consider-using-f-string
                             self._service_name, self._account_name),
                         message=(
                             "Keychain persistence not initialized. "
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msal-extensions-0.3.0/msal_extensions/token_cache.py 
new/msal-extensions-0.3.1/msal_extensions/token_cache.py
--- old/msal-extensions-0.3.0/msal_extensions/token_cache.py    2020-09-01 
22:42:14.000000000 +0200
+++ new/msal-extensions-0.3.1/msal_extensions/token_cache.py    2021-12-13 
05:46:45.000000000 +0100
@@ -15,7 +15,30 @@
 logger = logging.getLogger(__name__)
 
 class PersistedTokenCache(msal.SerializableTokenCache):
-    """A token cache using given persistence layer, coordinated by a file 
lock."""
+    """A token cache backed by a persistence layer, coordinated by a file lock,
+    to sustain a certain level of multi-process concurrency for a desktop app.
+
+    The scenario is that multiple instances of same desktop app
+    (or even multiple different apps)
+    create their own ``PersistedTokenCache`` instances,
+    which are all backed by the same token cache file on disk
+    (known as a persistence). The goal is to have Single Sign On (SSO).
+
+    Each instance of ``PersistedTokenCache`` holds a snapshot of the token 
cache
+    in memory.
+    Each :func:`~find` call will
+    automatically reload token cache from the persistence when necessary,
+    so that it will have fresh data.
+    Each :func:`~modify` call will
+    automatically reload token cache from the persistence when necessary,
+    so that new writes will be appended on top of latest token cache data,
+    and then the new data will be immediately flushed back to the persistence.
+
+    Note: :func:`~deserialize` and :func:`~serialize` remain the same
+    as their counterparts in the parent class ``msal.SerializableTokenCache``.
+    In other words, they do not have the "reload from persistence if necessary"
+    nor the "flush back to persistence" behavior.
+    """
 
     def __init__(self, persistence, lock_location=None):
         super(PersistedTokenCache, self).__init__()
@@ -50,9 +73,21 @@
             self._last_sync = time.time()
 
     def find(self, credential_type, **kwargs):  # pylint: 
disable=arguments-differ
-        with CrossPlatLock(self._lock_location):
-            self._reload_if_necessary()
-            return super(PersistedTokenCache, self).find(credential_type, 
**kwargs)
+        # Use optimistic locking rather than CrossPlatLock(self._lock_location)
+        retry = 3
+        for attempt in range(1, retry + 1):
+            try:
+                self._reload_if_necessary()
+            except Exception:  # pylint: disable=broad-except
+                # Presumably other processes are writing the file, causing 
dirty read
+                if attempt < retry:
+                    logger.debug("Unable to load token cache file in No. %d 
attempt", attempt)
+                    time.sleep(0.5)
+                else:
+                    raise  # End of retry. Re-raise the exception as-is.
+            else:  # If reload encountered no error, the data is considered 
intact
+                return super(PersistedTokenCache, self).find(credential_type, 
**kwargs)
+        return []  # Not really reachable here. Just to keep pylint happy.
 
 
 class FileTokenCache(PersistedTokenCache):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msal-extensions-0.3.0/msal_extensions/windows.py 
new/msal-extensions-0.3.1/msal_extensions/windows.py
--- old/msal-extensions-0.3.0/msal_extensions/windows.py        2020-09-01 
22:42:14.000000000 +0200
+++ new/msal-extensions-0.3.1/msal_extensions/windows.py        2021-12-13 
05:46:45.000000000 +0100
@@ -5,6 +5,9 @@
 _LOCAL_FREE = ctypes.windll.kernel32.LocalFree
 _GET_LAST_ERROR = ctypes.windll.kernel32.GetLastError
 _MEMCPY = ctypes.cdll.msvcrt.memcpy
+_MEMCPY.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t]  # Note:
+    # Suggested by 
https://github.com/AzureAD/microsoft-authentication-extensions-for-python/issues/85
  # pylint: disable=line-too-long
+    # Matching 
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/memcpy-wmemcpy?view=msvc-160
  # pylint: disable=line-too-long
 _CRYPT_PROTECT_DATA = ctypes.windll.crypt32.CryptProtectData
 _CRYPT_UNPROTECT_DATA = ctypes.windll.crypt32.CryptUnprotectData
 _CRYPTPROTECT_UI_FORBIDDEN = 0x01
@@ -67,7 +70,7 @@
 
         if _CRYPT_PROTECT_DATA(
                 ctypes.byref(message_blob),
-                u"python_data",
+                u"python_data",  # pylint: disable=redundant-u-string-prefix
                 entropy,
                 None,
                 None,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/msal-extensions-0.3.0/msal_extensions.egg-info/PKG-INFO 
new/msal-extensions-0.3.1/msal_extensions.egg-info/PKG-INFO
--- old/msal-extensions-0.3.0/msal_extensions.egg-info/PKG-INFO 2020-09-01 
22:43:13.000000000 +0200
+++ new/msal-extensions-0.3.1/msal_extensions.egg-info/PKG-INFO 2021-12-13 
05:46:55.000000000 +0100
@@ -1,104 +1,109 @@
 Metadata-Version: 2.1
 Name: msal-extensions
-Version: 0.3.0
+Version: 0.3.1
 Summary: UNKNOWN
 Home-page: UNKNOWN
-License: UNKNOWN
-Description: 
-        # Microsoft Authentication Extensions for Python
-        
-        The Microsoft Authentication Extensions for Python offers secure 
mechanisms for client applications to perform cross-platform token cache 
serialization and persistence. It gives additional support to the [Microsoft 
Authentication Library for Python 
(MSAL)](https://github.com/AzureAD/microsoft-authentication-library-for-python).
 
-        
-        MSAL Python supports an in-memory cache by default and provides the 
[SerializableTokenCache](https://msal-python.readthedocs.io/en/latest/#msal.SerializableTokenCache)
 to perform cache serialization. You can read more about this in the MSAL 
Python 
[documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-python-token-cache-serialization).
 Developers are required to implement their own cache persistance across 
multiple platforms and Microsoft Authentication Extensions makes this simpler.
-        
-        The supported platforms are Windows, Mac and Linux. 
-        - Windows - 
[DPAPI](https://docs.microsoft.com/en-us/dotnet/standard/security/how-to-use-data-protection)
 is used for encryption.
-        - MAC - The MAC KeyChain is used.
-        - Linux - [LibSecret](https://wiki.gnome.org/Projects/Libsecret) is 
used for encryption.
-        
-        > Note: It is recommended to use this library for cache persistance 
support for Public client applications such as Desktop apps only. In web 
applications, this may lead to scale and performance issues. Web applications 
are recommended to persist the cache in session. Take a look at this [webapp 
sample](https://github.com/Azure-Samples/ms-identity-python-webapp).
-        
-        ## Installation
-        
-        You can find Microsoft Authentication Extensions for Python on 
[Pypi](https://pypi.org/project/msal-extensions/).
-        1. If you haven't already, [install and/or upgrade the 
pip](https://pip.pypa.io/en/stable/installing/)
-           of your Python environment to a recent version. We tested with pip 
18.1.
-        2. Run `pip install msal-extensions`.
-        
-        ## Versions
-        
-        This library follows [Semantic Versioning](http://semver.org/).
-        
-        You can find the changes for each version under
-        
[Releases](https://github.com/AzureAD/microsoft-authentication-extensions-for-python/releases).
-        
-        ## Usage
-        
-        The Microsoft Authentication Extensions library provides the 
`PersistedTokenCache` which accepts a platform-dependent persistence instance. 
This token cache can then be used to instantiate the `PublicClientApplication` 
in MSAL Python. 
-        
-        The token cache includes a file lock, and auto-reload behavior under 
the hood.
-        
-        
-        
-        Here is an example of this pattern for multiple platforms (taken from 
the complete [sample 
here](https://github.com/AzureAD/microsoft-authentication-extensions-for-python/blob/dev/sample/token_cache_sample.py)):
-        
-        ```python
-        def build_persistence(location, fallback_to_plaintext=False):
-            """Build a suitable persistence instance based your current OS"""
-            if sys.platform.startswith('win'):
-                return FilePersistenceWithDataProtection(location)
-            if sys.platform.startswith('darwin'):
-                return KeychainPersistence(location, "my_service_name", 
"my_account_name")
-            if sys.platform.startswith('linux'):
-                try:
-                    return LibsecretPersistence(
-                        location,
-                        schema_name="my_schema_name",
-                        attributes={"my_attr1": "foo", "my_attr2": "bar"},
-                        )
-                except:  # pylint: disable=bare-except
-                    if not fallback_to_plaintext:
-                        raise
-                    logging.exception("Encryption unavailable. Opting in to 
plain text.")
-            return FilePersistence(location)
-        
-        persistence = build_persistence("token_cache.bin")
-        print("Is this persistence encrypted?", persistence.is_encrypted)
-        
-        cache = PersistedTokenCache(persistence)
-        ```
-        Now you can use it in an MSAL application like this:
-        ```python
-        app = msal.PublicClientApplication("my_client_id", token_cache=cache)
-        ```
-        
-        ## Community Help and Support
-        
-        We leverage Stack Overflow to work with the community on supporting 
Azure Active Directory and its SDKs, including this one!
-        We highly recommend you ask your questions on Stack Overflow (we're 
all on there!).
-        Also browse existing issues to see if someone has had your question 
before.
-        
-        We recommend you use the "msal" tag so we can see it!
-        Here is the latest Q&A on Stack Overflow for MSAL:
-        
[http://stackoverflow.com/questions/tagged/msal](http://stackoverflow.com/questions/tagged/msal)
-        
-        
-        ## Contributing
-        
-        All code is licensed under the MIT license and we triage actively on 
GitHub.
-        
-        This project welcomes contributions and suggestions.  Most 
contributions require you to agree to a
-        Contributor License Agreement (CLA) declaring that you have the right 
to, and actually do, grant us
-        the rights to use your contribution. For details, visit 
https://cla.microsoft.com.
-        
-        When you submit a pull request, a CLA-bot will automatically determine 
whether you need to provide
-        a CLA and decorate the PR appropriately (e.g., label, comment). Simply 
follow the instructions
-        provided by the bot. You will only need to do this once across all 
repos using our CLA.
-        
-        
-        ## We value and adhere to the Microsoft Open Source Code of Conduct
-        
-        This project has adopted the [Microsoft Open Source Code of 
Conduct](https://opensource.microsoft.com/codeofconduct/). For more information 
see the [Code of Conduct 
FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact 
[openc...@microsoft.com](mailto:openc...@microsoft.com) with any additional 
questions or comments.
+License: MIT
+Project-URL: Changelog, 
https://github.com/AzureAD/microsoft-authentication-extensions-for-python/releases
 Platform: UNKNOWN
-Classifier: Development Status :: 2 - Pre-Alpha
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Development Status :: 4 - Beta
 Description-Content-Type: text/markdown
+License-File: LICENSE
+
+
+# Microsoft Authentication Extensions for Python
+
+The Microsoft Authentication Extensions for Python offers secure mechanisms 
for client applications to perform cross-platform token cache serialization and 
persistence. It gives additional support to the [Microsoft Authentication 
Library for Python 
(MSAL)](https://github.com/AzureAD/microsoft-authentication-library-for-python).
 
+
+MSAL Python supports an in-memory cache by default and provides the 
[SerializableTokenCache](https://msal-python.readthedocs.io/en/latest/#msal.SerializableTokenCache)
 to perform cache serialization. You can read more about this in the MSAL 
Python 
[documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-python-token-cache-serialization).
 Developers are required to implement their own cache persistance across 
multiple platforms and Microsoft Authentication Extensions makes this simpler.
+
+The supported platforms are Windows, Mac and Linux. 
+- Windows - 
[DPAPI](https://docs.microsoft.com/en-us/dotnet/standard/security/how-to-use-data-protection)
 is used for encryption.
+- MAC - The MAC KeyChain is used.
+- Linux - [LibSecret](https://wiki.gnome.org/Projects/Libsecret) is used for 
encryption.
+
+> Note: It is recommended to use this library for cache persistance support 
for Public client applications such as Desktop apps only. In web applications, 
this may lead to scale and performance issues. Web applications are recommended 
to persist the cache in session. Take a look at this [webapp 
sample](https://github.com/Azure-Samples/ms-identity-python-webapp).
+
+## Installation
+
+You can find Microsoft Authentication Extensions for Python on 
[Pypi](https://pypi.org/project/msal-extensions/).
+1. If you haven't already, [install and/or upgrade the 
pip](https://pip.pypa.io/en/stable/installing/)
+   of your Python environment to a recent version. We tested with pip 18.1.
+2. Run `pip install msal-extensions`.
+
+## Versions
+
+This library follows [Semantic Versioning](http://semver.org/).
+
+You can find the changes for each version under
+[Releases](https://github.com/AzureAD/microsoft-authentication-extensions-for-python/releases).
+
+## Usage
+
+The Microsoft Authentication Extensions library provides the 
`PersistedTokenCache` which accepts a platform-dependent persistence instance. 
This token cache can then be used to instantiate the `PublicClientApplication` 
in MSAL Python. 
+
+The token cache includes a file lock, and auto-reload behavior under the hood.
+
+
+
+Here is an example of this pattern for multiple platforms (taken from the 
complete [sample 
here](https://github.com/AzureAD/microsoft-authentication-extensions-for-python/blob/dev/sample/token_cache_sample.py)):
+
+```python
+def build_persistence(location, fallback_to_plaintext=False):
+    """Build a suitable persistence instance based your current OS"""
+    if sys.platform.startswith('win'):
+        return FilePersistenceWithDataProtection(location)
+    if sys.platform.startswith('darwin'):
+        return KeychainPersistence(location, "my_service_name", 
"my_account_name")
+    if sys.platform.startswith('linux'):
+        try:
+            return LibsecretPersistence(
+                location,
+                schema_name="my_schema_name",
+                attributes={"my_attr1": "foo", "my_attr2": "bar"},
+                )
+        except:  # pylint: disable=bare-except
+            if not fallback_to_plaintext:
+                raise
+            logging.exception("Encryption unavailable. Opting in to plain 
text.")
+    return FilePersistence(location)
+
+persistence = build_persistence("token_cache.bin")
+print("Is this persistence encrypted?", persistence.is_encrypted)
+
+cache = PersistedTokenCache(persistence)
+```
+Now you can use it in an MSAL application like this:
+```python
+app = msal.PublicClientApplication("my_client_id", token_cache=cache)
+```
+
+## Community Help and Support
+
+We leverage Stack Overflow to work with the community on supporting Azure 
Active Directory and its SDKs, including this one!
+We highly recommend you ask your questions on Stack Overflow (we're all on 
there!).
+Also browse existing issues to see if someone has had your question before.
+
+We recommend you use the "msal" tag so we can see it!
+Here is the latest Q&A on Stack Overflow for MSAL:
+[http://stackoverflow.com/questions/tagged/msal](http://stackoverflow.com/questions/tagged/msal)
+
+
+## Contributing
+
+All code is licensed under the MIT license and we triage actively on GitHub.
+
+This project welcomes contributions and suggestions.  Most contributions 
require you to agree to a
+Contributor License Agreement (CLA) declaring that you have the right to, and 
actually do, grant us
+the rights to use your contribution. For details, visit 
https://cla.microsoft.com.
+
+When you submit a pull request, a CLA-bot will automatically determine whether 
you need to provide
+a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow 
the instructions
+provided by the bot. You will only need to do this once across all repos using 
our CLA.
+
+
+## We value and adhere to the Microsoft Open Source Code of Conduct
+
+This project has adopted the [Microsoft Open Source Code of 
Conduct](https://opensource.microsoft.com/codeofconduct/). For more information 
see the [Code of Conduct 
FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact 
[openc...@microsoft.com](mailto:openc...@microsoft.com) with any additional 
questions or comments.
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/msal-extensions-0.3.0/msal_extensions.egg-info/SOURCES.txt 
new/msal-extensions-0.3.1/msal_extensions.egg-info/SOURCES.txt
--- old/msal-extensions-0.3.0/msal_extensions.egg-info/SOURCES.txt      
2020-09-01 22:43:13.000000000 +0200
+++ new/msal-extensions-0.3.1/msal_extensions.egg-info/SOURCES.txt      
2021-12-13 05:46:55.000000000 +0100
@@ -1,3 +1,4 @@
+LICENSE
 README.md
 setup.cfg
 setup.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/msal-extensions-0.3.0/msal_extensions.egg-info/requires.txt 
new/msal-extensions-0.3.1/msal_extensions.egg-info/requires.txt
--- old/msal-extensions-0.3.0/msal_extensions.egg-info/requires.txt     
2020-09-01 22:43:13.000000000 +0200
+++ new/msal-extensions-0.3.1/msal_extensions.egg-info/requires.txt     
2021-12-13 05:46:55.000000000 +0100
@@ -1,10 +1,16 @@
 msal<2.0.0,>=0.4.1
 
-[:platform_system != "Windows"]
-portalocker~=1.0
-
-[:platform_system == "Windows"]
-portalocker~=1.6
-
 [:python_version < "3.0"]
 pathlib2
+
+[:python_version == "2.7" and platform_system != "Windows"]
+portalocker<2,>=1.0
+
+[:python_version == "2.7" and platform_system == "Windows"]
+portalocker<2,>=1.6
+
+[:python_version >= "3.5" and platform_system != "Windows"]
+portalocker<3,>=1.0
+
+[:python_version >= "3.5" and platform_system == "Windows"]
+portalocker<3,>=1.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msal-extensions-0.3.0/setup.cfg 
new/msal-extensions-0.3.1/setup.cfg
--- old/msal-extensions-0.3.0/setup.cfg 2020-09-01 22:43:13.000000000 +0200
+++ new/msal-extensions-0.3.1/setup.cfg 2021-12-13 05:46:55.792970000 +0100
@@ -1,6 +1,13 @@
 [bdist_wheel]
 universal = 1
 
+[metadata]
+license = MIT
+project_urls = Changelog = 
https://github.com/AzureAD/microsoft-authentication-extensions-for-python/releases
+classifiers = 
+       License :: OSI Approved :: MIT License
+       Development Status :: 4 - Beta
+
 [egg_info]
 tag_build = 
 tag_date = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/msal-extensions-0.3.0/setup.py 
new/msal-extensions-0.3.1/setup.py
--- old/msal-extensions-0.3.0/setup.py  2020-09-01 22:42:14.000000000 +0200
+++ new/msal-extensions-0.3.1/setup.py  2021-12-13 05:46:45.000000000 +0100
@@ -19,14 +19,20 @@
     packages=find_packages(),
     long_description=long_description,
     long_description_content_type="text/markdown",
-    classifiers=[
-        'Development Status :: 2 - Pre-Alpha',
-    ],
     package_data={'': ['LICENSE']},
     install_requires=[
         'msal>=0.4.1,<2.0.0',
-        "portalocker~=1.6;platform_system=='Windows'",
-        "portalocker~=1.0;platform_system!='Windows'",
+
+        # In order to implement these requirements:
+        #       Lowerbound = (1.6 if playform_system == 'Windows' else 1.0)
+        #       Upperbound < (3 if python_version >= '3.5' else 2)
+        # The following 4 lines use the `and` syntax defined here:
+        #       https://www.python.org/dev/peps/pep-0508/#grammar
+        "portalocker<3,>=1.0;python_version>='3.5' and 
platform_system!='Windows'",
+        "portalocker<2,>=1.0;python_version=='2.7' and 
platform_system!='Windows'",
+        "portalocker<3,>=1.6;python_version>='3.5' and 
platform_system=='Windows'",
+        "portalocker<2,>=1.6;python_version=='2.7' and 
platform_system=='Windows'",
+
         "pathlib2;python_version<'3.0'",
         ## We choose to NOT define a hard dependency on this.
         # "pygobject>=3,<4;platform_system=='Linux'",

Reply via email to