Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-jupyter-server-fileid for 
openSUSE:Factory checked in at 2024-11-08 11:59:53
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-jupyter-server-fileid (Old)
 and      /work/SRC/openSUSE:Factory/.python-jupyter-server-fileid.new.2017 
(New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-jupyter-server-fileid"

Fri Nov  8 11:59:53 2024 rev:6 rq:1222549 version:0.9.3

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-jupyter-server-fileid/python-jupyter-server-fileid.changes
        2024-03-07 18:32:41.260256480 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-jupyter-server-fileid.new.2017/python-jupyter-server-fileid.changes
      2024-11-08 12:04:21.857939844 +0100
@@ -1,0 +2,11 @@
+Thu Nov  7 17:56:29 UTC 2024 - Ben Greiner <c...@bnavigator.de>
+
+- Update to 0.9.3
+  * Don't commit when garbage-collected in a different thread #81
+    (@davidbrochart)
+- Release 0.9.2
+  * Check for ID before creating a new record #78 (@Zsailer)
+  * Use a context manager for all write actions to prevent
+    indefinite database locks #77 (@Zsailer)
+
+-------------------------------------------------------------------

Old:
----
  jupyter_server_fileid-0.9.1.tar.gz

New:
----
  jupyter_server_fileid-0.9.3.tar.gz

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

Other differences:
------------------
++++++ python-jupyter-server-fileid.spec ++++++
--- /var/tmp/diff_new_pack.uJ6Ff2/_old  2024-11-08 12:04:22.269957097 +0100
+++ /var/tmp/diff_new_pack.uJ6Ff2/_new  2024-11-08 12:04:22.269957097 +0100
@@ -16,8 +16,8 @@
 #
 
 
-%define pyversion 0.9.1
-%define distversion 0.9.1
+%define pyversion 0.9.3
+%define distversion 0.9.3
 %if 0%{?suse_version} > 1500
 %bcond_without libalternatives
 %else
@@ -89,13 +89,7 @@
 %check
 # flaky on obs
 donttest="test_get_path_oob_move_nested"
-export PYTHONDONTWRITEBYTECODE=1
-%{python_expand # don't test anything on python39: no jupyter-server-test 
anymore
-export PYTHONPATH=%{buildroot}%{$python_sitelib}
-if [ ${python_flavor} != "python39" ]; then
-  $python -m pytest  -k "not ($donttest)"
-fi
-}
+%pytest  -k "not ($donttest)"
 
 %pre
 %python_libalternatives_reset_alternative jupyter-fileid

++++++ jupyter_server_fileid-0.9.1.tar.gz -> jupyter_server_fileid-0.9.3.tar.gz 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jupyter_server_fileid-0.9.1/.github/workflows/prep-release.yml 
new/jupyter_server_fileid-0.9.3/.github/workflows/prep-release.yml
--- old/jupyter_server_fileid-0.9.1/.github/workflows/prep-release.yml  
2020-02-02 01:00:00.000000000 +0100
+++ new/jupyter_server_fileid-0.9.3/.github/workflows/prep-release.yml  
2020-02-02 01:00:00.000000000 +0100
@@ -12,6 +12,10 @@
       post_version_spec:
         description: "Post Version Specifier"
         required: false
+      silent:
+        description: "Set a placeholder in the changelog and don't publish the 
release."
+        required: false
+        type: boolean
       since:
         description: "Use PRs with activity since this date or git reference"
         required: false
@@ -22,6 +26,8 @@
 jobs:
   prep_release:
     runs-on: ubuntu-latest
+    permissions:
+      contents: write
     steps:
       - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
 
@@ -29,9 +35,11 @@
         id: prep-release
         uses: jupyter-server/jupyter_releaser/.github/actions/prep-release@v2
         with:
-          token: ${{ secrets.ADMIN_GITHUB_TOKEN }}
+          token: ${{ secrets.GITHUB_TOKEN }}
           version_spec: ${{ github.event.inputs.version_spec }}
+          silent: ${{ github.event.inputs.silent }}
           post_version_spec: ${{ github.event.inputs.post_version_spec }}
+          target: ${{ github.event.inputs.target }}
           branch: ${{ github.event.inputs.branch }}
           since: ${{ github.event.inputs.since }}
           since_last_stable: ${{ github.event.inputs.since_last_stable }}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jupyter_server_fileid-0.9.1/.github/workflows/publish-changelog.yml 
new/jupyter_server_fileid-0.9.3/.github/workflows/publish-changelog.yml
--- old/jupyter_server_fileid-0.9.1/.github/workflows/publish-changelog.yml     
1970-01-01 01:00:00.000000000 +0100
+++ new/jupyter_server_fileid-0.9.3/.github/workflows/publish-changelog.yml     
2020-02-02 01:00:00.000000000 +0100
@@ -0,0 +1,34 @@
+name: "Publish Changelog"
+on:
+  release:
+    types: [published]
+
+  workflow_dispatch:
+    inputs:
+      branch:
+        description: "The branch to target"
+        required: false
+
+jobs:
+  publish_changelog:
+    runs-on: ubuntu-latest
+    environment: release
+    steps:
+      - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
+
+      - uses: actions/create-github-app-token@v1
+        id: app-token
+        with:
+          app-id: ${{ vars.APP_ID }}
+          private-key: ${{ secrets.APP_PRIVATE_KEY }}
+
+      - name: Publish changelog
+        id: publish-changelog
+        uses: 
jupyter-server/jupyter_releaser/.github/actions/publish-changelog@v2
+        with:
+          token: ${{ steps.app-token.outputs.token }}
+          branch: ${{ github.event.inputs.branch }}
+
+      - name: "** Next Step **"
+        run: |
+          echo "Merge the changelog update PR: ${{ 
steps.publish-changelog.outputs.pr_url }}"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jupyter_server_fileid-0.9.1/.github/workflows/publish-release.yml 
new/jupyter_server_fileid-0.9.3/.github/workflows/publish-release.yml
--- old/jupyter_server_fileid-0.9.1/.github/workflows/publish-release.yml       
2020-02-02 01:00:00.000000000 +0100
+++ new/jupyter_server_fileid-0.9.3/.github/workflows/publish-release.yml       
2020-02-02 01:00:00.000000000 +0100
@@ -15,28 +15,32 @@
 jobs:
   publish_release:
     runs-on: ubuntu-latest
