Skip to content

Commit

Permalink
Merge pull request #50 from sarugaku/feature/48
Browse files Browse the repository at this point in the history
Provide a way to capture or wrap streams
  • Loading branch information
techalchemy committed Dec 10, 2018
2 parents 3c882ed + 7380135 commit 6ddc3ec
Show file tree
Hide file tree
Showing 20 changed files with 707 additions and 119 deletions.
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ install:
- "pipenv install --dev"
- "pipenv run pip install --upgrade -e .[spinner,tests]"
script:
- "pipenv run pytest -v -n auto tests/"
- "pipenv run pytest -v tests/"

jobs:
include:
Expand All @@ -33,7 +33,7 @@ jobs:
- stage: coverage
python: "3.6"
install:
- "pip install --upgrade pip pipenv pytest-cov pytest-xdist pytest-timeout pytest"
- "pip install --upgrade pip pipenv pytest-cov pytest-timeout pytest"
- "pipenv install --dev"
script:
- "pipenv run pytest -n auto --timeout 300 --cov=vistir --cov-report=term-missing --cov-report=xml --cov-report=html tests"
- "pipenv run pytest --timeout 300 --cov=vistir --cov-report=term-missing --cov-report=xml --cov-report=html tests"
121 changes: 120 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ default encoding:
* ``vistir.contextmanagers.atomic_open_for_write``
* ``vistir.contextmanagers.cd``
* ``vistir.contextmanagers.open_file``
* ``vistir.contextmanagers.replaced_stream``
* ``vistir.contextmanagers.spinner``
* ``vistir.contextmanagers.temp_environ``
* ``vistir.contextmanagers.temp_path``
Expand Down Expand Up @@ -203,6 +204,23 @@ to pair this with an iterator which employs a sensible chunk size.
shutil.copyfileobj(fp, filecontents)
.. _`replaced_stream`:

A context manager to temporarily swap out *stream_name* with a stream wrapper. This will
capture the stream output and prevent it from being written as normal.

.. code-block:: python
>>> orig_stdout = sys.stdout
>>> with replaced_stream("stdout") as stdout:
... sys.stdout.write("hello")
... assert stdout.getvalue() == "hello"
... assert orig_stdout.getvalue() != "hello"
>>> sys.stdout.write("hello")
'hello'
.. _`spinner`:

**spinner**
Expand Down Expand Up @@ -286,8 +304,13 @@ The following Miscellaneous utilities are available as helper methods:
* ``vistir.misc.partialclass``
* ``vistir.misc.to_text``
* ``vistir.misc.to_bytes``
* ``vistir.misc.divide``
* ``vistir.misc.take``
* ``vistir.misc.chunked``
* ``vistir.misc.decode_for_output``

* ``vistir.misc.get_canonical_encoding_name``
* ``vistir.misc.get_wrapped_stream``
* ``vistir.misc.StreamWrapper``

.. _`shell_escape`:

Expand Down Expand Up @@ -401,6 +424,62 @@ Converts arbitrary byte-convertable input to bytes while handling errors.
b'this is some text'
.. _`chunked`:

**chunked**
////////////

Splits an iterable up into groups *of the specified length*, per `more itertools`_. Returns an iterable.

This example will create groups of chunk size **5**, which means there will be *6 groups*.

.. code-block:: python
>>> chunked_iterable = vistir.misc.chunked(5, range(30))
>>> for chunk in chunked_iterable:
... add_to_some_queue(chunk)
.. _more itertools: https://more-itertools.readthedocs.io/en/latest/api.html#grouping


.. _`take`:

**take**
/////////

Take elements from the supplied iterable without consuming it.

