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 2025-03-19 22:33:20
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-msal-extensions (Old)
and /work/SRC/openSUSE:Factory/.python-msal-extensions.new.4956 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-msal-extensions"
Wed Mar 19 22:33:20 2025 rev:13 rq:1254234 version:1.3.1
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-msal-extensions/python-msal-extensions.changes
2024-11-25 23:21:45.975338675 +0100
+++
/work/SRC/openSUSE:Factory/.python-msal-extensions.new.4956/python-msal-extensions.changes
2025-03-19 22:33:35.325784952 +0100
@@ -1,0 +2,15 @@
+Tue Mar 18 09:39:10 UTC 2025 - John Paul Adrian Glaubitz
<[email protected]>
+
+- Update to version 1.3.1
+ * Do not install tests in site-packages by @musicinmybrain in (#139)
+ * Also dropped Python 3.7 and 3.8 since this release
+- from version 1.3.0
+ * Fix a typo in README.md (persistance/persistence)
+ by @musicinmybrain in (#133)
+ * Maintenance by @rayluo in (#137)
+ * Allow portalocker version 3 by @musicinmybrain in (#136)
+ * Make portalocker optional (opt in by pip install
+ msal-extensions[portalocker]) by @rayluo in (#117)
+- Drop me_relax-portalocker.patch, fixed upstream
+
+-------------------------------------------------------------------
Old:
----
me_relax-portalocker.patch
msal_extensions-1.2.0.tar.gz
New:
----
msal_extensions-1.3.1.tar.gz
BETA DEBUG BEGIN:
Old: msal-extensions[portalocker]) by @rayluo in (#117)
- Drop me_relax-portalocker.patch, fixed upstream
BETA DEBUG END:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-msal-extensions.spec ++++++
--- /var/tmp/diff_new_pack.f6Gii7/_old 2025-03-19 22:33:36.441831936 +0100
+++ /var/tmp/diff_new_pack.f6Gii7/_new 2025-03-19 22:33:36.441831936 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-msal-extensions
#
-# Copyright (c) 2024 SUSE LLC
+# Copyright (c) 2025 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -18,14 +18,13 @@
%{?sle15_python_module_pythons}
Name: python-msal-extensions
-Version: 1.2.0
+Version: 1.3.1
Release: 0
Summary: Microsoft Authentication Library (MSAL) for Python Extensions
License: MIT
Group: Development/Languages/Python
URL:
https://github.com/AzureAD/microsoft-authentication-library-for-python
Source:
https://files.pythonhosted.org/packages/source/m/msal-extensions/msal_extensions-%{version}.tar.gz
-Patch: me_relax-portalocker.patch
BuildRequires: %{python_module devel}
BuildRequires: %{python_module pip}
BuildRequires: %{python_module setuptools}
@@ -57,7 +56,6 @@
%prep
%setup -q -n msal_extensions-%{version}
-%patch -P0 -p1
%build
%pyproject_wheel
++++++ msal_extensions-1.2.0.tar.gz -> msal_extensions-1.3.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal_extensions-1.2.0/PKG-INFO
new/msal_extensions-1.3.1/PKG-INFO
--- old/msal_extensions-1.2.0/PKG-INFO 2024-06-23 04:15:32.950193200 +0200
+++ new/msal_extensions-1.3.1/PKG-INFO 2025-03-15 00:50:59.740693800 +0100
@@ -1,6 +1,6 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.2
Name: msal-extensions
-Version: 1.2.0
+Version: 1.3.1
Summary: Microsoft Authentication Library extensions (MSAL EX) provides a
persistence API that can save your data on disk, encrypted on Windows, macOS
and Linux. Concurrent data access will be coordinated by a file lock mechanism.
License: MIT License
Project-URL: Changelog,
https://github.com/AzureAD/microsoft-authentication-extensions-for-python/releases
@@ -14,18 +14,24 @@
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
-Requires-Python: >=3.7
+Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: msal<2,>=1.29
-Requires-Dist: portalocker<3,>=1.4
+Provides-Extra: portalocker
+Requires-Dist: portalocker<4,>=1.4; extra == "portalocker"
+Dynamic: description
+Dynamic: description-content-type
+Dynamic: provides-extra
+Dynamic: requires-dist
+Dynamic: requires-python
# 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.
+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 persistence 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.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal_extensions-1.2.0/README.md
new/msal_extensions-1.3.1/README.md
--- old/msal_extensions-1.2.0/README.md 2024-06-23 04:15:27.000000000 +0200
+++ new/msal_extensions-1.3.1/README.md 2025-03-15 00:50:56.000000000 +0100
@@ -3,7 +3,7 @@
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.
+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 persistence 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.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal_extensions-1.2.0/msal_extensions/__init__.py
new/msal_extensions-1.3.1/msal_extensions/__init__.py
--- old/msal_extensions-1.2.0/msal_extensions/__init__.py 2024-06-23
04:15:27.000000000 +0200
+++ new/msal_extensions-1.3.1/msal_extensions/__init__.py 2025-03-15
00:50:56.000000000 +0100
@@ -1,5 +1,5 @@
"""Provides auxiliary functionality to the `msal` package."""
-__version__ = "1.2.0" # Note: During/after release, copy this number to
Dockerfile
+__version__ = "1.3.1" # Note: During/after release, copy this number to
Dockerfile
from .persistence import (
FilePersistence,
@@ -8,6 +8,5 @@
KeychainPersistence,
LibsecretPersistence,
)
-from .cache_lock import CrossPlatLock
-from .token_cache import PersistedTokenCache
+from .token_cache import PersistedTokenCache, CrossPlatLock, LockError
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal_extensions-1.2.0/msal_extensions/cache_lock.py
new/msal_extensions-1.3.1/msal_extensions/cache_lock.py
--- old/msal_extensions-1.2.0/msal_extensions/cache_lock.py 2024-06-23
04:15:27.000000000 +0200
+++ new/msal_extensions-1.3.1/msal_extensions/cache_lock.py 2025-03-15
00:50:56.000000000 +0100
@@ -5,12 +5,15 @@
import time
import logging
-import portalocker
+import portalocker # pylint: disable=import-error
logger = logging.getLogger(__name__)
+LockError = portalocker.exceptions.LockException
+
+
class CrossPlatLock(object):
"""Offers a mechanism for waiting until another process is finished
interacting with a shared
resource. This is specifically written to interact with a class of the
same name in the .NET
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal_extensions-1.2.0/msal_extensions/filelock.py
new/msal_extensions-1.3.1/msal_extensions/filelock.py
--- old/msal_extensions-1.2.0/msal_extensions/filelock.py 1970-01-01
01:00:00.000000000 +0100
+++ new/msal_extensions-1.3.1/msal_extensions/filelock.py 2025-03-15
00:50:56.000000000 +0100
@@ -0,0 +1,62 @@
+"""A cross-process lock based on exclusive creation of a given file name"""
+import os
+import sys
+import errno
+import time
+import logging
+
+
+logger = logging.getLogger(__name__)
+
+
+class LockError(RuntimeError):
+ """It will be raised when unable to obtain a lock"""
+
+
+class CrossPlatLock(object):
+ """This implementation relies only on ``open(..., 'x')``"""
+ def __init__(self, lockfile_path):
+ self._lockpath = lockfile_path
+
+ def __enter__(self):
+ self._create_lock_file('{} {}'.format(
+ os.getpid(),
+ sys.argv[0],
+ ).encode('utf-8')) # pylint: disable=consider-using-f-string
+ return self
+
+ def _create_lock_file(self, content):
+ timeout = 5
+ check_interval = 0.25
+ current_time = getattr(time, "monotonic", time.time)
+ timeout_end = current_time() + timeout
+ while timeout_end > current_time():
+ try:
+ with open(self._lockpath, 'xb') as lock_file: # pylint:
disable=unspecified-encoding
+ lock_file.write(content)
+ return None # Happy path
+ except ValueError: # This needs to be the first clause, for
Python 2 to hit it
+ raise LockError("Python 2 does not support atomic creation of
file")
+ except FileExistsError: # Only Python 3 will reach this clause
+ logger.debug(
+ "Process %d found existing lock file, will retry after %f
second",
+ os.getpid(), check_interval)
+ time.sleep(check_interval)
+ raise LockError(
+ "Unable to obtain lock, despite trying for {} second(s). "
+ "You may want to manually remove the stale lock file {}".format(
+ timeout,
+ self._lockpath,
+ ))
+
+ def __exit__(self, *args):
+ try:
+ os.remove(self._lockpath)
+ except OSError as ex: # pylint: disable=invalid-name
+ if ex.errno in (errno.ENOENT, errno.EACCES):
+ # Probably another process has raced this one
+ # and ended up clearing or locking the file for itself.
+ logger.debug("Unable to remove lock file")
+ else:
+ raise
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal_extensions-1.2.0/msal_extensions/libsecret.py
new/msal_extensions-1.3.1/msal_extensions/libsecret.py
--- old/msal_extensions-1.2.0/msal_extensions/libsecret.py 2024-06-23
04:15:27.000000000 +0200
+++ new/msal_extensions-1.3.1/msal_extensions/libsecret.py 2025-03-15
00:50:56.000000000 +0100
@@ -40,7 +40,7 @@
class LibSecretAgent(object):
"""A loader/saver built on top of low-level libsecret"""
# Inspired by
https://developer.gnome.org/libsecret/unstable/py-examples.html
- def __init__( # pylint: disable=too-many-arguments
+ def __init__( # pylint:
disable=too-many-arguments,too-many-positional-arguments
self,
schema_name,
attributes, # {"name": "value", ...}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal_extensions-1.2.0/msal_extensions/token_cache.py
new/msal_extensions-1.3.1/msal_extensions/token_cache.py
--- old/msal_extensions-1.2.0/msal_extensions/token_cache.py 2024-06-23
04:15:27.000000000 +0200
+++ new/msal_extensions-1.3.1/msal_extensions/token_cache.py 2025-03-15
00:50:56.000000000 +0100
@@ -5,7 +5,13 @@
import msal
-from .cache_lock import CrossPlatLock
+try: # It needs portalocker
+ from .cache_lock import ( # pylint: disable=unused-import
+ CrossPlatLock,
+ LockError, # We don't use LockError in this file, but __init__.py
uses it.
+ )
+except ImportError: # Falls back to file-based lock
+ from .filelock import CrossPlatLock, LockError # pylint:
disable=unused-import
from .persistence import _mkdir_p, PersistenceNotFound
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/msal_extensions-1.2.0/msal_extensions.egg-info/PKG-INFO
new/msal_extensions-1.3.1/msal_extensions.egg-info/PKG-INFO
--- old/msal_extensions-1.2.0/msal_extensions.egg-info/PKG-INFO 2024-06-23
04:15:32.000000000 +0200
+++ new/msal_extensions-1.3.1/msal_extensions.egg-info/PKG-INFO 2025-03-15
00:50:59.000000000 +0100
@@ -1,6 +1,6 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.2
Name: msal-extensions
-Version: 1.2.0
+Version: 1.3.1
Summary: Microsoft Authentication Library extensions (MSAL EX) provides a
persistence API that can save your data on disk, encrypted on Windows, macOS
and Linux. Concurrent data access will be coordinated by a file lock mechanism.
License: MIT License
Project-URL: Changelog,
https://github.com/AzureAD/microsoft-authentication-extensions-for-python/releases
@@ -14,18 +14,24 @@
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
-Requires-Python: >=3.7
+Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: msal<2,>=1.29
-Requires-Dist: portalocker<3,>=1.4
+Provides-Extra: portalocker
+Requires-Dist: portalocker<4,>=1.4; extra == "portalocker"
+Dynamic: description
+Dynamic: description-content-type
+Dynamic: provides-extra
+Dynamic: requires-dist
+Dynamic: requires-python
# 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.
+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 persistence 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.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/msal_extensions-1.2.0/msal_extensions.egg-info/SOURCES.txt
new/msal_extensions-1.3.1/msal_extensions.egg-info/SOURCES.txt
--- old/msal_extensions-1.2.0/msal_extensions.egg-info/SOURCES.txt
2024-06-23 04:15:32.000000000 +0200
+++ new/msal_extensions-1.3.1/msal_extensions.egg-info/SOURCES.txt
2025-03-15 00:50:59.000000000 +0100
@@ -4,6 +4,7 @@
setup.py
msal_extensions/__init__.py
msal_extensions/cache_lock.py
+msal_extensions/filelock.py
msal_extensions/libsecret.py
msal_extensions/osx.py
msal_extensions/persistence.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/msal_extensions-1.2.0/msal_extensions.egg-info/requires.txt
new/msal_extensions-1.3.1/msal_extensions.egg-info/requires.txt
--- old/msal_extensions-1.2.0/msal_extensions.egg-info/requires.txt
2024-06-23 04:15:32.000000000 +0200
+++ new/msal_extensions-1.3.1/msal_extensions.egg-info/requires.txt
2025-03-15 00:50:59.000000000 +0100
@@ -1,2 +1,4 @@
msal<2,>=1.29
-portalocker<3,>=1.4
+
+[portalocker]
+portalocker<4,>=1.4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal_extensions-1.2.0/setup.py
new/msal_extensions-1.3.1/setup.py
--- old/msal_extensions-1.2.0/setup.py 2024-06-23 04:15:27.000000000 +0200
+++ new/msal_extensions-1.3.1/setup.py 2025-03-15 00:50:56.000000000 +0100
@@ -13,17 +13,21 @@
setup(
name='msal-extensions',
version=__version__,
- packages=find_packages(),
+ packages=find_packages(exclude=["tests"]),
long_description=long_description,
long_description_content_type="text/markdown",
package_data={'': ['LICENSE']},
- python_requires=">=3.7",
+ python_requires=">=3.9",
install_requires=[
'msal>=1.29,<2', # Use TokenCache.search() from MSAL Python 1.29+
- 'portalocker<3,>=1.4',
## We choose to NOT define a hard dependency on this.
# "pygobject>=3,<4;platform_system=='Linux'",
],
+ extras_require={
+ "portalocker": [
+ 'portalocker<4,>=1.4',
+ ],
+ },
tests_require=['pytest'],
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal_extensions-1.2.0/tests/test_agnostic_backend.py
new/msal_extensions-1.3.1/tests/test_agnostic_backend.py
--- old/msal_extensions-1.2.0/tests/test_agnostic_backend.py 2024-06-23
04:15:27.000000000 +0200
+++ new/msal_extensions-1.3.1/tests/test_agnostic_backend.py 2025-03-15
00:50:56.000000000 +0100
@@ -1,12 +1,15 @@
+import json
import os
import shutil
import tempfile
+from unittest.mock import patch
import sys
import msal
import pytest
from msal_extensions import *
+from .http_client import MinimalResponse
@pytest.fixture
@@ -16,18 +19,19 @@
shutil.rmtree(test_folder, ignore_errors=True)
def _test_token_cache_roundtrip(persistence):
- client_id = os.getenv('AZURE_CLIENT_ID')
- client_secret = os.getenv('AZURE_CLIENT_SECRET')
- if not (client_id and client_secret):
- pytest.skip('no credentials present to test TokenCache round-trip
with.')
-
desired_scopes = ['https://graph.microsoft.com/.default']
apps = [ # Multiple apps sharing same persistence
msal.ConfidentialClientApplication(
- client_id, client_credential=client_secret,
+ "fake_client_id", client_credential="fake_client_secret",
token_cache=PersistedTokenCache(persistence)) for i in range(2)]
- token1 = apps[0].acquire_token_for_client(scopes=desired_scopes)
- assert token1["token_source"] == "identity_provider", "Initial token
should come from IdP"
+ with patch.object(apps[0].http_client, "post",
return_value=MinimalResponse(
+ status_code=200, text=json.dumps({
+ "token_type": "Bearer",
+ "access_token": "app token",
+ "expires_in": 3600,
+ }))) as mocked_post:
+ token1 = apps[0].acquire_token_for_client(scopes=desired_scopes)
+ assert token1["token_source"] == "identity_provider", "Initial token
should come from IdP"
token2 = apps[1].acquire_token_for_client(scopes=desired_scopes) # Hit
token cache in MSAL 1.23+
assert token2["token_source"] == "cache", "App2 should hit cache written
by app1"
assert token1['access_token'] == token2['access_token'], "Cache should hit"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/msal_extensions-1.2.0/tests/test_cache_lock_file_perf.py
new/msal_extensions-1.3.1/tests/test_cache_lock_file_perf.py
--- old/msal_extensions-1.2.0/tests/test_cache_lock_file_perf.py
2024-06-23 04:15:27.000000000 +0200
+++ new/msal_extensions-1.3.1/tests/test_cache_lock_file_perf.py
2025-03-15 00:50:56.000000000 +0100
@@ -5,7 +5,7 @@
import pytest
-from cache_file_generator import _acquire_lock_and_write_to_cache
+from .cache_file_generator import _acquire_lock_and_write_to_cache
@pytest.fixture
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/msal_extensions-1.2.0/tests/test_crossplatlock.py
new/msal_extensions-1.3.1/tests/test_crossplatlock.py
--- old/msal_extensions-1.2.0/tests/test_crossplatlock.py 2024-06-23
04:15:27.000000000 +0200
+++ new/msal_extensions-1.3.1/tests/test_crossplatlock.py 2025-03-15
00:50:56.000000000 +0100
@@ -1,5 +1,5 @@
import pytest
-from msal_extensions.cache_lock import CrossPlatLock
+from msal_extensions import CrossPlatLock
def test_ensure_file_deleted():
@@ -10,6 +10,7 @@
except NameError:
FileNotFoundError = IOError
+ print("Testing with {}".format(CrossPlatLock))
with CrossPlatLock(lockfile):
pass