jenkins-bot has submitted this change. ( 
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/769693 )

Change subject: [cleanup] no longer use win32_unicode for Python 3.6+
......................................................................

[cleanup] no longer use win32_unicode for Python 3.6+

This reverts revert 13f59c7f18593601a6635d2f94ad3066b7bec0a3.

- flash target in UI._print if necessary. This has to be done if the
  after a text is processed with UI._print and before a color is changed
- get console_handle to set color attribute in Win32UI.encounter_color
- define isatty() for Python 3.5 to keep the old behaviour
- update and simplify tests
- remove unused utils.FakeModule
- ignore win32_unicode.py from coverage

Bug: T303373
Bug: T283808
Bug: T281042
Change-Id: Icd3f45a8a907bf2c4a11da68e25339b79de11eaf
---
M .codecov.yml
M pywikibot/userinterfaces/terminal_interface_base.py
M pywikibot/userinterfaces/terminal_interface_win32.py
M pywikibot/userinterfaces/win32_unicode.py
M tests/ui_tests.py
M tests/utils.py
6 files changed, 47 insertions(+), 73 deletions(-)

Approvals:
  Chris Maynor: Looks good to me, but someone else must approve
  Xqt: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/.codecov.yml b/.codecov.yml
index 3314ceb..b19bd5e 100644
--- a/.codecov.yml
+++ b/.codecov.yml
@@ -17,6 +17,7 @@
     - pywikibot/backports.py
     - pywikibot/daemonize.py
     - pywikibot/families/__init__.py
+    - pywikibot/userinterfaces/win32_unicode.py
     - scripts/archive/
     - scripts/userscripts/
     - scripts/maintenance/colors.py
diff --git a/pywikibot/userinterfaces/terminal_interface_base.py 
b/pywikibot/userinterfaces/terminal_interface_base.py
index 21c4c87..b855863 100755
--- a/pywikibot/userinterfaces/terminal_interface_base.py
+++ b/pywikibot/userinterfaces/terminal_interface_base.py
@@ -190,8 +190,13 @@

             if current_color != next_color and colorized:
                 # set the new color, but only if they change
+                # flush first to enable color change on Windows (T283808)
+                target_stream.flush()
                 self.encounter_color(color_stack[-1], target_stream)

+        # finally flush stream to show the text, required for Windows (T303373)
+        target_stream.flush()
+
     def output(self, text, targetStream=None) -> None:
         """Forward text to cache and flush if output is not locked.

diff --git a/pywikibot/userinterfaces/terminal_interface_win32.py 
b/pywikibot/userinterfaces/terminal_interface_win32.py
index 1a0ef51..20d4b12 100755
--- a/pywikibot/userinterfaces/terminal_interface_win32.py
+++ b/pywikibot/userinterfaces/terminal_interface_win32.py
@@ -6,7 +6,8 @@
 #
 import ctypes

-from pywikibot.userinterfaces import terminal_interface_base, win32_unicode
+from pywikibot.tools import PYTHON_VERSION
+from pywikibot.userinterfaces import terminal_interface_base


 windowsColors = {
@@ -37,16 +38,18 @@
     def __init__(self) -> None:
         """Initializer."""
         super().__init__()
-        (stdin, stdout, stderr, argv) = win32_unicode.get_unicode_console()
-        self.stdin = stdin
-        self.stdout = stdout
-        self.stderr = stderr
-        self.argv = argv
-        self.encoding = 'utf-8'
+        if PYTHON_VERSION == (3, 5):  # issue1602 solved in Python 3.6
+            from pywikibot.userinterfaces import win32_unicode
+            stdin, stdout, stderr, argv = win32_unicode.get_unicode_console()
+            self.stdin = stdin
+            self.stdout = stdout
+            self.stderr = stderr
+            self.argv = argv
+            self.encoding = 'utf-8'

     def support_color(self, target_stream):
         """Return whether the target stream supports actually color."""
-        return getattr(target_stream, '_hConsole', None) is not None
+        return target_stream.isatty()

     def encounter_color(self, color, target_stream) -> None:
         """Set the new color."""
@@ -55,8 +58,21 @@
         # Merge foreground/backgroung color if needed.
         if bg is not None:
             windows_color = windowsColors[bg] << 4 | windows_color
-        ctypes.windll.kernel32.SetConsoleTextAttribute(
-            target_stream._hConsole, windows_color)
+
+        if target_stream == self.stdin:
+            addr = -10
+        elif target_stream == self.stdout:
+            addr = -11
+        elif target_stream == self.stderr:
+            addr = -12
+        else:
+            super().encounter_color(color, target_stream)
+
+        from ctypes.wintypes import DWORD, HANDLE
+        get_handle = ctypes.WINFUNCTYPE(HANDLE, DWORD)(
+            ('GetStdHandle', ctypes.windll.kernel32))
+        handle = get_handle(DWORD(addr))
+        ctypes.windll.kernel32.SetConsoleTextAttribute(handle, windows_color)

     def _raw_input(self):
         data = self.stdin.readline()
diff --git a/pywikibot/userinterfaces/win32_unicode.py 
b/pywikibot/userinterfaces/win32_unicode.py
index ae7c1f5..75008a4 100755
--- a/pywikibot/userinterfaces/win32_unicode.py
+++ b/pywikibot/userinterfaces/win32_unicode.py
@@ -153,6 +153,10 @@
             _complain('{}.writelines: {!r}'.format(self.name, e))
             raise
 
+    def isatty(self):
+        """Return True if the stream is interactive."""
+        return self._hConsole is not None
+

 def old_fileno(std_name):
     """Return the fileno or None if that doesn't work."""
