Merlijn van Deen has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/86386


Change subject: Bug 54726 - Add Windows unicode cmd argument support
......................................................................

Bug 54726 - Add Windows unicode cmd argument support

Instead of working with the encoded sys.argv, we now use the unicode
pywikibot.argvu, which is set by the active userinterface. The UI
knows how to get the correct unicode argv (depending on OS).

pwb.py is adapted to use pwb.argvu in addition to sys.argv

Change-Id: Ifde7e42587f4a4493ca3c5d8f5ed1ab06bbd806b
---
M pwb.py
M pywikibot/bot.py
M pywikibot/userinterfaces/terminal_interface_base.py
M pywikibot/userinterfaces/terminal_interface_win32.py
M tests/ui_tests.py
5 files changed, 45 insertions(+), 33 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/pywikibot/core 
refs/changes/86/86386/1

diff --git a/pwb.py b/pwb.py
index 5ad35d9..a7c9290 100644
--- a/pwb.py
+++ b/pwb.py
@@ -22,13 +22,11 @@
 import os
 import sys
 
-
-def run_python_file(filename, args):
+def run_python_file(filename, argv, argvu):
     """Run a python file as if it were the main program on the command line.
 
     `filename` is the path to the file to execute, it need not be a .py file.
-    `args` is the argument array to present as sys.argv, including the first
-    element representing the file being executed.
+    `args` is the argument array to present as sys.argv, as unicode strings.
 
     """
     # Create a module to serve as __main__
@@ -40,8 +38,11 @@
 
     # Set sys.argv and the first path element properly.
     old_argv = sys.argv
+    old_argvu = pwb.argvu
     old_path0 = sys.path[0]
-    sys.argv = args
+
+    sys.argv = argv
+    pwb.argvu = argvu
     sys.path[0] = os.path.dirname(filename)
 
     try:
@@ -54,6 +55,7 @@
         # Restore the old argv and path
         sys.argv = old_argv
         sys.path[0] = old_path0
+        pwb.argvu = old_argvu
 
 #### end of snippet
 
@@ -86,9 +88,11 @@
     print "Please follow the prompts to create it:"
     run_python_file('generate_user_files.py', ['generate_user_files.py'])
 
+import pywikibot as pwb
 if len(sys.argv) > 1:
     fn = sys.argv[1]
-    args = sys.argv[1:]
+    argv = sys.argv[1:]
+    argvu = pwb.argvu[1:]
 
     if not os.path.exists(fn):
         testpath = os.path.join(os.path.split(__file__)[0], 'scripts', fn)
@@ -100,4 +104,4 @@
                 fn = testpath
             else:
                 raise Exception("%s not found!" % fn)
-    run_python_file(fn, args)
+    run_python_file(fn, argv, argvu)
diff --git a/pywikibot/bot.py b/pywikibot/bot.py
index 8aaa050..758c7d0 100644
--- a/pywikibot/bot.py
+++ b/pywikibot/bot.py
@@ -40,7 +40,7 @@
                       % config.userinterface,
                       fromlist=['UI'])
 ui = uiModule.UI()
-
+argvu = ui.argvu()
 
 # Logging module configuration
 
@@ -503,35 +503,16 @@
 
     """
     # get commandline arguments
-    called = sys.argv[0].strip()
+    called = argvu[0].strip()
     if ".py" in called:  # could end with .pyc, .pyw, etc. on some platforms
         # clip off the '.py?' filename extension
         called = called[:called.rindex('.py')]
     return os.path.basename(called)
 
-
-def _decodeArg(arg):
-    if sys.platform == 'win32':
-        if config.console_encoding in ('cp437', 'cp850'):
-            # Western Windows versions give parameters encoded as windows-1252
-            # even though the console encoding is cp850 or cp437.
-            return unicode(arg, 'windows-1252')
-        elif config.console_encoding == 'cp852':
-            # Central/Eastern European Windows versions give parameters encoded
-            # as windows-1250 even though the console encoding is cp852.
-            return unicode(arg, 'windows-1250')
-        else:
-            return unicode(arg, config.console_encoding)
-    else:
-        # Linux uses the same encoding for both.
-        # I don't know how non-Western Windows versions behave.
-        return unicode(arg, config.console_encoding)
-
-
 def handleArgs(*args):
     """Handle standard command line arguments, return the rest as a list.
 
