From ffb1e0a3f37aa8238d50f5443c2f85d83c5f84aa Mon Sep 17 00:00:00 2001 From: "emerson.prado" Date: Tue, 5 Mar 2019 13:52:58 -0300 Subject: Add type selection helper function for regex coercing tests --- tests/test_expect.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/test_expect.py b/tests/test_expect.py index 2c74744..2232e37 100755 --- a/tests/test_expect.py +++ b/tests/test_expect.py @@ -25,11 +25,14 @@ import time import signal import sys import os +import re import pexpect from . import PexpectTestCase from .utils import no_coverage_env +PY3 = bool(sys.version_info.major >= 3) + # Many of these test cases blindly assume that sequential directory # listings of the /bin directory will yield the same results. # This may not be true, but seems adequate for testing now. @@ -101,6 +104,23 @@ class ExpectTestCase (PexpectTestCase.PexpectTestCase): p.sendeof () p.expect (pexpect.EOF) + def _select_types(self, encoding=None): + if encoding is None: + if PY3: + expect_string = 'String' + expected_type = bytes + else: + expect_string = u'String' + expected_type = str + else: + if PY3: + expect_string = b'String' + expected_type = str + else: + expect_string = 'String' + expected_type = unicode + return re.compile(expect_string), expected_type + def test_expect_order (self): '''This tests that patterns are matched in the same order as given in the pattern_list. -- cgit v1.2.1 From f6d7ffa4760b50bcec29f7e8eeed8bd2d5fe88bb Mon Sep 17 00:00:00 2001 From: "emerson.prado" Date: Tue, 5 Mar 2019 13:54:20 -0300 Subject: Add unit tests for regex coercing functions --- tests/test_expect.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/test_expect.py b/tests/test_expect.py index 2232e37..4726b94 100755 --- a/tests/test_expect.py +++ b/tests/test_expect.py @@ -121,6 +121,36 @@ class ExpectTestCase (PexpectTestCase.PexpectTestCase): expected_type = unicode return re.compile(expect_string), expected_type + def test_coerce_expect_re_enc_none (self): + '''This test that compiled regex patterns will always be bytes type + when spawn objects have no encoding or encoding=None + ''' + r, expected_type = self._select_types() + p = pexpect.spawn('true') + c = pexpect.spawnbase.SpawnBase._coerce_expect_re(p, r) + self.assertIsInstance(c.pattern, expected_type) + p.expect (pexpect.EOF) + + def test_coerce_expect_re_enc_ascii (self): + '''This test that compiled regex patterns won't ever be bytes type + when spawn objects have ascii encoding + ''' + r, expected_type = self._select_types('ascii') + p = pexpect.spawn('true', encoding='ascii') + c = pexpect.spawnbase.SpawnBase._coerce_expect_re(p, r) + self.assertIsInstance(c.pattern, expected_type) + p.expect (pexpect.EOF) + + def test_coerce_expect_re_enc_utf8 (self): + '''This test that compiled regex patterns won't ever be bytes type + when spawn objects have utf-8 encoding + ''' + r, expected_type = self._select_types('utf-8') + p = pexpect.spawn('true', encoding='utf-8') + c = pexpect.spawnbase.SpawnBase._coerce_expect_re(p, r) + self.assertIsInstance(c.pattern, expected_type) + p.expect (pexpect.EOF) + def test_expect_order (self): '''This tests that patterns are matched in the same order as given in the pattern_list. -- cgit v1.2.1 From e0cf843260dc7209905952b926d42fab35e80ff1 Mon Sep 17 00:00:00 2001 From: "emerson.prado" Date: Tue, 5 Mar 2019 14:13:58 -0300 Subject: Add integration tests for regex coercing functions --- tests/test_expect.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/test_expect.py b/tests/test_expect.py index 4726b94..31a4592 100755 --- a/tests/test_expect.py +++ b/tests/test_expect.py @@ -151,6 +151,30 @@ class ExpectTestCase (PexpectTestCase.PexpectTestCase): self.assertIsInstance(c.pattern, expected_type) p.expect (pexpect.EOF) + def test_expect_regex_enc_none (self): + '''This test that bytes mode spawn objects (encoding=None) + parses correctly regex patterns compiled from non-bytes type objects + ''' + p = pexpect.spawn('cat', echo=False, timeout=5) + p.sendline ('We are the Knights who say "Ni!"') + index = p.expect ([re.compile('We are the Knights who say "Ni!"'), + pexpect.EOF, pexpect.TIMEOUT]) + self.assertEqual(index, 0) + p.sendeof () + p.expect_exact (pexpect.EOF) + + def test_expect_regex_enc_utf8 (self): + '''This test that non-bytes mode spawn objects (encoding='utf-8') + parses correctly regex patterns compiled from bytes type objects + ''' + p = pexpect.spawn('cat', echo=False, timeout=5, encoding='utf-8') + p.sendline ('We are the Knights who say "Ni!"') + index = p.expect ([re.compile(b'We are the Knights who say "Ni!"'), + pexpect.EOF, pexpect.TIMEOUT]) + self.assertEqual(index, 0) + p.sendeof () + p.expect_exact (pexpect.EOF) + def test_expect_order (self): '''This tests that patterns are matched in the same order as given in the pattern_list. -- cgit v1.2.1 From ec916dd69f4eabee35dc62c903c16cf9131d49d0 Mon Sep 17 00:00:00 2001 From: "emerson.prado" Date: Mon, 4 Mar 2019 15:47:05 -0300 Subject: Coerce compiled regex patterns to bytes type in bytes mode --- pexpect/spawnbase.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pexpect/spawnbase.py b/pexpect/spawnbase.py index 63c0b42..5bf10a5 100644 --- a/pexpect/spawnbase.py +++ b/pexpect/spawnbase.py @@ -138,6 +138,13 @@ class SpawnBase(object): return s.encode('ascii') return s + # In bytes mode, regex patterns should also be of bytes type + def _coerce_expect_re(self, r): + p = r.pattern + if self.encoding is None and not isinstance(p, bytes): + return re.compile(p.encode('utf-8')) + return r + def _coerce_send_string(self, s): if self.encoding is None and not isinstance(s, bytes): return s.encode('utf-8') @@ -232,6 +239,7 @@ class SpawnBase(object): elif p is TIMEOUT: compiled_pattern_list.append(TIMEOUT) elif isinstance(p, type(re.compile(''))): + p = self._coerce_expect_re(p) compiled_pattern_list.append(p) else: self._pattern_type_err(p) -- cgit v1.2.1 From 5834c9631b12efd53dc9bc21190f895bb0a3d31a Mon Sep 17 00:00:00 2001 From: "emerson.prado" Date: Tue, 5 Mar 2019 14:25:17 -0300 Subject: Coerce compiled regex patterns to non-bytes type in non-bytes mode --- pexpect/spawnbase.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pexpect/spawnbase.py b/pexpect/spawnbase.py index 5bf10a5..ee96cfa 100644 --- a/pexpect/spawnbase.py +++ b/pexpect/spawnbase.py @@ -143,6 +143,9 @@ class SpawnBase(object): p = r.pattern if self.encoding is None and not isinstance(p, bytes): return re.compile(p.encode('utf-8')) + # And vice-versa + elif self.encoding is not None and isinstance(p, bytes): + return re.compile(p.decode('utf-8')) return r def _coerce_send_string(self, s): -- cgit v1.2.1