+    environment: release
+    permissions:
+      id-token: write
     steps:
       - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
 
+      - uses: actions/create-github-app-token@v1
+        id: app-token
+        with:
+          app-id: ${{ vars.APP_ID }}
+          private-key: ${{ secrets.APP_PRIVATE_KEY }}
+
       - name: Populate Release
         id: populate-release
         uses: 
jupyter-server/jupyter_releaser/.github/actions/populate-release@v2
         with:
-          token: ${{ secrets.ADMIN_GITHUB_TOKEN }}
+          token: ${{ steps.app-token.outputs.token }}
           branch: ${{ github.event.inputs.branch }}
           release_url: ${{ github.event.inputs.release_url }}
           steps_to_skip: ${{ github.event.inputs.steps_to_skip }}
 
       - name: Finalize Release
         id: finalize-release
-        env:
-          PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
-          PYPI_TOKEN_MAP: ${{ secrets.PYPI_TOKEN_MAP }}
-          TWINE_USERNAME: __token__
-          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
-        uses: 
jupyter-server/jupyter-releaser/.github/actions/finalize-release@v2
+        uses: 
jupyter-server/jupyter_releaser/.github/actions/finalize-release@v2
         with:
-          token: ${{ secrets.ADMIN_GITHUB_TOKEN }}
+          token: ${{ steps.app-token.outputs.token }}
           release_url: ${{ steps.populate-release.outputs.release_url }}
 
       - name: "** Next Step **"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jupyter_server_fileid-0.9.1/.github/workflows/test-python.yml 
new/jupyter_server_fileid-0.9.3/.github/workflows/test-python.yml
--- old/jupyter_server_fileid-0.9.1/.github/workflows/test-python.yml   
2020-02-02 01:00:00.000000000 +0100
+++ new/jupyter_server_fileid-0.9.3/.github/workflows/test-python.yml   
2020-02-02 01:00:00.000000000 +0100
@@ -84,8 +84,9 @@
         uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
         with:
           python_version: "3.7"
