cs.queues


Namecs.queues JSON
Version 20240412 PyPI version JSON
download
home_pageNone
Summarysome Queue subclasses and ducktypes
upload_time2024-04-12 04:48:26
maintainerNone
docs_urlNone
authorNone
requires_pythonNone
licenseGNU General Public License v3 or later (GPLv3+)
keywords python2 python3
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            Queue-like items: iterable queues, channels, etc.

*Latest release 20240412*:
* QueueIterator: new next_batch and iter_batch methods for collecting items in batches.
* QueueIterator: bugfix put(), do not hold the lock around the internal Queue.put, can deadlock the corresponding next/get.

## Class `Channel`

A zero-storage data passage.
Unlike a `Queue`, `put(item)` blocks waiting for the matching `get()`.

*Method `Channel.__init__(self)`*:
pylint: disable=consider-using-with

*Method `Channel.__call__(self, *a)`*:
Call the `Channel`.
With no arguments, do a `.get()`.
With an argument, do a `.put()`.

*Method `Channel.__iter__(self)`*:
A `Channel` is iterable.

*Method `Channel.__next__(self)`*:
`next(Channel)` calls `Channel.get()`.

*Method `Channel.__str__(self)`*:
pylint: disable=consider-using-with

*Method `Channel.close(self)`*:
Close the `Channel`, preventing further `put()`s.

*Method `Channel.get(self, *a, **kw)`*:
Wrapper function to check that this instance is not closed.

*Method `Channel.put(self, *a, **kw)`*:
Wrapper function to check that this instance is not closed.

## Function `get_batch(q, max_batch=128, *, poll_delay=0.01)`

Get up to `max_batch` closely spaced items from the queue `q`.
Return the batch. Raise `Queue_Empty` if the first `q.get()` raises.

Block until the first item arrives. While the batch's size is
less that `max_batch` and there is another item available
within `poll_delay` seconds, append that item to the batch.

This requires `get_batch()` to be the sole consumer of `q`
for correct operation as it polls `q.empty()`.

## Function `IterablePriorityQueue(capacity=0, name=None)`

Factory to create an iterable `PriorityQueue`.

## Function `IterableQueue(capacity=0, name=None)`

Factory to create an iterable queue.
Note that the returned queue is already open
and needs a close.

## Class `ListQueue`

A simple iterable queue based on a `list`.

*Method `ListQueue.__init__(self, queued=None, *, unique=None)`*:
Initialise the queue.

Parameters:
* `queued` is an optional iterable of initial items for the queue
* `unique`: optional signature function, default `None`

The `unique` parameter provides iteration via the
`cs.seq.unrepeated` iterator filter which yields only items
not seen earlier in the iteration.
If `unique` is `None` or `False` iteration iterates
over the queue items directly.
If `unique` is `True`, iteration uses the default mode
where items are compared for equality.
Otherwise `unique` may be a callable which produces a
value to use to detect repetitions, used as the `cs.seq.unrepeated`
`signature` parameter.

Example:

    >>> items = [1, 2, 3, 1, 2, 5]
    >>> list(ListQueue(items))
    [1, 2, 3, 1, 2, 5]
    >>> list(ListQueue(items, unique=True))
    [1, 2, 3, 5]

*Method `ListQueue.__bool__(self)`*:
A `ListQueue` looks a bit like a container,
and is false when empty.

*Method `ListQueue.__iter__(self)`*:
A `ListQueue` is iterable.

*Method `ListQueue.__next__(self)`*:
Iteration gets from the queue.

*Method `ListQueue.append(self, item)`*:
Append an item to the queue, aka `put`.

*Method `ListQueue.extend(self, items)`*:
Convenient/performant queue-lots-of-items.

*Method `ListQueue.get(self)`*:
Get pops from the start of the list.

*Method `ListQueue.insert(self, index, item)`*:
Insert `item` at `index` in the queue.

*Method `ListQueue.prepend(self, items, offset=0)`*:
Insert `items` at `offset` (default `0`, the front of the queue).

*Method `ListQueue.put(self, item)`*:
Put appends to the queue.

## `NullQ = <NullQueue:NullQ blocking=False>`

A queue-like object that discards its inputs.
Calls to `.get()` raise `Queue_Empty`.

## Class `NullQueue(cs.resources.MultiOpenMixin)`

