Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-queuelib for openSUSE:Factory 
checked in at 2026-08-25 13:19:37
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-queuelib (Old)
 and      /work/SRC/openSUSE:Factory/.python-queuelib.new.1258 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-queuelib"

Tue Aug 25 13:19:37 2026 rev:9 rq:1373450 version:1.10.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-queuelib/python-queuelib.changes  
2026-03-23 17:12:43.904088173 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-queuelib.new.1258/python-queuelib.changes    
    2026-08-25 13:19:42.031135312 +0200
@@ -1,0 +2,12 @@
+Mon Aug 24 16:47:34 UTC 2026 - Martin Pluskal <[email protected]>
+
+- Update to 1.10.0:
+  * Added clear(), which removes every item from a queue while
+    keeping it open
+  * Fixed RoundRobinQueue.pop() dropping falsy items
+  * Added support for Python 3.15
+- Refresh summary and description to also mention the in-memory
+  queues
+- List installed files explicitly instead of globbing sitelib
+
+-------------------------------------------------------------------

Old:
----
  queuelib-1.9.0.tar.gz

New:
----
  queuelib-1.10.0.tar.gz

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

Other differences:
------------------
++++++ python-queuelib.spec ++++++
--- /var/tmp/diff_new_pack.h4Oxzn/_old  2026-08-25 13:19:43.360182112 +0200
+++ /var/tmp/diff_new_pack.h4Oxzn/_new  2026-08-25 13:19:43.364182253 +0200
@@ -18,9 +18,9 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-queuelib
-Version:        1.9.0
+Version:        1.10.0
 Release:        0
-Summary:        Collection of Persistent (Disk-Based) Queues
+Summary:        Collection of In-Memory and Persistent (Disk-Based) Queues
 License:        BSD-3-Clause
 URL:            https://github.com/scrapy/queuelib
 Source:         
https://files.pythonhosted.org/packages/source/q/queuelib/queuelib-%{version}.tar.gz
@@ -38,10 +38,12 @@
 %python_subpackages
 
 %description
-Queuelib is a collection of persistent (disk-based) queues for Python.
+Queuelib is a Python library that implements object collections which are
+stored in memory or persisted to disk, provide a simple API, and run fast.
 
-Queuelib goals are speed and simplicity. It was originally part of the
-`Scrapy framework`_ and stripped out on its own library.
+Queuelib provides collections for queues (FIFO), stacks (LIFO), queues sorted
+by priority and queues that are emptied in a round-robin fashion. Queuelib
+collections are not thread-safe.
 
 %prep
 %setup -q -n queuelib-%{version}
@@ -59,5 +61,6 @@
 %files %{python_files}
 %doc README.rst NEWS
 %license LICENSE