-    Takes the commandline arguments, converts them to Unicode, processes all
+    Takes the commandline arguments as Unicode strings, processes all
     global parameters such as -lang or -log. Returns a list of all arguments
     that are not global. This makes sure that global arguments are applied
     first, regardless of the order in which the arguments were given.
@@ -541,7 +522,10 @@
     """
     # get commandline arguments if necessary
     if not args:
-        args = sys.argv[1:]
+        # it's the version in pywikibot.__init__ that is changed by scripts,
+        # not the one in pywikibot.bot.
+        from pywikibot import argvu
+        args = argvu[1:]
     # get the name of the module calling this function. This is
     # required because the -help option loads the module's docstring and 
because
     # the module name will be used for the filename of the log.
@@ -552,7 +536,6 @@
     username = None
     do_help = False
     for arg in args:
-        arg = _decodeArg(arg)
         if arg == '-help':
             do_help = True
         elif arg.startswith('-family:'):
diff --git a/pywikibot/userinterfaces/terminal_interface_base.py 
b/pywikibot/userinterfaces/terminal_interface_base.py
index 84f7102..1225ae3 100755
--- a/pywikibot/userinterfaces/terminal_interface_base.py
+++ b/pywikibot/userinterfaces/terminal_interface_base.py
@@ -45,6 +45,7 @@
         self.stdin = sys.stdin
         self.stdout = sys.stdout
         self.stderr = sys.stderr
+        self.argv = sys.argv
         self.encoding = config.console_encoding
         self.transliteration_target = config.transliteration_target
 
@@ -262,6 +263,8 @@
             return wikipedia.input(
                 u'What is the solution of the CAPTCHA at this url ?')
 
+    def argvu(self):
+        return [s.decode(self.encoding) for s in self.argv]
 
 class TerminalHandler(logging.Handler):
     """A handler class that writes logging records, appropriately formatted, to
diff --git a/pywikibot/userinterfaces/terminal_interface_win32.py 
b/pywikibot/userinterfaces/terminal_interface_win32.py
index 3507701..a18caec 100755
--- a/pywikibot/userinterfaces/terminal_interface_win32.py
+++ b/pywikibot/userinterfaces/terminal_interface_win32.py
@@ -44,14 +44,14 @@
         terminal_interface_base.UI.__init__(self)
         self.encoding = 'ascii'
 
-
 class Win32CtypesUI(Win32BaseUI):
     def __init__(self):
         Win32BaseUI.__init__(self)
-        from win32_unicode import stdin, stdout, stderr
+        from win32_unicode import stdin, stdout, stderr, argv
         self.stdin = stdin
         self.stdout = stdout
         self.stderr = stderr
+        self.argv = argv
         self.encoding = 'utf-8'
 
     def printColorized(self, text, targetStream):
diff --git a/tests/ui_tests.py b/tests/ui_tests.py
index 343e3fc..51adc82 100644
--- a/tests/ui_tests.py
+++ b/tests/ui_tests.py
@@ -446,6 +446,28 @@
 
             self.assertEqual(returned, u"Заглавная_страница")
 
+    class TestWindowsTerminalUnicodeArguments(WindowsTerminalTestCase):
+        @classmethod
+        def setUpClass(cls):
+            import inspect
+            cls.setUpProcess(["cmd", "/k", "echo off"])
+
+        @classmethod
+        def tearDownClass(cls):
+            cls.tearDownProcess()
+            pass
+
+        def testOutputUnicodeText_no_transliterate(self):
+            self.sendstdin(u"""python -c "import os, pywikibot; 
os.system('cls'); pywikibot.output(u'\\n'.join(pywikibot.handleArgs()))" Alpha 
Bετα Гамма دلتا\n""")
+            while(True):
+                lines = self.getstdouterr().split("\n")
+                if len(lines) >= 4 and lines[0] == "Alpha":
+                    break
+                time.sleep(1)
+
+            # empty line is the new command line
+            self.assertEqual(lines, [u"Alpha", u"Bετα", u"Гамма", u"دلتا", 
u""])
+
     try:
         try:
             unittest.main()

-- 
To view, visit https://gerrit.wikimedia.org/r/86386
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ifde7e42587f4a4493ca3c5d8f5ed1ab06bbd806b
Gerrit-PatchSet: 1
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: Merlijn van Deen <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to