A queue-like object that discards its inputs.
Calls to `.get()` raise `Queue_Empty`.

*Method `NullQueue.__init__(self, blocking=False, name=None)`*:
Initialise the `NullQueue`.

Parameters:
* `blocking`: optional; if true, calls to `.get()` block until
  `.shutdown()`; default: `False`.
* `name`: optional name for this `NullQueue`.

*Method `NullQueue.get(self)`*:
Get the next value. Always raises `Queue_Empty`.
If `.blocking,` delay until `.shutdown()`.

*Method `NullQueue.put(self, item)`*:
Put a value onto the queue; it is discarded.

*Method `NullQueue.shutdown(self)`*:
Shut down the queue.

*Method `NullQueue.startup(self)`*:
Start the queue.

## Class `PushQueue(cs.resources.MultiOpenMixin)`

A puttable object which looks like an iterable `Queue`.

In this base class,
calling `.put(item)` calls `functor` supplied at initialisation
to trigger a function on data arrival
whose iterable of results are put onto the output queue.

As an example, the `cs.pipeline.Pipeline` class
uses subclasses of `PushQueue` for each pipeline stage,
overriding the `.put(item)` method
to mediate the call of `functor` through `cs.later.Later`
as resource controlled concurrency.

*Method `PushQueue.__init__(self, name, functor, outQ)`*:
Initialise the PushQueue with the callable `functor`
and the output queue `outQ`.

Parameters:
* `functor` is a one-to-many function which accepts a single
  item of input and returns an iterable of outputs; it may be a
  generator. These outputs are passed to `outQ.put` individually as
  received.
* `outQ` is a `MultiOpenMixin` which accepts via its `.put()` method.

*Method `PushQueue.put(self, *a, **kw)`*:
Wrapper function to check that this instance is not closed.

*Method `PushQueue.startup_shutdown(self)`*:
Open/close the output queue.

## Class `QueueIterator(cs.resources.MultiOpenMixin)`

A `QueueIterator` is a wrapper for a `Queue` (or ducktype) which
presents an iterator interface to collect items.
It does not offer the `.get` or `.get_nowait` methods.

*Method `QueueIterator.__iter__(self)`*:
Iterable interface for the queue.

*Method `QueueIterator.__next__(self)`*:
Return the next item from the queue.
If the queue is closed, raise `StopIteration`.

*Method `QueueIterator.empty(self)`*:
Test if the queue is empty.

*Method `QueueIterator.iter_batch(self, batch_size=1024)`*:
A generator which yields batches of items from the queue.

*Method `QueueIterator.join(self)`*:
Wait for the queue items to complete.

*Method `QueueIterator.next(self)`*:
Return the next item from the queue.
If the queue is closed, raise `StopIteration`.

*Method `QueueIterator.next_batch(self, batch_size=1024, block_once=False)`*:
Obtain a batch of immediately available items from the queue.
Up to `batch_size` items will be obtained, default 1024.
Return a list of the items.
If the queue is empty an empty list is returned.
If the queue is not empty, continue collecting items until
the queue is empty or the batch size is reached.
If `block_once` is true, wait for the first item;
this mode never returns an empty list except at the end of the iterator.

*Method `QueueIterator.put(self, *a, **kw)`*:
Wrapper function to check that this instance is not closed.

*Method `QueueIterator.startup_shutdown(self)`*:
`MultiOpenMixin` support; puts the sentinel onto the underlying queue
on the final close.

*Method `QueueIterator.task_done(self)`*:
Report that an item has been processed.

## Class `TimerQueue`

Class to run a lot of "in the future" jobs without using a bazillion
Timer threads.

*Method `TimerQueue.add(self, when, func)`*:
Queue a new job to be called at 'when'.
'func' is the job function, typically made with `functools.partial`.

*Method `TimerQueue.close(self, cancel=False)`*:
Close the `TimerQueue`. This forbids further job submissions.
If `cancel` is supplied and true, cancel all pending jobs.
Note: it is still necessary to call `TimerQueue.join()` to
wait for all pending jobs.

*Method `TimerQueue.join(self)`*:
Wait for the main loop thread to finish.

# Release Log



*Release 20240412*:
* QueueIterator: new next_batch and iter_batch methods for collecting items in batches.
* QueueIterator: bugfix put(), do not hold the lock around the internal Queue.put, can deadlock the corresponding next/get.

