contextlib: depend on ucontextlib and fix tests

pull/52/head
Delio Brignoli 2015-10-20 23:20:02 +02:00 zatwierdzone przez Paul Sokolovsky
rodzic de39c2417c
commit 680364d20c
4 zmienionych plików z 11 dodań i 135 usunięć

Wyświetl plik

@ -8,101 +8,7 @@ Not implemented:
"""
class ContextDecorator(object):
"A base class or mixin that enables context managers to work as decorators."
def _recreate_cm(self):
"""Return a recreated instance of self.
Allows an otherwise one-shot context manager like
_GeneratorContextManager to support use as
a decorator via implicit recreation.
This is a private interface just for _GeneratorContextManager.
See issue #11647 for details.
"""
return self
def __call__(self, func):
def inner(*args, **kwds):
with self._recreate_cm():
return func(*args, **kwds)
return inner
class _GeneratorContextManager(ContextDecorator):
"""Helper for @contextmanager decorator."""
def __init__(self, func, *args, **kwds):
self.gen = func(*args, **kwds)
self.func, self.args, self.kwds = func, args, kwds
def _recreate_cm(self):
# _GCM instances are one-shot context managers, so the
# CM must be recreated each time a decorated function is
# called
return self.__class__(self.func, *self.args, **self.kwds)
def __enter__(self):
try:
return next(self.gen)
except StopIteration:
raise RuntimeError("generator didn't yield") from None
def __exit__(self, type, value, traceback):
if type is None:
try:
next(self.gen)
except StopIteration:
return
else:
raise RuntimeError("generator didn't stop")
else:
if value is None:
# Need to force instantiation so we can reliably
# tell if we get the same exception back
value = type()
try:
self.gen.throw(type, value, traceback)
raise RuntimeError("generator didn't stop after throw()")
except StopIteration as exc:
# Suppress the exception *unless* it's the same exception that
# was passed to throw(). This prevents a StopIteration
# raised inside the "with" statement from being suppressed
return exc is not value
def contextmanager(func):
"""@contextmanager decorator.
Typical usage:
@contextmanager
def some_generator(<arguments>):
<setup>
try:
yield <value>
finally:
<cleanup>
This makes this:
with some_generator(<arguments>) as <variable>:
<body>
equivalent to this:
<setup>
try:
<variable> = <value>
<body>
finally:
<cleanup>
"""
def helper(*args, **kwds):
return _GeneratorContextManager(func, *args, **kwds)
return helper
from ucontextlib import *
class closing(object):

Wyświetl plik

@ -1,4 +1,5 @@
srctype = cpython
type = module
version = 3.4.2-1
version = 3.4.2-2
long_desc = Port of contextlib for micropython
depends = ucontextlib

Wyświetl plik

@ -6,7 +6,7 @@ from setuptools import setup
setup(name='micropython-contextlib',
version='3.4.2-1',
version='3.4.2-2',
description='CPython contextlib module ported to MicroPython',
long_description='This is a module ported from CPython standard library to be compatible with\nMicroPython interpreter. Usually, this means applying small patches for\nfeatures not supported (yet, or at all) in MicroPython. Sometimes, heavier\nchanges are required. Note that CPython modules are written with availability\nof vast resources in mind, and may not work for MicroPython ports with\nlimited heap. If you are affected by such a case, please help reimplement\nthe module from scratch.',
url='https://github.com/micropython/micropython/issues/405',
@ -15,4 +15,5 @@ setup(name='micropython-contextlib',
maintainer='MicroPython Developers',
maintainer_email='micro-python@googlegroups.com',
license='Python',
py_modules=['contextlib'])
py_modules=['contextlib'],
install_requires=['micropython-ucontextlib'])

Wyświetl plik

@ -1,38 +1,8 @@
from unittest import TestCase, run_class
from contextlib import contextmanager, closing, suppress
import unittest
from contextlib import closing, suppress
class ContextManagerTestCase(TestCase):
def setUp(self):
self._history = []
@contextmanager
def manager(x):
self._history.append('start')
try:
yield x
finally:
self._history.append('finish')
self._manager = manager
def test_context_manager(self):
with self._manager(123) as x:
self.assertEqual(x, 123)
self.assertEqual(self._history, ['start', 'finish'])
def test_context_manager_on_error(self):
exc = Exception()
try:
with self._manager(123) as x:
raise exc
except Exception as e:
self.assertEqual(exc, e)
self.assertEqual(self._history, ['start', 'finish'])
class ClosingTestCase(TestCase):
class ClosingTestCase(unittest.TestCase):
class Closable:
def __init__(self):
@ -58,7 +28,7 @@ class ClosingTestCase(TestCase):
self.assertTrue(closable.closed)
class SuppressTestCase(TestCase):
class SuppressTestCase(unittest.TestCase):
def test_suppress(self):
with suppress(ValueError, TypeError):
@ -68,6 +38,4 @@ class SuppressTestCase(TestCase):
if __name__ == '__main__':
run_class(ContextManagerTestCase)
run_class(ClosingTestCase)
run_class(SuppressTestCase)
unittest.main()