Skip to content

Commit

Permalink
Merge pull request #27 from RazerM/feature/py36plus
Browse files Browse the repository at this point in the history
  • Loading branch information
pquentin committed Jul 6, 2020
2 parents 16e6bfb + d0b8f2c commit 0d0cfb0
Show file tree
Hide file tree
Showing 18 changed files with 64 additions and 183 deletions.
8 changes: 2 additions & 6 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,12 @@ os: Visual Studio 2015

environment:
matrix:
- PYTHON: "C:\\Python27"
- PYTHON: "C:\\Python27-x64"
- PYTHON: "C:\\Python34"
- PYTHON: "C:\\Python34-x64"
- PYTHON: "C:\\Python35"
- PYTHON: "C:\\Python35-x64"
- PYTHON: "C:\\Python36"
- PYTHON: "C:\\Python36-x64"
- PYTHON: "C:\\Python37"
- PYTHON: "C:\\Python37-x64"
- PYTHON: "C:\\Python38"
- PYTHON: "C:\\Python38-x64"

build_script:
- "git --no-pager log -n2"
Expand Down
20 changes: 5 additions & 15 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
language: python
sudo: false
dist: trusty
dist: bionic

matrix:
include:
- python: 3.6
- python: 3.8
env: CHECK_DOCS=1
- python: 3.6
- python: 3.8
env: CHECK_FORMATTING=1
- python: pypy
- python: pypy3.5
- python: 2.7
- python: 3.4
- python: 3.5.0
- python: 3.5.2
- python: pypy3.6-7.2.0
- python: 3.6
- python: 3.7
dist: xenial
sudo: required
- python: 3.8-dev
dist: xenial
sudo: required
- python: 3.8