-      - name: Install miniumum versions
-        uses: jupyterlab/maintainer-tools/.github/actions/install-minimums@v1
+          dependency_type: minimum
+      - name: Install
+        run: pip install -e ".[test]"
       - name: Run the unit tests
         run: |
           pytest -vv -W default || pytest -vv -W default --lf
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_server_fileid-0.9.1/CHANGELOG.md 
new/jupyter_server_fileid-0.9.3/CHANGELOG.md
--- old/jupyter_server_fileid-0.9.1/CHANGELOG.md        2020-02-02 
01:00:00.000000000 +0100
+++ new/jupyter_server_fileid-0.9.3/CHANGELOG.md        2020-02-02 
01:00:00.000000000 +0100
@@ -2,6 +2,41 @@
 
 <!-- <START NEW CHANGELOG ENTRY> -->
 
+## 0.9.3
+
+([Full 
Changelog](https://github.com/jupyter-server/jupyter_server_fileid/compare/v0.9.2...7ee71f63fd6fce6535f8f99f9d47199cd934bb31))
+
+### Merged PRs
+
+- Don't commit when garbage-collected in a different thread 
[#81](https://github.com/jupyter-server/jupyter_server_fileid/pull/81) 
([@davidbrochart](https://github.com/davidbrochart))
+
+### Contributors to this release
+
+([GitHub contributors page for this 
release](https://github.com/jupyter-server/jupyter_server_fileid/graphs/contributors?from=2024-04-18&to=2024-09-06&type=c))
+
+[@davidbrochart](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server_fileid+involves%3Adavidbrochart+updated%3A2024-04-18..2024-09-06&type=Issues)
+
+<!-- <END NEW CHANGELOG ENTRY> -->
+
+## 0.9.2
+
+([Full 
Changelog](https://github.com/jupyter-server/jupyter_server_fileid/compare/v0.9.1...501a1230ac2e934c70bbb7267144f16fe6ed3484))
+
+### Bugs fixed
+
+- Check for ID before creating a new record 
[#78](https://github.com/jupyter-server/jupyter_server_fileid/pull/78) 
([@Zsailer](https://github.com/Zsailer))
+- Use a context manager for all write actions to prevent indefinite database 
locks [#77](https://github.com/jupyter-server/jupyter_server_fileid/pull/77) 
([@Zsailer](https://github.com/Zsailer))
+
+### Maintenance and upkeep improvements
+
+- Update Release Scripts 
[#79](https://github.com/jupyter-server/jupyter_server_fileid/pull/79) 
([@blink1073](https://github.com/blink1073))
+
+### Contributors to this release
+
+([GitHub contributors page for this 
release](https://github.com/jupyter-server/jupyter_server_fileid/graphs/contributors?from=2023-12-19&to=2024-04-18&type=c))
+
+[@blink1073](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server_fileid+involves%3Ablink1073+updated%3A2023-12-19..2024-04-18&type=Issues)
 | 
[@welcome](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server_fileid+involves%3Awelcome+updated%3A2023-12-19..2024-04-18&type=Issues)
 | 
[@Zsailer](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server_fileid+involves%3AZsailer+updated%3A2023-12-19..2024-04-18&type=Issues)
+
 ## 0.9.1
 
 ([Full 
Changelog](https://github.com/jupyter-server/jupyter_server_fileid/compare/v0.9.0...a5e65c99791a20e4684c55f631d2d7fef3c3fdad))
@@ -22,8 +57,6 @@
 
 
[@cmd-ntrf](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server_fileid+involves%3Acmd-ntrf+updated%3A2023-04-09..2023-12-19&type=Issues)
 | 
[@codecov](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server_fileid+involves%3Acodecov+updated%3A2023-04-09..2023-12-19&type=Issues)
 | 
[@dlqqq](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server_fileid+involves%3Adlqqq+updated%3A2023-04-09..2023-12-19&type=Issues)
 | 
[@stonebig](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server_fileid+involves%3Astonebig+updated%3A2023-04-09..2023-12-19&type=Issues)
 | 
[@welcome](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server_fileid+involves%3Awelcome+updated%3A2023-04-09..2023-12-19&type=Issues)
 | 
[@Zsailer](https://github.com/search?q=repo%3Ajupyter-server%2Fjupyter_server_fileid+involves%3AZsailer+updated%3A2023-04-09..2023-12-19&type=Issues)
 
-<!-- <END NEW CHANGELOG ENTRY> -->
-
 ## 0.9.0
 
 ([Full 
Changelog](https://github.com/jupyter-server/jupyter_server_fileid/compare/v0.8.0...505806162b4df60b4cbb461cfec1266b81df32ce))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jupyter_server_fileid-0.9.1/PKG-INFO 
new/jupyter_server_fileid-0.9.3/PKG-INFO
--- old/jupyter_server_fileid-0.9.1/PKG-INFO    2020-02-02 01:00:00.000000000 
+0100
+++ new/jupyter_server_fileid-0.9.3/PKG-INFO    2020-02-02 01:00:00.000000000 
+0100
@@ -1,6 +1,6 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.3
 Name: jupyter_server_fileid
-Version: 0.9.1
+Version: 0.9.3
 Summary: Jupyter Server extension providing an implementation of the File ID 
service.
 Project-URL: Home, https://github.com/jupyter-server/jupyter_server_fileid
 Author-email: "David L. Qiu" <da...@qiu.dev>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jupyter_server_fileid-0.9.1/jupyter_server_fileid/__init__.py 
new/jupyter_server_fileid-0.9.3/jupyter_server_fileid/__init__.py
--- old/jupyter_server_fileid-0.9.1/jupyter_server_fileid/__init__.py   
2020-02-02 01:00:00.000000000 +0100
+++ new/jupyter_server_fileid-0.9.3/jupyter_server_fileid/__init__.py   
2020-02-02 01:00:00.000000000 +0100
@@ -1,7 +1,7 @@
 """A Jupyter Server extension providing an implementation of the File ID 
service."""
 from .extension import FileIdExtension
 
-__version__ = "0.9.1"
+__version__ = "0.9.3"
 
 
 def _jupyter_server_extension_points():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/jupyter_server_fileid-0.9.1/jupyter_server_fileid/manager.py 
new/jupyter_server_fileid-0.9.3/jupyter_server_fileid/manager.py
--- old/jupyter_server_fileid-0.9.1/jupyter_server_fileid/manager.py    
2020-02-02 01:00:00.000000000 +0100
+++ new/jupyter_server_fileid-0.9.3/jupyter_server_fileid/manager.py    
2020-02-02 01:00:00.000000000 +0100
@@ -312,23 +312,22 @@
 
     def _create(self, path: str) -> str:
         path = self._normalize_path(path)
-        id = self._uuid()
-        self.con.execute("INSERT INTO Files (id, path) VALUES (?, ?)", (id, 
path))
-        return id
-
-    def index(self, path: str) -> str:
-        path = self._normalize_path(path)
         row = self.con.execute("SELECT id FROM Files WHERE path = ?", 
(path,)).fetchone()
         existing_id = row and row[0]
 
         if existing_id:
             return existing_id
 
-        # create new record
-        id = self._create(path)
-        self.con.commit()
+        id = self._uuid()
+        self.con.execute("INSERT INTO Files (id, path) VALUES (?, ?)", (id, 
path))
         return id
 
+    def index(self, path: str) -> str:
+        # create new record
+        with self.con:
+            id = self._create(path)
+            return id
+
     def get_id(self, path: str) -> Optional[str]:
         path = self._normalize_path(path)
         row = self.con.execute("SELECT id FROM Files WHERE path = ?", 
(path,)).fetchone()
@@ -340,37 +339,36 @@
         return self._from_normalized_path(path)
 
     def move(self, old_path: str, new_path: str) -> None:
-        old_path = self._normalize_path(old_path)
-        new_path = self._normalize_path(new_path)
-        row = self.con.execute("SELECT id FROM Files WHERE path = ?", 
(old_path,)).fetchone()
-        id = row and row[0]
-
-        if id:
-            self.con.execute("UPDATE Files SET path = ? WHERE path = ?", 
(new_path, old_path))
-            self._move_recursive(old_path, new_path, posixpath)
-        else:
-            id = self._create(new_path)
+        with self.con:
+            old_path = self._normalize_path(old_path)
+            new_path = self._normalize_path(new_path)
+            row = self.con.execute("SELECT id FROM Files WHERE path = ?", 
(old_path,)).fetchone()
+            id = row and row[0]
+
+            if id:
+                self.con.execute("UPDATE Files SET path = ? WHERE path = ?", 
(new_path, old_path))
+                self._move_recursive(old_path, new_path, posixpath)
+            else:
+                id = self._create(new_path)
 
-        self.con.commit()
-        return id
+            return id
 
     def copy(self, from_path: str, to_path: str) -> Optional[str]:
-        from_path = self._normalize_path(from_path)
-        to_path = self._normalize_path(to_path)
+        with self.con:
+            from_path = self._normalize_path(from_path)
+            to_path = self._normalize_path(to_path)
 
-        id = self._create(to_path)
-        self._copy_recursive(from_path, to_path, posixpath)
+            id = self._create(to_path)
+            self._copy_recursive(from_path, to_path, posixpath)
 
-        self.con.commit()
-        return id
+            return id
 
     def delete(self, path: str) -> None:
-        path = self._normalize_path(path)
+        with self.con:
+            path = self._normalize_path(path)
 
-        self.con.execute("DELETE FROM Files WHERE path = ?", (path,))
-        self._delete_recursive(path, posixpath)
-
-        self.con.commit()
+            self.con.execute("DELETE FROM Files WHERE path = ?", (path,))
+            self._delete_recursive(path, posixpath)
 
     def save(self, path: str) -> None:
         return
@@ -388,8 +386,14 @@
         """Cleans up `ArbitraryFileIdManager` by committing any pending
         transactions and closing the connection."""
         if hasattr(self, "con"):
-            self.con.commit()
-            self.con.close()
+            # If garbage collection happens in a different thread than the 
thread where
+            # the SQLite object was created, committing will fail anyway. We 
just ignore
+            # the exception if this is the case.
+            try:
+                self.con.commit()
+                self.con.close()
+            except sqlite3.ProgrammingError:
+                pass
 
 
 class LocalFileIdManager(BaseFileIdManager):
@@ -626,6 +630,7 @@
         # otherwise update existing record with new path, moving any indexed
         # children if necessary. then return its id
         self._update(id, path=path)
+
         if stat_info.is_dir and old_path != path:
             self._move_recursive(old_path, path)
             self._update_cursor = True
@@ -672,6 +677,17 @@
         dangerous and may throw a runtime error if the file is not guaranteed 
to
         have a unique `ino`.
         """
+        # If the path exists
+        existing_id, ino = None, None
+        row = self.con.execute("SELECT id, ino FROM Files WHERE path = ?", 
(path,)).fetchone()
+        if row:
+            existing_id, ino = row
+
+        # If the file ID already exists and the current file matches our 
records
+        # return the file ID instead of creating a new one.
+        if existing_id and stat_info.ino == ino:
+            return existing_id
+
         id = self._uuid()
         self.con.execute(
             "INSERT INTO Files (id, path, ino, crtime, mtime, is_dir) VALUES 
(?, ?, ?, ?, ?, ?)",
@@ -718,39 +734,38 @@
     def index(self, path, stat_info=None, commit=True):
         """Returns the file ID for the file at `path`, creating a new file ID 
if
         one does not exist. Returns None only if file does not exist at 
path."""
-        path = self._normalize_path(path)
-        stat_info = stat_info or self._stat(path)
-        if not stat_info:
-            return None
+        with self.con:
+            path = self._normalize_path(path)
+            stat_info = stat_info or self._stat(path)
+            if not stat_info:
+                return None
 
-        # if file is symlink, then index the path it refers to instead
-        if stat_info.is_symlink:
-            return self.index(os.path.realpath(path))
+            # if file is symlink, then index the path it refers to instead
+            if stat_info.is_symlink:
+                return self.index(os.path.realpath(path))
+
+            # sync file at path and return file ID if it exists
+            id = self._sync_file(path, stat_info)
+            if id is not None:
+                return id
 
-        # sync file at path and return file ID if it exists
-        id = self._sync_file(path, stat_info)
-        if id is not None:
+            # otherwise, create a new record and return the file ID
+            id = self._create(path, stat_info)
             return id
 
-        # otherwise, create a new record and return the file ID
-        id = self._create(path, stat_info)
-        if commit:
-            self.con.commit()
-        return id
-
     def get_id(self, path):
         """Retrieves the file ID associated with a file path. Returns None if
         the file has not yet been indexed or does not exist at the given
         path."""
-        path = self._normalize_path(path)
-        stat_info = self._stat(path)
-        if not stat_info:
-            return None
+        with self.con:
+            path = self._normalize_path(path)
+            stat_info = self._stat(path)
+            if not stat_info:
+                return None
 
-        # then sync file at path and retrieve id, if any
-        id = self._sync_file(path, stat_info)
-        self.con.commit()
-        return id
+            # then sync file at path and retrieve id, if any
+            id = self._sync_file(path, stat_info)
+            return id
 
     def get_path(self, id):
         """Retrieves the file path associated with a file ID. The file path is
@@ -795,26 +810,26 @@
     def move(self, old_path, new_path):
         """Handles file moves by updating the file path of the associated file
         ID.  Returns the file ID. Returns None if file does not exist at 
new_path."""
-        old_path = self._normalize_path(old_path)
-        new_path = self._normalize_path(new_path)
+        with self.con:
+            old_path = self._normalize_path(old_path)
+            new_path = self._normalize_path(new_path)
 
-        # verify file exists at new_path
-        stat_info = self._stat(new_path)
-        if stat_info is None:
-            return None
+            # verify file exists at new_path
+            stat_info = self._stat(new_path)
+            if stat_info is None:
+                return None
 
-        # sync the file and see if it was already indexed
-        #
-        # originally this method did not call _sync_file() for performance
-        # reasons, but this is needed to handle an edge case:
-        # https://github.com/jupyter-server/jupyter_server_fileid/issues/62
-        id = self._sync_file(new_path, stat_info)
-        if id is None:
-            # if no existing record, create a new one
-            id = self._create(new_path, stat_info)
+            # sync the file and see if it was already indexed
+            #
+            # originally this method did not call _sync_file() for performance
+            # reasons, but this is needed to handle an edge case:
+            # https://github.com/jupyter-server/jupyter_server_fileid/issues/62
+            id = self._sync_file(new_path, stat_info)
+            if id is None:
+                # if no existing record, create a new one
+                id = self._create(new_path, stat_info)
 
-        self.con.commit()
-        return id
+            return id
 
     def _copy_recursive(self, from_path: str, to_path: str, _: str = "") -> 
None:
         """Copy all children of a given directory at `from_path` to a new
@@ -859,13 +874,13 @@
     def delete(self, path):
         """Handles file deletions by deleting the associated record in the File
         table. Returns None."""
-        path = self._normalize_path(path)
+        with self.con:
+            path = self._normalize_path(path)
 
-        if os.path.isdir(path):
-            self._delete_recursive(path)
+            if os.path.isdir(path):
+                self._delete_recursive(path)
 
-        self.con.execute("DELETE FROM Files WHERE path = ?", (path,))
-        self.con.commit()
+            self.con.execute("DELETE FROM Files WHERE path = ?", (path,))
 
     def save(self, path):
         """Handles file saves (edits) by updating recorded stat info.
@@ -878,21 +893,21 @@
         JupyterLab.  This would (wrongly) preserve the association b/w the old
         file ID and the current path rather than create a new file ID.
         """
-        path = self._normalize_path(path)
+        with self.con:
+            path = self._normalize_path(path)
 
-        # look up record by ino and path
-        stat_info = self._stat(path)
-        row = self.con.execute(
-            "SELECT id FROM Files WHERE ino = ? AND path = ?", (stat_info.ino, 
path)
-        ).fetchone()
-        # if no record exists, return early
-        if row is None:
-            return
-
-        # otherwise, update the stat info
-        (id,) = row
-        self._update(id, stat_info)
-        self.con.commit()
+            # look up record by ino and path
+            stat_info = self._stat(path)
+            row = self.con.execute(
+                "SELECT id FROM Files WHERE ino = ? AND path = ?", 
(stat_info.ino, path)
+            ).fetchone()
+            # if no record exists, return early
+            if row is None:
+                return
+
+            # otherwise, update the stat info
+            (id,) = row
+            self._update(id, stat_info)
 
     def get_handlers_by_action(self) -> Dict[str, Optional[Callable[[Dict[str, 
Any]], Any]]]:
         return {

Reply via email to