2.2 series

2022-04-21. Release 2.2.5

2022-03-14. Release 2.2.4.post1

  • Update to ‘typing_extensions>=3.10’.

2022-03-02. Release 2.2.4

2021-12-12. Release 2.2.3

2021-12-02. Release 2.2.2

  • slides() allows the value NO_FILL to signal no filling of the last chunk.

2021-11-29. Releases 2.2.1.post1 and 2.2.0.post1

2021-10-26. Release 2.2.1

  • Added support for Python 3.10

2021-09-08. Release 2.2.0

  • Drop support for Python 3.5, 3.6 and 3.7 and commit to support Python 3.8, and 3.9.

    The code might run in Python 3.6+, but we’re not testing anymore on those versions.

  • Remove long-deprecated functions and classes:

    •, and

This release marks the last release of the series of 2.1.x. We simply don’t have the manpower to keep many branches at the same time.

2.1 series

2021-11-29. Release 2.1.11

This release marks the last release of the series of 2.1.x. We simply don’t have the manpower to keep many branches at the same time.

2020-10-28. Release 2.1.10

  • Improve type hints for several modules.

    We run mypy 0.782 in a large project of ours that uses many modules of and we discovered no major roadblocks. So we think this deserves its own release.

    The list of modules we deem are complete:

    We’ve published several post-releases for 2.1.10 (2.1.10.post2, 2.1.10.post3, …). Those releases don’t introduce new functions or bug-fixes, only more and more support for type hints (those we’ve missed in the 2.1.10 release).

  • Add official support for Python 3.9. The list of Python versions we support is currently:

    • Python 3.6
    • Python 3.7
    • Python 3.8, and
    • Python 3.9.

2020-07-05. Release 2.1.9

  • Add official support for Python 3.8 and drop support for Python 3.5.

    Even though our packages have been tested with Python 3.8 for a while. This release marks the official support.

    Dropping support for Python 3.5 means we no longer going to test our changes in Python 3.5.

  • Backport module graphlib from Python 3.9 in Refer to the standard documentation.

  • Add function

2020-03-31. Release 2.1.8

  • Make comparable with unknown types by returning NotImplemented instead of raising the error directly. See MR !28 for an example.

2020-03-10. Release 2.1.7

2020-01-21. Release 2.1.6

  • Deprecate in favor of stdlib’s itertools.islice().

2019-12-12. Release 2.1.5

  • Deprecate iter_final_subclasses() and get_final_subclasses().
  • Stop support for Python 3.4.
  • Fix bug #6: Instances of boolean were not pickable.

2019-10-26. Release 2.1.4

2019-05-26. Release 2.1.3

2019-05-26. Release 2.1.2

2019-03-13. Release 2.1.1

  • Fix packaging issue. No functional changes.

2019-02-27. Release 2.1.0

  • Repackage xoutil under You can still import from the xoutil namespace.
  • Remove deprecated module xoutil.logger.
  • Remove package xoutil.eight.
  • Remove deprecated xoutil.decorator.memoized_property, use
  • Remove deprecated functions and classes xoutil.future.inspect.type_name, xoutil.future.functools.ctuple, and xoutil.future.functools.compose.
  • Remove deprecated top-level imports: xoutil.Unset, xoutil.Undefined, xoutil.Ignored and xoutil.Invalid.
  • Add
  • Allow to customize Quantity in and, by argument, in new().
  • Deprecate, and
  • Re-implement in terms of heapq.merge().
  • Add
  • Add, and
  • Deprecate module
  • Deprecate module
  • Deprecate; use instead.
  • Remove deprecated module
  • Remove deprecated module xotl.tool.logical.
  • Remove deprecated module
  • Remove deprecated function

2.0 series


End-of-life for xoutil 2.0

xoutil 2.0.7 will be the last release in the xoutil 2.0.x series that adds new functionality. Any future release in this series will be bug-fix only.

Since the pair-wise releases of 1.9.x and 2.0.x some new functionality has been added to some version of 1.9.x that is not present in some releases of the 2.0.x series.

This created some dose of unease for users wanting a new feature in 1.9.3 in a package where Python 2/3 was not a true concern; they were forced to require ‘xoutil>=1.9.3,!=2.0.0,!=2.0.1,!=2.0.2’ to avoid the package manager to select a version without the needed feature.

This end-of-life notice puts an end to this issue.

2018-11-07. Release 2.0.9

