Skip to content

Commit

Permalink
Merge branch 'release-1.0.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
bskinn committed Nov 14, 2018
2 parents 178b73b + 2ee1154 commit 8857c60
Show file tree
Hide file tree
Showing 20 changed files with 929 additions and 658 deletions.
13 changes: 13 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[run]
omit =
# Don't do coverage on test code
tempvars/test/*
tests.py

# Don't cover code in the env
env/*

[report]
exclude_lines =
pragma: no cover
^\s*pass\s*$
8 changes: 4 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ python:
- 3.4
- 3.5
- 3.6
- 3.7-dev
script:
- python tests.py -a
- coverage run tests.py -a
- flake8 tempvars
- cd doc
- make doctest

- echo $TRAVIS_PYTHON_VERSION | grep -e '^3\.6' && codecov || echo "No codecov."
- sh -c 'cd doc; make doctest'

30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,36 @@ with TempVars(...) as tv:

### [Unreleased]

...


### [1.0.1] - 2018-11-14

This release ***should not*** affect the behavior of the
package in any way.

#### Refactored

* Remove duplicative call to `inspect.currentframe()` in
`TempVars._ns_default`
* Replace custom `copy_if_not_none()` inner function with
built-in `copy.copy()`, in `__attrs_post_init__()`
* Refactor the temporary variable popping operations to
a more concise form in both `__enter__()`
and `__exit__()`

#### Administrative

* Switched to [`black`](https://github.com/ambv/black)-style
code formatting
* Switched source file headers from comment blocks to
module docstrings
* Relocated some commentary from code comments to method
docstrings


### [1.0.0] - 2017-10-19

#### Added

* `TempVars` now emits a warning if it is instantiated without
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2017 Brian Skinn
Copyright (c) 2017-2018 Brian Skinn

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
194 changes: 129 additions & 65 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,105 +1,169 @@
tempvars
--------

*A context manager for handling temporary variables in Jupyter Notebook,
IPython, etc.*

A frustrating aspect of working with Jupyter notebooks
is debugging a worksheet for half an hour
and discovering a carried-over variable name was hanging around
in the notebook namespace and causing
the misbehavior, or opening a notebook that "worked fine" the last
time it was used because of random variables lingering in the
namespace. The ``TempVars`` context manager avoids these pitfalls by
tempvars: A context manager for handling temporary variables
============================================================

**Current Development Version:**

.. image:: https://travis-ci.org/bskinn/tempvars.svg?branch=dev
:target: https://travis-ci.org/bskinn/tempvars

.. image:: https://codecov.io/gh/bskinn/tempvars/branch/dev/graph/badge.svg
:target: https://codecov.io/gh/bskinn/tempvars

**Most Recent Stable Release:**

.. image:: https://img.shields.io/pypi/v/tempvars.svg
:target: https://pypi.org/project/tempvars

.. image:: https://img.shields.io/pypi/pyversions/tempvars.svg

**Info:**

.. image:: https://img.shields.io/readthedocs/tempvars/latest.svg
:target: http://tempvars.readthedocs.io/en/latest/

.. image:: https://img.shields.io/github/license/mashape/apistatus.svg
:target: https://github.com/bskinn/tempvars/blob/master/LICENSE.txt

.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
:target: https://github.com/ambv/black

----

**Use Jupyter Notebook?**

**Constantly run into problems from obsolete variables hanging around
in the namespace?**

``tempvars`` *can help.*

Developing in Jupyter notebooks can sometimes be frustrating.
For example, it's aggravating to debug a worksheet for half an hour,
only to discover that a carried-over variable name was hanging around
in the notebook namespace and causing problems.
Or, to open a notebook that "worked fine" the last
time it was used, but only because of random, obsolete variables that happened
to be lingering in the namespace.
Wrapping notebook code in functions/classes is an effective way of avoiding
these sorts of problems, but it's rarely effective or efficient to
do this in the initial exploratory phase of in-notebook development.

``TempVars`` is a context manager that helps to avoid these pitfalls by
clearing selected identifiers from the namespace for the duration of
the ``with`` suite, then restoring them afterwards (or not, if desired).
its scope, then restoring them afterwards (or not, if desired).
Further, any variables created within the managed context
that match the criteria passed to ``TempVars`` are removed from
that match the ``TempVars`` filtering criteria are removed from
the namespace upon exiting, ensuring these values do not spuriously
contribute to following code. For convenience, all variables
that were removed from the namespace at both entry and exit
are stored with their values for later reference (see example code below).
removed from the namespace at entry and exit
are stored for later reference (see example code below).

**NOTE:** Due to the way Python handles non-global variable scopes, ``TempVars``
Due to the way Python handles non-global scopes, ``TempVars``
can only be used at the global scope. *Any attempt
to use* ``TempVars`` *in non-global contexts will
result in a* ``RuntimeError``. Viable use-cases include Jupyter notebooks,
the IPython and basic Python REPLs, and the outermost scope of executed and
imported modules. Preliminary testing indicates it also works with
`cauldron-notebook <https://github.com/sernst/cauldron>`__, though
it may be less helpful there due to the step-local scoping paradigm used
it may be less helpful there due to its step-local scoping paradigm
(shared values must be passed around via ``cauldron.shared``).

**NOTE ALSO** that ``tempvars`` is *Python 3 only*.
----

After installing with ``pip install tempvars``, import as:

.. code:: python
>>> from tempvars import TempVars
Example usage:
For typical use in a Jupyter notebook cell, the recommended approach
is to pick a marker to use on all variables that are to be temporary,
and enclose the entire cell in a ``TempVars`` context. For example,
one could prefix all temporary variables with `t_` and make use
of the `starts` argument:

.. code:: python
>>> t_var1 = 5
>>> t_var2 = 7
>>> x = 15
>>> y = 20
>>> with TempVars(names=['x']) as tv1:
... with TempVars(starts=['t_'], restore=False) as tv2:
... print('x' in dir())
... print('t_var1' in dir())
... print('t_var2' in dir())
... print(y)
... print(tv1.stored_nsvars)
... print(sorted(tv2.stored_nsvars.keys()))
... print(tv2.stored_nsvars['t_var1'])
... print(tv2.stored_nsvars['t_var2'])
... x = -3
... t_var3 = -7
... print((x, t_var3, y))
False
False
>>> foo = 5
>>> with TempVars(starts=['t_']):
... print(foo)
... t_bar = 8
... print(foo + t_bar)
5
13
>>> print('t_bar' in dir())
False
20
{'x': 15}
['t_var1', 't_var2']
A similar effect can be achieved with a suffix such as `_t` and
the `ends` argument.

Temporary variable masking can also be introduced to existing
code in a more selective fashion via the `names` argument:

.. code:: python
>>> foo = 5
>>> bar = 7
>>> with TempVars(names=['bar']):
... print(foo)
... print('bar' in dir())
5
7
(-3, -7, 20)
>>> print((x, y))
(15, 20)
>>> print('t_var1' in dir())
False
>>> print('t_var2' in dir())
>>> print(foo * bar)
35
Setting the `restore` argument to ``False`` instructs ``TempVars``
not to restore any masked variables to the namespace after its
context exits. This is potentially useful to avoid carryover of
common helper variables (`arr`, `df`, `i`, etc.) to downstream cells
that may have been created earlier in a notebook:

.. code:: python
>>> for k in ['foo', 'bar']:
... pass
>>> print(k)
bar
>>> with TempVars(names=['k'], restore=False):
... print('k' in dir())
False
>>> print('t_var3' in dir())
>>> print('k' in dir())
False
>>> print(tv1.retained_tempvars)
{'x': -3}
>>> print(tv2.retained_tempvars)
{'t_var3': -7}
``TempVars`` stores the values of variables it removes from the namespace,
should they need to be accessed. A bound `with`/`as` statement must be
used in order to enable this:

Administrative
--------------
.. code:: python
>>> foo = 5
>>> with TempVars(names=['foo']) as tv:
... print('foo' in dir())
... print(tv.stored_nsvars['foo'])
... foo = 8
... print(foo)
False
5
8
>>> print(foo)
5
>>> print(tv.retained_tempvars['foo'])
8
----

Branches named with the prefix ``v.`` are volatile. The history there
may be rewritten dramatically, without warning.

Available on PyPI: ``pip install tempvars``.
Available on `PyPI <https://pypi.org/project/tempvars>`__: ``pip install tempvars``.

Source on `GitHub <https://github.com/bskinn/tempvars>`__. Bug reports
and feature requests are welcomed at the
Full documentation at
`Read the Docs <http://tempvars.readthedocs.io/en/latest/>`__.

Source on `GitHub <https://github.com/bskinn/tempvars>`__.
Bug reports and feature requests are welcomed at the
`Issues <https://github.com/bskinn/tempvars/issues>`__ page there.
If you like the idea of an enhancement already in the Issues list,
please comment to say so; it'll help with prioritization.

Full documentation at
`Read the Docs <http://tempvars.readthedocs.io>`__.

Copyright (c) Brian Skinn 2017
Copyright (c) Brian Skinn 2017-2018

License: The MIT License. See `LICENSE.txt <https://github.com/bskinn/tempvars/blob/master/LICENSE.txt>`__
for full license terms.
Expand Down
4 changes: 4 additions & 0 deletions black
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#! /bin/bash

black setup.py tests.py tempvars tempvars/test -l 79

4 changes: 4 additions & 0 deletions black.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@echo off

black.exe setup.py tests.py tempvars tempvars\test -l 79

3 changes: 2 additions & 1 deletion doc/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
tempvars API
============

.. automodule:: tempvars
.. autoclass:: tempvars.TempVars
:members:
16 changes: 10 additions & 6 deletions doc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import re
import sys
sys.path.insert(0, os.path.abspath('../..'))

Expand Down Expand Up @@ -55,18 +56,21 @@
master_doc = 'index'

# General information about the project.
project = 'tempvars'
copyright = '2017, Brian Skinn'
author = 'Brian Skinn'
project = "tempvars"
copyright = "2017-2018, Brian Skinn"
author = "Brian Skinn"

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
from tempvars import __version__

# The short X.Y version.
version = '1.0'
version = re.match(r"\d+\.\d+", __version__).group()

# The full version, including alpha/beta/rc tags.
release = '1.0'
release = __version__

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down Expand Up @@ -276,5 +280,5 @@ def isphx_subst(s):

intersphinx_mapping = {
'python': ('https://docs.python.org/3.5', isphx_subst('python')),
'attrs': ('http://www.attrs.org/en/stable', isphx_subst('attrs'))
'attrs': ('https://www.attrs.org/en/stable', isphx_subst('attrs'))
}
2 changes: 1 addition & 1 deletion doc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ in the usage instructions.
**NOTE:** Due to the way Python handles non-global variable scopes, |TempVars|
can only be used at the global scope. *Any attempt
to use* |TempVars| *in non-global contexts will result in a*
:exc:`~exceptions.RuntimeError`. Viable use-cases include Jupyter notebooks,
:exc:`RuntimeError`. Viable use-cases include Jupyter notebooks,
the IPython and basic Python REPLs, and the outermost scope of executed and
imported modules. Preliminary testing indicates it also works with
`cauldron-notebook <https://github.com/sernst/cauldron>`__, though
Expand Down
Loading

0 comments on commit 8857c60

Please sign in to comment.