.. code-block:: python
>>> iterable = range(30)
>>> first_10 = take(10, iterable)
>>> [i for i in first_10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [i for i in iterable]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
.. _`divide`:

**divide**
////////////

Splits an iterable up into the *specified number of groups*, per `more itertools`_. Returns an iterable.

.. code-block:: python
>>> iterable = range(30)
>>> groups = []
>>> for grp in vistir.misc.divide(3, iterable):
... groups.append(grp)
>>> groups
[<tuple_iterator object at 0x7fb7966006a0>, <tuple_iterator object at 0x7fb796652780>, <tuple_iterator object at 0x7fb79650a2b0>]
.. _more itertools: https://more-itertools.readthedocs.io/en/latest/api.html#grouping


.. _`decode_for_output`:

**decode_for_output**
Expand All @@ -411,6 +490,46 @@ outputs using the system preferred locale using ``locale.getpreferredencoding(Fa
with some additional hackery on linux systems.


.. _`get_canonical_encoding_name`:

**get_canonical_encoding_name**
////////////////////////////////

Given an encoding name, get the canonical name from a codec lookup.

.. code-block:: python
>>> vistir.misc.get_canonical_encoding_name("utf8")
"utf-8"
.. _`get_wrapped_stream`:

**get_wrapped_stream**
//////////////////////

Given a stream, wrap it in a `StreamWrapper` instance and return the wrapped stream.

.. code-block:: python
>>> stream = sys.stdout
>>> wrapped_stream = vistir.misc.get_wrapped_stream(sys.stdout)
.. _`StreamWrapper`:

**StreamWrapper**
//////////////////

A stream wrapper and compatibility class for handling wrapping file-like stream objects
which may be used in place of ``sys.stdout`` and other streams.

.. code-block:: python
>>> wrapped_stream = vistir.misc.StreamWrapper(sys.stdout, encoding="utf-8", errors="replace", line_buffering=True)
>>> wrapped_stream = vistir.misc.StreamWrapper(io.StringIO(), encoding="utf-8", errors="replace", line_buffering=True)
🐉 Path Utilities
------------------

Expand Down
6 changes: 3 additions & 3 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ environment:
install:
- "SET PATH=%PYTHON%\\;%PYTHON%\\Scripts;%PATH%"
- "python --version"
- "python -m pip install --upgrade pip pipenv"
- "python -m pip install --upgrade pip pipenv pytest pytest-timeout pytest-cov"
- "python -m pipenv install --dev"
- "python -m pipenv run pip install -e .[tests,spinner]"
- "python -m pipenv run pip install --upgrade -e .[tests,spinner]"

build: off

Expand All @@ -24,4 +24,4 @@ test_script:
- "subst T: %TEMP%"
- "set TEMP=T:\\"
- "set TMP=T:\\"
- "python -m pipenv run pytest -n auto -v tests"
- "python -m pipenv run pytest -ra tests"
31 changes: 26 additions & 5 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,30 @@
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import codecs
import os
import re
import sys
docs_dir = os.path.abspath(os.path.dirname(__file__))
src_dir = os.path.join(os.path.dirname(docs_dir), "src", "vistir")
sys.path.insert(0, src_dir)
version_file = os.path.join(src_dir, "__init__.py")


def read_file(path):
# intentionally *not* adding an encoding option to open, See:
# https://github.com/pypa/virtualenv/issues/201#issuecomment-3145690
with codecs.open(path, 'r') as fp:
return fp.read()


def find_version(file_path):
version_file = read_file(file_path)
version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]",
version_file, re.M)
if version_match:
return version_match.group(1)
return '0.0.0'


# -- Project information -----------------------------------------------------
Expand All @@ -25,10 +44,12 @@
copyright = '2018, Dan Ryan <dan@danryan.co>'
author = 'Dan Ryan <dan@danryan.co>'

release = find_version(version_file)
version = '.'.join(release.split('.')[:2])
# The short X.Y version
version = '0.0'
# version = '0.0'
# The full version, including alpha/beta/rc tags
release = '0.0.0.dev0'
# release = '0.0.0.dev0'


# -- General configuration ---------------------------------------------------
Expand Down Expand Up @@ -132,11 +153,11 @@
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
'papersize': 'letterpaper',

# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
'pointsize': '10pt',

# Additional stuff for the LaTeX preamble.
#
Expand Down Expand Up @@ -173,7 +194,7 @@
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'vistir', 'vistir Documentation',
author, 'vistir', 'One line description of project.',
author, 'vistir', 'Miscellaneous utilities for dealing with filesystems, paths, projects, subprocesses, and more.',
'Miscellaneous'),
]

Expand Down
Loading

0 comments on commit 6ddc3ec

Please sign in to comment.