Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

POC: Reconfigure existing streams #78

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ python:
- 3.6
- 3.7
- 3.8-dev
- pypy3
jobs:
include:
- os: windows
Expand All @@ -24,6 +23,6 @@ jobs:
script:
- python --version
- pip list
- pytest --cov=src
- PYTHONUNBUFFERED=1 pytest --cov=src
- if (( $PYTHON_MAJOR == 3 && $PYTHON_MINOR == 7 )); then tox -e flake8; else echo "No flake8."; fi
- if (( $PYTHON_MAJOR == 3 && $PYTHON_MINOR == 7 )); then codecov; else echo "No codecov."; fi
2 changes: 1 addition & 1 deletion azure-job.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,5 @@ jobs:
- script: ${{ cmd.value.cmd }}
displayName: ${{ cmd.value.name }}

- script: pytest
- script: python -u -m pytest
displayName: Run pytest (Python ${{ python.value.spec }})
2 changes: 1 addition & 1 deletion azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ jobs:
- script: pip install -r requirements-ci.txt
displayName: Install CI requirements

- script: pytest -v -W error::Warning
- script: PYTHONUNBUFFERED=1 pytest -v -W error::Warning
displayName: Run pytest, exposing underlying warnings (Python 3.7)

- job: docs_display_warnings
Expand Down
18 changes: 16 additions & 2 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@
import os
import sys
import warnings
from io import TextIOBase

import _pytest.warnings
import pytest

from stdio_mgr import stdio_mgr
from stdio_mgr.stdio_mgr import _choose_inject_impl, BufferReplaceStdioManager


@pytest.fixture(scope="session")
Expand Down Expand Up @@ -74,10 +75,23 @@ def enable_warnings_plugin(request):
yield


def pytest_generate_tests(metafunc):
"""Parametrize fixture stdio_mgr."""
if "stdio_mgr" not in metafunc.fixturenames:
return

if isinstance(sys.stdin, TextIOBase):
impls = [BufferReplaceStdioManager, _choose_inject_impl()]
else:
impls = [BufferReplaceStdioManager]

metafunc.parametrize("stdio_mgr", impls)


@pytest.fixture(autouse=True, scope="session")
def add_stdio_mgr(doctest_namespace):
"""Add stdio_mgr to doctest namespace."""
doctest_namespace["stdio_mgr"] = stdio_mgr
doctest_namespace["stdio_mgr"] = BufferReplaceStdioManager
doctest_namespace["os"] = os


Expand Down
65 changes: 65 additions & 0 deletions src/stdio_mgr/compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
r"""``stdio_mgr.compat`` *code module*.

``stdio_mgr.compat`` provides backports of Python standard library.

**Author**
John Vandenberg (jayvdb@gmail.com)

**File Created**
6 Sep 2019

**Copyright**
\(c) Brian Skinn 2018-2019

**Source Repository**
http://www.github.com/bskinn/stdio-mgr

**Documentation**
See README.rst at the GitHub repository

**License**
The Python-2.0 License.

**Members**

"""
import abc

# AbstractContextManager was introduced in Python 3.6
# and may be used with typing.ContextManager.
# See https://github.com/jazzband/contextlib2/pull/21 for more complete backport
try:
from contextlib import AbstractContextManager
except ImportError: # pragma: no cover
# Copied from _collections_abc
def _check_methods(cls, *methods):
mro = cls.__mro__
for method in methods:
for base in mro:
if method in base.__dict__:
if base.__dict__[method] is None:
return NotImplemented
break
else:
return NotImplemented
return True

# Copied from contextlib
class AbstractContextManager(abc.ABC):
"""An abstract base class for context managers."""

def __enter__(self):
"""Return `self` upon entering the runtime context."""
return self

@abc.abstractmethod
def __exit__(self, exc_type, exc_value, traceback):
"""Raise any exception triggered within the runtime context."""
return None

@classmethod
def __subclasshook__(cls, subclass):
"""Check whether subclass is considered a subclass of this ABC."""
if cls is AbstractContextManager:
return _check_methods(subclass, "__enter__", "__exit__")
return NotImplemented
Loading