From e99dd6fa948618015ec19ae1e7f4326e5bb63d21 Mon Sep 17 00:00:00 2001 From: Simon Chopin Date: Tue, 30 Apr 2013 17:28:27 +0200 Subject: [PATCH 1/4] Fix several typos Bug: https://fedorahosted.org/kitchen/ticket/8 Patch-Name: fix_typos --- kitchen2/docs/api-pycompat27.rst | 2 +- kitchen2/docs/designing-unicode-apis.rst | 2 +- kitchen2/docs/hacking.rst | 2 +- kitchen2/docs/unicode-frustrations.rst | 6 +++--- kitchen2/kitchen/i18n/__init__.py | 6 +++--- kitchen2/kitchen/pycompat25/collections/_defaultdict.py | 2 +- kitchen2/kitchen/text/display.py | 6 +++--- releaseutils.py | 2 +- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/kitchen2/docs/api-pycompat27.rst b/kitchen2/docs/api-pycompat27.rst index 6ef6db1..9654b31 100644 --- a/kitchen2/docs/api-pycompat27.rst +++ b/kitchen2/docs/api-pycompat27.rst @@ -31,5 +31,5 @@ New API Feature Ver .. seealso:: - The stdlib :mod:`subprocess` documenation + The stdlib :mod:`subprocess` documentation For complete documentation on how to use subprocess diff --git a/kitchen2/docs/designing-unicode-apis.rst b/kitchen2/docs/designing-unicode-apis.rst index 24265fb..5c909a9 100644 --- a/kitchen2/docs/designing-unicode-apis.rst +++ b/kitchen2/docs/designing-unicode-apis.rst @@ -581,7 +581,7 @@ you should consider when designing a :class:`unicode`-only API: that you may not have thought of. Corner cases in these other places may mean that processing bytes is desirable. 2. In python2, byte :class:`str` and :class:`unicode` are often used - interchangably with each other. That means that people programming against + interchangeably with each other. That means that people programming against your API may have received :class:`str` from some other API and it would be most convenient for their code if your API accepted it. diff --git a/kitchen2/docs/hacking.rst b/kitchen2/docs/hacking.rst index 530b7f2..5eb03c7 100644 --- a/kitchen2/docs/hacking.rst +++ b/kitchen2/docs/hacking.rst @@ -272,7 +272,7 @@ version. Criteria for subpackages in kitchen =================================== -Supackages within kitchen should meet these criteria: +Subpackages within kitchen should meet these criteria: * Generally useful or needed for other pieces of kitchen. diff --git a/kitchen2/docs/unicode-frustrations.rst b/kitchen2/docs/unicode-frustrations.rst index c46e797..5175104 100644 --- a/kitchen2/docs/unicode-frustrations.rst +++ b/kitchen2/docs/unicode-frustrations.rst @@ -33,7 +33,7 @@ In python-2.x, there's two types that deal with text. with byte :class:`str` as those devices are going to need to deal with concrete implementations of what bytes represent your abstract characters. -In the python2 world many APIs use these two classes interchangably but there +In the python2 world many APIs use these two classes interchangeably but there are several important APIs where only one or the other will do the right thing. When you give the wrong type of string to an API that wants the other type, you may end up with an exception being raised (:exc:`UnicodeDecodeError` @@ -122,7 +122,7 @@ we're all set:: So that was simple, right? Well... there's one gotcha that makes things a bit harder to debug sometimes. When you attempt to write non-:term:`ASCII` -:class:`unicode` strings to a file-like object you get a traceback everytime. +:class:`unicode` strings to a file-like object you get a traceback every time. But what happens when you use :func:`print`? The terminal is a file-like object so it should raise an exception right? The answer to that is.... *sometimes*: @@ -539,7 +539,7 @@ a short example that uses many kitchen functions to do its work:: # Note that we do not let implici type conversion from str to # unicode transform b_filename into a unicode string. That might # fail as python would use the ASCII filename. Instead we use - # to_unicode() to explictly transform in a way that we know will + # to_unicode() to explicitly transform in a way that we know will # not traceback. print _(u'filename: %s') % to_unicode(b_filename) print _(u'file size: %s') % size diff --git a/kitchen2/kitchen/i18n/__init__.py b/kitchen2/kitchen/i18n/__init__.py index 80fe3ea..b694409 100644 --- a/kitchen2/kitchen/i18n/__init__.py +++ b/kitchen2/kitchen/i18n/__init__.py @@ -295,8 +295,8 @@ class DummyTranslations(object, gettext.NullTranslations): def _reencode_if_necessary(self, message, output_encoding): '''Return a byte string that's valid in a specific charset. - .. warning:: This method may mangle the message if the inpput encoding - is not known or the message isn't represntable in the chosen + .. warning:: This method may mangle the message if the input encoding + is not known or the message isn't representable in the chosen output encoding. ''' valid = False @@ -721,7 +721,7 @@ def get_translation_object(domain, localedirs=tuple(), languages=None, objects by default. These are superior to the :class:`gettext.GNUTranslations` and :class:`gettext.NullTranslations` objects because they are consistent in the string type they return and - they fix several issues that can causethe |stdlib|_ objects to throw + they fix several issues that can cause the |stdlib|_ objects to throw :exc:`UnicodeError`. 2. This function takes multiple directories to search for :term:`message catalogs`. diff --git a/kitchen2/kitchen/pycompat25/collections/_defaultdict.py b/kitchen2/kitchen/pycompat25/collections/_defaultdict.py index 94ff7c2..d29c29c 100644 --- a/kitchen2/kitchen/pycompat25/collections/_defaultdict.py +++ b/kitchen2/kitchen/pycompat25/collections/_defaultdict.py @@ -73,7 +73,7 @@ the defaultdict class provided by python-2.5 and above. # Pylint disabled messages # -# :C0103: We're defnining a compatible class name therefore we need to match +# :C0103: We're defining a compatible class name therefore we need to match # the format of that name. import types diff --git a/kitchen2/kitchen/text/display.py b/kitchen2/kitchen/text/display.py index 81234de..792878b 100644 --- a/kitchen2/kitchen/text/display.py +++ b/kitchen2/kitchen/text/display.py @@ -3,7 +3,7 @@ # Copyright (c) 2013 Red Hat, Inc. # Copyright (c) 2010 Ville Skyttä # Copyright (c) 2009 Tim Lauridsen -# Copyright (c) 2007 Marcus Kuhn +# Copyright (c) 2007 Markus Kuhn # # kitchen is free software; you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free @@ -20,7 +20,7 @@ # # Authors: # James Antill -# Marcus Kuhn +# Markus Kuhn # Toshio Kuratomi # Tim Lauridsen # Ville Skyttä @@ -211,7 +211,7 @@ def _generate_combining_table(): This is used to generate the :data:`~kitchen.text.display._COMBINING` table. ''' - # Marcus Kuhn's sorted list of non-overlapping intervals of non-spacing + # Markus Kuhn's sorted list of non-overlapping intervals of non-spacing # characters generated ifrom Unicode 5.0 data by: # "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" markus_kuhn_combining_5_0 = ( diff --git a/releaseutils.py b/releaseutils.py index d2e64cf..828c071 100755 --- a/releaseutils.py +++ b/releaseutils.py @@ -47,7 +47,7 @@ def main(): shutil.rmtree('locale') except OSError as e: # If the error is that locale does not exist, we're okay. We're - # deleting it here, afterall + # deleting it here, after all if e.errno != 2: raise From 727e0eb7f33edfca9f1d18997fb2766a2dd3c9fd Mon Sep 17 00:00:00 2001 From: Simon Chopin Date: Thu, 8 Oct 2015 09:26:23 -0700 Subject: [PATCH 2/4] Remove the pycompat* submodules Those are not needed in Debian as we already ship the latest runtime version. Forwarded: not-needed Last-Update: 2013-04-30 Patch-Name: remove_compat_layers --- kitchen2/docs/api-overview.rst | 3 - kitchen2/docs/api-pycompat24.rst | 34 - kitchen2/docs/api-pycompat25.rst | 8 - kitchen2/docs/api-pycompat27.rst | 35 - kitchen2/kitchen/text/converters.py | 3 - kitchen2/kitchen/text/misc.py | 3 - .../tests/subprocessdata/sigchild_ignore.py | 11 - kitchen2/tests/test__all__.py | 2 - kitchen2/tests/test_base64.py | 190 --- kitchen2/tests/test_collections.py | 3 - kitchen2/tests/test_defaultdict.py | 180 -- kitchen2/tests/test_pycompat.py | 25 - kitchen2/tests/test_pycompat24.py | 109 -- kitchen2/tests/test_subprocess.py | 1467 ----------------- kitchen3/docs/api-overview.rst | 3 - kitchen3/docs/api-pycompat24.rst | 34 - kitchen3/docs/api-pycompat25.rst | 8 - kitchen3/docs/api-pycompat27.rst | 35 - .../tests/subprocessdata/sigchild_ignore.py | 11 - kitchen3/tests/test__all__.py | 2 - kitchen3/tests/test_collections.py | 3 - kitchen3/tests/test_deprecation_py3.py | 65 - kitchen3/tests/test_pycompat.py | 25 - setup.py | 14 - 24 files changed, 2273 deletions(-) delete mode 100644 kitchen2/docs/api-pycompat24.rst delete mode 100644 kitchen2/docs/api-pycompat25.rst delete mode 100644 kitchen2/docs/api-pycompat27.rst delete mode 100644 kitchen2/tests/subprocessdata/sigchild_ignore.py delete mode 100644 kitchen2/tests/test_base64.py delete mode 100644 kitchen2/tests/test_defaultdict.py delete mode 100644 kitchen2/tests/test_pycompat.py delete mode 100644 kitchen2/tests/test_pycompat24.py delete mode 100644 kitchen2/tests/test_subprocess.py delete mode 100644 kitchen3/docs/api-pycompat24.rst delete mode 100644 kitchen3/docs/api-pycompat25.rst delete mode 100644 kitchen3/docs/api-pycompat27.rst delete mode 100644 kitchen3/tests/subprocessdata/sigchild_ignore.py delete mode 100644 kitchen3/tests/test_deprecation_py3.py delete mode 100644 kitchen3/tests/test_pycompat.py diff --git a/kitchen2/docs/api-overview.rst b/kitchen2/docs/api-overview.rst index dda56fe..e53a94d 100644 --- a/kitchen2/docs/api-overview.rst +++ b/kitchen2/docs/api-overview.rst @@ -16,9 +16,6 @@ that may drag in more dependencies can be found on the `project webpage`_ api-collections api-iterutils api-versioning - api-pycompat24 - api-pycompat25 - api-pycompat27 api-exceptions .. _`project webpage`: https://fedorahosted.org/kitchen diff --git a/kitchen2/docs/api-pycompat24.rst b/kitchen2/docs/api-pycompat24.rst deleted file mode 100644 index a3247b6..0000000 --- a/kitchen2/docs/api-pycompat24.rst +++ /dev/null @@ -1,34 +0,0 @@ -======================= -Python 2.4 Compatibiity -======================= - - -------------------- -Sets for python-2.3 -------------------- - -.. automodule:: kitchen.pycompat24.sets -.. autofunction:: kitchen.pycompat24.sets.add_builtin_set - ----------------------------------- -Partial new style base64 interface ----------------------------------- - -.. automodule:: kitchen.pycompat24.base64 - :members: - ----------- -Subprocess ----------- - -.. seealso:: - - :mod:`kitchen.pycompat27.subprocess` - Kitchen includes the python-2.7 version of subprocess which has a new - function, :func:`~kitchen.pycompat27.subprocess.check_output`. When - you import :mod:`pycompat24.subprocess` you will be getting the - python-2.7 version of subprocess rather than the 2.4 version (where - subprocess first appeared). This choice was made so that we can - concentrate our efforts on keeping the single version of subprocess up - to date rather than working on a 2.4 version that very few people - would need specifically. diff --git a/kitchen2/docs/api-pycompat25.rst b/kitchen2/docs/api-pycompat25.rst deleted file mode 100644 index 1841c6a..0000000 --- a/kitchen2/docs/api-pycompat25.rst +++ /dev/null @@ -1,8 +0,0 @@ -======================== -Python 2.5 Compatibility -======================== - -.. automodule:: kitchen.pycompat25 - -.. automodule:: kitchen.pycompat25.collections._defaultdict - diff --git a/kitchen2/docs/api-pycompat27.rst b/kitchen2/docs/api-pycompat27.rst deleted file mode 100644 index 9654b31..0000000 --- a/kitchen2/docs/api-pycompat27.rst +++ /dev/null @@ -1,35 +0,0 @@ -======================== -Python 2.7 Compatibility -======================== - -.. module:: kitchen.pycompat27.subprocess - --------------------------- -Subprocess from Python 2.7 --------------------------- - -The :mod:`subprocess` module included here is a direct import from -python-2.7's |stdlib|_. You can access it via:: - - >>> from kitchen.pycompat27 import subprocess - -The motivation for including this module is that various API changing -improvements have been made to subprocess over time. The following is a list -of the known changes to :mod:`subprocess` with the python version they were -introduced in: - -==================================== === -New API Feature Ver -==================================== === -:exc:`subprocess.CalledProcessError` 2.5 -:func:`subprocess.check_call` 2.5 -:func:`subprocess.check_output` 2.7 -:meth:`subprocess.Popen.send_signal` 2.6 -:meth:`subprocess.Popen.terminate` 2.6 -:meth:`subprocess.Popen.kill` 2.6 -==================================== === - -.. seealso:: - - The stdlib :mod:`subprocess` documentation - For complete documentation on how to use subprocess diff --git a/kitchen2/kitchen/text/converters.py b/kitchen2/kitchen/text/converters.py index e4bcb0d..eb518cb 100644 --- a/kitchen2/kitchen/text/converters.py +++ b/kitchen2/kitchen/text/converters.py @@ -50,9 +50,6 @@ import codecs import warnings import xml.sax.saxutils -from kitchen.pycompat24 import sets -sets.add_builtin_set() - from kitchen.text.exceptions import ControlCharError, XmlEncodeError from kitchen.text.misc import guess_encoding, html_entities_unescape, \ isbytestring, isunicodestring, process_control_chars diff --git a/kitchen2/kitchen/text/misc.py b/kitchen2/kitchen/text/misc.py index 333e363..babb68e 100644 --- a/kitchen2/kitchen/text/misc.py +++ b/kitchen2/kitchen/text/misc.py @@ -43,11 +43,8 @@ try: except ImportError: chardet = None -from kitchen.pycompat24 import sets from kitchen.text.exceptions import ControlCharError -sets.add_builtin_set() - # Define a threshold for chardet confidence. If we fall below this we decode # byte strings we're guessing about as latin1 _CHARDET_THRESHHOLD = 0.6 diff --git a/kitchen2/tests/subprocessdata/sigchild_ignore.py b/kitchen2/tests/subprocessdata/sigchild_ignore.py deleted file mode 100644 index 5b6dd08..0000000 --- a/kitchen2/tests/subprocessdata/sigchild_ignore.py +++ /dev/null @@ -1,11 +0,0 @@ -import os -import signal, sys -sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..')) - -from kitchen.pycompat27.subprocess import _subprocess as subprocess - -# On Linux this causes os.waitpid to fail with OSError as the OS has already -# reaped our child process. The wait() passing the OSError on to the caller -# and causing us to exit with an error is what we are testing against. -signal.signal(signal.SIGCHLD, signal.SIG_IGN) -subprocess.Popen([sys.executable, '-c', 'print("albatross")']).wait() diff --git a/kitchen2/tests/test__all__.py b/kitchen2/tests/test__all__.py index dda287a..e08d699 100644 --- a/kitchen2/tests/test__all__.py +++ b/kitchen2/tests/test__all__.py @@ -4,8 +4,6 @@ from nose import tools import os import types import warnings -from kitchen.pycompat24.sets import add_builtin_set -add_builtin_set() def logit(msg): log = open('/var/tmp/test.log', 'a') diff --git a/kitchen2/tests/test_base64.py b/kitchen2/tests/test_base64.py deleted file mode 100644 index 49e1cd1..0000000 --- a/kitchen2/tests/test_base64.py +++ /dev/null @@ -1,190 +0,0 @@ -import unittest -from kitchen.pycompat24.base64 import _base64 as base64 - - - -class LegacyBase64TestCase(unittest.TestCase): - def test_encodestring(self): - eq = self.assertEqual - eq(base64.encodestring("www.python.org"), "d3d3LnB5dGhvbi5vcmc=\n") - eq(base64.encodestring("a"), "YQ==\n") - eq(base64.encodestring("ab"), "YWI=\n") - eq(base64.encodestring("abc"), "YWJj\n") - eq(base64.encodestring(""), "") - eq(base64.encodestring("abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789!@#0^&*();:<>,. []{}"), - "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE" - "RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT" - "Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n") - - def test_decodestring(self): - eq = self.assertEqual - eq(base64.decodestring("d3d3LnB5dGhvbi5vcmc=\n"), "www.python.org") - eq(base64.decodestring("YQ==\n"), "a") - eq(base64.decodestring("YWI=\n"), "ab") - eq(base64.decodestring("YWJj\n"), "abc") - eq(base64.decodestring("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE" - "RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT" - "Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n"), - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789!@#0^&*();:<>,. []{}") - eq(base64.decodestring(''), '') - - def test_encode(self): - eq = self.assertEqual - from cStringIO import StringIO - infp = StringIO('abcdefghijklmnopqrstuvwxyz' - 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' - '0123456789!@#0^&*();:<>,. []{}') - outfp = StringIO() - base64.encode(infp, outfp) - eq(outfp.getvalue(), - 'YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE' - 'RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT' - 'Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n') - - def test_decode(self): - from cStringIO import StringIO - infp = StringIO('d3d3LnB5dGhvbi5vcmc=') - outfp = StringIO() - base64.decode(infp, outfp) - self.assertEqual(outfp.getvalue(), 'www.python.org') - - - -class BaseXYTestCase(unittest.TestCase): - def test_b64encode(self): - eq = self.assertEqual - # Test default alphabet - eq(base64.b64encode("www.python.org"), "d3d3LnB5dGhvbi5vcmc=") - eq(base64.b64encode('\x00'), 'AA==') - eq(base64.b64encode("a"), "YQ==") - eq(base64.b64encode("ab"), "YWI=") - eq(base64.b64encode("abc"), "YWJj") - eq(base64.b64encode(""), "") - eq(base64.b64encode("abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789!@#0^&*();:<>,. []{}"), - "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE" - "RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NT" - "Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==") - # Test with arbitrary alternative characters - eq(base64.b64encode('\xd3V\xbeo\xf7\x1d', altchars='*$'), '01a*b$cd') - # Test standard alphabet - eq(base64.standard_b64encode("www.python.org"), "d3d3LnB5dGhvbi5vcmc=") - eq(base64.standard_b64encode("a"), "YQ==") - eq(base64.standard_b64encode("ab"), "YWI=") - eq(base64.standard_b64encode("abc"), "YWJj") - eq(base64.standard_b64encode(""), "") - eq(base64.standard_b64encode("abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789!@#0^&*();:<>,. []{}"), - "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE" - "RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NT" - "Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==") - # Test with 'URL safe' alternative characters - eq(base64.urlsafe_b64encode('\xd3V\xbeo\xf7\x1d'), '01a-b_cd') - - def test_b64decode(self): - eq = self.assertEqual - eq(base64.b64decode("d3d3LnB5dGhvbi5vcmc="), "www.python.org") - eq(base64.b64decode('AA=='), '\x00') - eq(base64.b64decode("YQ=="), "a") - eq(base64.b64decode("YWI="), "ab") - eq(base64.b64decode("YWJj"), "abc") - eq(base64.b64decode("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE" - "RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT" - "Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ=="), - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789!@#0^&*();:<>,. []{}") - eq(base64.b64decode(''), '') - # Test with arbitrary alternative characters - eq(base64.b64decode('01a*b$cd', altchars='*$'), '\xd3V\xbeo\xf7\x1d') - # Test standard alphabet - eq(base64.standard_b64decode("d3d3LnB5dGhvbi5vcmc="), "www.python.org") - eq(base64.standard_b64decode("YQ=="), "a") - eq(base64.standard_b64decode("YWI="), "ab") - eq(base64.standard_b64decode("YWJj"), "abc") - eq(base64.standard_b64decode(""), "") - eq(base64.standard_b64decode("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE" - "RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0NT" - "Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ=="), - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789!@#0^&*();:<>,. []{}") - # Test with 'URL safe' alternative characters - eq(base64.urlsafe_b64decode('01a-b_cd'), '\xd3V\xbeo\xf7\x1d') - - def test_b64decode_error(self): - self.assertRaises(TypeError, base64.b64decode, 'abc') - - def test_b32encode(self): - eq = self.assertEqual - eq(base64.b32encode(''), '') - eq(base64.b32encode('\x00'), 'AA======') - eq(base64.b32encode('a'), 'ME======') - eq(base64.b32encode('ab'), 'MFRA====') - eq(base64.b32encode('abc'), 'MFRGG===') - eq(base64.b32encode('abcd'), 'MFRGGZA=') - eq(base64.b32encode('abcde'), 'MFRGGZDF') - - def test_b32decode(self): - eq = self.assertEqual - eq(base64.b32decode(''), '') - eq(base64.b32decode('AA======'), '\x00') - eq(base64.b32decode('ME======'), 'a') - eq(base64.b32decode('MFRA===='), 'ab') - eq(base64.b32decode('MFRGG==='), 'abc') - eq(base64.b32decode('MFRGGZA='), 'abcd') - eq(base64.b32decode('MFRGGZDF'), 'abcde') - - def test_b32decode_casefold(self): - eq = self.assertEqual - eq(base64.b32decode('', True), '') - eq(base64.b32decode('ME======', True), 'a') - eq(base64.b32decode('MFRA====', True), 'ab') - eq(base64.b32decode('MFRGG===', True), 'abc') - eq(base64.b32decode('MFRGGZA=', True), 'abcd') - eq(base64.b32decode('MFRGGZDF', True), 'abcde') - # Lower cases - eq(base64.b32decode('me======', True), 'a') - eq(base64.b32decode('mfra====', True), 'ab') - eq(base64.b32decode('mfrgg===', True), 'abc') - eq(base64.b32decode('mfrggza=', True), 'abcd') - eq(base64.b32decode('mfrggzdf', True), 'abcde') - # Expected exceptions - self.assertRaises(TypeError, base64.b32decode, 'me======') - # Mapping zero and one - eq(base64.b32decode('MLO23456'), 'b\xdd\xad\xf3\xbe') - eq(base64.b32decode('M1023456', map01='L'), 'b\xdd\xad\xf3\xbe') - eq(base64.b32decode('M1023456', map01='I'), 'b\x1d\xad\xf3\xbe') - - def test_b32decode_error(self): - self.assertRaises(TypeError, base64.b32decode, 'abc') - self.assertRaises(TypeError, base64.b32decode, 'ABCDEF==') - - def test_b16encode(self): - eq = self.assertEqual - eq(base64.b16encode('\x01\x02\xab\xcd\xef'), '0102ABCDEF') - eq(base64.b16encode('\x00'), '00') - - def test_b16decode(self): - eq = self.assertEqual - eq(base64.b16decode('0102ABCDEF'), '\x01\x02\xab\xcd\xef') - eq(base64.b16decode('00'), '\x00') - # Lower case is not allowed without a flag - self.assertRaises(TypeError, base64.b16decode, '0102abcdef') - # Case fold - eq(base64.b16decode('0102abcdef', True), '\x01\x02\xab\xcd\xef') - - - -#from test import test_support -#def test_main(): -# test_support.run_unittest(__name__) -# -#if __name__ == '__main__': -# test_main() diff --git a/kitchen2/tests/test_collections.py b/kitchen2/tests/test_collections.py index 5e4dbd4..8765594 100644 --- a/kitchen2/tests/test_collections.py +++ b/kitchen2/tests/test_collections.py @@ -3,9 +3,6 @@ import unittest from nose import tools -from kitchen.pycompat24.sets import add_builtin_set -add_builtin_set() - from kitchen import collections def test_strict_dict_get_set(): diff --git a/kitchen2/tests/test_defaultdict.py b/kitchen2/tests/test_defaultdict.py deleted file mode 100644 index 5848d28..0000000 --- a/kitchen2/tests/test_defaultdict.py +++ /dev/null @@ -1,180 +0,0 @@ -"""Unit tests for collections.defaultdict.""" - -import os -import copy -import tempfile -import unittest - -from kitchen.pycompat25.collections._defaultdict import defaultdict - -def foobar(): - return list - -class TestDefaultDict(unittest.TestCase): - - def test_basic(self): - d1 = defaultdict() - self.assertEqual(d1.default_factory, None) - d1.default_factory = list - d1[12].append(42) - self.assertEqual(d1, {12: [42]}) - d1[12].append(24) - self.assertEqual(d1, {12: [42, 24]}) - d1[13] - d1[14] - self.assertEqual(d1, {12: [42, 24], 13: [], 14: []}) - self.assert_(d1[12] is not d1[13] is not d1[14]) - d2 = defaultdict(list, foo=1, bar=2) - self.assertEqual(d2.default_factory, list) - self.assertEqual(d2, {"foo": 1, "bar": 2}) - self.assertEqual(d2["foo"], 1) - self.assertEqual(d2["bar"], 2) - self.assertEqual(d2[42], []) - self.assert_("foo" in d2) - self.assert_("foo" in d2.keys()) - self.assert_("bar" in d2) - self.assert_("bar" in d2.keys()) - self.assert_(42 in d2) - self.assert_(42 in d2.keys()) - self.assert_(12 not in d2) - self.assert_(12 not in d2.keys()) - d2.default_factory = None - self.assertEqual(d2.default_factory, None) - try: - d2[15] - except KeyError, err: - self.assertEqual(err.args, (15,)) - else: - self.fail("d2[15] didn't raise KeyError") - self.assertRaises(TypeError, defaultdict, 1) - - def test_missing(self): - d1 = defaultdict() - self.assertRaises(KeyError, d1.__missing__, 42) - d1.default_factory = list - self.assertEqual(d1.__missing__(42), []) - - def test_repr(self): - d1 = defaultdict() - self.assertEqual(d1.default_factory, None) - self.assertEqual(repr(d1), "defaultdict(None, {})") - self.assertEqual(eval(repr(d1)), d1) - d1[11] = 41 - self.assertEqual(repr(d1), "defaultdict(None, {11: 41})") - d2 = defaultdict(int) - self.assertEqual(d2.default_factory, int) - d2[12] = 42 - self.assertEqual(repr(d2), "defaultdict(, {12: 42})") - def foo(): return 43 - d3 = defaultdict(foo) - - self.assert_(d3.default_factory is foo) - d3[13] - self.assertEqual(repr(d3), "defaultdict(%s, {13: 43})" % repr(foo)) - - def test_print(self): - d1 = defaultdict() - def foo(): return 42 - d2 = defaultdict(foo, {1: 2}) - # NOTE: We can't use tempfile.[Named]TemporaryFile since this - # code must exercise the tp_print C code, which only gets - # invoked for *real* files. - tfn = tempfile.mktemp() - try: - f = open(tfn, "w+") - try: - print >>f, d1 - print >>f, d2 - f.seek(0) - self.assertEqual(f.readline(), repr(d1) + "\n") - self.assertEqual(f.readline(), repr(d2) + "\n") - finally: - f.close() - finally: - os.remove(tfn) - - def test_copy(self): - d1 = defaultdict() - d2 = d1.copy() - self.assertEqual(type(d2), defaultdict) - self.assertEqual(d2.default_factory, None) - self.assertEqual(d2, {}) - d1.default_factory = list - d3 = d1.copy() - self.assertEqual(type(d3), defaultdict) - self.assertEqual(d3.default_factory, list) - self.assertEqual(d3, {}) - d1[42] - d4 = d1.copy() - self.assertEqual(type(d4), defaultdict) - self.assertEqual(d4.default_factory, list) - self.assertEqual(d4, {42: []}) - d4[12] - self.assertEqual(d4, {42: [], 12: []}) - - # Issue 6637: Copy fails for empty default dict - d = defaultdict() - d['a'] = 42 - e = d.copy() - self.assertEqual(e['a'], 42) - - def test_shallow_copy(self): - d1 = defaultdict(foobar, {1: 1}) - d2 = copy.copy(d1) - self.assertEqual(d2.default_factory, foobar) - self.assertEqual(d2, d1) - d1.default_factory = list - d2 = copy.copy(d1) - self.assertEqual(d2.default_factory, list) - self.assertEqual(d2, d1) - - def test_deep_copy(self): - d1 = defaultdict(foobar, {1: [1]}) - d2 = copy.deepcopy(d1) - self.assertEqual(d2.default_factory, foobar) - self.assertEqual(d2, d1) - self.assert_(d1[1] is not d2[1]) - d1.default_factory = list - d2 = copy.deepcopy(d1) - self.assertEqual(d2.default_factory, list) - self.assertEqual(d2, d1) - - def test_keyerror_without_factory(self): - d1 = defaultdict() - try: - d1[(1,)] - except KeyError, err: - self.assertEqual(err.args[0], (1,)) - else: - self.fail("expected KeyError") - - def test_recursive_repr(self): - # Issue2045: stack overflow when default_factory is a bound method - class sub(defaultdict): - def __init__(self): - self.default_factory = self._factory - def _factory(self): - return [] - d = sub() - self.assert_(repr(d).startswith( - "defaultdict(>f, d - finally: - f.close() - finally: - os.remove(tfn) - - -#from test import test_support -#def test_main(): -# test_support.run_unittest(TestDefaultDict) -# -#if __name__ == "__main__": -# test_main() diff --git a/kitchen2/tests/test_pycompat.py b/kitchen2/tests/test_pycompat.py deleted file mode 100644 index 50a059b..0000000 --- a/kitchen2/tests/test_pycompat.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# -import unittest -from nose import tools - -class TestUsableModules(unittest.TestCase): - def test_subprocess(self): - '''Test that importing subprocess as a module works - ''' - try: - from kitchen.pycompat24.subprocess import Popen - except ImportError: - tools.ok_(False, 'Unable to import pycompat24.subprocess as a module') - try: - from kitchen.pycompat27.subprocess import Popen - except ImportError: - tools.ok_(False, 'Unable to import pycompat27.subprocess as a module') - - def test_base64(self): - '''Test that importing base64 as a module works - ''' - try: - from kitchen.pycompat24.base64 import b64encode - except ImportError: - tools.ok_(False, 'Unable to import pycompat24.base64 as a module') diff --git a/kitchen2/tests/test_pycompat24.py b/kitchen2/tests/test_pycompat24.py deleted file mode 100644 index adea7fe..0000000 --- a/kitchen2/tests/test_pycompat24.py +++ /dev/null @@ -1,109 +0,0 @@ -# -*- coding: utf-8 -*- -# -import unittest -from nose import tools -from nose.plugins.skip import SkipTest - -import __builtin__ -import base64 as py_b64 -import warnings - -from kitchen.pycompat24 import sets -from kitchen.pycompat24.base64 import _base64 as base64 - -class TestSetsNoOverwrite(unittest.TestCase): - def setUp(self): - self.set_val = None - self.frozenset_val = None - if not hasattr(__builtin__, 'set'): - __builtin__.set = self.set_val - else: - self.set_val = __builtin__.set - if not hasattr(__builtin__, 'frozenset'): - __builtin__.frozenset = self.frozenset_val - else: - self.frozenset_val = __builtin__.frozenset - - def tearDown(self): - if self.frozenset_val == None: - del(__builtin__.frozenset) - if self.set_val == None: - del(__builtin__.set) - - def test_sets_dont_overwrite(self): - '''Test that importing sets when there's already a set and frozenset defined does not overwrite - ''' - sets.add_builtin_set() - tools.ok_(__builtin__.set == self.set_val) - tools.ok_(__builtin__.frozenset == self.frozenset_val) - -class TestDefineSets(unittest.TestCase): - def setUp(self): - warnings.simplefilter('ignore', DeprecationWarning) - self.set_val = None - self.frozenset_val = None - if hasattr(__builtin__, 'set'): - self.set_val = __builtin__.set - del(__builtin__.set) - if hasattr(__builtin__, 'frozenset'): - self.frozenset_val = __builtin__.frozenset - del(__builtin__.frozenset) - - def tearDown(self): - warnings.simplefilter('default', DeprecationWarning) - if self.set_val: - __builtin__.set = self.set_val - else: - del(__builtin__.set) - if self.frozenset_val: - __builtin__.frozenset = self.frozenset_val - else: - del(__builtin__.frozenset) - - def test_pycompat_defines_set(self): - '''Test that calling pycompat24.add_builtin_set() adds set and frozenset to __builtin__ - ''' - import sets as py_sets - sets.add_builtin_set() - if self.set_val: - tools.ok_(__builtin__.set == self.set_val) - tools.ok_(__builtin__.frozenset == self.frozenset_val) - else: - tools.ok_(__builtin__.set == py_sets.Set) - tools.ok_(__builtin__.frozenset == py_sets.ImmutableSet) - -class TestSubprocess(unittest.TestCase): - pass - -class TestBase64(unittest.TestCase): - b_byte_chars = ' '.join(map(chr, range(0, 256))) - b_byte_encoded = 'ACABIAIgAyAEIAUgBiAHIAggCSAKIAsgDCANIA4gDyAQIBEgEiATIBQgFSAWIBcgGCAZIBogGyAcIB0gHiAfICAgISAiICMgJCAlICYgJyAoICkgKiArICwgLSAuIC8gMCAxIDIgMyA0IDUgNiA3IDggOSA6IDsgPCA9ID4gPyBAIEEgQiBDIEQgRSBGIEcgSCBJIEogSyBMIE0gTiBPIFAgUSBSIFMgVCBVIFYgVyBYIFkgWiBbIFwgXSBeIF8gYCBhIGIgYyBkIGUgZiBnIGggaSBqIGsgbCBtIG4gbyBwIHEgciBzIHQgdSB2IHcgeCB5IHogeyB8IH0gfiB/IIAggSCCIIMghCCFIIYghyCIIIkgiiCLIIwgjSCOII8gkCCRIJIgkyCUIJUgliCXIJggmSCaIJsgnCCdIJ4gnyCgIKEgoiCjIKQgpSCmIKcgqCCpIKogqyCsIK0griCvILAgsSCyILMgtCC1ILYgtyC4ILkguiC7ILwgvSC+IL8gwCDBIMIgwyDEIMUgxiDHIMggySDKIMsgzCDNIM4gzyDQINEg0iDTINQg1SDWINcg2CDZINog2yDcIN0g3iDfIOAg4SDiIOMg5CDlIOYg5yDoIOkg6iDrIOwg7SDuIO8g8CDxIPIg8yD0IPUg9iD3IPgg+SD6IPsg/CD9IP4g/w==' - b_byte_encoded_urlsafe = 'ACABIAIgAyAEIAUgBiAHIAggCSAKIAsgDCANIA4gDyAQIBEgEiATIBQgFSAWIBcgGCAZIBogGyAcIB0gHiAfICAgISAiICMgJCAlICYgJyAoICkgKiArICwgLSAuIC8gMCAxIDIgMyA0IDUgNiA3IDggOSA6IDsgPCA9ID4gPyBAIEEgQiBDIEQgRSBGIEcgSCBJIEogSyBMIE0gTiBPIFAgUSBSIFMgVCBVIFYgVyBYIFkgWiBbIFwgXSBeIF8gYCBhIGIgYyBkIGUgZiBnIGggaSBqIGsgbCBtIG4gbyBwIHEgciBzIHQgdSB2IHcgeCB5IHogeyB8IH0gfiB_IIAggSCCIIMghCCFIIYghyCIIIkgiiCLIIwgjSCOII8gkCCRIJIgkyCUIJUgliCXIJggmSCaIJsgnCCdIJ4gnyCgIKEgoiCjIKQgpSCmIKcgqCCpIKogqyCsIK0griCvILAgsSCyILMgtCC1ILYgtyC4ILkguiC7ILwgvSC-IL8gwCDBIMIgwyDEIMUgxiDHIMggySDKIMsgzCDNIM4gzyDQINEg0iDTINQg1SDWINcg2CDZINog2yDcIN0g3iDfIOAg4SDiIOMg5CDlIOYg5yDoIOkg6iDrIOwg7SDuIO8g8CDxIPIg8yD0IPUg9iD3IPgg-SD6IPsg_CD9IP4g_w==' - - def test_base64_encode(self): - tools.ok_(base64.b64encode(self.b_byte_chars) == self.b_byte_encoded) - tools.ok_(base64.b64encode(self.b_byte_chars, altchars='-_') == self.b_byte_encoded_urlsafe) - tools.ok_(base64.standard_b64encode(self.b_byte_chars) == self.b_byte_encoded) - tools.ok_(base64.urlsafe_b64encode(self.b_byte_chars) == self.b_byte_encoded_urlsafe) - - tools.ok_(base64.b64encode(self.b_byte_chars) == self.b_byte_encoded) - tools.ok_(base64.b64encode(self.b_byte_chars, altchars='-_') == self.b_byte_encoded_urlsafe) - tools.ok_(base64.standard_b64encode(self.b_byte_chars) == self.b_byte_encoded) - tools.ok_(base64.urlsafe_b64encode(self.b_byte_chars) == self.b_byte_encoded_urlsafe) - - def test_base64_decode(self): - tools.ok_(base64.b64decode(self.b_byte_encoded) == self.b_byte_chars) - tools.ok_(base64.b64decode(self.b_byte_encoded_urlsafe, altchars='-_') == self.b_byte_chars) - tools.ok_(base64.standard_b64decode(self.b_byte_encoded) == self.b_byte_chars) - tools.ok_(base64.urlsafe_b64decode(self.b_byte_encoded_urlsafe) == self.b_byte_chars) - - tools.ok_(base64.b64decode(self.b_byte_encoded) == self.b_byte_chars) - tools.ok_(base64.b64decode(self.b_byte_encoded_urlsafe, altchars='-_') == self.b_byte_chars) - tools.ok_(base64.standard_b64decode(self.b_byte_encoded) == self.b_byte_chars) - tools.ok_(base64.urlsafe_b64decode(self.b_byte_encoded_urlsafe) == self.b_byte_chars) - - def test_base64_stdlib_compat(self): - if not hasattr(py_b64, 'b64encode'): - raise SkipTest('Python-2.3 doesn\'t have b64encode to compare against') - tools.ok_(base64.b64encode(self.b_byte_chars) == py_b64.b64encode(self.b_byte_chars)) - tools.ok_(base64.b64decode(self.b_byte_chars) == py_b64.b64decode(self.b_byte_chars)) diff --git a/kitchen2/tests/test_subprocess.py b/kitchen2/tests/test_subprocess.py deleted file mode 100644 index 010f660..0000000 --- a/kitchen2/tests/test_subprocess.py +++ /dev/null @@ -1,1467 +0,0 @@ -import unittest -from nose.plugins.skip import SkipTest -from kitchen.pycompat27.subprocess import _subprocess as subprocess -import sys -import StringIO -import signal -import os -import errno -import tempfile -import time -import re -# Not available on python2.6 or less -#import sysconfig - -mswindows = (sys.platform == "win32") - -# -# Depends on the following external programs: Python -# - -if mswindows: - SETBINARY = ('import msvcrt; msvcrt.setmode(sys.stdout.fileno(), ' - 'os.O_BINARY);') -else: - SETBINARY = '' - -def reap_children(): - """Use this function at the end of test_main() whenever sub-processes - are started. This will help ensure that no extra children (zombies) - stick around to hog resources and create problems when looking - for refleaks. - """ - - # Reap all our dead child processes so we don't leave zombies around. - # These hog resources and might be causing some of the buildbots to die. - if hasattr(os, 'waitpid'): - any_process = -1 - while True: - try: - # This will raise an exception on Windows. That's ok. - pid, status = os.waitpid(any_process, os.WNOHANG) - if pid == 0: - break - except: - break - -test_support = None -try: - from test import test_support - if not hasattr(test_support, 'reap_children'): - # No reap_children in python-2.3 - test_support.reap_children = reap_children -except ImportError: - pass - -# In a debug build, stuff like "[6580 refs]" is printed to stderr at -# shutdown time. That frustrates tests trying to check stderr produced -# from a spawned Python process. -def remove_stderr_debug_decorations(stderr): - return re.sub(r"\[\d+ refs\]\r?\n?$", "", stderr) - -try: - mkstemp = tempfile.mkstemp -except AttributeError: - # tempfile.mkstemp is not available - def mkstemp(): - """Replacement for mkstemp, calling mktemp.""" - fname = tempfile.mktemp() - return os.open(fname, os.O_RDWR|os.O_CREAT), fname - - -class BaseTestCase(unittest.TestCase): - def __init__(self, *args, **kwargs): - unittest.TestCase.__init__(self, *args, **kwargs) - if not hasattr(self, '_cleanups'): - self._cleanups = [] - if not hasattr(self, 'addCleanup'): - self.addCleanup = self._addCleanup - - def _addCleanup(self, function, *args, **kwargs): - self._cleanups.append((function, args, kwargs)) - - def setUp(self): - # Try to minimize the number of children we have so this test - # doesn't crash on some buildbots (Alphas in particular). - if test_support: - test_support.reap_children() - - def tearDown(self): - for inst in subprocess._active: - inst.wait() - subprocess._cleanup() - # assertFalse is not available in python-2.3 - self.failIf(subprocess._active, "subprocess._active not empty") - - if not hasattr(self, 'doCleanups'): - ok = True - while self._cleanups: - function, args, kwargs = self._cleanups.pop(-1) - try: - function(*args, **kwargs) - except Exception: - ok = False - - def assertStderrEqual(self, stderr, expected, msg=None): - # In a debug build, stuff like "[6580 refs]" is printed to stderr at - # shutdown time. That frustrates tests trying to check stderr produced - # from a spawned Python process. - actual = re.sub(r"\[\d+ refs\]\r?\n?$", "", stderr) - self.assertEqual(actual, expected, msg) - - -class ProcessTestCase(BaseTestCase): - - def test_call_seq(self): - # call() function with sequence argument - rc = subprocess.call([sys.executable, "-c", - "import sys; sys.exit(47)"]) - self.assertEqual(rc, 47) - - def test_check_call_zero(self): - # check_call() function with zero return code - rc = subprocess.check_call([sys.executable, "-c", - "import sys; sys.exit(0)"]) - self.assertEqual(rc, 0) - - def test_check_call_nonzero(self): - # check_call() function with non-zero return code - #with self.assertRaises(subprocess.CalledProcessError) as c: - try: - subprocess.check_call([sys.executable, "-c", - "import sys; sys.exit(47)"]) - #self.assertEqual(c.exception.returncode, 47) - except subprocess.CalledProcessError, e: - self.assertEqual(e.returncode, 47) - else: - self.fail("Expected CalledProcessError") - - def test_check_output(self): - # check_output() function with zero return code - output = subprocess.check_output( - [sys.executable, "-c", "print 'BDFL'"]) - #self.assertIn('BDFL', output) - self.assert_('BDFL' in output) - - def test_check_output_nonzero(self): - # check_call() function with non-zero return code - #with self.assertRaises(subprocess.CalledProcessError) as c: - try: - subprocess.check_output( - [sys.executable, "-c", "import sys; sys.exit(5)"]) - #self.assertEqual(c.exception.returncode, 5) - except subprocess.CalledProcessError, e: - self.assertEqual(e.returncode, 5) - else: - self.fail("Expected CalledProcessError") - - def test_check_output_stderr(self): - # check_output() function stderr redirected to stdout - output = subprocess.check_output( - [sys.executable, "-c", "import sys; sys.stderr.write('BDFL')"], - stderr=subprocess.STDOUT) - #self.assertIn('BDFL', output) - self.assert_('BDFL' in output) - - def test_check_output_stdout_arg(self): - # check_output() function stderr redirected to stdout - #with self.assertRaises(ValueError) as c: - try: - output = subprocess.check_output( - [sys.executable, "-c", "print 'will not be run'"], - stdout=sys.stdout) - #self.fail("Expected ValueError when stdout arg supplied.") - #self.assertIn('stdout', c.exception.args[0]) - except ValueError, e: - #self.assertIn('stdout', e.args[0]) - self.assert_('stdout' in e.args[0]) - else: - self.fail("Expected ValueError when stdout arg supplied.") - - def test_call_kwargs(self): - # call() function with keyword args - newenv = os.environ.copy() - newenv["FRUIT"] = "banana" - rc = subprocess.call([sys.executable, "-c", - 'import sys, os;' - 'sys.exit(os.getenv("FRUIT")=="banana")'], - env=newenv) - self.assertEqual(rc, 1) - - def test_invalid_args(self): - # Popen() called with invalid arguments should raise TypeError - # but Popen.__del__ should not complain (issue #12085) - #with test_support.captured_stderr() as s: - orig_stderr = getattr(sys, 'stderr') - setattr(sys, 'stderr', StringIO.StringIO()) - s = sys.stderr - try: - try: - subprocess.Popen(invalid_arg_name=1) - except TypeError: - pass - except: - self.fail("Expected TypeError") - else: - self.fail("Expected TypeError") - argcount = subprocess.Popen.__init__.func_code.co_argcount - too_many_args = [0] * (argcount + 1) - try: - subprocess.Popen(*too_many_args) - except TypeError: - pass - except: - self.fail("Expected TypeError") - else: - self.fail("Expected TypeError") - finally: - setattr(sys,'stderr', orig_stderr) - self.assertEqual(s.getvalue(), '') - - def test_stdin_none(self): - # .stdin is None when not redirected - p = subprocess.Popen([sys.executable, "-c", 'print "banana"'], - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - self.addCleanup(p.stdout.close) - self.addCleanup(p.stderr.close) - p.wait() - self.assertEqual(p.stdin, None) - - def test_stdout_none(self): - # .stdout is None when not redirected - p = subprocess.Popen([sys.executable, "-c", - 'print " this bit of output is from a ' - 'test of stdout in a different ' - 'process ..."'], - stdin=subprocess.PIPE, stderr=subprocess.PIPE) - self.addCleanup(p.stdin.close) - self.addCleanup(p.stderr.close) - p.wait() - self.assertEqual(p.stdout, None) - - def test_stderr_none(self): - # .stderr is None when not redirected - p = subprocess.Popen([sys.executable, "-c", 'print "banana"'], - stdin=subprocess.PIPE, stdout=subprocess.PIPE) - self.addCleanup(p.stdout.close) - self.addCleanup(p.stdin.close) - p.wait() - self.assertEqual(p.stderr, None) - - def test_executable_with_cwd(self): - python_dir = os.path.dirname(os.path.realpath(sys.executable)) - p = subprocess.Popen(["somethingyoudonthave", "-c", - "import sys; sys.exit(47)"], - executable=sys.executable, cwd=python_dir) - p.wait() - self.assertEqual(p.returncode, 47) - - # Not available on python2.3 and we know we're not building python itself - #@unittest.skipIf(sysconfig.is_python_build(), - # "need an installed Python. See #7774") - def test_executable_without_cwd(self): - # For a normal installation, it should work without 'cwd' - # argument. For test runs in the build directory, see #7774. - p = subprocess.Popen(["somethingyoudonthave", "-c", - "import sys; sys.exit(47)"], - executable=sys.executable) - p.wait() - self.assertEqual(p.returncode, 47) - - def test_stdin_pipe(self): - # stdin redirection - p = subprocess.Popen([sys.executable, "-c", - 'import sys; sys.exit(sys.stdin.read() == "pear")'], - stdin=subprocess.PIPE) - p.stdin.write("pear") - p.stdin.close() - p.wait() - self.assertEqual(p.returncode, 1) - - def test_stdin_filedes(self): - # stdin is set to open file descriptor - tf = tempfile.TemporaryFile() - d = tf.fileno() - os.write(d, "pear") - os.lseek(d, 0, 0) - p = subprocess.Popen([sys.executable, "-c", - 'import sys; sys.exit(sys.stdin.read() == "pear")'], - stdin=d) - p.wait() - self.assertEqual(p.returncode, 1) - - def test_stdin_fileobj(self): - # stdin is set to open file object - tf = tempfile.TemporaryFile() - tf.write("pear") - tf.seek(0) - p = subprocess.Popen([sys.executable, "-c", - 'import sys; sys.exit(sys.stdin.read() == "pear")'], - stdin=tf) - p.wait() - self.assertEqual(p.returncode, 1) - - def test_stdout_pipe(self): - # stdout redirection - p = subprocess.Popen([sys.executable, "-c", - 'import sys; sys.stdout.write("orange")'], - stdout=subprocess.PIPE) - self.addCleanup(p.stdout.close) - self.assertEqual(p.stdout.read(), "orange") - - def test_stdout_filedes(self): - # stdout is set to open file descriptor - tf = tempfile.TemporaryFile() - d = tf.fileno() - p = subprocess.Popen([sys.executable, "-c", - 'import sys; sys.stdout.write("orange")'], - stdout=d) - p.wait() - os.lseek(d, 0, 0) - self.assertEqual(os.read(d, 1024), "orange") - - def test_stdout_fileobj(self): - # stdout is set to open file object - tf = tempfile.TemporaryFile() - p = subprocess.Popen([sys.executable, "-c", - 'import sys; sys.stdout.write("orange")'], - stdout=tf) - p.wait() - tf.seek(0) - self.assertEqual(tf.read(), "orange") - - def test_stderr_pipe(self): - # stderr redirection - p = subprocess.Popen([sys.executable, "-c", - 'import sys; sys.stderr.write("strawberry")'], - stderr=subprocess.PIPE) - self.addCleanup(p.stderr.close) - #self.assertStderrEqual(p.stderr.read(), "strawberry") - self.assertEqual(remove_stderr_debug_decorations(p.stderr.read()), - "strawberry") - - def test_stderr_filedes(self): - # stderr is set to open file descriptor - tf = tempfile.TemporaryFile() - d = tf.fileno() - p = subprocess.Popen([sys.executable, "-c", - 'import sys; sys.stderr.write("strawberry")'], - stderr=d) - p.wait() - os.lseek(d, 0, 0) - #self.assertStderrEqual(os.read(d, 1024), "strawberry") - self.assertEqual(remove_stderr_debug_decorations(os.read(d, 1024)), - "strawberry") - - def test_stderr_fileobj(self): - # stderr is set to open file object - tf = tempfile.TemporaryFile() - p = subprocess.Popen([sys.executable, "-c", - 'import sys; sys.stderr.write("strawberry")'], - stderr=tf) - p.wait() - tf.seek(0) - #self.assertStderrEqual(tf.read(), "strawberry") - self.assertEqual(remove_stderr_debug_decorations(tf.read()), - "strawberry") - - def test_stdout_stderr_pipe(self): - # capture stdout and stderr to the same pipe - p = subprocess.Popen([sys.executable, "-c", - 'import sys;' - 'sys.stdout.write("apple");' - 'sys.stdout.flush();' - 'sys.stderr.write("orange")'], - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) - self.addCleanup(p.stdout.close) - #self.assertStderrEqual(p.stdout.read(), "appleorange") - output = p.stdout.read() - stripped = remove_stderr_debug_decorations(output) - self.assertEqual(stripped, "appleorange") - - def test_stdout_stderr_file(self): - # capture stdout and stderr to the same open file - tf = tempfile.TemporaryFile() - p = subprocess.Popen([sys.executable, "-c", - 'import sys;' - 'sys.stdout.write("apple");' - 'sys.stdout.flush();' - 'sys.stderr.write("orange")'], - stdout=tf, - stderr=tf) - p.wait() - tf.seek(0) - #self.assertStderrEqual(tf.read(), "appleorange") - output = tf.read() - stripped = remove_stderr_debug_decorations(output) - self.assertEqual(stripped, "appleorange") - - def test_stdout_filedes_of_stdout(self): - # stdout is set to 1 (#1531862). - cmd = r"import sys, os; sys.exit(os.write(sys.stdout.fileno(), '.\n'))" - rc = subprocess.call([sys.executable, "-c", cmd], stdout=1) - self.assertEqual(rc, 2) - - def test_cwd(self): - tmpdir = tempfile.gettempdir() - # We cannot use os.path.realpath to canonicalize the path, - # since it doesn't expand Tru64 {memb} strings. See bug 1063571. - cwd = os.getcwd() - os.chdir(tmpdir) - tmpdir = os.getcwd() - os.chdir(cwd) - p = subprocess.Popen([sys.executable, "-c", - 'import sys,os;' - 'sys.stdout.write(os.getcwd())'], - stdout=subprocess.PIPE, - cwd=tmpdir) - self.addCleanup(p.stdout.close) - normcase = os.path.normcase - self.assertEqual(normcase(p.stdout.read()), normcase(tmpdir)) - - def test_env(self): - newenv = os.environ.copy() - newenv["FRUIT"] = "orange" - p = subprocess.Popen([sys.executable, "-c", - 'import sys,os;' - 'sys.stdout.write(os.getenv("FRUIT"))'], - stdout=subprocess.PIPE, - env=newenv) - self.assertEqual(p.stdout.read(), "orange") - - def test_communicate_stdin(self): - p = subprocess.Popen([sys.executable, "-c", - 'import sys;' - 'sys.exit(sys.stdin.read() == "pear")'], - stdin=subprocess.PIPE) - p.communicate("pear") - self.assertEqual(p.returncode, 1) - - def test_communicate_stdout(self): - p = subprocess.Popen([sys.executable, "-c", - 'import sys; sys.stdout.write("pineapple")'], - stdout=subprocess.PIPE) - (stdout, stderr) = p.communicate() - self.assertEqual(stdout, "pineapple") - self.assertEqual(stderr, None) - - def test_communicate_stderr(self): - p = subprocess.Popen([sys.executable, "-c", - 'import sys; sys.stderr.write("pineapple")'], - stderr=subprocess.PIPE) - (stdout, stderr) = p.communicate() - self.assertEqual(stdout, None) - #self.assertStderrEqual(stderr, "pineapple") - self.assertEqual(remove_stderr_debug_decorations(stderr), "pineapple") - - def test_communicate(self): - p = subprocess.Popen([sys.executable, "-c", - 'import sys,os;' - 'sys.stderr.write("pineapple");' - 'sys.stdout.write(sys.stdin.read())'], - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - self.addCleanup(p.stdout.close) - self.addCleanup(p.stderr.close) - self.addCleanup(p.stdin.close) - (stdout, stderr) = p.communicate("banana") - self.assertEqual(stdout, "banana") - #self.assertStderrEqual(stderr, "pineapple") - self.assertEqual(remove_stderr_debug_decorations(stderr), - "pineapple") - - # Not available with python-2.6's unittest: Reimplement by - # raising SkipTest from nose - # This test is Linux specific for simplicity to at least have - # some coverage. It is not a platform specific bug. - #@unittest.skipUnless(os.path.isdir('/proc/%d/fd' % os.getpid()), - # "Linux specific") - # Test for the fd leak reported in http://bugs.python.org/issue2791. - def test_communicate_pipe_fd_leak(self): - if not os.path.isdir('/proc/%d/fd' % os.getpid()): - raise SkipTest('Linux specific') - fd_directory = '/proc/%d/fd' % os.getpid() - num_fds_before_popen = len(os.listdir(fd_directory)) - p = subprocess.Popen([sys.executable, "-c", "print()"], - stdout=subprocess.PIPE) - p.communicate() - num_fds_after_communicate = len(os.listdir(fd_directory)) - del p - num_fds_after_destruction = len(os.listdir(fd_directory)) - self.assertEqual(num_fds_before_popen, num_fds_after_destruction) - self.assertEqual(num_fds_before_popen, num_fds_after_communicate) - - def test_communicate_returns(self): - # communicate() should return None if no redirection is active - p = subprocess.Popen([sys.executable, "-c", - "import sys; sys.exit(47)"]) - (stdout, stderr) = p.communicate() - self.assertEqual(stdout, None) - self.assertEqual(stderr, None) - - def test_communicate_pipe_buf(self): - # communicate() with writes larger than pipe_buf - # This test will probably deadlock rather than fail, if - # communicate() does not work properly. - x, y = os.pipe() - if mswindows: - pipe_buf = 512 - else: - pipe_buf = os.fpathconf(x, "PC_PIPE_BUF") - os.close(x) - os.close(y) - p = subprocess.Popen([sys.executable, "-c", - 'import sys,os;' - 'sys.stdout.write(sys.stdin.read(47));' - 'sys.stderr.write("xyz"*%d);' - 'sys.stdout.write(sys.stdin.read())' % pipe_buf], - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - self.addCleanup(p.stdout.close) - self.addCleanup(p.stderr.close) - self.addCleanup(p.stdin.close) - string_to_write = "abc"*pipe_buf - (stdout, stderr) = p.communicate(string_to_write) - self.assertEqual(stdout, string_to_write) - - def test_writes_before_communicate(self): - # stdin.write before communicate() - p = subprocess.Popen([sys.executable, "-c", - 'import sys,os;' - 'sys.stdout.write(sys.stdin.read())'], - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - self.addCleanup(p.stdout.close) - self.addCleanup(p.stderr.close) - self.addCleanup(p.stdin.close) - p.stdin.write("banana") - (stdout, stderr) = p.communicate("split") - self.assertEqual(stdout, "bananasplit") - #self.assertStderrEqual(stderr, "") - self.assertEqual(remove_stderr_debug_decorations(stderr), "") - - def test_universal_newlines(self): - p = subprocess.Popen([sys.executable, "-c", - 'import sys,os;' + SETBINARY + - 'sys.stdout.write("line1\\n");' - 'sys.stdout.flush();' - 'sys.stdout.write("line2\\r");' - 'sys.stdout.flush();' - 'sys.stdout.write("line3\\r\\n");' - 'sys.stdout.flush();' - 'sys.stdout.write("line4\\r");' - 'sys.stdout.flush();' - 'sys.stdout.write("\\nline5");' - 'sys.stdout.flush();' - 'sys.stdout.write("\\nline6");'], - stdout=subprocess.PIPE, - universal_newlines=1) - self.addCleanup(p.stdout.close) - stdout = p.stdout.read() - if hasattr(file, 'newlines'): - # Interpreter with universal newline support - self.assertEqual(stdout, - "line1\nline2\nline3\nline4\nline5\nline6") - else: - # Interpreter without universal newline support - self.assertEqual(stdout, - "line1\nline2\rline3\r\nline4\r\nline5\nline6") - - def test_universal_newlines_communicate(self): - # universal newlines through communicate() - p = subprocess.Popen([sys.executable, "-c", - 'import sys,os;' + SETBINARY + - 'sys.stdout.write("line1\\n");' - 'sys.stdout.flush();' - 'sys.stdout.write("line2\\r");' - 'sys.stdout.flush();' - 'sys.stdout.write("line3\\r\\n");' - 'sys.stdout.flush();' - 'sys.stdout.write("line4\\r");' - 'sys.stdout.flush();' - 'sys.stdout.write("\\nline5");' - 'sys.stdout.flush();' - 'sys.stdout.write("\\nline6");'], - stdout=subprocess.PIPE, stderr=subprocess.PIPE, - universal_newlines=1) - self.addCleanup(p.stdout.close) - self.addCleanup(p.stderr.close) - (stdout, stderr) = p.communicate() - if hasattr(file, 'newlines'): - # Interpreter with universal newline support - self.assertEqual(stdout, - "line1\nline2\nline3\nline4\nline5\nline6") - else: - # Interpreter without universal newline support - self.assertEqual(stdout, - "line1\nline2\rline3\r\nline4\r\nline5\nline6") - - def test_no_leaking(self): - if not test_support: - raise SkipTest("No test_support module available.") - - # Make sure we leak no resources - if not mswindows: - max_handles = 1026 # too much for most UNIX systems - else: - max_handles = 2050 # too much for (at least some) Windows setups - handles = [] - try: - for i in range(max_handles): - try: - handles.append(os.open(test_support.TESTFN, - os.O_WRONLY | os.O_CREAT)) - except OSError, e: - if e.errno != errno.EMFILE: - raise - break - else: - # python-2.3 unittest doesn't have skipTest. Reimplement with nose - #self.skipTest("failed to reach the file descriptor limit " - # "(tried %d)" % max_handles) - raise SkipTest("failed to reach the file descriptor limit " - "(tried %d)" % max_handles) - - # Close a couple of them (should be enough for a subprocess) - for i in range(10): - os.close(handles.pop()) - # Loop creating some subprocesses. If one of them leaks some fds, - # the next loop iteration will fail by reaching the max fd limit. - for i in range(15): - p = subprocess.Popen([sys.executable, "-c", - "import sys;" - "sys.stdout.write(sys.stdin.read())"], - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - data = p.communicate("lime")[0] - self.assertEqual(data, "lime") - finally: - for h in handles: - os.close(h) - - def test_list2cmdline(self): - self.assertEqual(subprocess.list2cmdline(['a b c', 'd', 'e']), - '"a b c" d e') - self.assertEqual(subprocess.list2cmdline(['ab"c', '\\', 'd']), - 'ab\\"c \\ d') - self.assertEqual(subprocess.list2cmdline(['ab"c', ' \\', 'd']), - 'ab\\"c " \\\\" d') - self.assertEqual(subprocess.list2cmdline(['a\\\\\\b', 'de fg', 'h']), - 'a\\\\\\b "de fg" h') - self.assertEqual(subprocess.list2cmdline(['a\\"b', 'c', 'd']), - 'a\\\\\\"b c d') - self.assertEqual(subprocess.list2cmdline(['a\\\\b c', 'd', 'e']), - '"a\\\\b c" d e') - self.assertEqual(subprocess.list2cmdline(['a\\\\b\\ c', 'd', 'e']), - '"a\\\\b\\ c" d e') - self.assertEqual(subprocess.list2cmdline(['ab', '']), - 'ab ""') - - - def test_poll(self): - p = subprocess.Popen([sys.executable, - "-c", "import time; time.sleep(1)"]) - count = 0 - while p.poll() is None: - time.sleep(0.1) - count += 1 - # We expect that the poll loop probably went around about 10 times, - # but, based on system scheduling we can't control, it's possible - # poll() never returned None. It "should be" very rare that it - # didn't go around at least twice. - #self.assertGreaterEqual(count, 2) - self.assert_(count >= 2) - # Subsequent invocations should just return the returncode - self.assertEqual(p.poll(), 0) - - - def test_wait(self): - p = subprocess.Popen([sys.executable, - "-c", "import time; time.sleep(2)"]) - self.assertEqual(p.wait(), 0) - # Subsequent invocations should just return the returncode - self.assertEqual(p.wait(), 0) - - - def test_invalid_bufsize(self): - # an invalid type of the bufsize argument should raise - # TypeError. - #with self.assertRaises(TypeError): - try: - subprocess.Popen([sys.executable, "-c", "pass"], "orange") - except TypeError: - pass - else: - self.fail("Expected TypeError") - - def test_leaking_fds_on_error(self): - # see bug #5179: Popen leaks file descriptors to PIPEs if - # the child fails to execute; this will eventually exhaust - # the maximum number of open fds. 1024 seems a very common - # value for that limit, but Windows has 2048, so we loop - # 1024 times (each call leaked two fds). - for i in range(1024): - # Windows raises IOError. Others raise OSError. - #with self.assertRaises(EnvironmentError) as c: - try: - subprocess.Popen(['nonexisting_i_hope'], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - #if c.exception.errno != 2: # ignore "no such file" - # raise c.exception - # Windows raises IOError - except EnvironmentError, err: - if err.errno not in (errno.ENOENT, errno.EACCES): # ignore "no such file" - raise err - except: - self.fail("Expected EnvironmentError") - else: - self.fail("Expected EnvironmentError") - - def test_handles_closed_on_exception(self): - # If CreateProcess exits with an error, ensure the - # duplicate output handles are released - ifhandle, ifname = mkstemp() - ofhandle, ofname = mkstemp() - efhandle, efname = mkstemp() - try: - subprocess.Popen (["*"], stdin=ifhandle, stdout=ofhandle, - stderr=efhandle) - except OSError: - os.close(ifhandle) - os.remove(ifname) - os.close(ofhandle) - os.remove(ofname) - os.close(efhandle) - os.remove(efname) - self.assert_(not os.path.exists(ifname)) - self.assert_(not os.path.exists(ofname)) - self.assert_(not os.path.exists(efname)) - - def test_communicate_epipe(self): - # Issue 10963: communicate() should hide EPIPE - p = subprocess.Popen([sys.executable, "-c", 'pass'], - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - self.addCleanup(p.stdout.close) - self.addCleanup(p.stderr.close) - self.addCleanup(p.stdin.close) - p.communicate("x" * 2**20) - - def test_communicate_epipe_only_stdin(self): - # Issue 10963: communicate() should hide EPIPE - p = subprocess.Popen([sys.executable, "-c", 'pass'], - stdin=subprocess.PIPE) - self.addCleanup(p.stdin.close) - time.sleep(2) - p.communicate("x" * 2**20) - -# context manager -class _SuppressCoreFiles(object): - """Try to prevent core files from being created.""" - old_limit = None - - def __enter__(self): - """Try to save previous ulimit, then set it to (0, 0).""" - try: - import resource - self.old_limit = resource.getrlimit(resource.RLIMIT_CORE) - resource.setrlimit(resource.RLIMIT_CORE, (0, 0)) - except (ImportError, ValueError, resource.error): - pass - - if sys.platform == 'darwin': - # Check if the 'Crash Reporter' on OSX was configured - # in 'Developer' mode and warn that it will get triggered - # when it is. - # - # This assumes that this context manager is used in tests - # that might trigger the next manager. - value = subprocess.Popen(['/usr/bin/defaults', 'read', - 'com.apple.CrashReporter', 'DialogType'], - stdout=subprocess.PIPE).communicate()[0] - if value.strip() == 'developer': - print "this tests triggers the Crash Reporter, that is intentional" - sys.stdout.flush() - - def __exit__(self, *args): - """Return core file behavior to default.""" - if self.old_limit is None: - return - try: - import resource - resource.setrlimit(resource.RLIMIT_CORE, self.old_limit) - except (ImportError, ValueError, resource.error): - pass - - # python-2.3 unittest doesn't have skipUnless. Reimplement as SkipTest from nose - #@unittest.skipUnless(hasattr(signal, 'SIGALRM'), - # "Requires signal.SIGALRM") - def test_communicate_eintr(self): - if not hasattr(signal, 'SIGALRM'): - raise SkipTest('Requires signal.SIGALRM') - # Issue #12493: communicate() should handle EINTR - def handler(signum, frame): - pass - old_handler = signal.signal(signal.SIGALRM, handler) - self.addCleanup(signal.signal, signal.SIGALRM, old_handler) - - # the process is running for 2 seconds - args = [sys.executable, "-c", 'import time; time.sleep(2)'] - for stream in ('stdout', 'stderr'): - kw = {stream: subprocess.PIPE} - #with subprocess.Popen(args, **kw) as process: - try: - process = subprocess.Popen(args, **kw) - signal.alarm(1) - # communicate() will be interrupted by SIGALRM - process.communicate() - finally: - process.close() - - -# Not available with python-2.3's unittest. Reimplement with SkipTest from -# nose -#@unittest.skipIf(mswindows, "POSIX specific tests") -class POSIXProcessTestCase(BaseTestCase): - def setUp(self): - if mswindows: - raise SkipTest('POSIX specific tests') - - def test_exceptions(self): - # caught & re-raised exceptions - #with self.assertRaises(OSError) as c: - try: - p = subprocess.Popen([sys.executable, "-c", ""], - cwd="/this/path/does/not/exist") - # The attribute child_traceback should contain "os.chdir" somewhere. - #self.assertIn("os.chdir", c.exception.child_traceback) - except OSError, e: - self.assertNotEqual(e.child_traceback.find("os.chdir"), -1) - except: - self.fail("Expected OSError") - else: - self.fail("Expected OSError") - - def _suppress_core_files(self): - """Try to prevent core files from being created. - Returns previous ulimit if successful, else None. - """ - try: - import resource - old_limit = resource.getrlimit(resource.RLIMIT_CORE) - resource.setrlimit(resource.RLIMIT_CORE, (0,0)) - return old_limit - except (ImportError, ValueError, resource.error): - return None - - def _unsuppress_core_files(self, old_limit): - """Return core file behavior to default.""" - if old_limit is None: - return - try: - import resource - resource.setrlimit(resource.RLIMIT_CORE, old_limit) - except (ImportError, ValueError, resource.error): - return - - def test_run_abort(self): - # returncode handles signal termination - #with _SuppressCoreFiles(): - old_limit = self._suppress_core_files() - try: - p = subprocess.Popen([sys.executable, "-c", - "import os; os.abort()"]) - finally: - self._unsuppress_core_files(old_limit) - - #p.wait() - p.wait() - self.assertEqual(-p.returncode, signal.SIGABRT) - - def test_preexec(self): - # preexec function - p = subprocess.Popen([sys.executable, "-c", - "import sys, os;" - "sys.stdout.write(os.getenv('FRUIT'))"], - stdout=subprocess.PIPE, - preexec_fn=lambda: os.putenv("FRUIT", "apple")) - self.addCleanup(p.stdout.close) - self.assertEqual(p.stdout.read(), "apple") - - def test_args_string(self): - # args is a string - f, fname = mkstemp() - os.write(f, "#!/bin/sh\n") - os.write(f, "exec '%s' -c 'import sys; sys.exit(47)'\n" % - sys.executable) - os.close(f) - # 0o is not available in python2.5 - #os.chmod(fname, 0o700) - os.chmod(fname, 0700) - p = subprocess.Popen(fname) - p.wait() - os.remove(fname) - self.assertEqual(p.returncode, 47) - - def test_invalid_args(self): - # invalid arguments should raise ValueError - self.assertRaises(ValueError, subprocess.call, - [sys.executable, "-c", - "import sys; sys.exit(47)"], - startupinfo=47) - self.assertRaises(ValueError, subprocess.call, - [sys.executable, "-c", - "import sys; sys.exit(47)"], - creationflags=47) - - def test_shell_sequence(self): - # Run command through the shell (sequence) - newenv = os.environ.copy() - newenv["FRUIT"] = "apple" - p = subprocess.Popen(["echo $FRUIT"], shell=1, - stdout=subprocess.PIPE, - env=newenv) - self.addCleanup(p.stdout.close) - self.assertEqual(p.stdout.read().strip(), "apple") - - def test_shell_string(self): - # Run command through the shell (string) - newenv = os.environ.copy() - newenv["FRUIT"] = "apple" - p = subprocess.Popen("echo $FRUIT", shell=1, - stdout=subprocess.PIPE, - env=newenv) - self.addCleanup(p.stdout.close) - self.assertEqual(p.stdout.read().strip(), "apple") - - def test_call_string(self): - # call() function with string argument on UNIX - f, fname = mkstemp() - os.write(f, "#!/bin/sh\n") - os.write(f, "exec '%s' -c 'import sys; sys.exit(47)'\n" % - sys.executable) - os.close(f) - os.chmod(fname, 0700) - rc = subprocess.call(fname) - os.remove(fname) - self.assertEqual(rc, 47) - - def test_specific_shell(self): - # Issue #9265: Incorrect name passed as arg[0]. - shells = [] - for prefix in ['/bin', '/usr/bin/', '/usr/local/bin']: - for name in ['bash', 'ksh']: - sh = os.path.join(prefix, name) - if os.path.isfile(sh): - shells.append(sh) - if not shells: # Will probably work for any shell but csh. - - # skipTest unavailable on python<2.7 reimplement with nose - #self.skipTest("bash or ksh required for this test") - raise SkipTest("bash or ksh required for this test") - sh = '/bin/sh' - if os.path.isfile(sh) and not os.path.islink(sh): - # Test will fail if /bin/sh is a symlink to csh. - shells.append(sh) - for sh in shells: - p = subprocess.Popen("echo $0", executable=sh, shell=True, - stdout=subprocess.PIPE) - self.addCleanup(p.stdout.close) - self.assertEqual(p.stdout.read().strip(), sh) - - def _kill_process(self, method, *args): - # Do not inherit file handles from the parent. - # It should fix failures on some platforms. - p = subprocess.Popen([sys.executable, "-c", """if 1: - import sys, time - sys.stdout.write('x\\n') - sys.stdout.flush() - time.sleep(30) - """], - close_fds=True, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - # Wait for the interpreter to be completely initialized before - # sending any signal. - p.stdout.read(1) - getattr(p, method)(*args) - return p - - # These are still hanging with x86_64 Fedora 12 (python-2.6) subprocess - # backport from current trunk run under nosetests - - def test_send_signal(self): - #if hang DISABLED #2777 - p = self._kill_process('send_signal', signal.SIGINT) - _, stderr = p.communicate() - self.assert_('KeyboardInterrupt' in stderr) - self.assertNotEqual(p.wait(), 0) - - def test_kill(self): - #if hang DISABLED #2777 - p = self._kill_process('kill') - _, stderr = p.communicate() - self.assertStderrEqual(stderr, '') - self.assertEqual(p.wait(), -signal.SIGKILL) - - def test_terminate(self): - #if hang DISABLED #2777 - p = self._kill_process('terminate') - _, stderr = p.communicate() - self.assertStderrEqual(stderr, '') - self.assertEqual(p.wait(), -signal.SIGTERM) - - def check_close_std_fds(self, fds): - # Issue #9905: test that subprocess pipes still work properly with - # some standard fds closed - stdin = 0 - newfds = [] - for a in fds: - b = os.dup(a) - newfds.append(b) - if a == 0: - stdin = b - try: - for fd in fds: - os.close(fd) - out, err = subprocess.Popen([sys.executable, "-c", - 'import sys;' - 'sys.stdout.write("apple");' - 'sys.stdout.flush();' - 'sys.stderr.write("orange")'], - stdin=stdin, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE).communicate() - err = re.sub(r"\[\d+ refs\]\r?\n?$", "", err).strip() - self.assertEqual((out, err), ('apple', 'orange')) - finally: - for b, a in zip(newfds, fds): - os.dup2(b, a) - for b in newfds: - os.close(b) - - def test_close_fd_0(self): - self.check_close_std_fds([0]) - - def test_close_fd_1(self): - self.check_close_std_fds([1]) - - def test_close_fd_2(self): - self.check_close_std_fds([2]) - - def test_close_fds_0_1(self): - self.check_close_std_fds([0, 1]) - - def test_close_fds_0_2(self): - self.check_close_std_fds([0, 2]) - - def test_close_fds_1_2(self): - self.check_close_std_fds([1, 2]) - - def test_close_fds_0_1_2(self): - # Issue #10806: test that subprocess pipes still work properly with - # all standard fds closed. - self.check_close_std_fds([0, 1, 2]) - - def check_swap_fds(self, stdin_no, stdout_no, stderr_no): - # open up some temporary files - temps = [mkstemp() for i in range(3)] - temp_fds = [fd for fd, fname in temps] - try: - # unlink the files -- we won't need to reopen them - for fd, fname in temps: - os.unlink(fname) - - # save a copy of the standard file descriptors - saved_fds = [os.dup(fd) for fd in range(3)] - try: - # duplicate the temp files over the standard fd's 0, 1, 2 - for fd, temp_fd in enumerate(temp_fds): - os.dup2(temp_fd, fd) - - # write some data to what will become stdin, and rewind - os.write(stdin_no, "STDIN") - os.lseek(stdin_no, 0, 0) - - # now use those files in the given order, so that subprocess - # has to rearrange them in the child - p = subprocess.Popen([sys.executable, "-c", - 'import sys; got = sys.stdin.read();' - 'sys.stdout.write("got %s"%got); sys.stderr.write("err")'], - stdin=stdin_no, - stdout=stdout_no, - stderr=stderr_no) - p.wait() - - for fd in temp_fds: - os.lseek(fd, 0, 0) - - out = os.read(stdout_no, 1024) - err = re.sub(r"\[\d+ refs\]\r?\n?$", "", os.read(stderr_no, 1024)).strip() - finally: - for std, saved in enumerate(saved_fds): - os.dup2(saved, std) - os.close(saved) - - self.assertEqual(out, "got STDIN") - self.assertEqual(err, "err") - - finally: - for fd in temp_fds: - os.close(fd) - - # When duping fds, if there arises a situation where one of the fds is - # either 0, 1 or 2, it is possible that it is overwritten (#12607). - # This tests all combinations of this. - def test_swap_fds(self): - self.check_swap_fds(0, 1, 2) - self.check_swap_fds(0, 2, 1) - self.check_swap_fds(1, 0, 2) - self.check_swap_fds(1, 2, 0) - self.check_swap_fds(2, 0, 1) - self.check_swap_fds(2, 1, 0) - - def test_wait_when_sigchild_ignored(self): - # NOTE: sigchild_ignore.py may not be an effective test on all OSes. - if not test_support: - raise SkipTest("No test_support module available.") - sigchild_ignore = test_support.findfile(os.path.join("subprocessdata", - "sigchild_ignore.py")) - p = subprocess.Popen([sys.executable, sigchild_ignore], - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = p.communicate() - self.assertEqual(0, p.returncode, "sigchild_ignore.py exited" - " non-zero with this error:\n%s" % stderr) - - - def test_zombie_fast_process_del(self): - # Issue #12650: on Unix, if Popen.__del__() was called before the - # process exited, it wouldn't be added to subprocess._active, and would - # remain a zombie. - # spawn a Popen, and delete its reference before it exits - p = subprocess.Popen([sys.executable, "-c", - 'import sys, time;' - 'time.sleep(0.2)'], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - self.addCleanup(p.stdout.close) - self.addCleanup(p.stderr.close) - ident = id(p) - pid = p.pid - del p - # check that p is in the active processes list - # assertIn not in python< 2.7 - #self.assertIn(ident, [id(o) for o in subprocess._active]) - self.assert_(ident in [id(o) for o in subprocess._active]) - - def test_leak_fast_process_del_killed(self): - # Issue #12650: on Unix, if Popen.__del__() was called before the - # process exited, and the process got killed by a signal, it would never - # be removed from subprocess._active, which triggered a FD and memory - # leak. - # spawn a Popen, delete its reference and kill it - p = subprocess.Popen([sys.executable, "-c", - 'import time;' - 'time.sleep(3)'], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - self.addCleanup(p.stdout.close) - self.addCleanup(p.stderr.close) - ident = id(p) - pid = p.pid - del p - os.kill(pid, signal.SIGKILL) - # check that p is in the active processes list - # assertIn not in python < 2.7 - self.assert_(ident in [id(o) for o in subprocess._active]) - #self.assertIn(ident, [id(o) for o in subprocess._active]) - - # let some time for the process to exit, and create a new Popen: this - # should trigger the wait() of p - time.sleep(0.2) - #with self.assertRaises(EnvironmentError) as c: - try: - try: - proc = subprocess.Popen(['nonexisting_i_hope'], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - finally: - pass - except EnvironmentError: - pass - except: - self.fail('Expected EnvironmentError') - else: - self.fail('Expected EnvironmentError') - # p should have been wait()ed on, and removed from the _active list - #self.assertRaises(OSError, os.waitpid, pid, 0) - try: - os.waitpid(pid, 0) - except OSError: - pass - except: - self.fail('Expected OSError') - else: - self.fail('Expected OSError') - #self.assertNotIn(ident, [id(o) for o in subprocess._active]) - self.assert_(ident not in [id(o) for o in subprocess._active]) - - def test_pipe_cloexec(self): - # Issue 12786: check that the communication pipes' FDs are set CLOEXEC, - # and are not inherited by another child process. - p1 = subprocess.Popen([sys.executable, "-c", - 'import os;' - 'os.read(0, 1)' - ], - stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - - p2 = subprocess.Popen([sys.executable, "-c", """if True: - import os, errno, sys - for fd in %r: - try: - os.close(fd) - except OSError, e: - if e.errno != errno.EBADF: - raise - else: - sys.exit(1) - sys.exit(0) - """ % [f.fileno() for f in (p1.stdin, p1.stdout, - p1.stderr)] - ], - stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, close_fds=False) - p1.communicate('foo') - _, stderr = p2.communicate() - - self.assertEqual(p2.returncode, 0, "Unexpected error: " + repr(stderr)) - - -# Not available with python-2.3's unittest, reimplement with SkipTest from -# nose -##@unittest.skipUnless(mswindows, "Windows specific tests") -class Win32ProcessTestCase(BaseTestCase): - def setUp(self): - if not mswindows: - raise SkipTest('Windows specific tests') - - def test_startupinfo(self): - # startupinfo argument - # We uses hardcoded constants, because we do not want to - # depend on win32all. - STARTF_USESHOWWINDOW = 1 - SW_MAXIMIZE = 3 - startupinfo = subprocess.STARTUPINFO() - startupinfo.dwFlags = STARTF_USESHOWWINDOW - startupinfo.wShowWindow = SW_MAXIMIZE - # Since Python is a console process, it won't be affected - # by wShowWindow, but the argument should be silently - # ignored - subprocess.call([sys.executable, "-c", "import sys; sys.exit(0)"], - startupinfo=startupinfo) - - def test_creationflags(self): - # creationflags argument - CREATE_NEW_CONSOLE = 16 - sys.stderr.write(" a DOS box should flash briefly ...\n") - subprocess.call(sys.executable + - ' -c "import time; time.sleep(0.25)"', - creationflags=CREATE_NEW_CONSOLE) - - def test_invalid_args(self): - # invalid arguments should raise ValueError - self.assertRaises(ValueError, subprocess.call, - [sys.executable, "-c", - "import sys; sys.exit(47)"], - preexec_fn=lambda: 1) - self.assertRaises(ValueError, subprocess.call, - [sys.executable, "-c", - "import sys; sys.exit(47)"], - stdout=subprocess.PIPE, - close_fds=True) - - def test_close_fds(self): - # close file descriptors - rc = subprocess.call([sys.executable, "-c", - "import sys; sys.exit(47)"], - close_fds=True) - self.assertEqual(rc, 47) - - def test_shell_sequence(self): - # Run command through the shell (sequence) - newenv = os.environ.copy() - newenv["FRUIT"] = "physalis" - p = subprocess.Popen(["set"], shell=1, - stdout=subprocess.PIPE, - env=newenv) - self.addCleanup(p.stdout.close) - #self.assertIn("physalis", p.stdout.read()) - self.assert_("physalis" in p.stdout.read()) - - def test_shell_string(self): - # Run command through the shell (string) - newenv = os.environ.copy() - newenv["FRUIT"] = "physalis" - p = subprocess.Popen("set", shell=1, - stdout=subprocess.PIPE, - env=newenv) - self.addCleanup(p.stdout.close) - #self.assertIn("physalis", p.stdout.read()) - self.assert_("physalis" in p.stdout.read()) - - def test_call_string(self): - # call() function with string argument on Windows - rc = subprocess.call(sys.executable + - ' -c "import sys; sys.exit(47)"') - self.assertEqual(rc, 47) - - def _kill_process(self, method, *args): - # Some win32 buildbot raises EOFError if stdin is inherited - p = subprocess.Popen([sys.executable, "-c", """if 1: - import sys, time - sys.stdout.write('x\\n') - sys.stdout.flush() - time.sleep(30) - """], - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - self.addCleanup(p.stdout.close) - self.addCleanup(p.stderr.close) - self.addCleanup(p.stdin.close) - # Wait for the interpreter to be completely initialized before - # sending any signal. - p.stdout.read(1) - getattr(p, method)(*args) - _, stderr = p.communicate() - self.assertStderrEqual(stderr, '') - returncode = p.wait() - self.assertNotEqual(returncode, 0) - - def test_send_signal(self): - #if hang DISABLED #2777 - self._kill_process('send_signal', signal.SIGTERM) - - def test_kill(self): - #if hang DISABLED #2777 - self._kill_process('kill') - - def test_terminate(self): - #if hang DISABLED #2777 - self._kill_process('terminate') - - -# Not available with python-2.3's unittest. reimplement with SkipTest from -# nose -#@unittest.skipUnless(getattr(subprocess, '_has_poll', False), -# "poll system call not supported") -class ProcessTestCaseNoPoll(ProcessTestCase): - def setUp(self): - if not getattr(subprocess, '_has_poll', False): - raise SkipTest('poll system call not supported') - subprocess._has_poll = False - ProcessTestCase.setUp(self) - - def tearDown(self): - subprocess._has_poll = True - ProcessTestCase.tearDown(self) - - -class HelperFunctionTests(unittest.TestCase): - # Not available with python-2.3's unittest. reimplement with SkipTest from - # nose - #@unittest.skipIf(mswindows, "errno and EINTR make no sense on windows") - def test_eintr_retry_call(self): - if mswindows: - raise SkipTest('errno and EINTR make no sense on windows') - record_calls = [] - def fake_os_func(*args): - record_calls.append(args) - if len(record_calls) == 2: - raise OSError(errno.EINTR, "fake interrupted system call") - # reversed() is not available in python-2.3 - args = list(args) - args.reverse() - return tuple(args) - - self.assertEqual((999, 256), - subprocess._eintr_retry_call(fake_os_func, 256, 999)) - self.assertEqual([(256, 999)], record_calls) - # This time there will be an EINTR so it will loop once. - self.assertEqual((666,), - subprocess._eintr_retry_call(fake_os_func, 666)) - self.assertEqual([(256, 999), (666,), (666,)], record_calls) - - -# SkipUnless is not available on python < 2.7, reimplement with nose -#@unittest.skipUnless(mswindows, "mswindows only") -class CommandsWithSpaces (BaseTestCase): - - def setUp(self): - if not mswindows: - raise SkipTest('mswindows only') - - super(CommandsWithSpaces, self).setUp() - f, fname = mkstemp(".py", "te st") - self.fname = fname.lower () - os.write(f, "import sys;" - "sys.stdout.write('%d %s' % (len(sys.argv), [a.lower () for a in sys.argv]))" - ) - os.close(f) - - def tearDown(self): - os.remove(self.fname) - super(CommandsWithSpaces, self).tearDown() - - def with_spaces(self, *args, **kwargs): - kwargs['stdout'] = subprocess.PIPE - p = subprocess.Popen(*args, **kwargs) - self.addCleanup(p.stdout.close) - self.assertEqual( - p.stdout.read ().decode("mbcs"), - "2 [%r, 'ab cd']" % self.fname - ) - - def test_shell_string_with_spaces(self): - # call() function with string argument with spaces on Windows - self.with_spaces('"%s" "%s" "%s"' % (sys.executable, self.fname, - "ab cd"), shell=1) - - def test_shell_sequence_with_spaces(self): - # call() function with sequence argument with spaces on Windows - self.with_spaces([sys.executable, self.fname, "ab cd"], shell=1) - - def test_noshell_string_with_spaces(self): - # call() function with string argument with spaces on Windows - self.with_spaces('"%s" "%s" "%s"' % (sys.executable, self.fname, - "ab cd")) - - def test_noshell_sequence_with_spaces(self): - # call() function with sequence argument with spaces on Windows - self.with_spaces([sys.executable, self.fname, "ab cd"]) - - -# We're using nosetests so we don't need this. This just leads to tests being -# run twice -#def test_main(): -# unit_tests = (ProcessTestCase, -# POSIXProcessTestCase, -# Win32ProcessTestCase, -# ProcessTestCaseNoPoll, -# HelperFunctionTests -# ) -# -# test_support.run_unittest(*unit_tests) -# test_support.reap_children() -# -#if __name__ == "__main__": -# test_main() diff --git a/kitchen3/docs/api-overview.rst b/kitchen3/docs/api-overview.rst index dda56fe..e53a94d 100644 --- a/kitchen3/docs/api-overview.rst +++ b/kitchen3/docs/api-overview.rst @@ -16,9 +16,6 @@ that may drag in more dependencies can be found on the `project webpage`_ api-collections api-iterutils api-versioning - api-pycompat24 - api-pycompat25 - api-pycompat27 api-exceptions .. _`project webpage`: https://fedorahosted.org/kitchen diff --git a/kitchen3/docs/api-pycompat24.rst b/kitchen3/docs/api-pycompat24.rst deleted file mode 100644 index a3247b6..0000000 --- a/kitchen3/docs/api-pycompat24.rst +++ /dev/null @@ -1,34 +0,0 @@ -======================= -Python 2.4 Compatibiity -======================= - - -------------------- -Sets for python-2.3 -------------------- - -.. automodule:: kitchen.pycompat24.sets -.. autofunction:: kitchen.pycompat24.sets.add_builtin_set - ----------------------------------- -Partial new style base64 interface ----------------------------------- - -.. automodule:: kitchen.pycompat24.base64 - :members: - ----------- -Subprocess ----------- - -.. seealso:: - - :mod:`kitchen.pycompat27.subprocess` - Kitchen includes the python-2.7 version of subprocess which has a new - function, :func:`~kitchen.pycompat27.subprocess.check_output`. When - you import :mod:`pycompat24.subprocess` you will be getting the - python-2.7 version of subprocess rather than the 2.4 version (where - subprocess first appeared). This choice was made so that we can - concentrate our efforts on keeping the single version of subprocess up - to date rather than working on a 2.4 version that very few people - would need specifically. diff --git a/kitchen3/docs/api-pycompat25.rst b/kitchen3/docs/api-pycompat25.rst deleted file mode 100644 index 2323c2f..0000000 --- a/kitchen3/docs/api-pycompat25.rst +++ /dev/null @@ -1,8 +0,0 @@ -======================== -Python 2.5 Compatibility -======================== - -.. automodule:: kitchen.pycompat25 - -.. automodule:: kitchen.pycompat25.collections.defaultdict - diff --git a/kitchen3/docs/api-pycompat27.rst b/kitchen3/docs/api-pycompat27.rst deleted file mode 100644 index 6ef6db1..0000000 --- a/kitchen3/docs/api-pycompat27.rst +++ /dev/null @@ -1,35 +0,0 @@ -======================== -Python 2.7 Compatibility -======================== - -.. module:: kitchen.pycompat27.subprocess - --------------------------- -Subprocess from Python 2.7 --------------------------- - -The :mod:`subprocess` module included here is a direct import from -python-2.7's |stdlib|_. You can access it via:: - - >>> from kitchen.pycompat27 import subprocess - -The motivation for including this module is that various API changing -improvements have been made to subprocess over time. The following is a list -of the known changes to :mod:`subprocess` with the python version they were -introduced in: - -==================================== === -New API Feature Ver -==================================== === -:exc:`subprocess.CalledProcessError` 2.5 -:func:`subprocess.check_call` 2.5 -:func:`subprocess.check_output` 2.7 -:meth:`subprocess.Popen.send_signal` 2.6 -:meth:`subprocess.Popen.terminate` 2.6 -:meth:`subprocess.Popen.kill` 2.6 -==================================== === - -.. seealso:: - - The stdlib :mod:`subprocess` documenation - For complete documentation on how to use subprocess diff --git a/kitchen3/tests/subprocessdata/sigchild_ignore.py b/kitchen3/tests/subprocessdata/sigchild_ignore.py deleted file mode 100644 index 5b6dd08..0000000 --- a/kitchen3/tests/subprocessdata/sigchild_ignore.py +++ /dev/null @@ -1,11 +0,0 @@ -import os -import signal, sys -sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..')) - -from kitchen.pycompat27.subprocess import _subprocess as subprocess - -# On Linux this causes os.waitpid to fail with OSError as the OS has already -# reaped our child process. The wait() passing the OSError on to the caller -# and causing us to exit with an error is what we are testing against. -signal.signal(signal.SIGCHLD, signal.SIG_IGN) -subprocess.Popen([sys.executable, '-c', 'print("albatross")']).wait() diff --git a/kitchen3/tests/test__all__.py b/kitchen3/tests/test__all__.py index d25cb3f..7ceef8b 100644 --- a/kitchen3/tests/test__all__.py +++ b/kitchen3/tests/test__all__.py @@ -4,8 +4,6 @@ from nose import tools import os import types import warnings -from kitchen.pycompat24.sets import add_builtin_set -add_builtin_set() def logit(msg): log = open('/var/tmp/test.log', 'a') diff --git a/kitchen3/tests/test_collections.py b/kitchen3/tests/test_collections.py index e3da84b..12a6d04 100644 --- a/kitchen3/tests/test_collections.py +++ b/kitchen3/tests/test_collections.py @@ -3,9 +3,6 @@ import unittest from nose import tools -from kitchen.pycompat24.sets import add_builtin_set -add_builtin_set() - from kitchen import collections def test_strict_dict_get_set(): diff --git a/kitchen3/tests/test_deprecation_py3.py b/kitchen3/tests/test_deprecation_py3.py deleted file mode 100644 index f03c0df..0000000 --- a/kitchen3/tests/test_deprecation_py3.py +++ /dev/null @@ -1,65 +0,0 @@ -# -*- coding: utf-8 -*- - -from nose import tools - -import sys -import warnings - -import importlib -from kitchen.pycompat25.collections import defaultdict - -class TestPendingDeprecationModules(object): - def __init__(self): - kitchen_path = 'kitchen' - collections_path = 'kitchen/collections' - pycompat24_path = 'kitchen/pycompat24' - pycompat25_path = 'kitchen/pycompat25' - pycompat27_path = 'kitchen/pycompat27' - - self.module_data = ( - ('strictdict', 'kitchen.collections.strictdict', collections_path), - ('pycompat24', 'kitchen.pycompat24', kitchen_path), - ('base64', 'kitchen.pycompat24.base64', pycompat24_path), - ('sets', 'kitchen.pycompat24.sets', pycompat24_path), - ('subprocess', 'kitchen.pycompat24.subprocess', pycompat24_path), - ('pycompat25', 'kitchen.pycompat25', kitchen_path), - ('collections', 'kitchen.pycompat25.collections', pycompat25_path), - ('pycompat27', 'kitchen.pycompat27', kitchen_path), - ('subprocess', 'kitchen.pycompat27.subprocess', pycompat27_path), - ) - - def setUp(self): - for module in sys.modules.values(): - if hasattr(module, '__warningregistry__'): - del module.__warningregistry__ - - def check_modules(self, module_name, module_fqn, module_path): - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') - # imp.load_module will load even if it has already been loaded. - # We need to ensure that happens in order to trigger the - # deprecation warnings - importlib.find_loader(module_fqn, module_path).load_module() - warning_raised = False - for warning in (e.message for e in w): - if isinstance(warning, PendingDeprecationWarning) and \ - ('%s is deprecated' % module_name) in warning.args[0]: - warning_raised = True - break - tools.assert_true(warning_raised, msg='%s did not raise a PendingDeprecationWarning' % module_fqn) - - def test_modules(self): - for mod in self.module_data: - yield self.check_modules, mod[0], mod[1], mod[2] - - def test_defaultdict(self): - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') - defaultdict() - warning_raised = False - for warning in (e.message for e in w): - if isinstance(warning, PendingDeprecationWarning) and \ - ('defaultdict is deprecated') in warning.args[0]: - warning_raised = True - break - tools.assert_true(warning_raised, msg='kitchen.pycompat25.collections.defaultdict did not raise a PendingDeprecationWarning') diff --git a/kitchen3/tests/test_pycompat.py b/kitchen3/tests/test_pycompat.py deleted file mode 100644 index 50a059b..0000000 --- a/kitchen3/tests/test_pycompat.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# -import unittest -from nose import tools - -class TestUsableModules(unittest.TestCase): - def test_subprocess(self): - '''Test that importing subprocess as a module works - ''' - try: - from kitchen.pycompat24.subprocess import Popen - except ImportError: - tools.ok_(False, 'Unable to import pycompat24.subprocess as a module') - try: - from kitchen.pycompat27.subprocess import Popen - except ImportError: - tools.ok_(False, 'Unable to import pycompat27.subprocess as a module') - - def test_base64(self): - '''Test that importing base64 as a module works - ''' - try: - from kitchen.pycompat24.base64 import b64encode - except ImportError: - tools.ok_(False, 'Unable to import pycompat24.base64 as a module') diff --git a/setup.py b/setup.py index 4813cae..e1a5c48 100755 --- a/setup.py +++ b/setup.py @@ -15,13 +15,6 @@ if sys.version_info[0] == 2: 'kitchen.iterutils', 'kitchen.collections', 'kitchen.text', - 'kitchen.pycompat24', - 'kitchen.pycompat24.base64', - 'kitchen.pycompat24.sets', - 'kitchen.pycompat25', - 'kitchen.pycompat25.collections', - 'kitchen.pycompat27', - 'kitchen.pycompat27.subprocess', ] elif sys.version_info[0] == 3: source_dir = 'kitchen3' @@ -32,13 +25,6 @@ elif sys.version_info[0] == 3: 'kitchen.iterutils', 'kitchen.collections', 'kitchen.text', - 'kitchen.pycompat24', - 'kitchen.pycompat24.base64', - 'kitchen.pycompat24.sets', - 'kitchen.pycompat25', - 'kitchen.pycompat25.collections', - 'kitchen.pycompat27', - 'kitchen.pycompat27.subprocess', ] else: raise NotImplementedError("Python version unsupported %r" % sys.version) From 85b7e2bd2676a9a58bee2f088ee23f99b5666abe Mon Sep 17 00:00:00 2001 From: Simon Chopin Date: Tue, 30 Apr 2013 18:27:15 +0200 Subject: [PATCH 3/4] Make kitchen.text.converters.exception_to_* not swallow general errors such as KeyboardInterrupt Bug: https://fedorahosted.org/kitchen/ticket/9 Patch-Name: explicit_Exception_catching --- kitchen2/kitchen/text/converters.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kitchen2/kitchen/text/converters.py b/kitchen2/kitchen/text/converters.py index eb518cb..d925313 100644 --- a/kitchen2/kitchen/text/converters.py +++ b/kitchen2/kitchen/text/converters.py @@ -499,7 +499,7 @@ def exception_to_unicode(exc, converters=EXCEPTION_CONVERTERS): for func in converters: try: msg = func(exc) - except: + except Exception: pass else: break @@ -531,7 +531,7 @@ def exception_to_bytes(exc, converters=EXCEPTION_CONVERTERS): for func in converters: try: msg = func(exc) - except: + except Exception: pass else: break From 0951a7f3994334af3bc872813e7b9ccc13f7610f Mon Sep 17 00:00:00 2001 From: Sergio Durigan Junior Date: Sat, 9 Jul 2016 19:05:10 -0400 Subject: [PATCH 4/4] Update COMBINED table on kitchen3/kitchen/text/display.py Patch-Name: update-combined-table-display-py3.patch --- kitchen3/kitchen/text/display.py | 137 ++++++++++++++++--------------- 1 file changed, 72 insertions(+), 65 deletions(-) diff --git a/kitchen3/kitchen/text/display.py b/kitchen3/kitchen/text/display.py index 22aa642..56c0f37 100644 --- a/kitchen3/kitchen/text/display.py +++ b/kitchen3/kitchen/text/display.py @@ -111,69 +111,76 @@ def _interval_bisearch(value, table): return False _COMBINING = ( - (0x300, 0x36f), (0x483, 0x489), (0x591, 0x5bd), - (0x5bf, 0x5bf), (0x5c1, 0x5c2), (0x5c4, 0x5c5), - (0x5c7, 0x5c7), (0x600, 0x603), (0x610, 0x61a), - (0x64b, 0x65f), (0x670, 0x670), (0x6d6, 0x6e4), - (0x6e7, 0x6e8), (0x6ea, 0x6ed), (0x70f, 0x70f), - (0x711, 0x711), (0x730, 0x74a), (0x7a6, 0x7b0), - (0x7eb, 0x7f3), (0x816, 0x819), (0x81b, 0x823), - (0x825, 0x827), (0x829, 0x82d), (0x859, 0x85b), - (0x8e4, 0x8fe), (0x901, 0x902), (0x93c, 0x93c), - (0x941, 0x948), (0x94d, 0x94d), (0x951, 0x954), - (0x962, 0x963), (0x981, 0x981), (0x9bc, 0x9bc), - (0x9c1, 0x9c4), (0x9cd, 0x9cd), (0x9e2, 0x9e3), - (0xa01, 0xa02), (0xa3c, 0xa3c), (0xa41, 0xa42), - (0xa47, 0xa48), (0xa4b, 0xa4d), (0xa70, 0xa71), - (0xa81, 0xa82), (0xabc, 0xabc), (0xac1, 0xac5), - (0xac7, 0xac8), (0xacd, 0xacd), (0xae2, 0xae3), - (0xb01, 0xb01), (0xb3c, 0xb3c), (0xb3f, 0xb3f), - (0xb41, 0xb43), (0xb4d, 0xb4d), (0xb56, 0xb56), - (0xb82, 0xb82), (0xbc0, 0xbc0), (0xbcd, 0xbcd), - (0xc3e, 0xc40), (0xc46, 0xc48), (0xc4a, 0xc4d), - (0xc55, 0xc56), (0xcbc, 0xcbc), (0xcbf, 0xcbf), - (0xcc6, 0xcc6), (0xccc, 0xccd), (0xce2, 0xce3), - (0xd41, 0xd43), (0xd4d, 0xd4d), (0xdca, 0xdca), - (0xdd2, 0xdd4), (0xdd6, 0xdd6), (0xe31, 0xe31), - (0xe34, 0xe3a), (0xe47, 0xe4e), (0xeb1, 0xeb1), - (0xeb4, 0xeb9), (0xebb, 0xebc), (0xec8, 0xecd), - (0xf18, 0xf19), (0xf35, 0xf35), (0xf37, 0xf37), - (0xf39, 0xf39), (0xf71, 0xf7e), (0xf80, 0xf84), - (0xf86, 0xf87), (0xf90, 0xf97), (0xf99, 0xfbc), - (0xfc6, 0xfc6), (0x102d, 0x1030), (0x1032, 0x1032), - (0x1036, 0x1037), (0x1039, 0x103a), (0x1058, 0x1059), - (0x108d, 0x108d), (0x1160, 0x11ff), (0x135d, 0x135f), - (0x1712, 0x1714), (0x1732, 0x1734), (0x1752, 0x1753), - (0x1772, 0x1773), (0x17b4, 0x17b5), (0x17b7, 0x17bd), - (0x17c6, 0x17c6), (0x17c9, 0x17d3), (0x17dd, 0x17dd), - (0x180b, 0x180d), (0x18a9, 0x18a9), (0x1920, 0x1922), - (0x1927, 0x1928), (0x1932, 0x1932), (0x1939, 0x193b), - (0x1a17, 0x1a18), (0x1a60, 0x1a60), (0x1a75, 0x1a7c), - (0x1a7f, 0x1a7f), (0x1b00, 0x1b03), (0x1b34, 0x1b34), - (0x1b36, 0x1b3a), (0x1b3c, 0x1b3c), (0x1b42, 0x1b42), - (0x1b44, 0x1b44), (0x1b6b, 0x1b73), (0x1baa, 0x1bab), - (0x1be6, 0x1be6), (0x1bf2, 0x1bf3), (0x1c37, 0x1c37), - (0x1cd0, 0x1cd2), (0x1cd4, 0x1ce0), (0x1ce2, 0x1ce8), - (0x1ced, 0x1ced), (0x1cf4, 0x1cf4), (0x1dc0, 0x1de6), - (0x1dfc, 0x1dff), (0x200b, 0x200f), (0x202a, 0x202e), - (0x2060, 0x2063), (0x206a, 0x206f), (0x20d0, 0x20f0), - (0x2cef, 0x2cf1), (0x2d7f, 0x2d7f), (0x2de0, 0x2dff), - (0x302a, 0x302f), (0x3099, 0x309a), (0xa66f, 0xa66f), - (0xa674, 0xa67d), (0xa69f, 0xa69f), (0xa6f0, 0xa6f1), - (0xa806, 0xa806), (0xa80b, 0xa80b), (0xa825, 0xa826), - (0xa8c4, 0xa8c4), (0xa8e0, 0xa8f1), (0xa92b, 0xa92d), - (0xa953, 0xa953), (0xa9b3, 0xa9b3), (0xa9c0, 0xa9c0), - (0xaab0, 0xaab0), (0xaab2, 0xaab4), (0xaab7, 0xaab8), - (0xaabe, 0xaabf), (0xaac1, 0xaac1), (0xaaf6, 0xaaf6), - (0xabed, 0xabed), (0xfb1e, 0xfb1e), (0xfe00, 0xfe0f), - (0xfe20, 0xfe26), (0xfeff, 0xfeff), (0xfff9, 0xfffb), - (0x101fd, 0x101fd), (0x10a01, 0x10a03), (0x10a05, 0x10a06), - (0x10a0c, 0x10a0f), (0x10a38, 0x10a3a), (0x10a3f, 0x10a3f), - (0x11046, 0x11046), (0x110b9, 0x110ba), (0x11100, 0x11102), - (0x11133, 0x11134), (0x111c0, 0x111c0), (0x116b6, 0x116b7), - (0x1d165, 0x1d169), (0x1d16d, 0x1d182), (0x1d185, 0x1d18b), - (0x1d1aa, 0x1d1ad), (0x1d242, 0x1d244), (0xe0001, 0xe0001), - (0xe0020, 0xe007f), (0xe0100, 0xe01ef), ) + (0x300, 0x36f), (0x483, 0x489), (0x591, 0x5bd), + (0x5bf, 0x5bf), (0x5c1, 0x5c2), (0x5c4, 0x5c5), + (0x5c7, 0x5c7), (0x600, 0x603), (0x610, 0x61a), + (0x64b, 0x65f), (0x670, 0x670), (0x6d6, 0x6e4), + (0x6e7, 0x6e8), (0x6ea, 0x6ed), (0x70f, 0x70f), + (0x711, 0x711), (0x730, 0x74a), (0x7a6, 0x7b0), + (0x7eb, 0x7f3), (0x816, 0x819), (0x81b, 0x823), + (0x825, 0x827), (0x829, 0x82d), (0x859, 0x85b), + (0x8e3, 0x8ff), (0x901, 0x902), (0x93c, 0x93c), + (0x941, 0x948), (0x94d, 0x94d), (0x951, 0x954), + (0x962, 0x963), (0x981, 0x981), (0x9bc, 0x9bc), + (0x9c1, 0x9c4), (0x9cd, 0x9cd), (0x9e2, 0x9e3), + (0xa01, 0xa02), (0xa3c, 0xa3c), (0xa41, 0xa42), + (0xa47, 0xa48), (0xa4b, 0xa4d), (0xa70, 0xa71), + (0xa81, 0xa82), (0xabc, 0xabc), (0xac1, 0xac5), + (0xac7, 0xac8), (0xacd, 0xacd), (0xae2, 0xae3), + (0xb01, 0xb01), (0xb3c, 0xb3c), (0xb3f, 0xb3f), + (0xb41, 0xb43), (0xb4d, 0xb4d), (0xb56, 0xb56), + (0xb82, 0xb82), (0xbc0, 0xbc0), (0xbcd, 0xbcd), + (0xc3e, 0xc40), (0xc46, 0xc48), (0xc4a, 0xc4d), + (0xc55, 0xc56), (0xcbc, 0xcbc), (0xcbf, 0xcbf), + (0xcc6, 0xcc6), (0xccc, 0xccd), (0xce2, 0xce3), + (0xd41, 0xd43), (0xd4d, 0xd4d), (0xdca, 0xdca), + (0xdd2, 0xdd4), (0xdd6, 0xdd6), (0xe31, 0xe31), + (0xe34, 0xe3a), (0xe47, 0xe4e), (0xeb1, 0xeb1), + (0xeb4, 0xeb9), (0xebb, 0xebc), (0xec8, 0xecd), + (0xf18, 0xf19), (0xf35, 0xf35), (0xf37, 0xf37), + (0xf39, 0xf39), (0xf71, 0xf7e), (0xf80, 0xf84), + (0xf86, 0xf87), (0xf90, 0xf97), (0xf99, 0xfbc), + (0xfc6, 0xfc6), (0x102d, 0x1030), (0x1032, 0x1032), + (0x1036, 0x1037), (0x1039, 0x103a), (0x1058, 0x1059), + (0x108d, 0x108d), (0x1160, 0x11ff), (0x135d, 0x135f), + (0x1712, 0x1714), (0x1732, 0x1734), (0x1752, 0x1753), + (0x1772, 0x1773), (0x17b4, 0x17b5), (0x17b7, 0x17bd), + (0x17c6, 0x17c6), (0x17c9, 0x17d3), (0x17dd, 0x17dd), + (0x180b, 0x180d), (0x18a9, 0x18a9), (0x1920, 0x1922), + (0x1927, 0x1928), (0x1932, 0x1932), (0x1939, 0x193b), + (0x1a17, 0x1a18), (0x1a60, 0x1a60), (0x1a75, 0x1a7c), + (0x1a7f, 0x1a7f), (0x1ab0, 0x1abd), (0x1b00, 0x1b03), + (0x1b34, 0x1b34), (0x1b36, 0x1b3a), (0x1b3c, 0x1b3c), + (0x1b42, 0x1b42), (0x1b44, 0x1b44), (0x1b6b, 0x1b73), + (0x1baa, 0x1bab), (0x1be6, 0x1be6), (0x1bf2, 0x1bf3), + (0x1c37, 0x1c37), (0x1cd0, 0x1cd2), (0x1cd4, 0x1ce0), + (0x1ce2, 0x1ce8), (0x1ced, 0x1ced), (0x1cf4, 0x1cf4), + (0x1cf8, 0x1cf9), (0x1dc0, 0x1df5), (0x1dfc, 0x1dff), + (0x200b, 0x200f), (0x202a, 0x202e), (0x2060, 0x2063), + (0x206a, 0x206f), (0x20d0, 0x20f0), (0x2cef, 0x2cf1), + (0x2d7f, 0x2d7f), (0x2de0, 0x2dff), (0x302a, 0x302f), + (0x3099, 0x309a), (0xa66f, 0xa66f), (0xa674, 0xa67d), + (0xa69e, 0xa69f), (0xa6f0, 0xa6f1), (0xa806, 0xa806), + (0xa80b, 0xa80b), (0xa825, 0xa826), (0xa8c4, 0xa8c4), + (0xa8e0, 0xa8f1), (0xa92b, 0xa92d), (0xa953, 0xa953), + (0xa9b3, 0xa9b3), (0xa9c0, 0xa9c0), (0xaab0, 0xaab0), + (0xaab2, 0xaab4), (0xaab7, 0xaab8), (0xaabe, 0xaabf), + (0xaac1, 0xaac1), (0xaaf6, 0xaaf6), (0xabed, 0xabed), + (0xfb1e, 0xfb1e), (0xfe00, 0xfe0f), (0xfe20, 0xfe2f), + (0xfeff, 0xfeff), (0xfff9, 0xfffb), (0x101fd, 0x101fd), + (0x102e0, 0x102e0), (0x10376, 0x1037a), (0x10a01, 0x10a03), + (0x10a05, 0x10a06), (0x10a0c, 0x10a0f), (0x10a38, 0x10a3a), + (0x10a3f, 0x10a3f), (0x10ae5, 0x10ae6), (0x11046, 0x11046), + (0x1107f, 0x1107f), (0x110b9, 0x110ba), (0x11100, 0x11102), + (0x11133, 0x11134), (0x11173, 0x11173), (0x111c0, 0x111c0), + (0x111ca, 0x111ca), (0x11235, 0x11236), (0x112e9, 0x112ea), + (0x1133c, 0x1133c), (0x1134d, 0x1134d), (0x11366, 0x1136c), + (0x11370, 0x11374), (0x114c2, 0x114c3), (0x115bf, 0x115c0), + (0x1163f, 0x1163f), (0x116b6, 0x116b7), (0x1172b, 0x1172b), + (0x16af0, 0x16af4), (0x16b30, 0x16b36), (0x1bc9e, 0x1bc9e), + (0x1d165, 0x1d169), (0x1d16d, 0x1d182), (0x1d185, 0x1d18b), + (0x1d1aa, 0x1d1ad), (0x1d242, 0x1d244), (0x1e8d0, 0x1e8d6), + (0xe0001, 0xe0001), (0xe0020, 0xe007f), (0xe0100, 0xe01ef), ) ''' Internal table, provided by this module to list :term:`code points` which combine with other characters and therefore should have no :term:`textual @@ -187,8 +194,8 @@ a combining character. :func:`~kitchen.text.display._generate_combining_table` for how this table is generated -This table was last regenerated on python-3.2.3 with -:data:`unicodedata.unidata_version` 6.0.0 +This table was last regenerated on python-3.5 with +:data:`unicodedata.unidata_version` 8.0.0 ''' # New function from Toshio Kuratomi (LGPLv2+) def _generate_combining_table():