{"id":18084864,"url":"https://github.com/jwodder/morecontext","last_synced_at":"2025-04-12T20:10:09.137Z","repository":{"id":57443168,"uuid":"305384808","full_name":"jwodder/morecontext","owner":"jwodder","description":"Context managers for changing directory, setting attributes/envvars, etc.","archived":false,"fork":false,"pushed_at":"2025-01-23T14:38:56.000Z","size":78,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-28T23:35:39.036Z","etag":null,"topics":["available-on-pypi","chdir","context-managers","environ","envvar","monkeypatch","python","setenv","with"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jwodder.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-10-19T12:59:05.000Z","updated_at":"2025-01-23T14:38:59.000Z","dependencies_parsed_at":"2023-01-31T02:01:12.908Z","dependency_job_id":"b6ff83a1-1bdf-481f-8787-4e8c072be849","html_url":"https://github.com/jwodder/morecontext","commit_stats":{"total_commits":64,"total_committers":1,"mean_commits":64.0,"dds":0.0,"last_synced_commit":"ce1c44fc786677b354af56a6ee131823992d304d"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwodder%2Fmorecontext","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwodder%2Fmorecontext/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwodder%2Fmorecontext/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwodder%2Fmorecontext/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jwodder","download_url":"https://codeload.github.com/jwodder/morecontext/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248594191,"owners_count":21130316,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["available-on-pypi","chdir","context-managers","environ","envvar","monkeypatch","python","setenv","with"],"created_at":"2024-10-31T15:08:27.112Z","updated_at":"2025-04-12T20:10:09.115Z","avatar_url":"https://github.com/jwodder.png","language":"Python","readme":"|repostatus| |ci-status| |coverage| |pyversions| |license|\n\n.. |repostatus| image:: https://www.repostatus.org/badges/latest/active.svg\n    :target: https://www.repostatus.org/#active\n    :alt: Project Status: Active — The project has reached a stable, usable\n          state and is being actively developed.\n\n.. |ci-status| image:: https://github.com/jwodder/morecontext/actions/workflows/test.yml/badge.svg\n    :target: https://github.com/jwodder/morecontext/actions/workflows/test.yml\n    :alt: CI Status\n\n.. |coverage| image:: https://codecov.io/gh/jwodder/morecontext/branch/master/graph/badge.svg\n    :target: https://codecov.io/gh/jwodder/morecontext\n\n.. |pyversions| image:: https://img.shields.io/pypi/pyversions/morecontext.svg\n    :target: https://pypi.org/project/morecontext/\n\n.. |license| image:: https://img.shields.io/github/license/jwodder/morecontext.svg\n    :target: https://opensource.org/licenses/MIT\n    :alt: MIT License\n\n`GitHub \u003chttps://github.com/jwodder/morecontext\u003e`_\n| `PyPI \u003chttps://pypi.org/project/morecontext/\u003e`_\n| `Issues \u003chttps://github.com/jwodder/morecontext/issues\u003e`_\n| `Changelog \u003chttps://github.com/jwodder/morecontext/blob/master/CHANGELOG.md\u003e`_\n\n``morecontext`` provides context managers for some common minor operations:\nspecifically, changing the current working directory, an object's attribute, a\n``dict`` field, or an environment variable and then setting it back afterwards.\nSure, it's easy enough to implement these on your own, but why bother doing\nthat over \u0026 over again when you can let this package do it for you once?\n\nType annotated!  Fully tested!\n\n\nInstallation\n============\n``morecontext`` requires Python 3.8 or higher.  Just use `pip\n\u003chttps://pip.pypa.io\u003e`_ for Python 3 (You have pip, right?) to install\n``morecontext``::\n\n    python3 -m pip install morecontext\n\n\nExamples\n========\n\n\u003e\u003e\u003e import os\n\u003e\u003e\u003e import morecontext\n\u003e\u003e\u003e os.getcwd()\n'/some/dir'\n\u003e\u003e\u003e with morecontext.dirchanged('/some/other/dir'):\n...     # Now we're in /some/other/dir\n...     os.getcwd()\n...\n'/some/other/dir'\n\u003e\u003e\u003e # Out of the `with`, back to /some/dir\n\u003e\u003e\u003e os.getcwd()\n'/some/dir'\n\n\u003e\u003e\u003e d = {\"foo\": 42}\n\u003e\u003e\u003e with morecontext.itemset(d, \"foo\", \"bar\"):\n...     # d[\"foo\"] == \"bar\" in here\n...     d[\"foo\"]\n...     # If we change d[\"foo\"] in here, it'll still be set back to 42 on exit\n...     d[\"foo\"] = 3.14\n...\n'bar'\n\u003e\u003e\u003e # Out of the `with`, it's back to 42\n\u003e\u003e\u003e d[\"foo\"]\n42\n\n\nAPI\n===\n\nFunctions\n---------\n\nAll of the following context manager functions are defined with\n``contextlib.contextmanager``, so they can be used as function decorators as\nwell.  They also all return ``None`` on entry, so there's no point in writing\n\"``with dirchanged(path) as foo:``\"; just do \"``with dirchanged(path):``\".\n\nThese functions are not thread-safe.\n\n.. code:: python\n\n    dirchanged(dirpath: Union[str, bytes, os.PathLike]) -\u003e ContextManager[None]\n\nTemporarily change the current working directory.\n\n``dirchanged(dirpath)`` returns a context manager.  On entry, it stores the\ncurrent working directory path and then changes the current directory to\n``dirpath``.  On exit, it changes the current directory back to the stored\npath.\n\n.. code:: python\n\n    dirrollback() -\u003e ContextManager[None]\n\nSave \u0026 restore the current working directory.\n\n``dirrollback()`` returns a context manager that stores the current working\ndirectory on entry and changes back to that directory on exit.\n\n.. code:: python\n\n    attrset(obj: Any, name: str, value: Any) -\u003e ContextManager[None]\n\nTemporarily change the value of an object's attribute.\n\n``attrset(obj, name, value)`` returns a context manager.  On entry, it stores\nthe current value of the attribute of ``obj`` with name ``name``, and then it\nsets that attribute to ``value``.  On exit, it sets the attribute back to the\nstored value.\n\nIf the given attribute is unset on entry, the context manager will unset it on\nexit.\n\n.. code:: python\n\n    attrdel(obj: Any, name: str) -\u003e ContextManager[None]\n\nTemporarily unset an object's attribute.\n\n``attrdel(obj, name)`` returns a context manager.  On entry, it stores the\ncurrent value of the attribute of ``obj`` with name ``name``, and then it\nunsets that attribute.  On exit, it sets the attribute back to the stored\nvalue.\n\nIf the given attribute is unset on entry, the context manager will unset it on\nexit.\n\n.. code:: python\n\n    attrrollback(obj: Any, name: str, copy: bool = False, deepcopy: bool = False) -\u003e ContextManager[None]\n\nSave \u0026 restore the value of an object's attribute.\n\n``attrrollback(obj, name)`` returns a context manager that stores the value of\nthe attribute of ``obj`` with name ``name`` on entry and sets the attribute\nback to that value on exit.  If the given attribute is unset on entry, the\ncontext manager will unset it on exit.\n\nIf ``copy`` is true, a shallow copy of the attribute will be saved \u0026 restored.\nIf ``deepcopy`` is true, a deep copy of the attribute will be saved \u0026 restored.\nIf both options are true, ``deepcopy`` takes precedence.\n\n.. code:: python\n\n    itemset(d: MutableMapping[K,V], key: K, value: V) -\u003e ContextManager[None]\n\nTemporarily change the value of a mapping's entry.\n\n``itemset(d, key, value)`` returns a context manager.  On entry, it stores the\ncurrent value of ``d[key]``, and then it sets that field to ``value``.  On\nexit, it sets the field back to the stored value.\n\nIf the given field is unset on entry, the context manager will unset it on\nexit.\n\n.. code:: python\n\n    itemdel(d: MutableMapping[K, Any], key: K) -\u003e ContextManager[None]\n\nTemporarily unset a mapping's entry.\n\n``itemdel(d, key)`` returns a context manager.  On entry, it stores the current\nvalue of ``d[key]``, and then it unsets that field.  On exit, it sets the field\nback to the stored value.\n\nIf the given field is unset on entry, the context manager will unset it on\nexit.\n\n.. code:: python\n\n    itemrollback(d: MutableMapping[K, Any], key: K, copy: bool = False, deepcopy: bool = False) -\u003e ContextManager[None]\n\nSave \u0026 restore the value of a mapping's entry.\n\n``itemrollback(d, key)`` returns a context manager that stores the value of\n``d[key]`` on entry and sets the field back to that value on exit.  If the\ngiven field is unset on entry, the context manager will unset it on exit.\n\nIf ``copy`` is true, a shallow copy of the field will be saved \u0026 restored.  If\n``deepcopy`` is true, a deep copy of the field will be saved \u0026 restored.  If\nboth options are true, ``deepcopy`` takes precedence.\n\n.. code:: python\n\n    envset(name: str, value: str) -\u003e ContextManager[None]\n\nTemporarily set an environment variable.\n\n``envset(name, value)`` returns a context manager.  On entry, it stores the\ncurrent value of the environment variable ``name``, and then it sets that\nenvironment variable to ``value``.  On exit, it sets the environment variable\nback to the stored value.\n\nIf the given environment variable is unset on entry, the context manager will\nunset it on exit.\n\n.. code:: python\n\n    envdel(name: str) -\u003e ContextManager[None]\n\nTemporarily unset an environment variable.\n\n``envdel(name)`` returns a context manager.  On entry, it stores the current\nvalue of the environment variable ``name``, and then it unsets that environment\nvariable.  On exit, it sets the environment variable back to the stored value.\n\nIf the given environment variable is unset on entry, the context manager will\nunset it on exit.\n\n.. code:: python\n\n    envrollback(name: str) -\u003e ContextManager[None]\n\nSave \u0026 restore the value of an environment variable.\n\n``envrollback(name)`` returns a context manager that stores the value of the\nenvironment variable ``name`` on entry and sets the environment variable back\nto that value on exit.  If the given environment variable is unset on entry,\nthe context manager will unset it on exit.\n\n.. code:: python\n\n    additem(lst: MutableSequence[T], value: T, prepend: bool = False) -\u003e ContextManager[None]\n\nTemporarily add a value to a sequence.\n\n``additem(lst, value)`` returns a context manager that appends ``value`` to the\nsequence ``lst`` on entry and removes the last item (if any) in ``lst`` that\nequals ``value`` on exit.\n\nIf ``prepend`` is true, ``value`` is instead prepended to ``lst`` on entry, and\nthe first item in ``lst`` that equals ``value`` is removed on exit.\n\n\nClasses\n-------\n\n.. code:: python\n\n    class OpenClosable:\n        def open(self) -\u003e None:\n            ...\n\n        def close(self) -\u003e None:\n            ...\n\nA base class for creating simple reentrant_ context managers.  ``OpenClosable``\ndefines ``__enter__`` and ``__exit__`` methods that keep track of the number of\nnested ``with`` statements in effect and call the instance's ``open()`` and\n``close()`` methods when entering \u0026 exiting the outermost ``with``.\n\nSubclasses should override ``open()`` and/or ``close()`` with the desired\ncode to run on entering \u0026 exiting the outermost ``with``; the default\n``open()`` and ``close()`` methods defined by ``OpenClosable`` do nothing.\n\n.. _reentrant: https://docs.python.org/3/library/contextlib.html#reentrant-cms\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjwodder%2Fmorecontext","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjwodder%2Fmorecontext","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjwodder%2Fmorecontext/lists"}