*Release 20240318*:
QueueIterator.put: be more rigorous with the put + item count increment.

*Release 20240316*:
Fixed release upload artifacts.

*Release 20240305*:
New get_batch(q) to fetch closely spaced batches from a Queue.

*Release 20240211*:
ListQueue: new unique parameter which uses cs.seq.unrepeated in iteration.

*Release 20231129*:
* ListQueue: add __len__, __str__, __repr__.
* QueueIterator: use a mutex around the item counting.

*Release 20230331*:
* QueueIterator.startup_shutdown: try/finally for the terminating _put(self.sentinel).
* QueueIterator.__str__: show the underlying queue.
* QueueIterator: drop call to self.finalise(), no longer available or needed.

*Release 20221228*:
Minor doc update.

*Release 20221207*:
PushQueue: modernise the MutiOpenMixin startup_shutdown, do both open and close of self.outQ.

*Release 20220918*:
Expose formerly private _QueueIterator as QueueIterator, use a per-queue sentinel from cs.obj.Sentinel.

*Release 20220805*:
ListQueue: add "append" synonym for "put" in keeping with the list-ish flavour.

*Release 20220605*:
ListQueue: extend/prepend: reject str explicitly - although iterable, it is almost never what is intended.

*Release 20220317*:
Add missed import.

*Release 20220313*:
New ListQueue.prepend(items[,offset=0]) method.

*Release 20211116*:
ListQueue: new insert() method.

*Release 20210924*:
Channel: make a Channel iterable.

*Release 20210913*:
New ListQueue simple iterable queue based on a list with list-like .append and .extend.

*Release 20201025*:
Drop obsolete call to MultiOpenMixin.__init__.

*Release 20200718*:
_QueueIterator: set finalise_later via new MultiOpenMixin property, required by recent MultiOpenMixin change.

*Release 20200521*:
IterableQueue,IterablePriorityQueue: simplify wrappers, bypasses weird bug from overengineering these.

*Release 20191007*:
* PushQueue: improve __str__.
* Clean lint, drop cs.obj dependency.

*Release 20190812*:
_QueueIterator: do MultiOpenMixin.__init__ so that __str__ is functional.

*Release 20181022*:
Bugfix Channel, drasticly simplify PushQueue, other minor changes.

*Release 20160828*:
* Use "install_requires" instead of "requires" in DISTINFO.
* TimerQueue.add: support optional *a and **kw arguments for func.
* Many bugfixes and internal changes.

*Release 20150115*:
More PyPI metadata fixups.