2018-09-24. Release 2.0.8

  • Incorporates all (applicable) changes from release 1.9.8
  • Fix bug when comparing version numbers (xoutil.versions).

2018-09-14. Release 2.0.7

Incorporates all (applicable) changes from release 1.9.7

2018-07-30. Release 2.0.6

Incorporates all (applicable) changes from release 1.9.6:

2018-06-25. Release 2.0.5

Incorporates all (applicable) changes from release 1.9.5:

2018-05-09. Release

  • Packaging fix: the python tag for releases in the 2.0 branch was incorrectly set to “py2”. xoutil 2.0+ support only Python 3.4+.

    We’re removing the wrongly tagged releases from PyPI.

2018-05-08. Release 2.0.4

Incorporates all (applicable) changes from release 1.9.4:

2018-04-16. Release 2.0.3

2018-03-30. Release 2.0.2

2018-03-22. Release 2.0.1

2018-03-02. Release 2.0.0

  • This is the first release for which Python 2 no longer supported. It was a good time! Good bye, Python 2!

  • The following imports are no longer available. Look for them in xoutil.future:

    • xoutil.collection
    • xoutil.datetime
    • xoutil.functools
    • xoutil.inspect
    • xoutil.iterators
    • xoutil.json
    • xoutil.pprint
    • xoutil.subprocess
    • xoutil.textwrap
    • xoutil.threading
    • xoutil.types
  • Deprecate modules that only provided a unifying mechanism between Python 2 and 3, or that backported features from Python 3 to Python 2:

    • xoutil.annotate
    • xoutil.eight
    • xoutil.eight.urllib
  • Remove deprecated module xoutil.html.

1.9 series


End-of-life for xoutil 1.9

xoutil 1.9.7 will be the last release of xoutil that adds functionality. Future releases will be strictly bug-fix only.

2018-11-07. Release 1.9.9

  • Fix bug #4: xoutil.decorator.meta.flat_decorator() was not working in Python 3.
  • Deprecate xoutil.decorator.meta.flat_decorator().

2018-09-24. Release 1.9.8

  • Fix bug in xoutil.cli for Python 3.7.

2018-09-14. Release 1.9.7

  • Add support for Python 3.7.
  • is an alias to the stdlib’s ABC class if using Python 3.4+.
  • Rename xoutil.fp.iterators.iter_compose to xoutil.fp.iterators.kleisli_compose(). Leave iter_compose as deprecated alias.
  • Add xoutil.future.datetime.TimeSpan.diff()
  • Add xoutil.future.datetime.DateTimeSpan.

2018-07-30. Release 1.9.6

  • Add parameter ‘encoding’ to xoutil.eight.string.force() and xoutil.eight.string.safe_join().
  • Add xoutil.fp.iterators and xoutil.fp.iterators.iter_compose().

2018-06-25. Release 1.9.5

  • Add module xoutil.future.contextlib.

2018-05-08. Release 1.9.4

  • Fix xoutil.eight.iteritems(), xoutil.eight.itervalues() and xoutil.eight.iterkeys() to return an iterator.
  • is_valid_identifier() so that it uses str.isidentifier() in Python 3.
  • Add class method xoutil.future.collections.opendict.from_enum()

2018-04-16. Release 1.9.3

  • Make TimeSpan intersection inversible. Before, doing & TimeSpan() raised a TypeError, but swapping the operands worked. Now, both ways work.
  • Add xoutil.objects.delegator() and xoutil.objects.DelegatedAttribute.

2018-03-30. Release 1.9.2

  • xoutil.context.NullContext is now a Mapping.

2018-03-22. Release 1.9.1

  • Fix bug #29: Issues with xoutil.symbols.symbol documentation and implementation.
  • Fix bug #30: It was possible to define a dimension with two (or more) incompatible canonical units.
  • Fix bug #33: Reusing a context leaves the context unusable.
  • Renamed xoutil.tasking.StandardWait to xoutil.tasking.ConstantWait.

2018-03-02. Release 1.9.0

  • With the release of 2.0.0, xoutil ends it support for Python 2.

    Releases 1.9 are a continuation of the 1.8 series and don’t break any API found in the last release of that series: 1.8.8.

  • Add xoutil.objects.import_object().

  • Add xoutil.context.Context.from_defaults() and xoutil.context.Context.from_dicts().

  • Deprecate imports from top-level xoutil. The following objects should be imported from xoutil.symbols:

    • Unset
    • Undefined
    • Invalid
    • Ignored

