jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/423483 )
Change subject: [cleanup] Remove old for dropped python versions ......................................................................
[cleanup] Remove old for dropped python versions
- tools module: python 2.7.0 and python 2.6 aren't supported anymore Therefore the ContextManagerWrapper code part for bz2 and gzip files could be removed - bot module: total_seconds() was introduced with 2.7 - deprecate ContextManagerWrapper
Change-Id: I50cc95bc7b9a8845b11d2515a97313511668cdcd --- M pywikibot/bot.py M pywikibot/tools/__init__.py M tests/tools_tests.py 3 files changed, 56 insertions(+), 61 deletions(-)
Approvals: Dalba: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/bot.py b/pywikibot/bot.py index ceb9459..802ab04 100644 --- a/pywikibot/bot.py +++ b/pywikibot/bot.py @@ -96,7 +96,7 @@ ) from pywikibot.logging import critical from pywikibot.tools import ( - deprecated, deprecate_arg, deprecated_args, PY2, PYTHON_VERSION, + deprecated, deprecate_arg, deprecated_args, PY2, ) from pywikibot.tools._logging import ( LoggingFormatter as _LoggingFormatter, @@ -1380,10 +1380,7 @@ % (self._treat_counter, self._save_counter)) if hasattr(self, '_start_ts'): delta = (pywikibot.Timestamp.now() - self._start_ts) - if PYTHON_VERSION >= (2, 7): - seconds = int(delta.total_seconds()) - else: - seconds = delta.seconds + delta.days * 86400 + seconds = int(delta.total_seconds()) if delta.days: pywikibot.output("Execution time: %d days, %d seconds" % (delta.days, delta.seconds)) diff --git a/pywikibot/tools/__init__.py b/pywikibot/tools/__init__.py index 95eae41..4df67fc 100644 --- a/pywikibot/tools/__init__.py +++ b/pywikibot/tools/__init__.py @@ -988,48 +988,6 @@ raise StopIteration
-class ContextManagerWrapper(object): - - """ - Wraps an object in a context manager. - - It is redirecting all access to the wrapped object and executes 'close' when - used as a context manager in with-statements. In such statements the value - set via 'as' is directly the wrapped object. For example: - - >>> class Wrapper(object): - ... def close(self): pass - >>> an_object = Wrapper() - >>> wrapped = ContextManagerWrapper(an_object) - >>> with wrapped as another_object: - ... assert another_object is an_object - - It does not subclass the object though, so isinstance checks will fail - outside a with-statement. - """ - - def __init__(self, wrapped): - """Create a new wrapper.""" - super(ContextManagerWrapper, self).__init__() - super(ContextManagerWrapper, self).__setattr__('_wrapped', wrapped) - - def __enter__(self): - """Enter a context manager and use the wrapped object directly.""" - return self._wrapped - - def __exit__(self, exc_type, exc_value, traceback): - """Call close on the wrapped object when exiting a context manager.""" - self._wrapped.close() - - def __getattr__(self, name): - """Get the attribute from the wrapped object.""" - return getattr(self._wrapped, name) - - def __setattr__(self, name, value): - """Set the attribute in the wrapped object.""" - setattr(self._wrapped, name, value) - - def open_archive(filename, mode='rb', use_extension=True): """ Open a file and uncompress it if needed. @@ -1060,17 +1018,8 @@ It is also raised by bz2 when its content is invalid. gzip does not immediately raise that error but only on reading it. @return: A file-like object returning the uncompressed data in binary mode. - Before Python 2.7 the GzipFile object and before 2.7.1 the BZ2File are - wrapped in a ContextManagerWrapper with its advantages/disadvantages. @rtype: file-like object """ - def wrap(wrapped, sub_ver): - """Wrap in a wrapper when this is below Python version 2.7.""" - if PYTHON_VERSION < (2, 7, sub_ver): - return ContextManagerWrapper(wrapped) - else: - return wrapped - if mode in ('r', 'a', 'w'): mode += 'b' elif mode not in ('rb', 'ab', 'wb'): @@ -1097,9 +1046,9 @@ if extension == 'bz2': if isinstance(bz2, ImportError): raise bz2 - return wrap(bz2.BZ2File(filename, mode), 1) + return bz2.BZ2File(filename, mode) elif extension == 'gz': - return wrap(gzip.open(filename, mode), 0) + return gzip.open(filename, mode) elif extension == '7z': if mode != 'rb': raise NotImplementedError('It is not possible to write a 7z file.') @@ -1785,8 +1734,53 @@ sha.update(read_bytes) return sha.hexdigest()
+# deprecated parts ############################################################ + + +class ContextManagerWrapper(object): + + """ + DEPRECATED. Wraps an object in a context manager. + + It is redirecting all access to the wrapped object and executes 'close' + when used as a context manager in with-statements. In such statements the + value set via 'as' is directly the wrapped object. For example: + + >>> class Wrapper(object): + ... def close(self): pass + >>> an_object = Wrapper() + >>> wrapped = ContextManagerWrapper(an_object) + >>> with wrapped as another_object: + ... assert another_object is an_object + + It does not subclass the object though, so isinstance checks will fail + outside a with-statement. + """ + + def __init__(self, wrapped): + """Create a new wrapper.""" + super(ContextManagerWrapper, self).__init__() + super(ContextManagerWrapper, self).__setattr__('_wrapped', wrapped) + + def __enter__(self): + """Enter a context manager and use the wrapped object directly.""" + return self._wrapped + + def __exit__(self, exc_type, exc_value, traceback): + """Call close on the wrapped object when exiting a context manager.""" + self._wrapped.close() + + def __getattr__(self, name): + """Get the attribute from the wrapped object.""" + return getattr(self._wrapped, name) + + def __setattr__(self, name, value): + """Set the attribute in the wrapped object.""" + setattr(self._wrapped, name, value) +
wrapper = ModuleDeprecationWrapper(__name__) wrapper._add_deprecated_attr('Counter', collections.Counter) wrapper._add_deprecated_attr('OrderedDict', collections.OrderedDict) wrapper._add_deprecated_attr('count', itertools.count) +wrapper._add_deprecated_attr('ContextManagerWrapper', replacement_name='') diff --git a/tests/tools_tests.py b/tests/tools_tests.py index ab58205..e0429c0 100644 --- a/tests/tools_tests.py +++ b/tests/tools_tests.py @@ -16,7 +16,7 @@ import warnings
from pywikibot import tools -from pywikibot.tools import classproperty +from pywikibot.tools import classproperty, suppress_warnings
from tests import join_xml_data_path, mock from tests.aspects import ( @@ -49,7 +49,9 @@ def test_wrapper(self): """Create a test instance and verify the wrapper redirects.""" obj = self.DummyClass() - wrapped = tools.ContextManagerWrapper(obj) + with suppress_warnings( + 'pywikibot.tools.ContextManagerWrapper is deprecated.'): + wrapped = tools.ContextManagerWrapper(obj) self.assertIs(wrapped.class_var, obj.class_var) self.assertIs(wrapped.instance_var, obj.instance_var) self.assertIs(wrapped._wrapped, obj) @@ -63,7 +65,9 @@
def test_exec_wrapper(self): """Check that the wrapper permits exceptions.""" - wrapper = tools.ContextManagerWrapper(self.DummyClass()) + with suppress_warnings( + 'pywikibot.tools.ContextManagerWrapper is deprecated.'): + wrapper = tools.ContextManagerWrapper(self.DummyClass()) self.assertFalse(wrapper.closed) with self.assertRaisesRegex(ZeroDivisionError, '(integer division or modulo by zero|division by zero)'):