*Release 20150111*:
Initial PyPI release.


            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "cs.queues",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "python2, python3",
    "author": null,
    "author_email": "Cameron Simpson <cs@cskk.id.au>",
    "download_url": "https://files.pythonhosted.org/packages/7e/2e/940d3c637080c84d7c6ee940e8d4044e305202554cd3c554d0d22a2e8fcc/cs.queues-20240412.tar.gz",
    "platform": null,
    "description": "Queue-like items: iterable queues, channels, etc.\n\n*Latest release 20240412*:\n* QueueIterator: new next_batch and iter_batch methods for collecting items in batches.\n* QueueIterator: bugfix put(), do not hold the lock around the internal Queue.put, can deadlock the corresponding next/get.\n\n## Class `Channel`\n\nA zero-storage data passage.\nUnlike a `Queue`, `put(item)` blocks waiting for the matching `get()`.\n\n*Method `Channel.__init__(self)`*:\npylint: disable=consider-using-with\n\n*Method `Channel.__call__(self, *a)`*:\nCall the `Channel`.\nWith no arguments, do a `.get()`.\nWith an argument, do a `.put()`.\n\n*Method `Channel.__iter__(self)`*:\nA `Channel` is iterable.\n\n*Method `Channel.__next__(self)`*:\n`next(Channel)` calls `Channel.get()`.\n\n*Method `Channel.__str__(self)`*:\npylint: disable=consider-using-with\n\n*Method `Channel.close(self)`*:\nClose the `Channel`, preventing further `put()`s.\n\n*Method `Channel.get(self, *a, **kw)`*:\nWrapper function to check that this instance is not closed.\n\n*Method `Channel.put(self, *a, **kw)`*:\nWrapper function to check that this instance is not closed.\n\n## Function `get_batch(q, max_batch=128, *, poll_delay=0.01)`\n\nGet up to `max_batch` closely spaced items from the queue `q`.\nReturn the batch. Raise `Queue_Empty` if the first `q.get()` raises.\n\nBlock until the first item arrives. While the batch's size is\nless that `max_batch` and there is another item available\nwithin `poll_delay` seconds, append that item to the batch.\n\nThis requires `get_batch()` to be the sole consumer of `q`\nfor correct operation as it polls `q.empty()`.\n\n## Function `IterablePriorityQueue(capacity=0, name=None)`\n\nFactory to create an iterable `PriorityQueue`.\n\n## Function `IterableQueue(capacity=0, name=None)`\n\nFactory to create an iterable queue.\nNote that the returned queue is already open\nand needs a close.\n\n## Class `ListQueue`\n\nA simple iterable queue based on a `list`.\n\n*Method `ListQueue.__init__(self, queued=None, *, unique=None)`*:\nInitialise the queue.\n\nParameters:\n* `queued` is an optional iterable of initial items for the queue\n* `unique`: optional signature function, default `None`\n\nThe `unique` parameter provides iteration via the\n`cs.seq.unrepeated` iterator filter which yields only items\nnot seen earlier in the iteration.\nIf `unique` is `None` or `False` iteration iterates\nover the queue items directly.\nIf `unique` is `True`, iteration uses the default mode\nwhere items are compared for equality.\nOtherwise `unique` may be a callable which produces a\nvalue to use to detect repetitions, used as the `cs.seq.unrepeated`\n`signature` parameter.\n\nExample:\n\n    >>> items = [1, 2, 3, 1, 2, 5]\n    >>> list(ListQueue(items))\n    [1, 2, 3, 1, 2, 5]\n    >>> list(ListQueue(items, unique=True))\n    [1, 2, 3, 5]\n\n*Method `ListQueue.__bool__(self)`*:\nA `ListQueue` looks a bit like a container,\nand is false when empty.\n\n*Method `ListQueue.__iter__(self)`*:\nA `ListQueue` is iterable.\n\n*Method `ListQueue.__next__(self)`*:\nIteration gets from the queue.\n\n*Method `ListQueue.append(self, item)`*:\nAppend an item to the queue, aka `put`.\n\n*Method `ListQueue.extend(self, items)`*:\nConvenient/performant queue-lots-of-items.\n\n*Method `ListQueue.get(self)`*:\nGet pops from the start of the list.\n\n*Method `ListQueue.insert(self, index, item)`*:\nInsert `item` at `index` in the queue.\n\n*Method `ListQueue.prepend(self, items, offset=0)`*:\nInsert `items` at `offset` (default `0`, the front of the queue).\n\n*Method `ListQueue.put(self, item)`*:\nPut appends to the queue.\n\n## `NullQ = <NullQueue:NullQ blocking=False>`\n\nA queue-like object that discards its inputs.\nCalls to `.get()` raise `Queue_Empty`.\n\n## Class `NullQueue(cs.resources.MultiOpenMixin)`\n\nA queue-like object that discards its inputs.\nCalls to `.get()` raise `Queue_Empty`.\n\n*Method `NullQueue.__init__(self, blocking=False, name=None)`*:\nInitialise the `NullQueue`.\n\nParameters:\n* `blocking`: optional; if true, calls to `.get()` block until\n  `.shutdown()`; default: `False`.\n* `name`: optional name for this `NullQueue`.\n\n*Method `NullQueue.get(self)`*:\nGet the next value. Always raises `Queue_Empty`.\nIf `.blocking,` delay until `.shutdown()`.\n\n*Method `NullQueue.put(self, item)`*:\nPut a value onto the queue; it is discarded.\n\n*Method `NullQueue.shutdown(self)`*:\nShut down the queue.\n\n*Method `NullQueue.startup(self)`*:\nStart the queue.\n\n## Class `PushQueue(cs.resources.MultiOpenMixin)`\n\nA puttable object which looks like an iterable `Queue`.\n\nIn this base class,\ncalling `.put(item)` calls `functor` supplied at initialisation\nto trigger a function on data arrival\nwhose iterable of results are put onto the output queue.\n\nAs an example, the `cs.pipeline.Pipeline` class\nuses subclasses of `PushQueue` for each pipeline stage,\noverriding the `.put(item)` method\nto mediate the call of `functor` through `cs.later.Later`\nas resource controlled concurrency.\n\n*Method `PushQueue.__init__(self, name, functor, outQ)`*:\nInitialise the PushQueue with the callable `functor`\nand the output queue `outQ`.\n\nParameters:\n* `functor` is a one-to-many function which accepts a single\n  item of input and returns an iterable of outputs; it may be a\n  generator. These outputs are passed to `outQ.put` individually as\n  received.\n* `outQ` is a `MultiOpenMixin` which accepts via its `.put()` method.\n\n*Method `PushQueue.put(self, *a, **kw)`*:\nWrapper function to check that this instance is not closed.\n\n*Method `PushQueue.startup_shutdown(self)`*:\nOpen/close the output queue.\n\n## Class `QueueIterator(cs.resources.MultiOpenMixin)`\n\nA `QueueIterator` is a wrapper for a `Queue` (or ducktype) which\npresents an iterator interface to collect items.\nIt does not offer the `.get` or `.get_nowait` methods.\n\n*Method `QueueIterator.__iter__(self)`*:\nIterable interface for the queue.\n\n*Method `QueueIterator.__next__(self)`*:\nReturn the next item from the queue.\nIf the queue is closed, raise `StopIteration`.\n\n*Method `QueueIterator.empty(self)`*:\nTest if the queue is empty.\n\n*Method `QueueIterator.iter_batch(self, batch_size=1024)`*:\nA generator which yields batches of items from the queue.\n\n*Method `QueueIterator.join(self)`*:\nWait for the queue items to complete.\n\n*Method `QueueIterator.next(self)`*:\nReturn the next item from the queue.\nIf the queue is closed, raise `StopIteration`.\n\n*Method `QueueIterator.next_batch(self, batch_size=1024, block_once=False)`*:\nObtain a batch of immediately available items from the queue.\nUp to `batch_size` items will be obtained, default 1024.\nReturn a list of the items.\nIf the queue is empty an empty list is returned.\nIf the queue is not empty, continue collecting items until\nthe queue is empty or the batch size is reached.\nIf `block_once` is true, wait for the first item;\nthis mode never returns an empty list except at the end of the iterator.\n\n*Method `QueueIterator.put(self, *a, **kw)`*:\nWrapper function to check that this instance is not closed.\n\n*Method `QueueIterator.startup_shutdown(self)`*:\n`MultiOpenMixin` support; puts the sentinel onto the underlying queue\non the final close.\n\n*Method `QueueIterator.task_done(self)`*:\nReport that an item has been processed.\n\n## Class `TimerQueue`\n\nClass to run a lot of \"in the future\" jobs without using a bazillion\nTimer threads.\n\n*Method `TimerQueue.add(self, when, func)`*:\nQueue a new job to be called at 'when'.\n'func' is the job function, typically made with `functools.partial`.\n\n*Method `TimerQueue.close(self, cancel=False)`*:\nClose the `TimerQueue`. This forbids further job submissions.\nIf `cancel` is supplied and true, cancel all pending jobs.\nNote: it is still necessary to call `TimerQueue.join()` to\nwait for all pending jobs.\n\n*Method `TimerQueue.join(self)`*:\nWait for the main loop thread to finish.\n\n# Release Log\n\n\n\n*Release 20240412*:\n* QueueIterator: new next_batch and iter_batch methods for collecting items in batches.\n* QueueIterator: bugfix put(), do not hold the lock around the internal Queue.put, can deadlock the corresponding next/get.\n\n*Release 20240318*:\nQueueIterator.put: be more rigorous with the put + item count increment.\n\n*Release 20240316*:\nFixed release upload artifacts.\n\n*Release 20240305*:\nNew get_batch(q) to fetch closely spaced batches from a Queue.\n\n*Release 20240211*:\nListQueue: new unique parameter which uses cs.seq.unrepeated in iteration.\n\n*Release 20231129*:\n* ListQueue: add __len__, __str__, __repr__.\n* QueueIterator: use a mutex around the item counting.\n\n*Release 20230331*:\n* QueueIterator.startup_shutdown: try/finally for the terminating _put(self.sentinel).\n* QueueIterator.__str__: show the underlying queue.\n* QueueIterator: drop call to self.finalise(), no longer available or needed.\n\n*Release 20221228*:\nMinor doc update.\n\n*Release 20221207*:\nPushQueue: modernise the MutiOpenMixin startup_shutdown, do both open and close of self.outQ.\n\n*Release 20220918*:\nExpose formerly private _QueueIterator as QueueIterator, use a per-queue sentinel from cs.obj.Sentinel.\n\n*Release 20220805*:\nListQueue: add \"append\" synonym for \"put\" in keeping with the list-ish flavour.\n\n*Release 20220605*:\nListQueue: extend/prepend: reject str explicitly - although iterable, it is almost never what is intended.\n\n*Release 20220317*:\nAdd missed import.\n\n*Release 20220313*:\nNew ListQueue.prepend(items[,offset=0]) method.\n\n*Release 20211116*:\nListQueue: new insert() method.\n\n*Release 20210924*:\nChannel: make a Channel iterable.\n\n*Release 20210913*:\nNew ListQueue simple iterable queue based on a list with list-like .append and .extend.\n\n*Release 20201025*:\nDrop obsolete call to MultiOpenMixin.__init__.\n\n*Release 20200718*:\n_QueueIterator: set finalise_later via new MultiOpenMixin property, required by recent MultiOpenMixin change.\n\n*Release 20200521*:\nIterableQueue,IterablePriorityQueue: simplify wrappers, bypasses weird bug from overengineering these.\n\n*Release 20191007*:\n* PushQueue: improve __str__.\n* Clean lint, drop cs.obj dependency.\n\n*Release 20190812*:\n_QueueIterator: do MultiOpenMixin.__init__ so that __str__ is functional.\n\n*Release 20181022*:\nBugfix Channel, drasticly simplify PushQueue, other minor changes.\n\n*Release 20160828*:\n* Use \"install_requires\" instead of \"requires\" in DISTINFO.\n* TimerQueue.add: support optional *a and **kw arguments for func.\n* Many bugfixes and internal changes.\n\n*Release 20150115*:\nMore PyPI metadata fixups.\n\n*Release 20150111*:\nInitial PyPI release.\n\n",
    "bugtrack_url": null,
    "license": "GNU General Public License v3 or later (GPLv3+)",
    "summary": "some Queue subclasses and ducktypes",
    "version": "20240412",
    "project_urls": {
        "URL": "https://bitbucket.org/cameron_simpson/css/commits/all"
    },
    "split_keywords": [
        "python2",
        " python3"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "97eedb362d224185739cb2792d0ff07bf3467db36cdc7afaf4cf3bebc8e4d5f7",
                "md5": "6e4e1c3dd913906f18db5f722a4c443c",
                "sha256": "e95a3f5ef9760626b1b77d4f84c4fd146ffbf600ac123dd543db162a5e643b5f"
            },
            "downloads": -1,
            "filename": "cs.queues-20240412-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "6e4e1c3dd913906f18db5f722a4c443c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 11405,
            "upload_time": "2024-04-12T04:48:23",
            "upload_time_iso_8601": "2024-04-12T04:48:23.986495Z",
            "url": "https://files.pythonhosted.org/packages/97/ee/db362d224185739cb2792d0ff07bf3467db36cdc7afaf4cf3bebc8e4d5f7/cs.queues-20240412-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "7e2e940d3c637080c84d7c6ee940e8d4044e305202554cd3c554d0d22a2e8fcc",
                "md5": "7d6a6277ef6b2097e45dba694e335dfe",
                "sha256": "25259d4f6413fab6fd875c1eedc078e2971030a491138c4417c111e3d0e434e6"
            },
            "downloads": -1,
            "filename": "cs.queues-20240412.tar.gz",
            "has_sig": false,
            "md5_digest": "7d6a6277ef6b2097e45dba694e335dfe",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 12380,
            "upload_time": "2024-04-12T04:48:26",
            "upload_time_iso_8601": "2024-04-12T04:48:26.044107Z",
            "url": "https://files.pythonhosted.org/packages/7e/2e/940d3c637080c84d7c6ee940e8d4044e305202554cd3c554d0d22a2e8fcc/cs.queues-20240412.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-04-12 04:48:26",
    "github": false,
    "gitlab": false,
    "bitbucket": true,
    "codeberg": false,
    "bitbucket_user": "cameron_simpson",
    "bitbucket_project": "css",
    "lcname": "cs.queues"
}
        
Elapsed time: 0.23377s