1.8 series

2018-02-24. Release 1.8.8

  • Fix bug #28: xoutil.future.inspect.getattr_static() failed with Python’s 2 old classes.

2018-01-06. Release 1.8.7

  • Add parameter ‘encoding’ to slugify() and force_ascii(). (bug #25).
  • Stop using locale.getpreferredencoding() in force_encoding(). Also related to bug #25.

2018-01-02. Release 1.8.6

2017-12-22. Release 1.8.5

  • Deprecate module xoutil.logger.
  • Remove deprecated function xoutil.iterators.fake_dict_iteritems.
  • Add xoutil.objects.temp_attributes().
  • Add functions fst() and snd().

2017-12-15. Release 1.8.4

  • Add module xoutil.future.csv.
  • Add module xoutil.future.mimetypes.
  • Add module xoutil.eight.urllib.
  • The module xoutil.iterators is now officially named xoutil.future.itertools. The alias xoutil.iterators remains as a deprecated alias.
  • Add xoutil.future.itertools.merge().
  • Add xoutil.future.types._get_mro_attr() function.
  • Deprecate in xoutil.future.types module: mro_dict class; and the functions mro_get_value_list, mro_get_full_mapping, is_iterable, is_collection, is_mapping, is_string_like, is_scalar, is_module, are_instances, and no_instances.

2017-11-28. Release 1.8.3

  • Fix bug #20: xoutil.future.calendar may fail at import time.
  • Add xoutil.params.pop_keyword_values().
  • Add xoutil.future.collections.codedict. Deprecate module xoutil.formatter.

2017-11-22. Release 1.8.2

  • Add displacement operations left shift (<<) and right shift (>>) for TimeSpan.
  • Add xoutil.objects.smart_getter() and xoutil.objects.save_attributes().
  • Document experimental module xoutil.tasking.
  • Add extra (and experimental) module xoutil.testing.

2017-11-17. Release 1.8.1

  • Remove deprecated xoutil.objects.get_and_del_first_of(), xoutil.objects.smart_getattr(), and xoutil.objects.get_and_del_attr().
  • Remove deprecated arguments from xoutil.objects.xdir() and xoutil.objects.fdir().
  • Fix bug #17: is not wrappable.
  • Move xoutil.decorator.memoized_property to xoutil.objects.memoized_property module. Deprecate the first.
  • Deprecate xoutil.decorator.memoized_instancemethod.
  • Deprecate xoutil.decorator.reset_memoized(). Use reset().
  • Fix bug (unregistered): xoutil.objects.traverse() ignores its getter.

2017-11-03. Release 1.8.0

  • Remove deprecated xoutil.objects.metaclass, use xoutil.eight.meta.metaclass() instead.

  • Several modules are migrated to xoutil.future:

    • types.
    • collections.
    • datetime.
    • functools.
    • inspect.
    • codecs.
    • json.
    • threading.
    • subprocess.
    • pprint.
    • textwrap.


    All modules remain importable from its future-less version, however, deprecated.

  • Add function xoutil.deprecation.import_deprecated(), inject_deprecated() can be deprecated now.

  • Add function xoutil.deprecation.deprecate_linked() to deprecate full modules imported from a linked version. The main example are all sub-modules of xoutil.future.

  • Add function xoutil.deprecation.deprecate_module() to deprecate full modules when imported.

  • The module xoutil.string suffered a major reorganization due to ambiguity use of Strings in Python.

  • Create __crop__ protocol for small string representations, see xoutil.clipping.crop() for more information.

    Because clipping module is still experimental, definitive names of operator and main function must be validated before it could be considered definitive. Proposals are: “crop”, “small”, “short”, “compact”, “abbr”.

  • Remove xoutil.connote that was introduced provisionally in 1.7.1.

  • Module xoutil.params was introduced provisionally in 1.7.1, but now has been fully recovered.

    • Add function issue_9137() – Helper to fix issue 9137 (self ambiguity).
    • Add function check_count() – Checker for positional arguments actual count against constrains.
    • Add function check_default() – Default value getter when passed as a last excess positional argument.
    • Add function single() – Return true only when a unique argument is given.
    • Add function xoutil.params.keywords_only – Decorator to make a function to accepts its keywords arguments as keywords-only.
    • Add function pop_keyword_arg() – Tool to get a value from keyword arguments using several possible names.
    • Add class ParamManager – Parameter manager in a “smart” way.
    • Add class ParamScheme – Parameter scheme definition for a manager.
    • Add class ParamSchemeRow – Parameter scheme complement.
    • Remove xoutil.params.ParamConformer.
  • Module xoutil.values was recovered adding several new features (old name was deprecated).

  • Add experimental module xoutil.fp for Functional Programming stuffs.

  • Add experimental module xoutil.tasking.

  • Add xoutil.symbols. It replaces xoutil.logical that was introduced in 1.7.0, but never documented.

  • Remove deprecated module Add xoutil.objects.adapt_exception().

  • Remove deprecated xoutil.dim.meta.Signature.isunit().

1.7 series

2017-10-31. Release 1.7.12

  • xoutil.datetime.EmptyTimeSpan is now pickable.

2017-10-05. 1.7.11

  • Fix bug #9: TimeSpans are not hashable.

2017-09-21. 1.7.10

  • Fix bug #6: TimeSpan.overlaps was incorrectly defined.
  • Fix bug #5: TimeSpan can’t have a union method.

2017-09-20. 1.7.9

  • Deprecate xoutil.dim.meta.Signature.isunit().
  • Rename xoutil.dim.meta.QuantityType to xoutil.dim.meta.Dimension.
  • Fix bug in xoutil.datetime.TimeSpan. start_date and end_date now return an instance of Python’s instead of a sub-class.

2017-09-19. 1.7.8

  • Added module xoutil.dim – Facilities to work with concrete numbers.

2017-09-07. 1.7.7

  • Fixed bug in that prevented to use strftime() in subclasses.
  • Fixed bug in xoutil.datetime.TimeSpan.valid().

2017-09-05. Release 1.7.6

  • Fix a bug in xoutil.datetime.TimeSpan for Python 2. Representing a time span might fail with a ‘Maximum Recursion Detected’ error.

2017-09-05. Release 1.7.5

  • Added xoutil.datetime.TimeSpan.
  • Added the module xoutil.infinity.
  • Added the keyword argument on_error to xoutil.bound.until_errors().

2017-04-06. Release 1.7.4

  • Added the argument key to xoutil.iterators.delete_duplicates().
  • Added the function xoutil.iterators.iter_delete_duplicates().

2017-02-23. Release 1.7.3

  • Add xoutil.iterators.ungroup().
  • Add xoutil.future.datetime.get_next_month().

2017-02-07. Release 1.7.2

  • Add xoutil.bound.until() and xoutil.bound.until_errors().
  • Fix issue that made xoutil.uuid unusable. Introduced in version 1.7.1, commit 58eb359.
  • Remove support for Python 3.1 and Python 3.2.

2015-12-17. Release 1.7.1

  • Add xoutil.collections.PascalSet and xoutil.collections.BitPascalSet.
  • Add xoutil.functools.lwraps().
  • Add xoutil.objects.multi_getter(), xoutil.objects.get_branch_subclasses(), xoutil.objects.fix_method_documentation().
  • Add xoutil.string.safe_str()
  • Remove long deprecated modules: xoutil.aop and xoutil.proxy.
  • Deprecate xoutil.html entirely.
  • The following modules are included on a provisional basis. Backwards incompatible changes (up to and including removal of the module) may occur if deemed necessary by the core developers:
    • xoutil.connote.
    • xoutil.params.

Fixes in 1.7.1.post1:

  • Fix issue with both xoutil.string.safe_decode() and xoutil.string.safe_encode().

    Previously, the parameter encoding could contain an invalid encoding name and the function could fail.

Fixes in 1.7.1.post2:

  • Fix xoutil.string.cut_suffix(). The following invariant was being violated:

    >>> cut_suffix(v, '') == v  # for any value of 'v'


Due to lack of time, we have decided to release this version without proper releases of 1.7.0 and 1.6.11.

Unreleased. Release 1.7.0

This release was mainly focused in providing a new starting point for several other changes. This release is being synchronized with the last release of the 1.6.11 to allow deprecation messages to be included properly.

The following is the list of changes:

  • The defaults xoutil.objects.smart_copy() has being made keyword only.
  • Deprecates the pop() semantics, they shadow the dict.pop(). A new pop_level() is provided to explicitly pop a stack level. The same is done for the pop() method.
  • Deprecates function xoutil.iterators.fake_dict_iteritems.
  • Deprecates xoutil.objects.metaclass in favor for xoutil.eight.meta.metaclass().

1.6 series

Unreleased. Release 1.6.11

This is the last release of the 1.6 series. It’s being synchronized with release 1.7.0 to deprecate here what’s being changed there.

  • The defaults argument of xoutil.objects.smart_copy() is marked to be keyword-only in version 1.7.0.
  • Fixes a bug in xoutil.objects.smart_copy(). If defaults was None is was not being treated the same as being False, as documented. This bug was also fixed in version 1.7.0.
  • xoutil.objects.metaclass() will be moved to xoutil.eight.meta in version 1.7.0 and deprecated, it will be removed from xoutil.object in version 1.7.1.
  • This release will be the last to support Python 3.1, 3.2 and 3.3. Support will be kept for Python 2.7 and Python 3.4.

2015-04-15. Release 1.6.10

  • Fix repr() and str() issues with xoutil.cli.Command instances.

2015-04-03. Release 1.6.9

  • The defaults argument in xoutil.objects.smart_copy() is now keyword-only.
  • xoutil.context is now greenlet-safe without depending of gevent.

2015-01-26. Release 1.6.8

  • Added xoutil.records.date_reader().
  • Added a forward-compatible xoutil.inspect.getfullargspec.
  • Now contexts will support gevent-locals if available. See the note in the module documentation.
  • Minor fixes.

2014-12-17. Release 1.6.7

  • Added the strict argument to xoutil.records.datetime_reader().

  • You may now install xoutil[extra] so that not required but useful packages are installed when xoutil is installed.

    For now this only includes python-dateutil that allows the change in datetime_reader().

2014-11-26. Release 1.6.6

  • Improved the xoutil.string.normalize_slug() by providing both valid and invalid chars.
  • Added the xoutil.string.normalize_ascii().

2014-10-13. Release 1.6.5

  • Added the module xoutil.records.

  • Deleted deprecated xoutil.compat.

  • Deprecate the xoutil.six. It will removed in 1.7.0 (probably next release).

    Now xoutil requires six 1.8.0.

2014-09-13. Release 1.6.4

  • Fix bug in xoutil.fs.concatfiles(): There were leaked opened files.

2014-08-05. Release 1.6.3

  • Added the pre-release version of xoutil.bound module.

2014-08-04. Release 1.6.2

  • Fix encoding issues in xoutil.string.cut_prefix() and xoutil.string.cut_suffix().

    Previously this code failed:

    >>> from xoutil.string import cut_prefix
    >>> cut_prefix(u'-\xe1', '-')
    Traceback ...
    UnicodeEncodeError: 'ascii' ...

    Now both functions force its second argument to be of the same type of the first. See xoutil.string.safe_decode() and xoutil.string.safe_encode().

2014-07-18. Release 1.6.1

  • Added the yield parameter in xoutil.fs.ensure_filename().
  • Added the base parameter in xoutil.modules.moduleproperty().
  • Added the function xoutil.fs.concatfiles().

2014-06-02. Release 1.6.0

  • Changes the signature of xoutil.names.nameof(), also the semantics of the full parameter is improved.

    This is the major change in this release. Actually, this release has being prepared in sync with the release 1.5.6 (just a few days ago) to have this change passed while still keeping our versions scheme.

1.5 series

2014-05-29. Release 1.5.6

  • Warn about a future backwards incompatible change in the behavior of xoutil.names.nameof().

2014-05-13. Release 1.5.5

  • UserList are now collections in the sense of xoutil.types.is_collection().

  • Python 3.4 added to the list of tested Python environments. Notice this does not makes any warrants about identical behavior of things that were previously backported from Python 3.3.

    For instance, the xoutil.collections.ChainMap has been already backported from Python 3.4, so it will have the same signature and behavior across all supported Python versions.

    But other new things in Python 3.4 are not yet backported to xoutil.

  • Now xoutil.objects.metaclass() supports the __prepare__ classmethod of metaclasses. This is fully supported in Python 3.0+ and partially mocked in Python 2.7.

  • Backported xoutil.types.MappingProxyType from Python 3.3.

  • Backported xoutil.types.SimpleNamespace from Python 3.4.

  • Backported xoutil.types.DynamicClassAttribute from Python 3.4

  • Added function xoutil.iterators.delete_duplicates().

  • Added parameter ignore_underscore to xoutil.string.normalize_slug().

  • Added module xoutil.crypto with a function for generating passwords.

  • Fixed several bug in xoutil.functools.compose().

  • Makes xoutil.fs.path.rtrim() have a default value for the amount of step to traverse.

2014-04-08. Release 1.5.4

  • Fix a bug in xoutil.objects.extract_attrs(). It was not raising exceptions when some attribute was not found and default was not provided.

    Also now the function supports paths like xoutil.objects.get_traverser().

  • xoutil contains now a copy of the excellent project six exported as xoutil.six (not documented here). Thus the compatibility module xoutil.compat is now deprecated and will removed in the future.

    There are some things that xoutil.compat has that xoutil.six does not. For instance, six does not include fine grained python version markers. So if your code depends not on Python 3 v Python 2 dichotomy but on features introduced in Python 3.2 you must use the sys.version_info directly.

    Notwithstanding that, xoutil will slowly backport several Python 3.3 standard library features to Python 2.7 so that they are consistently used in any Python up to 2.7 (but 3.0).

2014-04-01. Release 1.5.3

  • Now xoutil supports Python 2.7, and 3.1+. Python 3.0 was not tested.

  • Added a strict parameter to xoutil.objects.smart_getter().

  • New function xoutil.objects.get_traverser().

  • The function prefers its default parameter instead of the application’s default command.

    Allow the xoutil.cli.Command to define a command_cli_name to change the name of the command. See

2014-03-03. Release 1.5.2

  • Deprecated function xoutil.objects.get_and_del_key(). Use the dict.pop() directly.

    To have consistent naming, renamed get_and_del_attr() and get_and_del_first_of() to popattr() and pop_first_of(). Old names are left as deprecated aliases.

  • Now xoutil.functools.update_wrapper(), xoutil.functools.wraps() and xoutil.functools.lru_cache() are Python 3.3 backports (or aliases).

  • New module xoutil.textwrap.

2014-02-14. Release 1.5.1

  • Added functions xoutil.objects.dict_merge(), xoutil.types.are_instances() and xoutil.types.no_instances().
  • Deprecated function xoutil.objects.smart_getattr(). Use xoutil.objects.get_first_of() instead.

2014-01-24. Release 1.5.0

  • Lots of removals. Practically all deprecated since 1.4.0 (or before). Let’s list a few but not all:
    • Both xoutil.Unset and xoutil.Ignored are no longer re-exported in xoutil.types.
    • Removes module xoutil.decorator.compat, since it only contained the deprecated decorator xoutil.decorator.compat.metaclass() in favor of xoutil.objects.metaclass().
    • Removes nameof and full_nameof from xoutil.objects in favor of xoutil.names.nameof().
    • Removes pow_ alias of xoutil.functools.power().
    • Removes the deprecated xoutil.decorator.decorator function. Use xoutil.decorator.meta.decorator() instead.
    • Now get_module_path() is documented and in module xoutil.modules.
  • Also we have documented a few more functions, including xoutil.fs.path.rtrim().
  • All modules below xoutil.aop are in risk and are being deprecated.

1.4 series

  • Adds xoutil.datetime.daterange().

  • Adds xoutil.objects.traverse().

  • Adds xoutil.fs.makedirs() and xoutil.fs.ensure_filename().

  • The fill argument in function xoutil.iterators.slides() now defaults to None. This is consistent with the intended usage of Unset and with the semantics of both xoutil.iterators.continuously_slides() and xoutil.iterators.first_n().

    Unset, as a default value for parameters, is meant to signify the absence of an argument and thus only would be valid if an absent argument had some kind of effect different from passing the argument.

  • Changes xoutil.modules.customize() API to separate options from custom attributes.

  • Includes a random parameter to xoutil.uuid.uuid().

  • Deprecations and introductions:
    • Importing xoutil.Unset and xoutil.Ignored from xoutil.types now issues a warning.
    • New style for declaring portable metaclasses in xoutil.objects.metaclass(), so xoutil.decorator.compat.metaclass() is now deprecated.
    • Adds the module xoutil.pprint and function xoutil.pprint.ppformat().
    • Adds the first version of package xoutil.cli.
    • Adds the filter parameter to functions xoutil.objects.xdir() and xoutil.objects.fdir() and deprecates attr_filter and value_filter.
    • Adds functions xoutil.objects.attrclass(), xoutil.objects.fulldir().
    • Adds function xoutil.iterators.continuously_slides().
    • Adds package xoutil.threading.
    • Adds package xoutil.html module and begins the port of xoutil.html.parser from Python 3.3 to xoutil, so that a common implementation for both Python 2.7 and Python 3.3 is available.
  • Bug fixes:
    • Fixes some errors with classical AOP weaving of functions in modules that where customized.
    • Fixes bugs with xoutil.modules: makes xoutil.modules.modulemethod() to customize the module, and improves performance.

2013-04-26. Release 1.4.0

  • Refactors xoutil.types as explained in types-140-refactor.
  • Changes involving xoutil.collections:
    • Moves SmartDict and SortedSmartDict from to xoutil.collections. They are still accessible from
    • Also there is now a xoutil.collections.SmartDictMixin that implements the update behind all smart dicts in xoutil.
    • xoutil.collections.StackedDict in now a SmartDict and thus gains zero-level initialization data.
  • Removals of deprecated, poorly tested, or incomplete features:
    • Removes deprecated xoutil.decorators. Use xoutil.decorator.
    • Removed xoutil.iterators.first(), and xoutil.iterators.get_first().
    • Removed xoutil.string.names(), xoutil.string.normalize_to_str() and xoutil.string.normalize_str_collection().
  • Newly deprecated functions:
    • Deprecates xoutil.iterators.obtain().
    • Deprecates xoutil.iterators.smart_dict() and in favor of xoutil.objects.smart_copy().
  • New features:
    • Introduces xoutil.iterators.first_non_null().
    • Adds xoutil.objects.copy_class() and updates xoutil.decorator.compat.metaclass() to use it.
  • Fixes a bug with xoutil.deprecation.deprecated() when used with classes: It changed the hierarchy and provoked infinite recursion in methods that use super.

1.3 series

  • Removes deprecated module xoutil.mdeco.

  • xoutil.context.Context now inherit from the newly created stacked dict class xoutil.collections.StackedDict. Whenever you enter a context a new level of the stacked dict is pushed, when you leave the context a level is <xoutil.collections.StackedDict.pop>`:meth:.

    This also removes the data attribute execution context used to have, and, therefore, this is an incompatible change.

  • Introduces xoutil.collections.OpenDictMixin and xoutil.collections.StackedDict.

  • Fixes a bug in xoutil.decorator.compat.metaclass(): Slots were not properly handed.

  • Fixes a bug with the simple xoutil.collections.opendict that allowed to shadow methods (even __getitem__) thus making the dict unusable.

1.2 series

2013-04-03. Release 1.2.3

  • Bug fixes in xoutil.proxy and xoutil.aop.classical.

2013-03-25. Release 1.2.2

  • Adds xoutil.bases - Implementations of base 32 and base 64 (numeric) representations.

2013-02-14. Release 1.2.1

  • Loads of improvements for Python 3k compatibility: Several modules were fixed or adapted to work on both Python 2.7 and Python 3.2. They include (but we might have forgotten some):
    • xoutil.context.
    • xoutil.aop.basic.
    • xoutil.deprecation.
    • xoutil.proxy.
  • Rescued xoutil.annotate and is going to be supported from now on.
  • Introduced module xoutil.subprocess and function xoutil.subprocess.call_and_check_output().
  • Introduced module xoutil.decorator.compat that enables constructions that are interoperable in Python 2 and Python 3.
  • Introduced, xoutil.iterators.izip(),, and xoutil.iterators.imap().

2013-01-04. Release 1.2.0

This is the first of the 1.2.0 series. It’s been given a bump in the minor version number because we’ve removed some deprecated functions and/or modules.

  • Several enhancements to xoutil.string to make it work on Python 2.7 and Python 3.2.

    Deprecates xoutil.string.normalize_to_str() in favor of the newly created xoutil.string.force_str() which is Python 3 friendly.

  • Backwards incompatible changes in xoutil.objects API. For instance, replaces getattr parameter with getter in xoutil.objects.xdir() and co.

  • Extracts decorator-making facilities from xoutil.decorators into xoutil.mdeco.

  • Fixes in xoutil.aop.extended. Added parameters in xoutil.aop.classical.weave().

  • Introduces xoutil.iterators.first_n() and deprecates xoutil.iterators.first() and xoutil.iterators.get_first().

  • Removes the zope.interface awareness from xoutil.context since it contained a very hard to catch bug. Furthermore, this was included to help the implementation of xotl.ql, and it’s no longer used there.

    This breaks version control policy since it was not deprecated beforehand, but we feel it’s needed to avoid spreading this bug.

  • Removed long-standing deprecated modules xoutil.default_dict, xoutil.memoize and xoutil.opendict.

  • Fixes bug in xoutil.datetime.strfdelta(). It used to show things like ‘1h 62min’.

  • Introduces xoutil.compat.class_type that holds class types for Python 2 or Python 3.

1.1 series

2012-11-01. Release 1.1.4

  • Introduces xoutil.compat.iteritems_(), xoutil.compat.iterkeys_() and xoutil.compat.itervalues_().
  • execution context are now aware of zope.interface interfaces; so that you may ask for a context name implementing a given interface, instead of the name itself.
  • Improves xoutil.formatter documentation.
  • Several fixes to xoutil.aop.classical. It has sudden backwards incompatible changes.
  • before and after methods may use the *args, **kwargs idiom to get the passed arguments of the weaved method.
  • Several minor fixes: Invalid warning about Unset not in xoutil.types

2012-08-22. Release 1.1.3

  • Adds function xoutil.fs.rmdirs() that removes empty dirs.
  • Adds functions xoutil.string.safe_join(), xoutil.string.safe_encode(), xoutil.string.safe_decode(), and xoutil.string.safe_strip(); and the class xoutil.string.SafeFormatter.
  • Adds function xoutil.cpystack.iter_frames().

2012-07-11. Release 1.1.2

  • Fixes all copyrights notices and chooses the PSF License for Python 3.2.3 as the license model for xoutil releases.
  • All releases from now on will be publicly available at github.

2012-07-06. Release 1.1.1

  • Improves deprecation warnings by pointing to the real calling filename
  • Removes all internal use of simple_memoize since it’s deprecated. We now use lru_cache().

2012-07-03. Release 1.1.0

  • Created the whole documentation Sphinx directory.
  • Removed xoutil.future since it was not properly tested.
  • Removed xoutil.annotate, since it’s not portable across Python’s VMs.
  • Introduced module xoutil.collections
  • Deprecated modules xoutil.default_dict, xoutil.opendict in favor of xoutil.collections.
  • Backported xoutil.functools.lru_cache() from Python 3.2.
  • Deprecated module xoutil.memoize in favor of xoutil.functools.lru_cache().

1.0 series

2012-06-15. Release 1.0.30

  • Introduces a new module :py`xoutil.proxy`:mod:.
  • Starts working on the sphinx documentation so that we move to 1.1 release we a decent documentation.

2012-06-01. Release 1.0.29.

  • Introduces xoutil.iterators.slides and xoutil.aop.basic.contextualized

2012-05-28. Release 1.0.28.

  • Fixes normalize path and other details
  • Makes validate_attrs to work with mappings as well as objects
  • Improves complementors to use classes as a special case of sources
  • Simplifies importing of legacy modules
  • PEP8

2012-05-22. Release 1.0.27.

  • Removes bugs that were not checked (tested) in the previous release.

2012-05-21. Release 1.0.26.

  • Changes in AOP classic. Now you have to rename after, before and around methods to _after, _before and _around.

    It is expected that the signature of those methods change in the future.

  • Introducing a default argument for xoutil.objects.get_first_of().

  • Other minor additions in the code. Refactoring and the like.

2012-04-30. Release 1.0.25.

  • Extends the classical AOP approach to modules. Implements an extended version with hooks.
  • Makes classical/extended AOP more reliable to TypeError’s in getattr. xoonko, may raise TypeError’s for TranslatableFields.

2012-04-27. Release 1.0.24.

  • Introduces a classical AOP implementation: xoutil.aop.classical.

2012-04-10. Release 1.0.23.

  • Introduces decorators: xoutil.decorators.instantiate and xoutil.aop.complementor

2012-04-05. Release 1.0.22

  • Allows annotation’s expressions to use defined local variables. Before this release the following code raised an error:

    >>> from xoutil.annotate import annotate
    >>> x1 = 1
    >>> @annotation('(a: x1)')
    ... def dummy():
    ...     pass
    Traceback (most recent call last):
    NameError: global name 'x1' is not defined
  • Fixes decorators to allow args-less decorators

2012-04-03. Release 1.0.21

  • Includes a new module xoutil.annotate that provides a way to place Python annotations in forward-compatible way.