script:
Expand Down
6 changes: 3 additions & 3 deletions ci/travis.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ python setup.py sdist --formats=zip
pip install dist/*.zip

if [ "$CHECK_FORMATTING" = "1" ]; then
pip install yapf==${YAPF_VERSION} isort
pip install yapf==${YAPF_VERSION} isort>=5
if ! yapf -rpd setup.py src tests; then
cat <<EOF
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Expand All @@ -67,15 +67,15 @@ EOF
# required for isort to order test imports correctly
pip install -Ur test-requirements.txt

if ! isort --recursive --check-only --diff . ; then
if ! isort --check-only --diff . ; then
cat <<EOF
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Formatting problems were found (listed above). To fix them, run
pip install isort
isort --recursive .
isort .
in your local checkout.
Expand Down
1 change: 0 additions & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Documentation build configuration file, created by
# sphinx-quickstart on Sat Jan 21 19:11:14 2017.
Expand Down
2 changes: 1 addition & 1 deletion docs/source/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ is the same as::

even if ``f`` raises an error.

On Python 3.5+, there's also :func:`acapture`::
There's also :func:`acapture`::

result = await outcome.acapture(f, *args, **kwargs)
x = result.unwrap()
Expand Down
1 change: 1 addition & 0 deletions newsfragments/27.removal.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Drop support for Python 2.7, 3.4, and 3.5.
1 change: 0 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ universal = 1
[isort]
multi_line_output = 4
skip = ./build, ./docs
not_skip = __init__.py
# ci/travis.sh installs outcome normally, so isort assumes it's third party
known_first_party = outcome

Expand Down
18 changes: 5 additions & 13 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
# coding: utf-8
from __future__ import absolute_import, division, print_function

from io import open

from setuptools import find_packages, setup

version = dict()

# read _version.py as bytes, otherwise exec will complain about
# 'coding: utf-8', which we want there for the normal Python 2 import
with open('src/outcome/_version.py', 'rb') as fp:
with open('src/outcome/_version.py') as fp:
version_mod = fp.read()

exec(version_mod, version)

LONG_DESC = open('README.rst', encoding='utf-8').read()
LONG_DESC = open('README.rst').read()

setup(
name='outcome',
Expand All @@ -33,7 +26,7 @@
packages=find_packages('src'),
package_dir={'': 'src'},
install_requires=['attrs>=19.2.0'],
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
python_requires='>=3.6',
keywords='result',
classifiers=[
'Development Status :: 5 - Production/Stable',
Expand All @@ -44,10 +37,9 @@
'Operating System :: POSIX :: Linux',
'Operating System :: MacOS :: MacOS X',
'Operating System :: Microsoft :: Windows',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
],
Expand Down
16 changes: 4 additions & 12 deletions src/outcome/__init__.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
# coding: utf-8
"""Top-level package for outcome."""
from __future__ import absolute_import, division, print_function

import sys

from ._impl import Error, Outcome, Value, acapture, capture
from ._util import AlreadyUsedError, fixup_module_metadata
from ._version import __version__

if sys.version_info >= (3, 5):
from ._async import Error, Outcome, Value, acapture, capture
__all__ = (
'Error', 'Outcome', 'Value', 'acapture', 'capture', 'AlreadyUsedError'
)
else:
from ._sync import Error, Outcome, Value, capture
__all__ = ('Error', 'Outcome', 'Value', 'capture', 'AlreadyUsedError')
__all__ = (
'Error', 'Outcome', 'Value', 'acapture', 'capture', 'AlreadyUsedError'
)

fixup_module_metadata(__name__, globals())
del fixup_module_metadata
68 changes: 0 additions & 68 deletions src/outcome/_async.py

This file was deleted.

46 changes: 38 additions & 8 deletions src/outcome/_sync.py → src/outcome/_impl.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
# coding: utf-8
from __future__ import absolute_import, division, print_function

import abc

import attr

from ._util import ABC, AlreadyUsedError, remove_tb_frames
from ._util import AlreadyUsedError, remove_tb_frames

__all__ = ['Error', 'Outcome', 'Value', 'capture']
__all__ = ['Error', 'Outcome', 'Value', 'acapture', 'capture']


def capture(sync_fn, *args, **kwargs):
Expand All @@ -24,8 +21,22 @@ def capture(sync_fn, *args, **kwargs):
return Error(exc)


async def acapture(async_fn, *args, **kwargs):
"""Run ``await async_fn(*args, **kwargs)`` and capture the result.
Returns:
Either a :class:`Value` or :class:`Error` as appropriate.
"""
try:
return Value(await async_fn(*args, **kwargs))
except BaseException as exc:
exc = remove_tb_frames(exc, 1)
return Error(exc)


@attr.s(repr=False, init=False, slots=True)
class Outcome(ABC):
class Outcome(abc.ABC):
"""An abstract class representing the result of a Python computation.
This class has two concrete subclasses: :class:`Value` representing a
Expand Down Expand Up @@ -69,6 +80,17 @@ def send(self, gen):
"""

@abc.abstractmethod
async def asend(self, agen):
"""Send or throw the contained value or exception into the given async
generator object.
Args:
agen: An async generator object supporting ``.asend()`` and
``.athrow()`` methods.
"""


@attr.s(frozen=True, repr=False, slots=True)
class Value(Outcome):
Expand All @@ -80,7 +102,7 @@ class Value(Outcome):
"""The contained value."""

def __repr__(self):
return 'Value({!r})'.format(self.value)
return f'Value({self.value!r})'

def unwrap(self):
self._set_unwrapped()
Expand All @@ -90,6 +112,10 @@ def send(self, gen):
self._set_unwrapped()
return gen.send(self.value)

async def asend(self, agen):
self._set_unwrapped()
return await agen.asend(self.value)


@attr.s(frozen=True, repr=False, slots=True)
class Error(Outcome):
Expand All @@ -101,7 +127,7 @@ class Error(Outcome):
"""The contained exception object."""

def __repr__(self):
return 'Error({!r})'.format(self.error)
return f'Error({self.error!r})'

def unwrap(self):
self._set_unwrapped()
Expand All @@ -113,3 +139,7 @@ def unwrap(self):
def send(self, it):
self._set_unwrapped()
return it.throw(self.error)

async def asend(self, agen):
self._set_unwrapped()
return await agen.athrow(self.error)
17 changes: 0 additions & 17 deletions src/outcome/_util.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
# coding: utf-8
from __future__ import absolute_import, division, print_function

import abc
import sys


class AlreadyUsedError(RuntimeError):
"""An Outcome can only be unwrapped once."""
pass
Expand All @@ -25,17 +18,7 @@ def fix_one(obj):


def remove_tb_frames(exc, n):
if sys.version_info < (3,):
return exc
tb = exc.__traceback__
for _ in range(n):
tb = tb.tb_next
return exc.with_traceback(tb)


if sys.version_info < (3,):

class ABC(object):
__metaclass__ = abc.ABCMeta
else:
ABC = abc.ABC
1 change: 0 additions & 1 deletion src/outcome/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding: utf-8
# This file is imported from __init__.py and exec'd from setup.py

__version__ = "1.0.1"
3 changes: 1 addition & 2 deletions test-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
pytest
pytest-cov
pytest-asyncio; python_version >= '3.5'
async-generator; python_version >= '3.5'
pytest-asyncio
2 changes: 0 additions & 2 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +0,0 @@
# coding: utf-8
from __future__ import absolute_import, division, print_function
18 changes: 0 additions & 18 deletions tests/conftest.py

This file was deleted.

0 comments on commit 0d0cfb0

Please sign in to comment.