Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-outcome for openSUSE:Factory 
checked in at 2021-10-20 20:23:21
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-outcome (Old)
 and      /work/SRC/openSUSE:Factory/.python-outcome.new.1890 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-outcome"

Wed Oct 20 20:23:21 2021 rev:5 rq:925639 version:1.1.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-outcome/python-outcome.changes    
2020-12-12 20:31:13.637780858 +0100
+++ /work/SRC/openSUSE:Factory/.python-outcome.new.1890/python-outcome.changes  
2021-10-20 20:24:04.057370050 +0200
@@ -1,0 +2,11 @@
+Wed Sep  1 20:18:41 UTC 2021 - Torsten Gruner <[email protected]>
+
+- update to version 1.1.0
+  * Tweaked the implementation of Error.unwrap to avoid creating a
+    reference cycle between the exception object and the unwrap
+    method's frame. This shouldn't affect most users, but it
+    slightly reduces the amount of work that CPython's cycle
+    collector has to do, and may reduce GC pauses in some cases. (#29)
+  * Drop support for Python 2.7, 3.4, and 3.5. (#27)
+
+-------------------------------------------------------------------

Old:
----
  outcome-1.0.1.tar.gz

New:
----
  outcome-1.1.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-outcome.spec ++++++
--- /var/tmp/diff_new_pack.VKXiuQ/_old  2021-10-20 20:24:05.109370700 +0200
+++ /var/tmp/diff_new_pack.VKXiuQ/_new  2021-10-20 20:24:05.113370702 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-outcome
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2021 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,8 +17,9 @@
 
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
+%define skip_python2 1
 Name:           python-outcome
-Version:        1.0.1
+Version:        1.1.0
 Release:        0
 Summary:        Function for capturing the outcome of Python function calls
 License:        MIT OR Apache-2.0

++++++ outcome-1.0.1.tar.gz -> outcome-1.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/outcome-1.0.1/.appveyor.yml 
new/outcome-1.1.0/.appveyor.yml
--- old/outcome-1.0.1/.appveyor.yml     2019-10-17 08:37:07.000000000 +0200
+++ new/outcome-1.1.0/.appveyor.yml     2020-11-17 04:06:26.000000000 +0100
@@ -4,16 +4,12 @@
 
 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"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/outcome-1.0.1/.travis.yml 
new/outcome-1.1.0/.travis.yml
--- old/outcome-1.0.1/.travis.yml       2019-10-17 08:37:07.000000000 +0200
+++ new/outcome-1.1.0/.travis.yml       2020-11-17 04:06:26.000000000 +0100
@@ -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:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/outcome-1.0.1/ci/travis.sh 
new/outcome-1.1.0/ci/travis.sh
--- old/outcome-1.0.1/ci/travis.sh      2019-10-17 08:37:07.000000000 +0200
+++ new/outcome-1.1.0/ci/travis.sh      2020-11-17 04:06:26.000000000 +0100
@@ -45,7 +45,7 @@
 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
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -67,7 +67,7 @@
     # 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
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -75,7 +75,7 @@
 Formatting problems were found (listed above). To fix them, run
 
    pip install isort
-   isort --recursive .
+   isort .
 
 in your local checkout.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/outcome-1.0.1/docs/source/conf.py 
new/outcome-1.1.0/docs/source/conf.py
--- old/outcome-1.0.1/docs/source/conf.py       2019-10-17 08:37:07.000000000 
+0200
+++ new/outcome-1.1.0/docs/source/conf.py       2020-11-17 04:06:26.000000000 
+0100
@@ -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.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/outcome-1.0.1/docs/source/history.rst 
new/outcome-1.1.0/docs/source/history.rst
--- old/outcome-1.0.1/docs/source/history.rst   2019-10-17 08:37:07.000000000 
+0200
+++ new/outcome-1.1.0/docs/source/history.rst   2020-11-17 04:06:26.000000000 
+0100
@@ -5,6 +5,25 @@
 
 .. towncrier release notes start
 
+Outcome 1.1.0 (2020-11-16)
+--------------------------
+
+Bugfixes
+~~~~~~~~
+
+- Tweaked the implementation of ``Error.unwrap`` to avoid creating a
+  reference cycle between the exception object and the ``unwrap``
+  method's frame. This shouldn't affect most users, but it slightly
+  reduces the amount of work that CPython's cycle collector has to do,
+  and may reduce GC pauses in some cases. (`#29 
<https://github.com/python-trio/outcome/issues/29>`__)
+
+
+Deprecations and Removals
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- Drop support for Python 2.7, 3.4, and 3.5. (`#27 
<https://github.com/python-trio/outcome/issues/27>`__)
+
+
 Outcome 1.0.1 (2019-10-16)
 --------------------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/outcome-1.0.1/docs/source/tutorial.rst 
new/outcome-1.1.0/docs/source/tutorial.rst
--- old/outcome-1.0.1/docs/source/tutorial.rst  2019-10-17 08:37:07.000000000 
+0200
+++ new/outcome-1.1.0/docs/source/tutorial.rst  2020-11-17 04:06:26.000000000 
+0100
@@ -16,7 +16,7 @@
 
 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()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/outcome-1.0.1/setup.cfg new/outcome-1.1.0/setup.cfg
--- old/outcome-1.0.1/setup.cfg 2019-10-17 08:37:07.000000000 +0200
+++ new/outcome-1.1.0/setup.cfg 2020-11-17 04:06:26.000000000 +0100
@@ -4,7 +4,6 @@
 [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
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/outcome-1.0.1/setup.py new/outcome-1.1.0/setup.py
--- old/outcome-1.0.1/setup.py  2019-10-17 08:37:07.000000000 +0200
+++ new/outcome-1.1.0/setup.py  2020-11-17 04:06:26.000000000 +0100
@@ -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',
@@ -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',
@@ -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',
     ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/outcome-1.0.1/src/outcome/__init__.py 
new/outcome-1.1.0/src/outcome/__init__.py
--- old/outcome-1.0.1/src/outcome/__init__.py   2019-10-17 08:37:07.000000000 
+0200
+++ new/outcome-1.1.0/src/outcome/__init__.py   2020-11-17 04:06:26.000000000 
+0100
@@ -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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/outcome-1.0.1/src/outcome/_async.py 
new/outcome-1.1.0/src/outcome/_async.py
--- old/outcome-1.0.1/src/outcome/_async.py     2019-10-17 08:37:07.000000000 
+0200
+++ new/outcome-1.1.0/src/outcome/_async.py     1970-01-01 01:00:00.000000000 
+0100
@@ -1,68 +0,0 @@
-import abc
-
-from ._sync import Error as ErrorBase
-from ._sync import Outcome as OutcomeBase
-from ._sync import Value as ValueBase
-from ._util import remove_tb_frames
-
-__all__ = ['Error', 'Outcome', 'Value', 'acapture', 'capture']
-
-
-def capture(sync_fn, *args, **kwargs):
-    """Run ``sync_fn(*args, **kwargs)`` and capture the result.
-
-    Returns:
-      Either a :class:`Value` or :class:`Error` as appropriate.
-
-    """
-    # _sync.capture references ErrorBase and ValueBase
-    try:
-        return Value(sync_fn(*args, **kwargs))
-    except BaseException as exc:
-        exc = remove_tb_frames(exc, 1)
-        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)
-
-
-class Outcome(OutcomeBase):
-    @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.
-
-        """
-
-
-class Value(Outcome, ValueBase):
-    async def asend(self, agen):
-        self._set_unwrapped()
-        return await agen.asend(self.value)
-
-
-class Error(Outcome, ErrorBase):
-    async def asend(self, agen):
-        self._set_unwrapped()
-        return await agen.athrow(self.error)
-
-
-# We don't need this for Sphinx, but do it anyway for IPython, IDEs, etc
-Outcome.__doc__ = OutcomeBase.__doc__
-Value.__doc__ = ValueBase.__doc__
-Error.__doc__ = ErrorBase.__doc__
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/outcome-1.0.1/src/outcome/_impl.py 
new/outcome-1.1.0/src/outcome/_impl.py
--- old/outcome-1.0.1/src/outcome/_impl.py      1970-01-01 01:00:00.000000000 
+0100
+++ new/outcome-1.1.0/src/outcome/_impl.py      2020-11-17 04:06:26.000000000 
+0100
@@ -0,0 +1,160 @@
+import abc
+
+import attr
+
+from ._util import AlreadyUsedError, remove_tb_frames
+
+__all__ = ['Error', 'Outcome', 'Value', 'acapture', 'capture']
+
+
+def capture(sync_fn, *args, **kwargs):
+    """Run ``sync_fn(*args, **kwargs)`` and capture the result.
+
+    Returns:
+      Either a :class:`Value` or :class:`Error` as appropriate.
+
+    """
+    try:
+        return Value(sync_fn(*args, **kwargs))
+    except BaseException as exc:
+        exc = remove_tb_frames(exc, 1)
+        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)
+
+
[email protected](repr=False, init=False, slots=True)
+class Outcome(abc.ABC):
+    """An abstract class representing the result of a Python computation.
+
+    This class has two concrete subclasses: :class:`Value` representing a
+    value, and :class:`Error` representing an exception.
+
+    In addition to the methods described below, comparison operators on
+    :class:`Value` and :class:`Error` objects (``==``, ``<``, etc.) check that
+    the other object is also a :class:`Value` or :class:`Error` object
+    respectively, and then compare the contained objects.
+
+    :class:`Outcome` objects are hashable if the contained objects are
+    hashable.
+
+    """
+    _unwrapped = attr.ib(default=False, eq=False, init=False)
+
+    def _set_unwrapped(self):
+        if self._unwrapped:
+            raise AlreadyUsedError
+        object.__setattr__(self, '_unwrapped', True)
+
+    @abc.abstractmethod
+    def unwrap(self):
+        """Return or raise the contained value or exception.
+
+        These two lines of code are equivalent::
+
+           x = fn(*args)
+           x = outcome.capture(fn, *args).unwrap()
+
+        """
+
+    @abc.abstractmethod
+    def send(self, gen):
+        """Send or throw the contained value or exception into the given
+        generator object.
+
+        Args:
+          gen: A generator object supporting ``.send()`` and ``.throw()``
+              methods.
+
+        """
+
+    @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.
+
+        """
+
+
[email protected](frozen=True, repr=False, slots=True)
+class Value(Outcome):
+    """Concrete :class:`Outcome` subclass representing a regular value.
+
+    """
+
+    value = attr.ib()
+    """The contained value."""
+
+    def __repr__(self):
+        return f'Value({self.value!r})'
+
+    def unwrap(self):
+        self._set_unwrapped()
+        return self.value
+
+    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)
+
+
[email protected](frozen=True, repr=False, slots=True)
+class Error(Outcome):
+    """Concrete :class:`Outcome` subclass representing a raised exception.
+
+    """
+
+    error = attr.ib(validator=attr.validators.instance_of(BaseException))
+    """The contained exception object."""
+
+    def __repr__(self):
+        return f'Error({self.error!r})'
+
+    def unwrap(self):
+        self._set_unwrapped()
+        # Tracebacks show the 'raise' line below out of context, so let's give
+        # this variable a name that makes sense out of context.
+        captured_error = self.error
+        try:
+            raise captured_error
+        finally:
+            # We want to avoid creating a reference cycle here. Python does
+            # collect cycles just fine, so it wouldn't be the end of the world
+            # if we did create a cycle, but the cyclic garbage collector adds
+            # latency to Python programs, and the more cycles you create, the
+            # more often it runs, so it's nicer to avoid creating them in the
+            # first place. For more details see:
+            #
+            #    https://github.com/python-trio/trio/issues/1770
+            #
+            # In particuar, by deleting this local variables from the 'unwrap'
+            # methods frame, we avoid the 'captured_error' object's
+            # __traceback__ from indirectly referencing 'captured_error'.
+            del captured_error, 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)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/outcome-1.0.1/src/outcome/_sync.py 
new/outcome-1.1.0/src/outcome/_sync.py
--- old/outcome-1.0.1/src/outcome/_sync.py      2019-10-17 08:37:07.000000000 
+0200
+++ new/outcome-1.1.0/src/outcome/_sync.py      1970-01-01 01:00:00.000000000 
+0100
@@ -1,115 +0,0 @@
-# coding: utf-8
-from __future__ import absolute_import, division, print_function
-
-import abc
-
-import attr
-
-from ._util import ABC, AlreadyUsedError, remove_tb_frames
-
-__all__ = ['Error', 'Outcome', 'Value', 'capture']
-
-
-def capture(sync_fn, *args, **kwargs):
-    """Run ``sync_fn(*args, **kwargs)`` and capture the result.
-
-    Returns:
-      Either a :class:`Value` or :class:`Error` as appropriate.
-
-    """
-    try:
-        return Value(sync_fn(*args, **kwargs))
-    except BaseException as exc:
-        exc = remove_tb_frames(exc, 1)
-        return Error(exc)
-
-
[email protected](repr=False, init=False, slots=True)
-class Outcome(ABC):
-    """An abstract class representing the result of a Python computation.
-
-    This class has two concrete subclasses: :class:`Value` representing a
-    value, and :class:`Error` representing an exception.
-
-    In addition to the methods described below, comparison operators on
-    :class:`Value` and :class:`Error` objects (``==``, ``<``, etc.) check that
-    the other object is also a :class:`Value` or :class:`Error` object
-    respectively, and then compare the contained objects.
-
-    :class:`Outcome` objects are hashable if the contained objects are
-    hashable.
-
-    """
-    _unwrapped = attr.ib(default=False, eq=False, init=False)
-
-    def _set_unwrapped(self):
-        if self._unwrapped:
-            raise AlreadyUsedError
-        object.__setattr__(self, '_unwrapped', True)
-
-    @abc.abstractmethod
-    def unwrap(self):
-        """Return or raise the contained value or exception.
-
-        These two lines of code are equivalent::
-
-           x = fn(*args)
-           x = outcome.capture(fn, *args).unwrap()
-
-        """
-
-    @abc.abstractmethod
-    def send(self, gen):
-        """Send or throw the contained value or exception into the given
-        generator object.
-
-        Args:
-          gen: A generator object supporting ``.send()`` and ``.throw()``
-              methods.
-
-        """
-
-
[email protected](frozen=True, repr=False, slots=True)
-class Value(Outcome):
-    """Concrete :class:`Outcome` subclass representing a regular value.
-
-    """
-
-    value = attr.ib()
-    """The contained value."""
-
-    def __repr__(self):
-        return 'Value({!r})'.format(self.value)
-
-    def unwrap(self):
-        self._set_unwrapped()
-        return self.value
-
-    def send(self, gen):
-        self._set_unwrapped()
-        return gen.send(self.value)
-
-
[email protected](frozen=True, repr=False, slots=True)
-class Error(Outcome):
-    """Concrete :class:`Outcome` subclass representing a raised exception.
-
-    """
-
-    error = attr.ib(validator=attr.validators.instance_of(BaseException))
-    """The contained exception object."""
-
-    def __repr__(self):
-        return 'Error({!r})'.format(self.error)
-
-    def unwrap(self):
-        self._set_unwrapped()
-        # Tracebacks show the 'raise' line below out of context, so let's give
-        # this variable a name that makes sense out of context.
-        captured_error = self.error
-        raise captured_error
-
-    def send(self, it):
-        self._set_unwrapped()
-        return it.throw(self.error)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/outcome-1.0.1/src/outcome/_util.py 
new/outcome-1.1.0/src/outcome/_util.py
--- old/outcome-1.0.1/src/outcome/_util.py      2019-10-17 08:37:07.000000000 
+0200
+++ new/outcome-1.1.0/src/outcome/_util.py      2020-11-17 04:06:26.000000000 
+0100
@@ -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
@@ -25,17 +18,7 @@
 
 
 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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/outcome-1.0.1/src/outcome/_version.py 
