Skip to content

Commit 16a7994

Browse files
WIP: Changes encoding. Fixes running chinese path in python2.7 (#1880)
Changes encoding. Fixes running chinese path in python2.7 under Windows (fixes Windows, breaks Linux :( ) Users are advised to move to Python 3.6 or higher.
1 parent 9b94ec6 commit 16a7994

File tree

4 files changed

+100
-60
lines changed

4 files changed

+100
-60
lines changed

src/robotide/contrib/testrunner/TestRunnerAgent.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,10 @@
9494
from robot.utils.encoding import SYSTEM_ENCODING
9595
except ImportError:
9696
encoding = None
97-
# print("TestRunnerAgent: Maybe you did not
98-
# installed RIDE under this Python?") # DEBUG
97+
# print("TestRunnerAgent: Maybe you did not installed RIDE under this Python?") # DEBUG
9998
raise # DEBUG
10099

100+
# print("DEBUG: console %s system %s" % (encoding.CONSOLE_ENCODING, encoding.SYSTEM_ENCODING))
101101

102102
if sys.hexversion > 0x2060000:
103103
import json

src/robotide/contrib/testrunner/runprofiles.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,12 @@
3737
from robotide.utils import (overrides, SYSTEM_ENCODING, ArgumentParser,
3838
is_unicode, PY3)
3939
from robotide.contrib.testrunner.usages import USAGE
40+
from sys import getfilesystemencoding
41+
4042
if PY3:
4143
from robotide.utils import unicode
4244

45+
OUTPUT_ENCODING = getfilesystemencoding()
4346

4447
class BaseProfile(object):
4548
"""Base class for all test runner profiles
@@ -254,10 +257,18 @@ def TagsPanel(self, parent):
254257
"Only run tests with these tags")
255258
exclude_cb = self._create_checkbox(panel, self.apply_exclude_tags,
256259
"Skip tests with these tags")
257-
self._include_tags = wx.TextCtrl(panel, wx.ID_ANY, size=(150, -1),
258-
value=self.include_tags)
259-
self._exclude_tags = wx.TextCtrl(panel, wx.ID_ANY, size=(150, -1),
260-
value=self.exclude_tags)
260+
try:
261+
self._include_tags = wx.TextCtrl(panel, wx.ID_ANY, size=(150, -1),
262+
value=self.include_tags)
263+
except UnicodeError:
264+
self._include_tags = wx.TextCtrl(panel, wx.ID_ANY, size=(150, -1),
265+
value="unicode_error")
266+
try:
267+
self._exclude_tags = wx.TextCtrl(panel, wx.ID_ANY, size=(150, -1),
268+
value=self.exclude_tags)
269+
except UnicodeError:
270+
self._exclude_tags = wx.TextCtrl(panel, wx.ID_ANY, size=(150, -1),
271+
value="unicode_error")
261272

262273
panel.Bind(wx.EVT_CHECKBOX, self.OnIncludeCheckbox, include_cb)
263274
panel.Bind(wx.EVT_CHECKBOX, self.OnExcludeCheckbox, exclude_cb)
@@ -308,11 +319,12 @@ def MySetToolTip(self, obj, tip):
308319
def _get_invalid_message(self, args):
309320
invalid = None
310321
try:
311-
# print("DEBUG: runprofiles get inv msg: %s\n
322+
# print("DEBUG: runprofiles get inv msg: %s\n" % args)
312323
# raw: %s\n" % (bytes(args), args) )
313-
if PY3:
314-
args = args.encode(SYSTEM_ENCODING) # DEBUG SYSTEM_ENCODING
324+
#if PY3:
325+
# args = args.encode(SYSTEM_ENCODING) # DEBUG SYSTEM_ENCODING
315326
_, invalid = ArgumentParser(USAGE).parse_args(args.split())
327+
# print("DEBUG: runprofiles get inv msg: %s\n" % args)
316328
except Information:
317329
return 'Does not execute - help or version option given'
318330
except (DataError, Exception) as e: # DEBUG not caught DataError?

src/robotide/contrib/testrunner/testrunner.py

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -52,28 +52,39 @@
5252
from robotide.context import IS_WINDOWS
5353
from robotide.contrib.testrunner import TestRunnerAgent
5454
from robotide.controller.testexecutionresults import TestExecutionResults
55-
from robotide.utils import PY2, is_unicode # , unicode
55+
from robotide.utils import PY2, is_unicode
5656
try:
5757
from robotide.lib.robot.utils import encoding
5858
except ImportError:
59-
encoding = None
59+
from robotide.lib.robot.utils.encodingsniffer import (get_console_encoding,
60+
get_system_encoding)
61+
CONSOLE_ENCODING = get_console_encoding()
62+
SYSTEM_ENCODING = get_system_encoding()
63+
encoding = {'CONSOLE': CONSOLE_ENCODING,
64+
'SYSTEM': SYSTEM_ENCODING}
65+
6066
# DEBUG we are forcing UTF-8
61-
if encoding:
67+
if IS_WINDOWS:
68+
encoding.OUTPUT_ENCODING = 'mbcs'
69+
else:
6270
encoding.OUTPUT_ENCODING = sys.getfilesystemencoding() # 'UTF-8'
71+
# print("DEBUG: console %s system %s output %s" % (encoding.CONSOLE_ENCODING, encoding.SYSTEM_ENCODING, encoding.OUTPUT_ENCODING))
6372

6473
ATEXIT_LOCK = threading.RLock()
6574

66-
# Solution from https://stackoverflow.com/questions/10009753/python-dealing-with-mixed-encoding-files
67-
def mixed_decoder(unicodeError):
68-
errStr = unicodeError[1]
69-
errLen = unicodeError.end - unicodeError.start
70-
nextPosition = unicodeError.start + errLen
71-
errHex = errStr[unicodeError.start:unicodeError.end].encode('hex')
72-
# return u'?', nextPosition
73-
return u'%s' % errHex, nextPosition # Comment this line out to get a question mark
75+
76+
# Solution from https://stackoverflow.com/questions/10009753/
77+
# python-dealing-with-mixed-encoding-files
78+
def mixed_decoder(unicode_error):
79+
err_str = unicode_error[1]
80+
err_len = unicode_error.end - unicode_error.start
81+
next_position = unicode_error.start + err_len
82+
err_hex = err_str[unicode_error.start:unicode_error.end].encode('hex')
83+
# Alternative, return u'?', next_position
84+
return u'%s' % err_hex, next_position # Comment this line out to get a ?
7485

7586

76-
codecs.register_error("mixed", mixed_decoder)
87+
# codecs.register_error("mixed", mixed_decoder)
7788

7889

7990
class TestRunner(object):
@@ -212,10 +223,7 @@ def send_step_over_signal(self):
212223

213224
def run_command(self, command, cwd):
214225
self._pid_to_kill = None
215-
if IS_WINDOWS:
216-
self._process = Process(cwd) # .encode(encoding.SYSTEM_ENCODING))
217-
else:
218-
self._process = Process(cwd.encode(encoding.OUTPUT_ENCODING))
226+
self._process = Process(cwd) # .encode(encoding.SYSTEM_ENCODING))
219227
# print("DEBUG: run_command command: %s\nCWD: %s\n" % (command, cwd))
220228
self._process.run_command(command)
221229

@@ -291,14 +299,23 @@ def _add_pythonpath_if_in_settings_and_not_given_by_user(
291299

292300
@staticmethod
293301
def _write_argfile(argfile, args):
294-
if PY2:
295-
f = codecs.open(argfile, "wb")
302+
if PY2 or IS_WINDOWS:
303+
f = codecs.open(argfile, "wb") #, encoding=encoding.OUTPUT_ENCODING)
296304
for item in args:
297305
if is_unicode(item):
298-
enc_arg = item.encode(encoding.CONSOLE_ENCODING) # DEBUG .OUTPUT_ENCODING)
306+
enc_arg = item.encode('utf-8') # encoding.OUTPUT_ENCODING) # DEBUG CONSOLE_ENCODING
299307
else:
300308
enc_arg = item
301-
f.write(enc_arg+"\n")
309+
try:
310+
f.write(enc_arg) #.encode(encoding.OUTPUT_ENCODING))
311+
f.write("\n".encode(encoding.OUTPUT_ENCODING))
312+
except UnicodeError:
313+
if PY2:
314+
f.write(bytes(item))
315+
else:
316+
f.write(bytes(item, 'utf-8'))
317+
f.write(b"\n")
318+
# print("DEBUG: unicodedecodeerror when writting arg file")
302319
else:
303320
f = codecs.open(argfile, "w", "utf-8")
304321
f.write("\n".join(args))
@@ -348,10 +365,7 @@ def run_command(self, command):
348365
else:
349366
subprocess_args['preexec_fn'] = os.setsid
350367
subprocess_args['shell'] = True
351-
if IS_WINDOWS:
352-
self._process = subprocess.Popen(command, **subprocess_args)
353-
else:
354-
self._process = subprocess.Popen(command.encode(encoding.OUTPUT_ENCODING), **subprocess_args)
368+
self._process = subprocess.Popen(command, **subprocess_args)
355369
self._process.stdin.close()
356370
self._output_stream = StreamReaderThread(self._process.stdout)
357371
self._error_stream = StreamReaderThread(self._process.stderr)
@@ -406,7 +420,9 @@ def _send_socket(self, data):
406420
if PY2:
407421
sock.send(data)
408422
else:
409-
sock.send(bytes(data, encoding.SYSTEM_ENCODING))
423+
sock.send(bytes(data, encoding.OUTPUT_ENCODING)) #DEBUG SYSTEM_ENCODING
424+
# except Exception:
425+
# print(r"DEBUG: Exception at send socket %s" % data)
410426
finally:
411427
sock.close()
412428

src/robotide/contrib/testrunner/testrunnerplugin.py

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -67,19 +67,21 @@
6767
from robotide.pluginapi import Plugin, ActionInfo
6868
from robotide.widgets import Label, ImageProvider
6969
from robotide.robotapi import LOG_LEVELS
70-
from robotide.utils import robottime, is_unicode, PY2, PY3
70+
from robotide.utils import robottime, is_unicode, PY2
7171
from sys import getfilesystemencoding
72-
try:
73-
from robotide.lib.robot.utils import encoding
74-
except ImportError:
75-
encoding = None
76-
# if encoding:
77-
# encoding.CONSOLE_ENCODING = getfilesystemencoding()
78-
79-
if PY3:
80-
from robotide.utils import unicode
81-
82-
# print("DEBUG: TestRunnerPlugin encoding=%s" % encoding)
72+
from robotide.lib.robot.utils.encodingsniffer import (get_console_encoding,
73+
get_system_encoding)
74+
CONSOLE_ENCODING = get_console_encoding()
75+
if PY2 and IS_WINDOWS:
76+
SYSTEM_ENCODING = 'mbcs'
77+
else:
78+
SYSTEM_ENCODING = get_system_encoding()
79+
OUTPUT_ENCODING = getfilesystemencoding()
80+
encoding = {'CONSOLE': CONSOLE_ENCODING,
81+
'SYSTEM': SYSTEM_ENCODING,
82+
'OUTPUT': OUTPUT_ENCODING}
83+
84+
#print("DEBUG: TestRunnerPlugin encoding=%s" % encoding)
8385

8486
ID_RUN = wx.NewId()
8587
ID_RUNDEBUG = wx.NewId()
@@ -300,12 +302,16 @@ def OnRun(self, event):
300302
return
301303
self._initialize_ui_for_running()
302304
command = self._create_command()
303-
self._output("command: %s\n" % command) # DEBUG encode
305+
if PY2:
306+
self._output("command: %s\n" % command) # DEBUG encode
307+
else:
308+
self._output("command: %s\n" % command, enc=False) # DEBUG on Py3 it not shows correct if tags with latin chars
304309
try:
305-
if PY2 and IS_WINDOWS:
310+
if PY2: # and IS_WINDOWS:
306311
cwd = self._get_current_working_dir() # DEBUG It fails if a directory has chinese or latin symbols
307-
cwd = cwd.encode(encoding.SYSTEM_ENCODING)
308-
self._test_runner.run_command(command, cwd)
312+
cwd = cwd.encode(encoding['OUTPUT']) # DEBUG SYSTEM_ENCODING
313+
# print("DEBUG: encoded cwd: %s" % cwd)
314+
self._test_runner.run_command(command.encode(encoding['OUTPUT']), cwd) # --include Áçãoµ
309315
else:
310316
self._test_runner.run_command(command, self._get_current_working_dir())
311317
# self._output("DEBUG: Passed test_runner.run_command\n")
@@ -489,7 +495,7 @@ def _format_command(self, argv):
489495
result = []
490496
for arg in argv:
491497
if PY2 and is_unicode(arg):
492-
arg = arg.encode(encoding.CONSOLE_ENCODING) # DEBUG "utf-8")
498+
arg = arg.encode(encoding['SYSTEM']) # DEBUG "utf-8") CONSOLE_ENCODING
493499
# print("DEBUG: PY2 unicode args %s" % arg)
494500
if "'" in arg or " " in arg or "&" in arg:
495501
# for windows, if there are spaces we need to use
@@ -508,7 +514,7 @@ def _show_notebook_tab(self):
508514
self._reload_model()
509515
self.show_tab(self.panel)
510516

511-
def _AppendText(self, textctrl, string, source="stdout"):
517+
def _AppendText(self, textctrl, string, source="stdout", enc=True):
512518
if not self.panel or not textctrl:
513519
return
514520
textctrl.update_scroll_width(string)
@@ -520,15 +526,21 @@ def _AppendText(self, textctrl, string, source="stdout"):
520526

521527
textctrl.SetReadOnly(False)
522528
try:
523-
if PY2:
524-
# textctrl.AppendText(string.encode(encoding.OUTPUT_ENCODING)) # DEBUG encoding.CONSOLE_ENCODING)) # DEBUG 'utf-8'))
525-
textctrl.AppendText(string.encode(encoding.SYSTEM_ENCODING)) # encoding.SYSTEM_ENCODING)) 'utf-8'
529+
if enc:
530+
textctrl.AppendText(string.encode(encoding['SYSTEM']))
526531
else:
527-
textctrl.AppendText(str(string)) # DEBUG
532+
textctrl.AppendText(string)
533+
# print("DEBUG _AppendText Printed OK")
528534
except UnicodeDecodeError as e:
529535
# I'm not sure why I sometimes get this, and I don't know what I
530536
# can do other than to ignore it.
531-
textctrl.AppendTextRaw(bytes(string)) # DEBUG .encode('utf-8'))
537+
if PY2:
538+
if is_unicode(string):
539+
textctrl.AppendTextRaw(bytes(string.encode('utf-8')))
540+
else:
541+
textctrl.AppendTextRaw(string)
542+
else:
543+
textctrl.AppendTextRaw(bytes(string, encoding['SYSTEM'])) # DEBUG .encode('utf-8'))
532544
# print(r"DEBUG UnicodeDecodeError appendtext string=%s\n" % string)
533545
pass
534546
except UnicodeEncodeError as e:
@@ -580,9 +592,9 @@ def _build_config_panel(self, parent):
580592
self.config_panel = panel
581593
return panel
582594

583-
def _output(self, string, source="stdout"):
595+
def _output(self, string, source="stdout", enc=True):
584596
"""Put output to the text control"""
585-
self._AppendText(self.out, string, source)
597+
self._AppendText(self.out, string, source, enc)
586598

587599
def _build_runner_toolbar(self):
588600
toolbar = wx.ToolBar(self.panel, wx.ID_ANY,
@@ -778,7 +790,7 @@ def _create_output_textctrl(self):
778790
face = font.GetFaceName()
779791
size = font.GetPointSize()
780792
textctrl.SetFont(font)
781-
# textctrl.StyleSetFontEncoding(wx.stc.STC_STYLE_DEFAULT, wx.FONTENCODING_SYSTEM) # DEBUG Chinese wx.FONTENCODING_CP936)
793+
# textctrl.StyleSetFontEncoding(wx.stc.STC_STYLE_DEFAULT, wx.FONTENCODING_CP936) # DEBUG Chinese wx.) wx.FONTENCODING_SYSTEM
782794
textctrl.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, "face:%s,size:%d" %
783795
(face, size))
784796
textctrl.StyleSetSpec(STYLE_STDERR, "fore:#b22222") # firebrick

0 commit comments

Comments
 (0)