NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #730 most downloaded on PyPI
When they're not builtins, they're boltons.
Last release 27 days ago
07 Sep 2026
Release timing varies
gaps range from 4 weeks to 1.8 years
Most releases are documented
notes for 49 of 58 stable releases
Nothing withdrawn
no release was ever pulled
14 years old
59 releases · first in 2013
Added statsutils.mode to return the most common value, breaking ties by first appearance
statsutils.mode to return the most common value, breaking ties by first appearance (#453)setutils.IndexedSet.update adding the iterables themselves instead of their elements when given multiple inputs (#474)strutils.iter_splitlines and strutils.indent splitting dates containing 28 or 29 instead of recognizing Unicode line separators (#475)strutils.ellipsize for word-boundary-aware text truncation with an ellipsisfuncutils.wraps passing arguments positionally to wrappers that only accept them as keywords (#261)tableutils.Table.to_text crashes on empty tables, None headers, and short header rows; empty headers now render no header row, matching to_htmltimeutils.isoparse misreading fractional seconds (.851 parsed as 851µs instead of 851000µs); >6-digit fractions now truncate instead of raisingtimeutils.daterange looping forever on non-advancing steps: zero and self-cancelling month/day steps now raise ValueError, wrong-direction steps yield nothing like range()strutils.MultiReplace raising KeyError on empty substitution maps (now a no-op)jsonutils.JSONLIterator hanging when a seek lands past the last newline, and negative rel_seek values seeking past EOF (sign bug)iterutils.xfrange yielding nothing for descending ranges; now shares frange's count-based semantics, so both agree at inexact float boundariesurlutils.parse_qsl ignoring its encoding argument when decoding keys and values (#455)dictutils.OrderedMultiDict.addlist dropping values from one-shot iterables, including the vendored copy in urlutils (#458)ecoutils.get_profile looking up identifying host, username, and working-directory information when scrub=True (#461)namedutils.namedtuple and namedutils.namedlist raising IndexError instead of ValueError for empty type and field names (#462)iterutils.GUIDerator error text to reflect the inclusive minimum size of 20 (#451)timeutils.decimal_relative_time and relative_time rejecting aware datetimes when the comparison time is omitted (#469)timeutils.USTimeZone handling of repeated and missing DST hours, including fold on UTC conversion (#441)mathutils.Bits negative indexing (#450)mathutils.Bits empty binary, hexadecimal, and byte round trips (#468)setutils.IndexedSet bulk difference and intersection updates with a single-pass rebuild (#440)listutils.BarrelList out-of-range indexing returning unrelated values (#440)listutils.BarrelList insertion clamping across multiple internal lists (#440)listutils.BarrelList popping after an internal list was emptied by indexed removals (#440)listutils.BarrelList.iter_slice slice normalization and reverse steps (#471)listutils.BarrelList.del_slice deletion across internal lists and through the end of the list (#472)jsonutils.JSONLIterator rejecting the documented rel_seek=1.0 endpoint (#465)jsonutils.JSONLIterator relative seeking in binary streams (#464)statsutils.Stats.get_histogram_counts division by zero for data with no interquartile spread (#467)jsonutils.reverse_iter_lines ignoring explicit and stream encodings (#463)jsonutils.reverse_iter_lines detaching the caller's text stream, preventing later reads and context-manager cleanup (#466)cacheutils.ThresholdCounter.update ignoring mapping and keyword counts (#476)cacheutils.LRI.update and cacheutils.LRU.update rejecting empty and keyword-only updates, and ignoring keywords when the source is the cache itself (#478)cacheutils.ThresholdCounter.most_common returning no pairs when the limit is omitted (#460)strutils.bytes2human failing to use the Y suffix for yottabyte-sized values (#459)urlutils.URL.get_authority dropping passwords when the username is empty (#477)strutils.args2sh and strutils.args2cmd ignoring the sep argument (#454)statsutils.Stats.pearson_type raising RuntimeError instead of classifying Pearson types IV, V, and VI (#434)statsutils.Stats.pearson_type division by zero at the exact coefficient boundary, preserving the existing Normal and Gamma cases (#434)setutils.complement subset and superset comparisons raising AttributeError (#438)mathutils.Bits accepting values too large for the requested bit lengthtbutils.ParsedException dropping Python 3.11+ traceback anchor lines during round trips (#333)strutils.pluralize handling of words ending in x, such as boxiterutils.backoff_iter division by zero with factor=1.0 and no count; equal bounds yield once, and unequal bounds raise ValueErrorFull Changelog: 26.1.0...26.2.0
One column per quarter.
(September 7, 2026)
statsutils.mode][statsutils.mode] to return the most common value, breaking ties by first appearance (#453)setutils.IndexedSet.update][setutils.IndexedSet.update] adding the iterables themselves instead of their elements when given multiple inputs (#474)strutils.iter_splitlines][strutils.iter_splitlines] and [strutils.indent][strutils.indent] splitting dates containing 28 or 29 instead of recognizing Unicode line separators (#475)strutils.ellipsize][strutils.ellipsize] for word-boundary-aware text truncation with an ellipsisfuncutils.wraps][funcutils.wraps] passing arguments positionally to wrappers that only accept them as keywords (#261)tableutils.Table.to_text][tableutils.Table] crashes on empty tables, None headers, and short header rows; empty headers now render no header row, matching to_htmltimeutils.isoparse][timeutils.isoparse] misreading fractional seconds (.851 parsed as 851µs instead of 851000µs); >6-digit fractions now truncate instead of raisingtimeutils.daterange][timeutils.daterange] looping forever on non-advancing steps: zero and self-cancelling month/day steps now raise ValueError, wrong-direction steps yield nothing like range()strutils.MultiReplace][strutils.MultiReplace] raising KeyError on empty substitution maps (now a no-op)jsonutils.JSONLIterator][jsonutils.JSONLIterator] hanging when a seek lands past the last newline, and negative rel_seek values seeking past EOF (sign bug)iterutils.xfrange][iterutils.xfrange] yielding nothing for descending ranges; now shares [frange][iterutils.frange]'s count-based semantics, so both agree at inexact float boundariesurlutils.parse_qsl][urlutils.parse_qsl] ignoring its encoding argument when decoding keys and values (#455)dictutils.OrderedMultiDict.addlist][dictutils.OrderedMultiDict.addlist] dropping values from one-shot iterables, including the vendored copy in urlutils (#458)ecoutils.get_profile][ecoutils.get_profile] looking up identifying host, username, and working-directory information when scrub=True (#461)namedutils.namedtuple][namedutils.namedtuple] and [namedutils.namedlist][namedutils.namedlist] raising IndexError instead of ValueError for empty type and field names (#462)iterutils.GUIDerator][iterutils.GUIDerator] error text to reflect the inclusive minimum size of 20 (#451)timeutils.decimal_relative_time][timeutils.decimal_relative_time] and relative_time rejecting aware datetimes when the comparison time is omitted (#469)timeutils.USTimeZone][timeutils.USTimeZone] handling of repeated and missing DST hours, including fold on UTC conversion (#441)mathutils.Bits][mathutils.Bits] negative indexing (#450)mathutils.Bits][mathutils.Bits] empty binary, hexadecimal, and byte round trips (#468)setutils.IndexedSet][setutils.IndexedSet] bulk difference and intersection updates with a single-pass rebuild (#440)listutils.BarrelList][listutils.BarrelList] out-of-range indexing returning unrelated values (#440)listutils.BarrelList][listutils.BarrelList] insertion clamping across multiple internal lists (#440)listutils.BarrelList][listutils.BarrelList] popping after an internal list was emptied by indexed removals (#440)listutils.BarrelList.iter_slice][listutils.BarrelList.iter_slice] slice normalization and reverse steps (#471)listutils.BarrelList.del_slice][listutils.BarrelList.del_slice] deletion across internal lists and through the end of the list (#472)jsonutils.JSONLIterator][jsonutils.JSONLIterator] rejecting the documented rel_seek=1.0 endpoint (#465)jsonutils.JSONLIterator][jsonutils.JSONLIterator] relative seeking in binary streams (#464)statsutils.Stats.get_histogram_counts][statsutils.Stats.get_histogram_counts] division by zero for data with no interquartile spread (#467)jsonutils.reverse_iter_lines][jsonutils.reverse_iter_lines] ignoring explicit and stream encodings (#463)jsonutils.reverse_iter_lines][jsonutils.reverse_iter_lines] detaching the caller's text stream, preventing later reads and context-manager cleanup (#466)cacheutils.ThresholdCounter.update][cacheutils.ThresholdCounter.update] ignoring mapping and keyword counts (#476)cacheutils.LRI.update][cacheutils.LRI.update] and [cacheutils.LRU.update][cacheutils.LRU.update] rejecting empty and keyword-only updates, and ignoring keywords when the source is the cache itself (#478)cacheutils.ThresholdCounter.most_common][cacheutils.ThresholdCounter.most_common] returning no pairs when the limit is omitted (#460)strutils.bytes2human][strutils.bytes2human] failing to use the Y suffix for yottabyte-sized values (#459)urlutils.URL.get_authority][urlutils.URL.get_authority] dropping passwords when the username is empty (#477)strutils.args2sh][strutils.args2sh] and [strutils.args2cmd][strutils.args2cmd] ignoring the sep argument (#454)statsutils.Stats.pearson_type][statsutils.Stats.pearson_type] raising RuntimeError instead of classifying Pearson types IV, V, and VI (#434)statsutils.Stats.pearson_type][statsutils.Stats.pearson_type] division by zero at the exact coefficient boundary, preserving the existing Normal and Gamma cases (#434)setutils.complement][setutils.complement] subset and superset comparisons raising AttributeError (#438)mathutils.Bits][mathutils.Bits] accepting values too large for the requested bit lengthtbutils.ParsedException][tbutils.ParsedException] dropping Python 3.11+ traceback anchor lines during round trips (#333)strutils.pluralize][strutils.pluralize] handling of words ending in x, such as boxiterutils.backoff_iter][iterutils.backoff_iter] division by zero with factor=1.0 and no count; equal bounds yield once, and unequal bounds raise ValueErrorFixed strutils.singularize mangling words ending in 'ss'
strutils.singularize mangling words ending in 'ss'fileutils.AtomicSaver to accept os.PathLikecopy.copy/copy.deepcopy collapsing dictutils.OrderedMultiDict valuesstrutils.MultiReplace match lookupsetutils.IndexedSet out-of-range negative indexing wrapping aroundsetutils.IndexedSet slicing after removalsFull Changelog: 26.0.0...26.1.0
(July 17, 2026)
strutils.singularize][strutils.singularize] mangling words ending in 'ss'fileutils.AtomicSaver][fileutils.AtomicSaver] to accept os.PathLikecopy.copy/copy.deepcopy collapsing [dictutils.OrderedMultiDict][dictutils.OrderedMultiDict] valuesstrutils.MultiReplace][strutils.MultiReplace] match lookupsetutils.IndexedSet][setutils.IndexedSet] out-of-range negative indexing wrapping aroundsetutils.IndexedSet][setutils.IndexedSet] slicing after removalsAdded funcutils.once decorator for one-time function execution
funcutils.once decorator for one-time function executionstrutils.human_readable_list for formatting lists as human-readable stringsiterutils.partition to accept multiple predicatescache option to iterutils.remap and iterutils.researchiterutils.split maxsplit=0 wrapping source object instead of its valueslistutils.BarrelList insert() raising IndexError on large negative indices (now clamps like built-in list)listutils.BarrelList sort() with multiple internal listsdictutils.OrderedMultiDict equality comparison against plain mappingsstrutils.bytes2human rollover at exact powers of 1024tbutils.ParsedException.from_string IndexError on truncated tracebackstableutils.Table.to_text column sizingstrutils.html2text handlingFull Changelog: 25.0.0...26.0.0
(June 19, 2026)
funcutils.once][funcutils.once] decorator for one-time function executionstrutils.human_readable_list][strutils.human_readable_list] for formatting lists as human-readable stringsiterutils.partition][iterutils.partition] to accept multiple predicatescache option to [iterutils.remap][iterutils.remap] and [iterutils.research][iterutils.research]iterutils.split][iterutils.split] maxsplit=0 wrapping source object instead of its valueslistutils.BarrelList][listutils.BarrelList] insert() raising IndexError on large negative indices (now clamps like built-in list)listutils.BarrelList][listutils.BarrelList] sort() with multiple internal listsdictutils.OrderedMultiDict][dictutils.OrderedMultiDict] equality comparison against plain mappingsstrutils.bytes2human][strutils.bytes2human] rollover at exact powers of 1024tbutils.ParsedException.from_string][tbutils.ParsedException] IndexError on truncated tracebackstableutils.Table.to_text][tableutils.Table] column sizingstrutils.html2text][strutils.html2text] handlingAdd fsync to fileutils.atomic_save
(February 2, 2025)
utcnow()fileutils.atomic_savefileutils.rotate_file(February 2, 2025)
utcnow()fileutils.atomic_save][fileutils.atomic_save]fileutils.rotate_file][fileutils.rotate_file]A few enhancements and one subtle bugfix.
(November 1, 2024)
A few enhancements and one subtle bugfix.
max_depth parameter to fileutils.iter_find_filesenter parameter to iterutils.research to support traversing custom data typesAlso Python 3.13 is passing tox locally.
(November 1, 2024)
max_depth parameter to [fileutils.iter_find_files][fileutils.iter_find_files]enter parameter to [iterutils.research][iterutils.research] to support traversing custom data typesiterutils.remap][iterutils.remap] for easier debuggingtypeutils.Sentinel][typeutils.make_sentinel] copy behavior to return selfPer the RFC in issue #365 , boltons is now Python 3 only . 3.7+ for now. If you're a Python 2 user, feel free to pin at boltons<24.0.0 .
Per the RFC in issue #365, boltons is now Python 3 only. 3.7+ for now.
If you're a Python 2 user, feel free to pin at boltons<24.0.0.
Other minor changes:
update() behavior with empty iterablessmall release with sdist packaging tweaks
small release with sdist packaging tweaks
(November 1, 2023)
Tiny release to include more test files in the sdist (source distribution) on PyPI.
bugfixes for LRU, OMD, and copy_function. fill/end for windowed/pairw…
bugfixes for LRU, OMD, and copy_function. fill/end for windowed/pairw…
(October 31, 2023)
fill/end parameters for iterutils.windowed and iterutils.pairwise, respectively (#350)cacheutils.LRU (#348)funcutils.copy_function maintains kw-only defaults (#336)ior (#341)Overdue update for Python 3.10 and 3.11 support ( #294 , #303 , #320 , #323 , #326 / #327 )
(February 19, 2023)
SpooledBytesIO/SpooledStringIO (#305)Bits.as_list behavior (#315)(February 19, 2023)
Overdue update for Python 3.10 and 3.11 support ([#294][i294], [#303][i303], [#320][i320], [#323][i323], [#326][i326]/[#327][i327])
Add [iterutils.chunk_ranges][iterutils.chunk_ranges] ([#312][i312])
Improvements to SpooledBytesIO/SpooledStringIO ([#305][i305])
Bugfix for infinite daterange issue when start and stop is the same ([#302][i302])
Fix Bits.as_list behavior ([#315][i315])
21.0.0
(May 16, 2021)
Fix OMD .addlist when the added list is empty
(May 16, 2021)
custom repr in format_invocation, faster iterutils import
custom repr in format_invocation, faster iterutils import
_(August 11, 2020)_
Improve import time of [iterutils][iterutils] by deferring hashlib/socket imports
Add custom repr parameter to [funcutils.format_invocation][funcutils.format_invocation]
20.2.0
---
_(June 21, 2020)_
Added [iterutils.lstrip][iterutils.lstrip], [iterutils.rstrip][iterutils.rstrip], [iterutils.strip][iterutils.strip]
More robust and complete [strutils.strip_ansi][strutils.strip_ansi]
Add [iterutils.untyped_sorted][iterutils.untyped_sorted]
Fixes to [IndexedSet][IndexedSet] rsub and index methods
Expose text mode flag in [fileutils.AtomicSaver][fileutils.AtomicSaver]
Add [strutils.int_list_complement][strutils.int_list_complement] and [strutils.int_list_to_int_tuples][strutils.int_list_to_int_tuples] to the _int_list_ suite.
Docs: intersphinx links finally point to Python 3 docs
20.1.0
---
_(March 29, 2020)_
Add [funcutils.update_wrapper][funcutils.update_wrapper], used to make a wrapper function reflect various aspects of the wrapped function's API.
Fix [FunctionBuilder][FunctionBuilder] handling of functions without __module__
Add partial support to [FunctionBuilder][FunctionBuilder]
Fix [NetstringSocket][socketutils.NetstringSocket]'s handling of arguments in read_ns
Fix [IndexedSet][IndexedSet]'s index() method to account for removals
Add seekable, readable, and writable to SpooledIOBase
Add a special case to singularize
Fix various warnings for Py3.9
20.0.0
---
_(January 8, 2020)_
New module [pathutils][pathutils]: - [pathutils.augpath][pathutils.augpath] augments a path by modifying its components - [pathutils.shrinkuser][pathutils.shrinkuser] inverts os.path.expanduser. - [pathutils.expandpath][pathutils.expandpath] shell-like environ and tilde expansion
add include_dirs param to [fileutils.iter_find_files][fileutils.iter_find_files]
Make [funcutils.format_invocation][funcutils.format_invocation] more deterministic
add [strutils.unwrap_text][strutils.unwrap_text] which does what you think to wrapped text
Py3 fixes - [iterutils.chunked][iterutils.chunked] to work with the bytes type ([#231][i231]) - [cacheutils.ThresholdCounter][cacheutils.ThresholdCounter]'s get_common_count()
[i231]: https://github.com/mahmoud/boltons/issues/231 [pathutils]: https://boltons.readthedocs.io/en/latest/pathutils.html [pathutils.augpath]: https://boltons.readthedocs.io/en/latest/pathutils.html#boltons.pathutils.augpath [pathutils.augpath]: https://boltons.readthedocs.io/en/latest/pathutils.html#boltons.pathutils.augpath [pathutils.shrinkuser]: https://boltons.readthedocs.io/en/latest/pathutils.html#boltons.pathutils.shrinkuser [pathutils.expandpath]: https://boltons.readthedocs.io/en/latest/pathutils.html#boltons.pathutils.expandpath [strutils.unwrap_text]: https://boltons.readthedocs.io/en/latest/strutils.html#boltons.strutils.unwrap_text
Nothing published for this version
Nothing published for this version
First release of the year! Also the first release in a while to add a new module, pathutils!
First release of the year! Also the first release in a while to add a new module, pathutils!
[pathutils.augpath][pathutils.augpath] augments a path by modifying its components
[pathutils.shrinkuser][pathutils.shrinkuser] inverts os.path.expanduser.
[pathutils.expandpath][pathutils.expandpath] shell-like environ and tilde expansion
add include_dirs param to [fileutils.iter_find_files][fileutils.iter_find_files]
Make [funcutils.format_invocation][funcutils.format_invocation] more deterministic
add [strutils.unwrap_text][strutils.unwrap_text] which does what you think to wrapped text
[iterutils.chunked][iterutils.chunked] to work with the bytes type ([#231][i231])
[cacheutils.ThresholdCounter][cacheutils.ThresholdCounter]'s get_common_count()
[i231]: https://github.com/mahmoud/boltons/issues/231 [pathutils]: https://boltons.readthedocs.io/en/latest/pathutils.html [pathutils.augpath]: https://boltons.readthedocs.io/en/latest/pathutils.html#boltons.pathutils.augpath [pathutils.augpath]: https://boltons.readthedocs.io/en/latest/pathutils.html#boltons.pathutils.augpath [pathutils.shrinkuser]: https://boltons.readthedocs.io/en/latest/pathutils.html#boltons.pathutils.shrinkuser [pathutils.expandpath]: https://boltons.readthedocs.io/en/latest/pathutils.html#boltons.pathutils.expandpath [strutils.unwrap_text]: https://boltons.readthedocs.io/en/latest/strutils.html#boltons.strutils.unwrap_text [fileutils.iter_find_files]: http://boltons.readthedocs.org/en/latest/fileutils.html#boltons.fileutils.iter_find_files [funcutils.format_invocation]: https://boltons.readthedocs.io/en/latest/funcutils.html#boltons.funcutils.format_invocation [iterutils.chunked]: http://boltons.readthedocs.org/en/latest/iterutils.html#boltons.iterutils.chunked [cacheutils.ThresholdCounter]: http://boltons.readthedocs.org/en/latest/cacheutils.html#boltons.cacheutils.ThresholdCounter
[See complete details for in the CHANGELOG](https://github.com/mahmoud/boltons/blob/master/CHANGELOG.md)
[funcutils.format_invocation][funcutils.format_invocation] for formatting simple function calls like func(pos1, pos2, kw_k=kw_v)
func(pos1, pos2, kw_k=kw_v)Type(pos, kw_k=kw_v)<Type k=v>(October 28, 2019)
Three funcutils:
func(pos1, pos2, kw_k=kw_v)Type(pos, kw_k=kw_v)<Type k=v>A few small fixes and enhancements.
A few small fixes and enhancements.
(October 19, 2019)
A bunch of small fixes and enhancements.
level arg__rsub__ for better interop with the builtin setformatargspec)A couple enhancements, a couple cleanups, across several modules.
A couple enhancements, a couple cleanups, across several modules.
(February 28, 2019)
Couple of enhancements, couple of cleanups.
get_arg_names() method, and its get_defaults_dict() method
finally includes kwonly argument defaults.A quick enhancement for wraps/FunctionBuilder supporting type annotations
A quick enhancement for wraps/FunctionBuilder supporting type annotations
(February 12, 2019)
Quick release to enhance [FunctionBuilder][funcutils.FunctionBuilder] and [funcutils.wraps][funcutils.wraps] to maintain function annotations on Python 3+. (#133, #134, #203)
Maybe the biggest boltons release yet. Several bugfixes, even more new features.
Maybe the biggest boltons release yet. Several bugfixes, even more new features.
(February 10, 2019)
A very big release indeed, perhaps the biggest yet. A big, big thank you to all the contributors!
A few bugfixes and a handy text utility.
A few bugfixes and a handy text utility.
(August 29, 2018)
A few bugfixes and a handy text utility.
Add MultiSub for multiple string substitutions in a single call ([#162][i162])
tableutils.Table.to_text() is more Markdown compatible
Add LICENSE to package ([#164][i164])
atomic_save works better with overwrite=True ([#161][i161])
Reduced memory footprint on tbutils._DeferredLine with __slots__
18.0.0
(March 2, 2018)
Add <thead> and <tbody> structure to tableutils.Table HTML
output, which helps with styling and other functionality (e.g.,
jQuery datatables).
Add [dictutils.subdict()][dictutils.subdict] to get a filtered version of a dictionary based on a subset of keys. ([#150][i150])
Add beta version of cacheutils.MinIDMap.
17.2.0
(December 16, 2017)
A big release with a lot of features and bugfixes, big and small. Just in time for the holidays!
Better handling of file and file-like objects in [remap][iterutils.remap]'s default_enter
Fix line-by-line iteration in [ioutils][ioutils] types
Change [strutils.slugify][strutils.slugify] to always output at least a single-character slug (in cases of all-punctuation/whitespace inputs).
Fix [DeferredValue][formatutils.DeferredValue] caching in [formatutils][formatutils]
Add [OneToOne][dictutils.OneToOne] to [dictutils][dictutils]
Add [MultiFileReader][ioutils.MultiFileReader] to [ioutils][ioutils] (see [#135][i135])
Support passing dir argument to [ioutils][ioutils] SpooledIO types
fix default arguments for [mathutils.clamp][mathutils.clamp] (see [#128][i128])
Add [iterutils.research][iterutils.research], a [remap][iterutils.remap]-based recursive search function for nested data
Improved and expanded [urlutils.SCHEME_PORT_MAP][urlutils.SCHEME_PORT_MAP]
Simplify [urlutils.find_all_links][urlutils.find_all_links] signature
17.1.0
(February 27, 2017)
Add urlutils module, with URL type and find_all_links function. also update Sentinel for Python 3 falsiness
Add urlutils module, complete with RFC3986-compliant URL type
Also add urlutils.find_all_links function, which heuristically
finds all links in plaintext, and creates URLs out of them.
Update typeutils.Sentinel to be appropriately falsy on Python 3
17.0.0
(January 24, 2017)
Several tweaks and enhancements to ring in the new year.
[tbutils][tbutils] objects like the [ExceptionInfo][tbutils.ExceptionInfo] are now more easily JSON-serializable thanks to a tweak to [Callpoint][tbutils.Callpoint].
SpooledIO objects like
[ioutils.SpooledBytesIO][ioutils.SpooledBytesIO] are now
bool-able.
[iterutils.bucketize][iterutils.bucketize] gains the
value_transform and key_filter arguments.
[cachedproperty][cacheutils.cachedproperty] properly maintains docstring
[funcutils.wraps][funcutils.wraps] maintains a reference to the
wrapped function with __wrapped__ attribute.
A bit of cleanup to be backwards compatible to Python 3.3
16.5.1
(November 6, 2016)
Mostly bug fixes and various tweaks, optimizations, and documentation. Also added a bit of functionality in the form of [ioutils][ioutils] and some GUID stuff.
Add [ioutils][ioutils] with [SpooledStringIO][ioutils.SpooledStringIO] and [SpooledBytesIO][ioutils.SpooledBytesIO], two in-memory file-like objects, like the stdlib [StringIO][StringIO], except that they automatically spill over to disk when they reach a configurable size.
Add [iterutils.GUIDerator][iterutils.GUIDerator] and [iterutils.SequentialGUIDerator][iterutils.SequentialGUIDerator], two methods of getting random iterables.
Add [mathutils.clamp][mathutils.clamp], a combined min-max function, like numpy's clip.
Optimized [iterutils.first][iterutils.first].
Enabled spillover kwargs in [funcutils.wraps][funcutils.wraps]
fix for default [remap][iterutils.remap] set support, fixes [#84][i84]
improving and testing exceptions around classmethod and staticmethod for [funcutils.wraps][funcutils.wraps] and [FunctionBuilder][funcutils.FunctionBuilder], fixes [#86][i86] to the degree possible.
16.5.0
(July 16, 2016)
A few minor changes, and medium-sized breaking change to [cacheutils][cacheutils].
[cacheutils][cacheutils] caching decorators now take the function/method into account by default. This was done by adding the scoped argument to [@cached][cacheutils.cached] and [@cachedmethod][cacheutils.cachedmethod] (and removing selfish from cachedmethod). also fixed a bug in a cachedmethod test, as well as added docs for scoped and key arguments. all of this to fix [#83][i83].
[tableutils.Table][tableutils.Table] cell html can be customized by
overriding get_cell_html method.
[funcutils.total_ordering][funcutils.total_ordering], a [functools.total_ordering][functools.total_ordering] backport for python 2.6.
[funcutils.FunctionBuilder][funcutils.FunctionBuilder] function names are now configurable.
16.4.1
(June 14, 2016)
This release primarily contains several [statsutils][statsutils] updates.
The biggest change was the addition of [Stats.format_histogram][statsutils.Stats.format_histogram] complete with Freedman bin selection and other useful options.
Added inter-quartile range (iqr) to [statsutils.Stats][statsutils.Stats]
Adding mad (median absolute deviation) to [Stats.describe][statsutils.Stats.describe], since median and std_dev were already there.
16.4.0
(June 8, 2016)
another significant release, thanks to the addition of funcutils.wraps and funcutils.FunctionBuilder. also iterutils.chunked speedup, and tbutils.ParsedException.to_string.
[See complete release details in the CHANGELOG]
A big release with a lot of features and bugfixes, big and small. Just in time for the holidays!
(December 16, 2017)
A big release with a lot of features and bugfixes, big and small. Just in time for the holidays!
Add urlutils module, with URL type and find_all_links function. also update Sentinel for Python 3 falsiness
(February 27, 2017)
Add urlutils module, with URL type and find_all_links function. also update Sentinel for Python 3 falsiness
URL typeurlutils.find_all_links function, which heuristically
finds all links in plaintext, and creates URLs out of them.Several tweaks and enhancements to ring in the new year. Changelog here.
Several tweaks and enhancements to ring in the new year. Changelog here.
Mostly bug fixes and various tweaks, optimizations, and documentation. Also added a bit of functionality in the form of ioutils and GUID stuff.
Mostly bug fixes and various tweaks, optimizations, and documentation. Also added a bit of functionality in the form of ioutils and GUID stuff.
A few minor changes and a medium-sized breaking change to cacheutils.
A few minor changes and a medium-sized breaking change to cacheutils.
This release primarily contains several statsutils updates, mostly the addition of histogram computation and display. See the CHANGELOG for details.
This release primarily contains several statsutils updates, mostly the addition of histogram computation and display. See the CHANGELOG for details.
another significant release, thanks to the addition of funcutils.wraps and funcutils.FunctionBuilder. also iterutils.chunked speedup, and tbutils.Pars
another significant release, thanks to the addition of funcutils.wraps and funcutils.FunctionBuilder. also iterutils.chunked speedup, and tbutils.ParsedException.to_string. See CHANGELOG for details.
a couple of follow-on ecoutils updates (and improved docs)
a couple of follow-on ecoutils updates (and improved docs)
(May 24, 2016)
Just a couple of [ecoutils][ecoutils] follow-ons, removing uuid dependency and adding the ability to scrub identifiable data.
ecoutils, debugutils.wrap_trace preview, timeutils.strpdate, timeutils.daterange, a few socketutils bugs/platform tweaks, statsutils.Stats improvement
big big update.
ecoutils, debugutils.wrap_trace preview, timeutils.strpdate, timeutils.daterange, a few socketutils bugs/platform tweaks, statsutils.Stats improvements (esp. describe), strutils.parse_/format_int_list, cacheutils.cachedproperty, and cacheutils.cachedmethod
(May 23, 2016)
Big, big update. Lots of additions, a few bugfixes.
[ecoutils][ecoutils] - Python runtime/environment profile generator
[timeutils.strpdate][timeutils.strpdate] - like datetime.datetime.strpdate but for date
[timeutils.daterange][timeutils.daterange] - like range() but for datetime.date objects
[strutils.parse_int_list][strutils.parse_int_list] and [strutils.format_int_list][strutils.format_int_list]
[cacheutils][cacheutils]
cacheutils.make_cache_key is now public, should others need it[statsutils.Stats][statsutils.Stats] update, several new methods, including [Stats.describe][statsutils.Stats.describe]
A few [socketutils][socketutils] platform tweaks
debugutils.wrap_trace preview
16.2.2
(May 3, 2016)
many small tweaks to socketutils.BufferedSocket, including optional inclusion of the delimiter in recv_until. also undid the enabling of bak files with AtomicSaver on windows
getsendbuffer() returns a bytestring and recv_size() uses the proper
._recvsize on the first socket fetchNothing published for this version
This version sees the soft debut of [socketutils][socketutils], which includes wrappers and tools for working with the built-in socket. A lot of [sock
(April 29, 2016)
This version sees the soft debut of [socketutils][socketutils], which includes wrappers and tools for working with the built-in socket. A lot of [socketutils.BufferedSocket][socketutils.BufferedSocket] changes.
adding shell args escaper-joiners to strutils (escape_shell_args, args2cmd, args2sh) as well as a rare breaking fix to [iterutils.pairwise][iterutils.
(April 18, 2016)
adding shell args escaper-joiners to strutils (escape_shell_args, args2cmd, args2sh) as well as a rare breaking fix to [iterutils.pairwise][iterutils.pairwise].
chunked, now it calls to windowed. pairwise([1, 2, 3, 4]) no
longer returns [(1, 2), (3, 4)]. Instead, it returns
[(1, 2), (2, 3), (3, 4)], which is what I always mean when I say
pairwise, but not what the original contributor implemented.Added [iterutils.same][iterutils.same], improvement of Windows [fileutils.AtomicSaver][fileutils.AtomicSaver] behavior for old filesystems, bugfix on
(March 6, 2016)
Added [iterutils.same][iterutils.same], improvement of Windows [fileutils.AtomicSaver][fileutils.AtomicSaver] behavior for old filesystems, bugfix on [strutils.is_uuid][strutils.is_uuid], expansion of [strutils.pluralize][strutils.pluralize], new trove classifiers and docs improvements!
True when all values in
iterable are the same.The centerpiece of this release is highly improved Windows support for [fileutils.atomic_save][fileutils.atomic_save] via ReplaceFile system call. Thi
(February 24, 2016)
The centerpiece of this release is highly improved Windows support for
[fileutils.atomic_save][fileutils.atomic_save] via
ReplaceFile
system call. This functionality is also made available directly via
[fileutils.replace][fileutils.replace], which is akin to Python 3.3+'s
[os.replace][os.replace], except that os.replace's approach has
arguably poorer behavior and atomicity
compared to fileutils.replace.
Also, a couple new strutils, and [iterutils.backoff][iterutils.backoff] grew a jitter argument.
DummyFile, Table.metadata, better exception handling, and in-progress iterutils.get_path
(January 24, 2016)
DummyFile, Table.metadata, better exception handling, and in-progress iterutils.get_path
One important fix and one small but handy string function.
One important fix and one small but handy string function.
Fixed an [LRU][cacheutils.LRU] bug related to the 15.1.1 refactor. Also enhanced LRU testing with doubly-linked list invariant enforcement.
Added [strutils.indent][strutils.indent], the counterpart to textwrap.dedent.
15.1.1
(November 18, 2015)
A lot of bugfixes and docfixes in 15.1.1.
updated AtomicSaver for better permissions handling, update BufferedSocket message sending, beta version of iterutils.get_path, several docs fixes, Stats zscore and cache bugfix, and an LRU refactor with significantly improved behavior and code factoring.
dest_perms and part_perms arguments to AtomicSaver and
atomic_save.delattr when hasattr in
[Stats.clear_cache][statsutils.Stats.clear_cache]__eq__Nothing published for this version
Reached the first release version of [iterutils.remap]iterutils.remap, fully tested and documented. Also a couple of tweaks to expose the [iterutils.u
(September 23, 2015)
Reached the first release version of [iterutils.remap]iterutils.remap, fully tested and documented. Also a couple of tweaks to expose the [iterutils.unique][iterutils.unique] docs.
a couple [dictutils.OMD][dictutils.OMD] fixes to [dictutils.OMD.pop][dictutils.OMD.pop] and [dictutils.OMD.popall][dictutils.OMD.popall] to make them
(September 9, 2015)
a couple [dictutils.OMD][dictutils.OMD] fixes to [dictutils.OMD.pop][dictutils.OMD.pop] and [dictutils.OMD.popall][dictutils.OMD.popall] to make them consistent with the docstrings. and the accompanying tests of course.
fix [dictutils.OMD.setdefault][dictutils.OMD.setdefault] to default to None and not empty list, per documentation (and add a test to the same effect)
15.0.1
(August 27, 2015)
Nothing published for this version
Finally the 15.0 major release. All passing PRs and feature requests from the first wave addressed and closed. tzutils merged into timeutils. AtomicSa
(August 19, 2015)
Finally the 15.0 major release. All passing PRs and feature requests from the first wave addressed and closed. tzutils merged into timeutils. AtomicSaver approach and API much improved. Several other features added:
Fix atomic saving open-file issue for Windows.
(July 31, 2015)
Fix atomic saving open-file issue for Windows.
BufferedSocket work, html2text, pairwise shortcut, is_container, plural typo fix, [timeutils.isoparse][timeutils.isoparse], [cacheutils.ThresholdCount
(July 30, 2015)
BufferedSocket work, html2text, pairwise shortcut, is_container, plural typo fix, [timeutils.isoparse][timeutils.isoparse], [cacheutils.ThresholdCounter][cacheutils.ThresholdCounter], and lots of testing
Fixed multiline exception message handling in ParsedException. added mathutils. adding a tentative version of socketutils. fix LRU.popitem. fix OMD.eq
(May 10, 2015)
Fixed multiline exception message handling in ParsedException. added mathutils. adding a tentative version of socketutils. fix LRU.popitem. fix OMD.eq.
LRU.popitem to return a key value pairAdd typeutils, remove compat.py, make ParsedException work with eval()ed code
(April 20, 2015)
Add typeutils, remove compat.py, make ParsedException work with eval()ed code
Add partial_ordering, fix LRU repr and addition behavior
(April 11, 2015)
Add partial_ordering, fix LRU repr and addition behavior
Nothing published for this version
Python 3 support and several community bugfixes. Docs clarifications, too.
(April 10, 2015)
Python 3 support and several community bugfixes. Docs clarifications, too.
A lot of bugfixes and Python 2.6 and PyPy compatibility changes thanks to community contributions and encouragement.
(April 10, 2015)
A lot of bugfixes and Python 2.6 and PyPy compatibility changes thanks to community contributions and encouragement.
Deprecate osutils, moving its contents into fileutils
(April 9, 2015)
First publicly released version. The major focus of this release was docs, docstrings, and Read The Docs.
Mostly a dictutils API update (addlist), but also gcutils.
(March 8, 2015)
Mostly a dictutils API update (addlist), but also gcutils.
Nothing published for this version
adding mboxutils for handy dandy /var/mail integrations like cronfed
(February 26, 2015)
adding mboxutils
updated tbutils, JSONL support, initial cacheutils, atomic writer, hashtags
(February 23, 2015)
updated tbutils, JSONL support, initial cacheutils, atomic writer, hashtags
add an initial version of deprutils (basic utils for facilitating deprecation)
(October 19, 2014)
First alpha release. Practically, everything not mentioned above was added in this release.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →