commit:     e17edfac6eeb227147395d691f997946a047bc07
Author:     Brian Harring <ferringb <AT> gmail <DOT> com>
AuthorDate: Sun Dec 14 17:38:18 2025 +0000
Commit:     Brian Harring <ferringb <AT> gmail <DOT> com>
CommitDate: Mon Dec 15 12:42:10 2025 +0000
URL:        
https://gitweb.gentoo.org/proj/pkgcore/snakeoil.git/commit/?id=e17edfac

Update news for the initial new functions that were added.

This should be all of them.  It doesn't cover the classes however,
which will be addressed next.

Signed-off-by: Brian Harring <ferringb <AT> gmail.com>

 NEWS.rst | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 74 insertions(+), 1 deletion(-)

diff --git a/NEWS.rst b/NEWS.rst
index f1125ec..401f929 100644
--- a/NEWS.rst
+++ b/NEWS.rst
@@ -9,6 +9,79 @@ snakeoil 0.11.0 (unreleased)
 
 - pytest-subtests ~= 0.15.0 is now a dependency for tests.
 
+Features
+~~~~~~~~~
+
+- ``snakeoil.delayed.regexp``: modern replacement for `demand_compile_regexp`.
+  This takes the standard re.compile arguments and delays creation of the 
regex until it's
+  accessed.
+
+- ``snakeoil.klass.abstractclassvar``: mechanism to force python's ``abc.ABC`` 
to treat a subclass as still abstract if a class variable hasn't been set.
+  The usage is unfortunately not purely an annotation due to how ``abc.ABC`` 
is implemented, but can be used like this:: python
+
+    class Base(abc.ABC):
+      must_be_defined: ClassVar[str] = abstractclassvar(str)
+
+    class StillABC(Base):
+      "this class is still abstract, thus cannot be instantiatied until 
must_be_defined"
+      pass
+
+    class NoLongerABC(StillABC):
+      "Do to the class var definition, this class can now be instantiated"
+      must_be_defined = "now defined"
+
+- ``snakeoil.klass.combine_metaclasses``: mildly esoteric functionality for 
combining two metaclasses into one inherited chain of types.
+  This is a convenience function; for example, it's used for combining 
``abc.ABC`` with ``WeakInstMeta``.
+
+- ``snakeoil.klass.copy_class_docs``: given a source class, transfer the 
documentation from that to the target class.
+  This is a convenience tool for when implementing non trivial 'shape' of 
another class that you can't inherit from.
+
+  Use this when you're implementing the shape of a class, but for whatever 
reason, cannot inherit from it.  Multiple implementations
+  in ``snakeoil.sequences`` and ``snakeoil.mappings`` implement the same api 
as things like ``set``- this is used for just transferring
+  the better documentation from the source class and injecting it into the 
target class.
+
+- ``snakeoil.klass.copy_docs``: this is for transferring the documentation 
between functions.
+  This may seem like duplication of ``functools.wraps``, but ``wraps`` does 
further mutations to the function that other tooling is
+  aware of.  ``copy_docs`` shouldn't be used for wrapping; it's for when 
you're implementing the same function in a different way, but
+  matching the API exactly.
+
+- ``snakeoil.klass.get_attrs_of``: Slots aware tool to do what ``vars()`` 
should.
+  Python's ``vars()`` only uses the `__dict__` of the object; it *cannot* 
return any slotted attribute unless something incorrect has occurred like a 
slot shadowing.
+
+  TL;dr: use this instead of `vars()`.  The only scenario it cannot find an 
attribute to return is if a class defined it's `__slots__` with a raw iterator, 
which is a misfeature of python and should never be used.
+
+- ``snakeoil.klass.get_instances_of``: Find every visitable instance of a 
given class.
+  This should be mostly used in tests, or in very specific scenarios where a 
registry pattern exists, but a proper registry hasn't been implemented.
+  For example in pkgcheck, there is no registry of checks- it has to scan for 
any derivative of a class to find it.  This is the instance version of that.
+
+  Note: this is a walk of the GC.  It's not cheap.  It cannot see instances 
only exist in `intern()`, nor can it see instances that are held by compiled 
extensions that do not participate in visit protocol.  Those extensions are 
broke, as a general rule.
+
+- ``snakeoil.klass.get_slot_of``: Helper function to extract slotting 
information of a class- just that layer of the class.
+- ``snakeoil.klass.get_slots_of``: Helper function to extract slotting 
information of the entire MRO of that class.
+- ``snakeoil.klass.get_subclasses_of``: Helper function to find all subclasses 
of a given class whilst optionally filtering out ``abc.ABC``.
+  The main usage of this is for pseudo registry implementations (which should 
implement the registry pattern instead), and for tests asserting certain code 
standards against a codebase.
+
+- ``snakeoil.klass.is_metaclass``: This is a version of 
``isinstance(something, type)`` that is able to see through ``proxy`` style 
objects that try to lie about what class they actually are.
+
+- ``snakeoil.python_namespaces.get_submodules_of``: Given a python import path 
or module, this will import and return all modules beneath that point in the 
namespace.
+  Use this rather than trying to implement it yourself; this accounts for all 
python extensions.
+
+- ``snakeoil.python_namespaces.import_module_from_path``: As it sounds, import 
python source from a given path returning that module.
+  The typical pattern people use is to manipulate ``sys.path`` temporarily 
which is *not* thread safe, and it pollutes ``sys.modules``.  This is the 
correct way to do an arbitrary import of something that isn't in a proper 
python namespace.
+
+- ``snakeoil.python_namespaces.import_submodules_of``: Convience function 
built around ``get_submodules_of``.  If you need to ensure some given python 
namespace has been imported- everything possible in it- this will do it in a 
one shot.
+- ``snakeoil.python_namespaces.protect_imports``:  None thread safe context 
manager allowing temporary ``sys.path`` and ``sys.modules`` manipulation, 
restoring it when it exits the context.
+  Do not use this in anything other than tests.  If you must import arbitrary 
source that isn't a python namespace during runtime, use 
``import_module_from_path``
+
+- ``snakeoil.python_namespaces.remove_py_extension``: Function to strip the 
suffix off a python source filename whilst accounting for issues of PEP3147.
+  Cpython allows both ``lib.cpython-311.so`` and ``lib.so`` as importable.  
This uses will properly strip either down to ``lib``.
+
+- ``snakeoil.sequences.unique_stable``.  This is a modernized 
``snakeoil.sequences.stable_unique``.
+  This requires all items to be hashable.  Given an iterable, it will remove 
duplicates while preserving the ordering items were first seen.
+
+  Via requiring items be hashable, this removes the quadratic fallback of 
``stable_unique`` for non hashable items.
+
+
 API deprecations
 ~~~~~~~~~~~~~~~~~~~
 - snakeoil.bash.iter_read_bash: Will be removed in 0.12.0
@@ -111,7 +184,7 @@ API removals
 - class.sequences.ChainedLists
 - class snakeoil.tar.TarInfo
 - module snakeoil.weakrefs
-
+ 
 snakeoil 0.10.11 (2025-05-31)
 -----------------------------
 

Reply via email to