new/outcome-1.1.0/src/outcome/_version.py
--- old/outcome-1.0.1/src/outcome/_version.py   2019-10-17 08:37:07.000000000 
+0200
+++ new/outcome-1.1.0/src/outcome/_version.py   2020-11-17 04:06:26.000000000 
+0100
@@ -1,4 +1,3 @@
-# coding: utf-8
 # This file is imported from __init__.py and exec'd from setup.py
 
-__version__ = "1.0.1"
+__version__ = "1.1.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/outcome-1.0.1/test-requirements.txt 
new/outcome-1.1.0/test-requirements.txt
--- old/outcome-1.0.1/test-requirements.txt     2019-10-17 08:37:07.000000000 
+0200
+++ new/outcome-1.1.0/test-requirements.txt     2020-11-17 04:06:26.000000000 
+0100
@@ -1,4 +1,3 @@
 pytest
 pytest-cov
-pytest-asyncio; python_version >= '3.5'
-async-generator; python_version >= '3.5'
+pytest-asyncio
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/outcome-1.0.1/tests/__init__.py 
new/outcome-1.1.0/tests/__init__.py
--- old/outcome-1.0.1/tests/__init__.py 2019-10-17 08:37:07.000000000 +0200
+++ new/outcome-1.1.0/tests/__init__.py 2020-11-17 04:06:26.000000000 +0100
@@ -1,2 +0,0 @@
-# coding: utf-8
-from __future__ import absolute_import, division, print_function
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/outcome-1.0.1/tests/conftest.py 
new/outcome-1.1.0/tests/conftest.py
--- old/outcome-1.0.1/tests/conftest.py 2019-10-17 08:37:07.000000000 +0200
+++ new/outcome-1.1.0/tests/conftest.py 1970-01-01 01:00:00.000000000 +0100
@@ -1,18 +0,0 @@
-# coding: utf-8
-from __future__ import absolute_import, division, print_function
-
-import sys
-
-import pytest
-
-
-class DummyCollector(pytest.collect.File):
-    def collect(self):
-        return []
-
-
-def pytest_pycollect_makemodule(path, parent):
-    # skip asyncio tests unless on Python 3.5+, because async/await
-    # is a SyntaxError.
-    if 'async' in path.basename and sys.version_info < (3, 5):
-        return DummyCollector(path, parent=parent)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/outcome-1.0.1/tests/test_async.py 
new/outcome-1.1.0/tests/test_async.py
--- old/outcome-1.0.1/tests/test_async.py       2019-10-17 08:37:07.000000000 
+0200
+++ new/outcome-1.1.0/tests/test_async.py       2020-11-17 04:06:26.000000000 
+0100
@@ -1,9 +1,7 @@
 import asyncio
-import sys
 import traceback
 
 import pytest
-from async_generator import async_generator, yield_
 
 import outcome
 from outcome import AlreadyUsedError, Error, Value
@@ -29,16 +27,13 @@
 
 
 async def test_asend():
-    @async_generator
     async def my_agen_func():
-        assert (await yield_(1)) == "value"
+        assert (yield 1) == "value"
         with pytest.raises(KeyError):
-            await yield_(2)
-        await yield_(3)
+            yield 2
+        yield 3
 
     my_agen = my_agen_func().__aiter__()
-    if sys.version_info < (3, 5, 2):
-        my_agen = await my_agen
     v = Value("value")
     e = Error(KeyError())
     assert (await my_agen.asend(None)) == 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/outcome-1.0.1/tests/test_sync.py 
new/outcome-1.1.0/tests/test_sync.py
--- old/outcome-1.0.1/tests/test_sync.py        2019-10-17 08:37:07.000000000 
+0200
+++ new/outcome-1.1.0/tests/test_sync.py        2020-11-17 04:06:26.000000000 
+0100
@@ -1,6 +1,3 @@
-# coding: utf-8
-from __future__ import absolute_import, division, print_function
-
 import sys
 import traceback
 
@@ -28,7 +25,7 @@
         e.unwrap()
     with pytest.raises(AlreadyUsedError):
         e.unwrap()