-%{python_sitelib}/*
+%{python_sitelib}/queuelib
+%{python_sitelib}/queuelib-%{version}*-info
 

++++++ queuelib-1.9.0.tar.gz -> queuelib-1.10.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/queuelib-1.9.0/NEWS new/queuelib-1.10.0/NEWS
--- old/queuelib-1.9.0/NEWS     2020-02-02 01:00:00.000000000 +0100
+++ new/queuelib-1.10.0/NEWS    2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,15 @@
 Queuelib release notes
 ======================
 
+Version 1.10.0
+---------------
+(released on 2026-08-24)
+
+* Added ``clear()``, to remove every item from a queue while keeping it open
+* Fixed ``RoundRobinQueue.pop()`` dropping falsy items
+* Added support for Python 3.15
+* Improved linting and CI configuration
+
 Version 1.9.0
 -------------
 (released on 2026-01-29)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/queuelib-1.9.0/PKG-INFO new/queuelib-1.10.0/PKG-INFO
--- old/queuelib-1.9.0/PKG-INFO 2020-02-02 01:00:00.000000000 +0100
+++ new/queuelib-1.10.0/PKG-INFO        2020-02-02 01:00:00.000000000 +0100
@@ -1,6 +1,6 @@
-Metadata-Version: 2.4
+Metadata-Version: 2.5
 Name: queuelib
-Version: 1.9.0
+Version: 1.10.0
 Summary: Collection of persistent (disk-based) and non-persistent 
(memory-based) queues
 Project-URL: Homepage, https://github.com/scrapy/queuelib
 Project-URL: Source, https://github.com/scrapy/queuelib
@@ -19,6 +19,7 @@
 Classifier: Programming Language :: Python :: 3.12
 Classifier: Programming Language :: Python :: 3.13
 Classifier: Programming Language :: Python :: 3.14
+Classifier: Programming Language :: Python :: 3.15
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Requires-Python: >=3.10
@@ -159,11 +160,130 @@
     >>> rr.pop()
     b'd'
 
+Clearing a queue
+================
 
-Mailing list
-============
+``clear()`` removes every item from a queue, freeing the disk space that they
+used, and leaves the queue open and usable::
+
+    >>> q.clear()
+    >>> len(q)
+    0
+
+``PriorityQueue`` and ``RoundRobinQueue`` also close their internal queues, the
+same way that ``pop()`` does when one of them becomes empty.
+
+Disk persistence
+================
+
+``FifoDiskQueue`` and ``LifoDiskQueue`` write their items to the path they get
+on instantiation, so that a queue can be resumed later, even by a different
+process.
+
+Each class uses that path differently:
+
+-   ``FifoDiskQueue`` uses a directory, which it creates, together with any
+    missing parent directory. Items go into chunk files (``q00000``,
+    ``q00001``, etc.), each holding up to ``chunksize`` items, and the queue
+    also keeps an ``info.json`` file there for its own bookkeeping.
+
+-   ``LifoDiskQueue`` uses a single file, whose parent directory must already
+    exist.
+
+The layout and the contents of those files are an implementation detail that
+may change in any release. Do not read or write them yourself, and do not
+expect a queue written by one version of Queuelib to be readable by a
+different one.
+
+Always close disk queues
+------------------------
+
+While a disk queue is open, its bookkeeping (number of items, read and write
+positions) only lives in memory, and ``close()`` is what writes it to disk.
+Queuelib never calls ``fsync()`` either, and ``LifoDiskQueue`` writes items
+through a buffered file object, so the most recent items may not have reached
+the disk at all.
+
+Calling ``close()`` is hence mandatory::
+
+    from contextlib import closing
+
+    with closing(FifoDiskQueue("queuedir")) as q:
+        q.push(b'a')
+
+If a process ends without calling ``close()``, the queue on disk keeps the
+bookkeeping that the last ``close()`` call wrote, which no longer matches the
+files. Items pushed since then become unreachable, and using the queue again
+is unsafe: it may report a wrong length, return items that had already been
+popped, delete files that still contain items, or raise ``OSError``. Queuelib
+offers no way to repair or to recover such a queue.
+
+Empty queues delete their files
+-------------------------------
+
+``close()`` on an empty queue deletes its file, or, in the case of
+``FifoDiskQueue``, its chunk files and its ``info.json`` file, and also its
+directory if nothing else remains in it. Using that same path again creates a
+new, empty queue.
+
+FifoDiskQueue frees disk space one chunk at a time
+--------------------------------------------------
+
+``FifoDiskQueue`` deletes a chunk file once every item in it has been popped.
+Until then, popped items keep using disk space, so a queue uses up to
+``chunksize`` items worth of disk space on top of the items that it holds.
+
+Lower ``chunksize`` to lower that overhead, at the cost of more chunk files and
+more file operations. For example, a queue that holds 400 items of 1 MB each
+uses about 100 GB of disk space with the default ``chunksize`` of 100000, and
+about 800 MB with a ``chunksize`` of 400.
+
+Reopening a FifoDiskQueue keeps its chunk size
+----------------------------------------------
+
+``FifoDiskQueue`` stores its ``chunksize`` when creating a queue, and reuses
+the stored value when reopening one, ignoring the ``chunksize`` parameter.
+
+Use one queue object per path at a time
+---------------------------------------
+
+Queuelib does not lock the files that it uses. On top of not being
+thread-safe, a given path must not be used by more than one open queue object
+at a time, in the same process or not. Such queue objects overwrite each
+other's items and bookkeeping; for example, two ``FifoDiskQueue`` objects on
+the same directory return the same items, and their ``close()`` calls may
+raise ``FileNotFoundError``.
+
+Persisting a PriorityQueue or a RoundRobinQueue
+-----------------------------------------------
+
+``PriorityQueue`` and ``RoundRobinQueue`` do not write anything to disk
+themselves; their persistence comes entirely from the queues that ``qfactory``
+builds, and it is up to ``qfactory`` to map a priority or a key to a valid
+path.
+
+Their ``close()`` method returns the priorities or keys whose underlying queue
+was not empty. Storing that value is your responsibility, and so is passing it
+back as ``startprios`` or ``start_domains`` on the next run::
+
+    >>> import json
+    >>> from queuelib import FifoDiskQueue, PriorityQueue
+    >>> qfactory = lambda priority: FifoDiskQueue('queue-dir-%s' % priority)
+    >>> pq = PriorityQueue(qfactory)
+    >>> pq.push(b'a', 3)
+    >>> active = pq.close()
+    >>> with open('active.json', 'w') as f:
+    ...     json.dump(active, f)
+    ...
+    >>> with open('active.json') as f:
+    ...     startprios = json.load(f)
+    ...
+    >>> pq = PriorityQueue(qfactory, startprios)
+    >>> pq.pop()
+    b'a'
 
-Use the `scrapy-users`_ mailing list for questions about Queuelib.
+Priorities and keys that you do not pass back are not detected, and the items
+in their queues stay on disk, unreachable.
 
 Bug tracker
 ===========
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/queuelib-1.9.0/README.rst 
new/queuelib-1.10.0/README.rst
--- old/queuelib-1.9.0/README.rst       2020-02-02 01:00:00.000000000 +0100
+++ new/queuelib-1.10.0/README.rst      2020-02-02 01:00:00.000000000 +0100
@@ -133,11 +133,130 @@
     >>> rr.pop()
     b'd'
 
+Clearing a queue
+================
 
-Mailing list
-============
+``clear()`` removes every item from a queue, freeing the disk space that they
+used, and leaves the queue open and usable::
 
-Use the `scrapy-users`_ mailing list for questions about Queuelib.
+    >>> q.clear()
+    >>> len(q)
+    0
+
+``PriorityQueue`` and ``RoundRobinQueue`` also close their internal queues, the
+same way that ``pop()`` does when one of them becomes empty.
+
+Disk persistence
+================
+
+``FifoDiskQueue`` and ``LifoDiskQueue`` write their items to the path they get
+on instantiation, so that a queue can be resumed later, even by a different
+process.
+
+Each class uses that path differently:
+
+-   ``FifoDiskQueue`` uses a directory, which it creates, together with any
+    missing parent directory. Items go into chunk files (``q00000``,
+    ``q00001``, etc.), each holding up to ``chunksize`` items, and the queue
+    also keeps an ``info.json`` file there for its own bookkeeping.
+
+-   ``LifoDiskQueue`` uses a single file, whose parent directory must already
+    exist.
+
+The layout and the contents of those files are an implementation detail that
+may change in any release. Do not read or write them yourself, and do not
+expect a queue written by one version of Queuelib to be readable by a
+different one.
+
+Always close disk queues
+------------------------
+
+While a disk queue is open, its bookkeeping (number of items, read and write
+positions) only lives in memory, and ``close()`` is what writes it to disk.
+Queuelib never calls ``fsync()`` either, and ``LifoDiskQueue`` writes items
+through a buffered file object, so the most recent items may not have reached
+the disk at all.
+
+Calling ``close()`` is hence mandatory::
+
+    from contextlib import closing
+
+    with closing(FifoDiskQueue("queuedir")) as q:
+        q.push(b'a')
+
+If a process ends without calling ``close()``, the queue on disk keeps the
+bookkeeping that the last ``close()`` call wrote, which no longer matches the
+files. Items pushed since then become unreachable, and using the queue again
+is unsafe: it may report a wrong length, return items that had already been
+popped, delete files that still contain items, or raise ``OSError``. Queuelib
+offers no way to repair or to recover such a queue.
+
+Empty queues delete their files
+-------------------------------
+
+``close()`` on an empty queue deletes its file, or, in the case of
+``FifoDiskQueue``, its chunk files and its ``info.json`` file, and also its
+directory if nothing else remains in it. Using that same path again creates a
+new, empty queue.
+
+FifoDiskQueue frees disk space one chunk at a time
+--------------------------------------------------
+
+``FifoDiskQueue`` deletes a chunk file once every item in it has been popped.
+Until then, popped items keep using disk space, so a queue uses up to
+``chunksize`` items worth of disk space on top of the items that it holds.
+
+Lower ``chunksize`` to lower that overhead, at the cost of more chunk files and
+more file operations. For example, a queue that holds 400 items of 1 MB each
+uses about 100 GB of disk space with the default ``chunksize`` of 100000, and
+about 800 MB with a ``chunksize`` of 400.
+
+Reopening a FifoDiskQueue keeps its chunk size
+----------------------------------------------
+
+``FifoDiskQueue`` stores its ``chunksize`` when creating a queue, and reuses
+the stored value when reopening one, ignoring the ``chunksize`` parameter.
+
+Use one queue object per path at a time
+---------------------------------------
+
+Queuelib does not lock the files that it uses. On top of not being
+thread-safe, a given path must not be used by more than one open queue object
+at a time, in the same process or not. Such queue objects overwrite each
+other's items and bookkeeping; for example, two ``FifoDiskQueue`` objects on
+the same directory return the same items, and their ``close()`` calls may
+raise ``FileNotFoundError``.
+
+Persisting a PriorityQueue or a RoundRobinQueue
+-----------------------------------------------
+
+``PriorityQueue`` and ``RoundRobinQueue`` do not write anything to disk
+themselves; their persistence comes entirely from the queues that ``qfactory``
+builds, and it is up to ``qfactory`` to map a priority or a key to a valid
+path.
+
+Their ``close()`` method returns the priorities or keys whose underlying queue
+was not empty. Storing that value is your responsibility, and so is passing it
+back as ``startprios`` or ``start_domains`` on the next run::
+
+    >>> import json
+    >>> from queuelib import FifoDiskQueue, PriorityQueue
+    >>> qfactory = lambda priority: FifoDiskQueue('queue-dir-%s' % priority)
+    >>> pq = PriorityQueue(qfactory)
+    >>> pq.push(b'a', 3)
+    >>> active = pq.close()
+    >>> with open('active.json', 'w') as f:
+    ...     json.dump(active, f)
+    ...
+    >>> with open('active.json') as f:
+    ...     startprios = json.load(f)
+    ...
+    >>> pq = PriorityQueue(qfactory, startprios)
+    >>> pq.pop()
+    b'a'
+
+Priorities and keys that you do not pass back are not detected, and the items
+in their queues stay on disk, unreachable.
 
 Bug tracker
 ===========
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/queuelib-1.9.0/pyproject.toml 
new/queuelib-1.10.0/pyproject.toml
--- old/queuelib-1.9.0/pyproject.toml   2020-02-02 01:00:00.000000000 +0100
+++ new/queuelib-1.10.0/pyproject.toml  2020-02-02 01:00:00.000000000 +0100
@@ -19,6 +19,7 @@
     "Programming Language :: Python :: 3.12",
     "Programming Language :: Python :: 3.13",
     "Programming Language :: Python :: 3.14",
+    "Programming Language :: Python :: 3.15",
     "Programming Language :: Python :: Implementation :: CPython",
     "Programming Language :: Python :: Implementation :: PyPy",
 ]
@@ -42,7 +43,7 @@
 ]
 
 [tool.bumpversion]
-current_version = "1.9.0"
+current_version = "1.10.0"
 commit = true
 tag = true
 tag_name = "v{new_version}"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/queuelib-1.9.0/queuelib/__init__.py 
new/queuelib-1.10.0/queuelib/__init__.py
--- old/queuelib-1.9.0/queuelib/__init__.py     2020-02-02 01:00:00.000000000 
+0100
+++ new/queuelib-1.10.0/queuelib/__init__.py    2020-02-02 01:00:00.000000000 
+0100
@@ -1,4 +1,4 @@
-__version__ = "1.9.0"
+__version__ = "1.10.0"
 
 from queuelib.pqueue import PriorityQueue
 from queuelib.queue import FifoDiskQueue, LifoDiskQueue
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/queuelib-1.9.0/queuelib/pqueue.py 
new/queuelib-1.10.0/queuelib/pqueue.py
--- old/queuelib-1.9.0/queuelib/pqueue.py       2020-02-02 01:00:00.000000000 
+0100
+++ new/queuelib-1.10.0/queuelib/pqueue.py      2020-02-02 01:00:00.000000000 
+0100
@@ -2,6 +2,8 @@
 
 from typing import TYPE_CHECKING, Any
 
+from queuelib.queue import _clear
+
 if TYPE_CHECKING:
     from collections.abc import Callable, Iterable
 
@@ -18,6 +20,9 @@
         * close()
         * __len__()
 
+    Internal queues may also implement clear(); those that do not are emptied
+    by popping.
+
     The constructor receives a qfactory argument, which is a callable used to
     instantiate a new (internal) queue when a new priority is allocated. The
     qfactory function is called with the priority number as first and only
@@ -66,6 +71,13 @@
             return None
         return self.queues[self.curprio].peek()
 
+    def clear(self) -> None:
+        for q in self.queues.values():
+            _clear(q)
+            q.close()
+        self.queues.clear()
+        self.curprio = None
+
     def close(self) -> list[int]:
         active = []
         for p, q in self.queues.items():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/queuelib-1.9.0/queuelib/queue.py 
new/queuelib-1.10.0/queuelib/queue.py
--- old/queuelib-1.9.0/queuelib/queue.py        2020-02-02 01:00:00.000000000 
+0100
+++ new/queuelib-1.10.0/queuelib/queue.py       2020-02-02 01:00:00.000000000 
+0100
@@ -11,6 +11,17 @@
 from typing import Any, BinaryIO, Literal, cast
 
 
+def _clear(queue: Any) -> None:
+    """Remove every item from *queue*, popping them one by one if it does not
+    implement ``clear()``."""
+    clear = getattr(queue, "clear", None)
+    if clear is not None:
+        clear()
+        return
+    while queue.pop() is not None:
+        pass
+
+
 class _BaseQueueMeta(type):
     """
     Metaclass to check queue classes against the necessary interface
@@ -72,6 +83,9 @@
     def peek(self) -> Any | None:
         return self.q[0] if self.q else None
 
+    def clear(self) -> None:
+        self.q.clear()
+
     def close(self) -> None:
         pass
 
@@ -159,6 +173,17 @@
         os.lseek(tfd, tfd_initial_pos, os.SEEK_SET)
         return data
 
+    def clear(self) -> None:
+        self.headf.close()
+        self.tailf.close()
+        for chunk in Path(self.path).glob("q*"):
+            chunk.unlink()
+        self.info["size"] = 0
+        self.info["tail"] = [0, 0, 0]
+        self.info["head"] = [0, 0]
+        self.headf = self._openchunk(0, "ab+")
+        self.tailf = self._openchunk(0)
+
     def close(self) -> None:
         self.headf.close()
         self.tailf.close()
@@ -243,6 +268,12 @@
         self.f.seek(-size - self.SIZE_SIZE, os.SEEK_END)
         return self.f.read(size)
 
+    def clear(self) -> None:
+        self.f.seek(0)
+        self.f.write(struct.pack(self.SIZE_FORMAT, 0))
+        self.f.truncate()
+        self.size = 0
+
     def close(self) -> None:
         if self.size:
             self.f.seek(0)
@@ -261,6 +292,7 @@
     _sql_push = "INSERT INTO queue (item) VALUES (?)"
     _sql_pop = "SELECT id, item FROM queue ORDER BY id LIMIT 1"
     _sql_del = "DELETE FROM queue WHERE id = ?"
+    _sql_clear = "DELETE FROM queue"
 
     def __init__(self, path: str | os.PathLike[str]) -> None:
         self._path = Path(path).resolve()
@@ -288,6 +320,10 @@
                 return cast("bytes", item)
         return None
 
+    def clear(self) -> None:
+        with self._db as conn:
+            conn.execute(self._sql_clear)
+
     def close(self) -> None:
         size = len(self)
         self._db.close()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/queuelib-1.9.0/queuelib/rrqueue.py 
new/queuelib-1.10.0/queuelib/rrqueue.py
--- old/queuelib-1.9.0/queuelib/rrqueue.py      2020-02-02 01:00:00.000000000 
+0100
+++ new/queuelib-1.10.0/queuelib/rrqueue.py     2020-02-02 01:00:00.000000000 
+0100
@@ -3,6 +3,8 @@
 from collections import deque
 from typing import TYPE_CHECKING, Any
 
+from queuelib.queue import _clear
+
 if TYPE_CHECKING:
     from collections.abc import Callable, Hashable, Iterable
 
@@ -17,6 +19,10 @@
         * peek()
         * close()
         * __len__()
+
+    Internal queues may also implement clear(); those that do not are emptied
+    by popping.
+
     The constructor receives a qfactory argument, which is a callable used to
     instantiate a new (internal) queue when a new key is allocated. The
     qfactory function is called with the key number as first and only argument.
@@ -53,6 +59,13 @@
             return None
         return self.queues[key].peek()
 
+    def clear(self) -> None:
+        for q in self.queues.values():
+            _clear(q)
+            q.close()
+        self.queues.clear()
+        self.key_queue.clear()
+
     def pop(self) -> Any | None:
         # pop until we find a valid object, closing necessary queues
         while True:
@@ -70,7 +83,7 @@
             else:
                 self.key_queue.appendleft(key)
 
-            if m:
+            if m is not None:
                 return m
 
     def close(self) -> list[Hashable]:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/queuelib-1.9.0/queuelib/tests/__init__.py 
new/queuelib-1.10.0/queuelib/tests/__init__.py
--- old/queuelib-1.9.0/queuelib/tests/__init__.py       2020-02-02 
01:00:00.000000000 +0100
+++ new/queuelib-1.10.0/queuelib/tests/__init__.py      2020-02-02 
01:00:00.000000000 +0100
@@ -1,7 +1,32 @@
+from __future__ import annotations
+
 import shutil
 import tempfile
 import unittest
 from pathlib import Path
+from typing import Any
+
+
+class DummyQueue:
+    """Minimal queue implementation, without the optional clear() method."""
+
+    def __init__(self) -> None:
+        self.q: list[Any] = []
+
+    def push(self, obj: Any) -> None:
+        self.q.append(obj)
+
+    def pop(self) -> Any | None:
+        return self.q.pop() if self.q else None
+
+    def peek(self) -> Any | None:
+        return self.q[-1] if self.q else None
+
+    def close(self) -> None:
+        pass
+
+    def __len__(self) -> int:
+        return len(self.q)
 
 
 class QueuelibTestCase(unittest.TestCase):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/queuelib-1.9.0/queuelib/tests/test_pqueue.py 
new/queuelib-1.10.0/queuelib/tests/test_pqueue.py
--- old/queuelib-1.9.0/queuelib/tests/test_pqueue.py    2020-02-02 
01:00:00.000000000 +0100
+++ new/queuelib-1.10.0/queuelib/tests/test_pqueue.py   2020-02-02 
01:00:00.000000000 +0100
@@ -11,7 +11,7 @@
     LifoMemoryQueue,
     LifoSQLiteQueue,
 )
-from queuelib.tests import QueuelibTestCase, track_closed
+from queuelib.tests import DummyQueue, QueuelibTestCase, track_closed
 
 
 class PQueueTestMixin:
@@ -54,6 +54,21 @@
         self.q.pop()
         assert sorted(self.q.close()) == [2, 3]
 
+    def test_clear(self):
+        self.q.clear()
+        assert len(self.q) == 0
+        self.q.push(b"a", 3)
+        self.q.push(b"b", 1)
+        iqueues = list(self.q.queues.values())
+        self.q.clear()
+        assert len(self.q) == 0
+        assert self.q.peek() is None
+        assert self.q.pop() is None
+        assert all(q.closed for q in iqueues)
+        self.q.push(b"c", 2)
+        assert self.q.pop() == b"c"
+        assert not self.q.close()
+
     def test_popped_internal_queues_closed(self):
         self.q.push(b"a", 3)
         self.q.push(b"b", 1)
@@ -210,3 +225,14 @@
     def qfactory(self, prio):
         path = Path(self.qdir, str(prio))
         return track_closed(LifoSQLiteQueue)(path)
+
+
+class DummyPriorityQueueTest(QueuelibTestCase):
+    def test_clear(self):
+        q = PriorityQueue(lambda prio: DummyQueue())
+        q.push(b"a", 1)
+        q.push(b"b", 2)
+        q.clear()
+        assert len(q) == 0
+        assert q.pop() is None
+        assert not q.close()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/queuelib-1.9.0/queuelib/tests/test_queue.py 
new/queuelib-1.10.0/queuelib/tests/test_queue.py
--- old/queuelib-1.9.0/queuelib/tests/test_queue.py     2020-02-02 
01:00:00.000000000 +0100
+++ new/queuelib-1.10.0/queuelib/tests/test_queue.py    2020-02-02 
01:00:00.000000000 +0100
@@ -1,7 +1,6 @@
 from __future__ import annotations
 
 from abc import abstractmethod
-from typing import Any
 from unittest import mock
 
 import pytest
@@ -15,27 +14,7 @@
     LifoMemoryQueue,
     LifoSQLiteQueue,
 )
-from queuelib.tests import QueuelibTestCase
-
-
-class DummyQueue:
-    def __init__(self) -> None:
-        self.q: list[Any] = []
-
-    def push(self, obj: Any) -> None:
-        self.q.append(obj)
-
-    def pop(self) -> Any | None:
-        return self.q.pop() if self.q else None
-
-    def peek(self) -> Any | None:
-        return self.q[-1] if self.q else None
-
-    def close(self) -> None:
-        pass
-
-    def __len__(self):
-        return len(self.q)
+from queuelib.tests import DummyQueue, QueuelibTestCase
 
 
 class InterfaceTest(QueuelibTestCase):
@@ -119,6 +98,20 @@
         assert len(q) == 0
         q.close()
 
+    def test_clear(self):
+        q = self.queue()
+        q.clear()
+        assert len(q) == 0
+        q.push(b"a")
+        q.push(b"b")
+        q.clear()
+        assert len(q) == 0
+        assert q.peek() is None
+        assert q.pop() is None
+        q.push(b"c")
+        assert q.pop() == b"c"
+        q.close()
+
     def test_peek_one_element(self):
         q = self.queue()
         assert q.peek() is None
@@ -226,20 +219,24 @@
 class PersistentTestMixin:
     chunksize = 100000
 
+    # Scrapy SerializableQueue doesn't raise TypeError for non-bytes objects,
+    # so this test fails when run for it.
     @pytest.mark.xfail(
         reason="Reenable once Scrapy.squeues stops extending from this 
testsuite"
     )
     def test_non_bytes_raises_typeerror(self):
         q = self.queue()
-        with pytest.raises(TypeError):
-            q.push(0)
-        with pytest.raises(TypeError):
-            q.push("")
-        with pytest.raises(TypeError):
-            q.push(None)
-        with pytest.raises(TypeError):
-            q.push(lambda x: x)
-        q.close()
+        try:
+            with pytest.raises(TypeError):
+                q.push(0)
+            with pytest.raises(TypeError):
+                q.push("")
+            with pytest.raises(TypeError):
+                q.push(None)
+            with pytest.raises(TypeError):
+                q.push(lambda x: x)
+        finally:
+            q.close()
 
     def test_text_in_windows(self):
         e1 = b"\r\n"
@@ -333,6 +330,14 @@
         assert len(chunks) == 1
         q.close()
 
+    def test_clear_removes_chunks(self):
+        q = self.queue()
+        for x in [b"0", b"1", b"2", b"3", b"4"]:
+            q.push(x)
+        q.clear()
+        assert list(self.qpath.glob("q*")) == [self.qpath / "q00000"]
+        q.close()
+
 
 class ChunkSize1FifoDiskQueueTest(FifoDiskQueueTest):
     chunksize = 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/queuelib-1.9.0/queuelib/tests/test_rrqueue.py 
new/queuelib-1.10.0/queuelib/tests/test_rrqueue.py
--- old/queuelib-1.9.0/queuelib/tests/test_rrqueue.py   2020-02-02 
01:00:00.000000000 +0100
+++ new/queuelib-1.10.0/queuelib/tests/test_rrqueue.py  2020-02-02 
01:00:00.000000000 +0100
@@ -11,7 +11,7 @@
     LifoSQLiteQueue,
 )
 from queuelib.rrqueue import RoundRobinQueue
-from queuelib.tests import QueuelibTestCase, track_closed
+from queuelib.tests import DummyQueue, QueuelibTestCase, track_closed
 
 
 class RRQueueTestMixin:
@@ -47,6 +47,21 @@
         assert sorted(self.q.close()) == ["1", "2", "3"]
         assert all(q.closed for q in iqueues)
 
+    def test_clear(self):
+        self.q.clear()
+        assert len(self.q) == 0
+        self.q.push(b"a", "3")
+        self.q.push(b"b", "1")
+        iqueues = list(self.q.queues.values())
+        self.q.clear()
+        assert len(self.q) == 0
+        assert self.q.peek() is None
+        assert self.q.pop() is None
+        assert all(q.closed for q in iqueues)
+        self.q.push(b"c", "2")
+        assert self.q.pop() == b"c"
+        assert not self.q.close()
+
     def test_close_return_active(self):
         self.q.push(b"b", "1")
         self.q.push(b"c", "2")
@@ -54,6 +69,19 @@
         self.q.pop()
         assert sorted(self.q.close()) == ["2", "3"]
 
+    def test_pop_returns_falsy_items(self):
+        self.q.push(b"", "a")
+        assert len(self.q) == 1
+        assert self.q.pop() == b""
+        assert len(self.q) == 0
+        assert self.q.pop() is None
+
+    def test_falsy_items_keep_round_robin_order(self):
+        self.q.push(b"one", "a")
+        self.q.push(b"", "b")
+        self.q.push(b"two", "c")
+        assert [self.q.pop(), self.q.pop(), self.q.pop()] == [b"one", b"", 
b"two"]
+
 
 class FifoTestMixin:
     def test_push_pop_peek_key(self):
@@ -224,3 +252,14 @@
     def qfactory(self, key):
         path = Path(self.qdir, str(key))
         return track_closed(LifoSQLiteQueue)(path)
+
+
+class DummyRRQueueTest(QueuelibTestCase):
+    def test_clear(self):
+        q = RoundRobinQueue(lambda key: DummyQueue())
+        q.push(b"a", "1")
+        q.push(b"b", "2")
+        q.clear()
+        assert len(q) == 0
+        assert q.pop() is None
+        assert not q.close()

Reply via email to