diff --git a/tests/ui_tests.py b/tests/ui_tests.py
index 8e78ea3..c9d8109 100644
--- a/tests/ui_tests.py
+++ b/tests/ui_tests.py
@@ -31,7 +31,6 @@
 )
 from pywikibot.userinterfaces.transliteration import NON_LATIN_DIGITS, _trans
 from tests.aspects import TestCase, TestCaseBase
-from tests.utils import FakeModule


 class Stream:
@@ -487,7 +486,10 @@

     """Base class for test cases requiring that colorized output is active."""

+    net = False
+
     expect_color = True
+    expected = 'Hello world you!'

     def setUp(self):
         """Force colorized_output to True."""
@@ -500,16 +502,6 @@
         pywikibot.config.colorized_output = self._old_config
         super().tearDown()

-
-class FakeUnixTest(FakeUIColorizedTestBase, FakeUITest):
-
-    """Test case to allow doing colorized Unix tests in any environment."""
-
-    net = False
-
-    expected = 'Hello world you!'
-    ui_class = terminal_interface_unix.UnixUI
-
     def _encounter_color(self, color, target_stream):
         """Verify that the written data, color and stream are correct."""
         self.assertIs(target_stream, self.stream)
@@ -520,6 +512,13 @@
                           sum(e[1] for e in self._colors[:self._index]))


+class FakeUnixTest(FakeUIColorizedTestBase, FakeUITest):
+
+    """Test case to allow doing colorized Unix tests in any environment."""
+
+    ui_class = terminal_interface_unix.UnixUI
+
+
 class FakeWin32Test(FakeUIColorizedTestBase, FakeUITest):

     """
@@ -530,54 +529,21 @@
     import these will be unpatched.
     """

-    net = False
-
-    expected = 'Hello world you!'
     ui_class = terminal_interface_win32.Win32UI

     def setUp(self):
         """Patch the ctypes import and initialize a stream and UI instance."""
         super().setUp()
-        self._orig_ctypes = terminal_interface_win32.ctypes
-        ctypes = FakeModule.create_dotted('ctypes.windll.kernel32')
-        ctypes.windll.kernel32.SetConsoleTextAttribute = self._handle_setattr
-        terminal_interface_win32.ctypes = ctypes
-        self.stream._hConsole = object()
-
-    def tearDown(self):
-        """Unpatch the ctypes import and check that all colors were used."""
-        terminal_interface_win32.ctypes = self._orig_ctypes
-        super().tearDown()
-
-    def _encounter_color(self, color, target_stream):
-        """Call the original method."""
-        self._orig_encounter_color(color, target_stream)
-
-    def _handle_setattr(self, handle, attribute):
-        """Dummy method to handle SetConsoleTextAttribute."""
-        self.assertIs(handle, self.stream._hConsole)
-        color = self._colors[self._index][0]
-        self._index += 1
-        color = terminal_interface_win32.windowsColors[color]
-        self.assertEqual(attribute, color)
-        self.assertLength(self.stream.getvalue(),
-                          sum(e[1] for e in self._colors[:self._index]))
+        self.stream.isatty = lambda: self.expect_color


 class FakeWin32UncolorizedTest(FakeWin32Test):

     """Test case to allow doing uncolorized Win32 tests in any environment."""

-    net = False
-
     expected = 'Hello world you! ***'
     expect_color = False

-    def setUp(self):
-        """Change the local stream's console to None to disable colors."""
-        super().setUp()
-        self.stream._hConsole = None
-

 if __name__ == '__main__':  # pragma: no cover
     with suppress(SystemExit):
diff --git a/tests/utils.py b/tests/utils.py
index 5731aae..35f3372 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -11,7 +11,6 @@
 import warnings
 from contextlib import contextmanager
 from subprocess import PIPE, Popen, TimeoutExpired
-from types import ModuleType

 import pywikibot
 from pywikibot import config
@@ -60,23 +59,6 @@
     return False


-class FakeModule(ModuleType):
-
-    """An empty fake module."""
-
-    @classmethod
-    def create_dotted(cls, name):
-        """Create a chain of modules based on the name separated by periods."""
-        modules = name.split('.')
-        mod = None
-        for mod_name in modules[::-1]:
-            module = cls(str(mod_name))
-            if mod:
-                setattr(module, mod.__name__, mod)
-            mod = module
-        return mod
-
-
 class WarningSourceSkipContextManager(warnings.catch_warnings):

     """

--
To view, visit https://gerrit.wikimedia.org/r/c/pywikibot/core/+/769693
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.wikimedia.org/r/settings

Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: Icd3f45a8a907bf2c4a11da68e25339b79de11eaf
Gerrit-Change-Number: 769693
Gerrit-PatchSet: 8
Gerrit-Owner: Xqt <[email protected]>
Gerrit-Reviewer: Chris Maynor <[email protected]>
Gerrit-Reviewer: JJMC89 <[email protected]>
Gerrit-Reviewer: Meno25 <[email protected]>
Gerrit-Reviewer: Merlijn van Deen <[email protected]>
Gerrit-Reviewer: Xqt <[email protected]>
Gerrit-Reviewer: jenkins-bot
Gerrit-MessageType: merged
_______________________________________________
Pywikibot-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to