-    assert repr(e) == "Error({!r})".format(exc)
+    assert repr(e) == f"Error({exc!r})"
 
     e = Error(exc)
     with pytest.raises(TypeError):
@@ -82,7 +79,6 @@
     assert {e1, e2, e3, e4} == {e1, e3}
 
 
[email protected](sys.version_info < (3,), reason="requires python 3")
 def test_Value_compare():
     assert Value(1) < Value(2)
     assert not Value(3) < Value(2)
@@ -112,7 +108,6 @@
     assert issubclass(Error, outcome.Outcome)
 
 
[email protected](sys.version_info < (3,), reason="requires python 3")
 def test_traceback_frame_removal():
     def raise_ValueError(x):
         raise ValueError(x)
@@ -123,3 +118,22 @@
     frames = traceback.extract_tb(exc_info.value.__traceback__)
     functions = [function for _, _, function, _ in frames]
     assert functions[-2:] == ['unwrap', 'raise_ValueError']
+
+
+def test_Error_unwrap_does_not_create_reference_cycles():
+    # See comment in Error.unwrap for why reference cycles are tricky
+    exc = ValueError()
+    err = Error(exc)
+    try:
+        err.unwrap()
+    except ValueError:
+        pass
+    # Top frame in the traceback is the current test function; we don't care
+    # about its references
+    assert exc.__traceback__.tb_frame is sys._getframe()
+    # The next frame down is the 'unwrap' frame; we want to make sure it
+    # doesn't reference the exception (or anything else for that matter, just
+    # to be thorough)
+    unwrap_frame = exc.__traceback__.tb_next.tb_frame
+    assert unwrap_frame.f_code.co_name == "unwrap"
+    assert unwrap_frame.f_locals == {}

Reply via email to