Skip to main content

Binder License Coverage Status Documentation Status

Anaconda Last Updated Platform Downloads

pyiron_snippets

This is a collection of independent python snippets which we in the pyiron project find generically useful.

To qualify for inclusion, a snippet must not have any dependencies outside the python standard library, and should fit reasonably inside a single file.

(Note that the tests may have non-standard dependencies, e.g. to ensure the snippets work in various edge cases we care about, but the actual snippets themselves must be able to behave well in a clean environment.)

Summary

Note that each snippet may have more functionality than shown in this readme -- taking a look at the source code and test suite is the best way to get an exhaustive sense of their capability -- but these examples will give you a sense of when each snippet is useful.

Colors

Just a shortcut to the seaborn.color_palette() of colors in hex:

>>> from pyiron_snippets import colors
>>> colors.SeabornColors.white
'#ffffff'

Deprecate

Easily indicate that some functionality is being deprecated

>>> from pyiron_snippets import deprecate
>>>
>>> @deprecate.deprecate(message="Use `bar(a, b)` instead", version="0.5.0")
... def foo(a, b):
...     pass
>>> 
>>> foo(1, 2)

Raises a warning like DeprecationWarning: __main__.foo is deprecated: Use bar(a, b) instead. It is not guaranteed to be in service in vers. 0.5.0 foo(1, 2)

Directory context

A context manager that changes the current working directory to the given path upon entering the context and reverts to the original directory upon exiting. If the specified path does not exist, it is created.

>>> import os
>>> from pyiron_snippets.directory_context import set_directory
>>> directory_before_context_is_applied = os.getcwd()
>>> with set_directory("tmp"):
...     os.path.relpath(os.getcwd(), directory_before_context_is_applied)
'tmp'

DotDict

A dictionary that allows dot-access. Has .items() etc.

>>> from pyiron_snippets import dotdict
>>>
>>> d = dotdict.DotDict({"a": 1})
>>> d.b = 2
>>> print(d.a, d.b)
1 2

Exception context

A variant of contextlib.ExitStack that only executes registered callbacks when an exception is raised, and only if that exception matches one of the specified exception types (or any exception, if types are not specified).

>>> from pyiron_snippets import exception_context
>>>
>>> def its_historical(history: list[str], message: str) -> None:
...     history.append(message)
>>>
>>> history = []
>>> try:
...     with exception_context.ExceptionExitStack(RuntimeError) as stack:
...         _ = stack.callback(its_historical, history, "with matching type")
...         raise RuntimeError("Application error")
... except RuntimeError:
...     history
['with matching type']

>>> history = []
>>> try:
...     with exception_context.ExceptionExitStack(TypeError, ValueError) as stack:
...         _ = stack.callback(its_historical, history, "with mis-matching types")
...         raise RuntimeError("Application error")
... except RuntimeError:
...     history
[]

The module also provides a wrapper, on_error, which provides a more compact interface if you only have a single callback function (as in the examples above):

>>> from pyiron_snippets import exception_context
>>>
>>> def its_historical(history: list[str], message: str) -> None:
...     history.append(message)
>>>
>>> history = []
>>>
>>> try:
...     with exception_context.on_error(
...         its_historical, 
...         RuntimeError, 
...         history,
...         "a more compact single-callback interface",
...     ):
...         raise RuntimeError("Application")
... except RuntimeError:
...     history
['a more compact single-callback interface']

Factory

Make dynamic classes that are still pickle-able

>>> from abc import ABC
>>> import pickle
>>>
>>> from pyiron_snippets import factory
>>>
>>> class HasN(ABC):
...     '''Some class I want to make dynamically subclass.'''
...     def __init_subclass__(cls, /, n=0, s="foo", **kwargs):
...         super(HasN, cls).__init_subclass__(**kwargs)
...         cls.n = n
...         cls.s = s
...
...     def __init__(self, x, y=0):
...         self.x = x
...         self.y = y
>>>
>>> @factory.classfactory
... def has_n_factory(n, s="wrapped_function", /):
...     return (
...         f"{HasN.__name__}{n}{s}",  # New class name
...         (HasN, ),  # Base class(es)
...         {},  # Class attributes dictionary
...         {"n": n, "s": s}
...  # dict of `builtins.type` kwargs (passed to `__init_subclass__`)
...     )
>>>
>>> Has2 = has_n_factory(2, "my_dynamic_class")
>>>
>>> foo = Has2(42, y=-1)
>>> print(foo.n, foo.s, foo.x, foo.y)
2 my_dynamic_class 42 -1
>>> reloaded = pickle.loads(pickle.dumps(foo))  # doctest: +SKIP
>>> print(reloaded.n, reloaded.s, reloaded.x, reloaded.y)  # doctest: +SKIP
2 my_dynamic_class 42 -1  # doctest: +SKIP

(Pickle doesn't play well with testing the docs -- you can't run pickle.dumps(pickle.loads(5)) either!)

Files

Shortcuts for filesystem manipulation

>>> from pyiron_snippets import files
>>>
>>> d = files.DirectoryObject("some_dir")
>>> d.dump(content="Some content", file_name="my_filename.txt")
PosixPath('some_dir/my_filename.txt')
>>> d.file_exists("my_filename.txt")
True
>>> d.delete()

Has post

A meta-class introducing a __post__ dunder which runs after the __init__ of everything in the MRO.

>>> from pyiron_snippets import has_post
>>>
>>> class Foo(metaclass=has_post.HasPost):
...     def __init__(self, x=0):
...         self.x = x
...         print(f"Foo.__init__: x = {self.x}")
>>>
>>> class Bar(Foo):
...     def __init__(self, x=0, post_extra=2):
...         super().__init__(x)
...         self.x += 1
...         print(f"Bar.__init__: x = {self.x}")
...
...     def __post__(self, *args, post_extra=2, **kwargs):
...         self.x += post_extra
...         print(f"Bar.__post__: x = {self.x}")
>>>
>>> Bar().x
Foo.__init__: x = 0
Bar.__init__: x = 1
Bar.__post__: x = 3
3

Honestly, try thinking if there's another way to solve your problem; this is a dark magic.

Import alarm

Fail gracefully when optional dependencies are missing for (optional) functionality.

>>> from pyiron_snippets import import_alarm
>>>
>>> with import_alarm.ImportAlarm(
...     "Some functionality unavailable: `magic` dependency missing"
... ) as my_magic_alarm:
...     import magic
>>>
>>> with import_alarm.ImportAlarm("This warning won't show up") as datetime_alarm:
...     import datetime
>>>
>>> class Foo:
...     @my_magic_alarm
...     @datetime_alarm
...     def __init__(self, x):
...         self.x = x
...
...     @property
...     def magical(self):
...         return magic.method(self.x)
...
...     def a_space_odyssey(self):
...         print(datetime.date(2001, 1, 1))
>>>
>>> foo = Foo(0)
>>>  # Raises a warning re `magic` (since that does not exist)
>>>  # but not re `datetime` (since it does and we certainly have it)
>>> foo.a_space_odyssey()
2001-01-01

>>> try:
...     foo.magical(0)
... except NameError as e:
...     print("ERROR:", e)
ERROR: name 'magic' is not defined

Logger

Configures the logger and writes to pyiron.log

Retrieve

Tools for retrieving objects from strings. Particularly useful when objects or references are serialized by reference to their library location.

>>> from pyiron_snippets import retrieve
>>> ThreadPoolExecutor = retrieve.import_from_string(
...     "concurrent.futures.ThreadPoolExecutor"
... )
>>> with ThreadPoolExecutor(max_workers=2) as executor:
...     future = executor.submit(pow, 2, 3)
...     print(future.result())
8

Includes an extra tool, get_importable_string_from_string_reduction for singleton-pattern string reductions.

Retry

If at first you don't succeed

>>> from time import time
>>>
>>> from pyiron_snippets import retry
>>>
>>> def at_most_three_seconds():
...     t = int(time())
...     if t % 3 != 0:
...         raise ValueError("Not yet!")
...     return t
>>>
>>> retry.retry(at_most_three_seconds, msg="Tried and failed...", error=ValueError) % 3
0

Depending on the system clock at invokation, this simple example may give warnings like UserWarning: Tried and failed... Trying again in 1.0s. Tried 1 times so far... up to two times.

Singleton

A metaclass for the singleton pattern.

>>> from pyiron_snippets import singleton
>>>
>>> class Foo(metaclass=singleton.Singleton):
...     pass
>>>
>>> foo1 = Foo()
>>> foo2 = Foo()
>>> foo1 is foo2
True

Versions

Tools for scraping the versions of python objects.

There are multiple public utilities, but the main entry point is a dataclass for finding the relevant module version of an arbitrary object (including an instance).

>>> from pyiron_snippets import versions
>>> 
>>> versions.VersionInfo.of(42)  # doctest: +ELLIPSIS
VersionInfo(module='builtins', qualname='int', version=...)

Metadata

Release files for pyiron-snippets 1.5.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyiron-snippets 1.5.1
File Size Uploaded Provenance Actions
pyiron_snippets-1.5.1.tar.gz 50.5 kB Without provenance Details for pyiron_snippets-1.5.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pyiron-snippets 1.5.1
File Interpreter ABI Platform Actions
pyiron_snippets-1.5.1-py3-none-any.whl Python 3 none any Details for pyiron_snippets-1.5.1-py3-none-any.whl

Total release size: 86.4 kB

Release files / pyiron_snippets-1.5.1.tar.gz

Download URL pyiron_snippets-1.5.1.tar.gz
Size 50.5 kB
Tags Source
SHA-256 checksum
How to use checksums
e7eb9d0495d58a422ca11c0a69fc4d25d3976dc598c47d1b3ecc4bb170efa14c
BLAKE2b-256 checksum
How to use checksums
26506f1ab1356369b34db31adfd8ea52f7963c0de0cf1d9b6334abd18a03fc09
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / pyiron_snippets-1.5.1-py3-none-any.whl

Download URL pyiron_snippets-1.5.1-py3-none-any.whl
Size 35.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ddd5840dbd96c411218b09abb953c2659292f64ec8c967874462fa6476d8c83d
BLAKE2b-256 checksum
How to use checksums
e92c02dcb89313e3277e35d8492743169dc6004d8a9bf9827f82c8f5c2fae1b7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Security for pyiron-snippets 1.5.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page