X Tutup
Skip to content

Commit a797769

Browse files
committed
Fixes to bytes/unicode strings encoding and decoding,
errors="ignore", see the UNICODE_ENCODE_ERRORS and BYTES_DECODE_ERRORS global variables in string_utils.pyx. Fixed Frame.ExecuteJavascript(), if the string contained utf-8 characters it would probably result in errors. Updated ExceptHook in the examples to handle UnicodeDecodeError exceptions when writing to the log file or printing invalid characters. Added PY_MAJOR_VERSION compile time constant. Changed the c string types in Cython to be always 'bytes' with the 'utf-8' encoding, any decoding to unicode should be explicit. Updated the way the cefpython module is imported in the examples, the previous method was treacherous. Changed the name of the ApplicationSettings["unicode_to_bytes_encoding"] option to "string_encoding". Fixed importing urlparse in Python 3. Updated CEF 1 to Chrome version 27.0.1453.110.
1 parent 597ade7 commit a797769

40 files changed

+664
-373
lines changed

cefpython/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,5 @@ cefpython_py27.pyd
3636
cefpython_py32.pyd
3737
cefpython_py27.so
3838
cefpython_py32.so
39+
40+
cython_includes/compile_time_constants.pxi
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
Chromium/CEF branch:
22
1453
33
Chromium release url:
4-
http://src.chromium.org/svn/releases/27.0.1453.93
4+
http://src.chromium.org/svn/releases/27.0.1453.110
55
CEF revision:
6-
1268
6+
1273
77
CEF repository url:
8-
http://chromiumembedded.googlecode.com/svn/branches/1453/cef1@1268
8+
http://chromiumembedded.googlecode.com/svn/branches/1453/cef1@1273

cefpython/cef1/linux/binaries_32bit/cefpython_py27.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def GetModuleDirectory():
6666
"product_version": "",
6767
"resources_dir_path": "",
6868
"session_storage_quota": 5*1024*1024,
69-
"unicode_to_bytes_encoding": "utf-8",
69+
"string_encoding": "utf-8",
7070
"uncaught_exception_stack_size": 0,
7171
"user_agent": "",
7272
}

cefpython/cef1/linux/binaries_32bit/pygtk_.py

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,25 +40,35 @@ def GetApplicationPath(file=None):
4040
return path
4141
return str(file)
4242

43-
def ExceptHook(type, value, traceObject):
43+
def ExceptHook(excType, excValue, traceObject):
4444
import traceback, os, time
45-
# This hook does the following: in case of exception display it,
46-
# write to error.log, shutdown CEF and exit application.
47-
error = "\n".join(traceback.format_exception(type, value, traceObject))
48-
error_file = GetApplicationPath("error.log")
45+
# This hook does the following: in case of exception write it to
46+
# the "error.log" file, display it to the console, shutdown CEF
47+
# and exit application immediately by ignoring "finally" (_exit()).
48+
errorMsg = "\n".join(traceback.format_exception(excType, excValue,
49+
traceObject))
50+
logFile = GetApplicationPath("error.log")
4951
try:
50-
with open(error_file, "a") as file:
51-
file.write("\n[%s] %s\n" % (time.strftime("%Y-%m-%d %H:%M:%S"), error))
52+
appEncoding = cefpython.g_applicationSettings["string_encoding"]
53+
except:
54+
appEncoding = "utf-8"
55+
if type(errorMsg) == bytes:
56+
errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace")
57+
try:
58+
with open(logFile, "a", encoding=appEncoding) as fp:
59+
fp.write("\n[%s] %s\n" % (
60+
time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg))
5261
except:
53-
# If this is an example run from
54-
# /usr/local/lib/python2.7/dist-packages/cefpython1/examples/
55-
# then we might have not permission to write to that directory.
5662
print("cefpython: WARNING: failed writing to error file: %s" % (
5763
error_file))
58-
print("\n"+error+"\n")
64+
# Convert error message to ascii before printing, otherwise
65+
# you may get error like this:
66+
# | UnicodeEncodeError: 'charmap' codec can't encode characters
67+
errorMsg = errorMsg.encode("ascii", errors="replace")
68+
errorMsg = errorMsg.decode("ascii", errors="replace")
69+
print("\n"+errorMsg+"\n")
5970
cefpython.QuitMessageLoop()
6071
cefpython.Shutdown()
61-
# So that "finally" does not execute.
6272
os._exit(1)
6373

6474
class PyGTKExample:
@@ -97,7 +107,7 @@ def __init__(self):
97107
browserSettings={"plugins_disabled": True},
98108
navigateUrl="file://"+GetApplicationPath("cefsimple.html"))
99109

100-
# Must be show_all() for VBox otherwise browser doesn't
110+
# Must be show_all() for VBox otherwise browser doesn't
101111
# appear when you just call show().
102112
self.vbox.show()
103113

@@ -145,7 +155,7 @@ def OnTimer(self):
145155

146156
def OnFocusIn(self, widget, data):
147157

148-
# This function is currently not called by any of code,
158+
# This function is currently not called by any of code,
149159
# but if you would like for browser to have automatic focus
150160
# add such line:
151161
# self.mainWindow.connect('focus-in-event', self.OnFocusIn)

cefpython/cef1/linux/binaries_32bit/wxpython.py

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,25 +49,35 @@ def GetApplicationPath(file=None):
4949
return path
5050
return str(file)
5151

52-
def ExceptHook(type, value, traceObject):
52+
def ExceptHook(excType, excValue, traceObject):
5353
import traceback, os, time
54-
# This hook does the following: in case of exception display it,
55-
# write to error.log, shutdown CEF and exit application.
56-
error = "\n".join(traceback.format_exception(type, value, traceObject))
57-
error_file = GetApplicationPath("error.log")
54+
# This hook does the following: in case of exception write it to
55+
# the "error.log" file, display it to the console, shutdown CEF
56+
# and exit application immediately by ignoring "finally" (_exit()).
57+
errorMsg = "\n".join(traceback.format_exception(excType, excValue,
58+
traceObject))
59+
logFile = GetApplicationPath("error.log")
5860
try:
59-
with open(error_file, "a") as file:
60-
file.write("\n[%s] %s\n" % (time.strftime("%Y-%m-%d %H:%M:%S"), error))
61+
appEncoding = cefpython.g_applicationSettings["string_encoding"]
62+
except:
63+
appEncoding = "utf-8"
64+
if type(errorMsg) == bytes:
65+
errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace")
66+
try:
67+
with open(logFile, "a", encoding=appEncoding) as fp:
68+
fp.write("\n[%s] %s\n" % (
69+
time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg))
6170
except:
62-
# If this is an example run from
63-
# /usr/local/lib/python2.7/dist-packages/cefpython1/examples/
64-
# then we might have not permission to write to that directory.
6571
print("cefpython: WARNING: failed writing to error file: %s" % (
6672
error_file))
67-
print("\n"+error+"\n")
73+
# Convert error message to ascii before printing, otherwise
74+
# you may get error like this:
75+
# | UnicodeEncodeError: 'charmap' codec can't encode characters
76+
errorMsg = errorMsg.encode("ascii", errors="replace")
77+
errorMsg = errorMsg.decode("ascii", errors="replace")
78+
print("\n"+errorMsg+"\n")
6879
cefpython.QuitMessageLoop()
6980
cefpython.Shutdown()
70-
# So that "finally" does not execute.
7181
os._exit(1)
7282

7383
class MainFrame(wx.Frame):

cefpython/cef1/linux/binaries_64bit/cefpython_py27.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def GetModuleDirectory():
6666
"product_version": "",
6767
"resources_dir_path": "",
6868
"session_storage_quota": 5*1024*1024,
69-
"unicode_to_bytes_encoding": "utf-8",
69+
"string_encoding": "utf-8",
7070
"uncaught_exception_stack_size": 0,
7171
"user_agent": "",
7272
}

cefpython/cef1/linux/binaries_64bit/pygtk_.py

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,25 +40,35 @@ def GetApplicationPath(file=None):
4040
return path
4141
return str(file)
4242

43-
def ExceptHook(type, value, traceObject):
43+
def ExceptHook(excType, excValue, traceObject):
4444
import traceback, os, time
45-
# This hook does the following: in case of exception display it,
46-
# write to error.log, shutdown CEF and exit application.
47-
error = "\n".join(traceback.format_exception(type, value, traceObject))
48-
error_file = GetApplicationPath("error.log")
45+
# This hook does the following: in case of exception write it to
46+
# the "error.log" file, display it to the console, shutdown CEF
47+
# and exit application immediately by ignoring "finally" (_exit()).
48+
errorMsg = "\n".join(traceback.format_exception(excType, excValue,
49+
traceObject))
50+
logFile = GetApplicationPath("error.log")
4951
try:
50-
with open(error_file, "a") as file:
51-
file.write("\n[%s] %s\n" % (time.strftime("%Y-%m-%d %H:%M:%S"), error))
52+
appEncoding = cefpython.g_applicationSettings["string_encoding"]
53+
except:
54+
appEncoding = "utf-8"
55+
if type(errorMsg) == bytes:
56+
errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace")
57+
try:
58+
with open(logFile, "a", encoding=appEncoding) as fp:
59+
fp.write("\n[%s] %s\n" % (
60+
time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg))
5261
except:
53-
# If this is an example run from
54-
# /usr/local/lib/python2.7/dist-packages/cefpython1/examples/
55-
# then we might have not permission to write to that directory.
5662
print("cefpython: WARNING: failed writing to error file: %s" % (
5763
error_file))
58-
print("\n"+error+"\n")
64+
# Convert error message to ascii before printing, otherwise
65+
# you may get error like this:
66+
# | UnicodeEncodeError: 'charmap' codec can't encode characters
67+
errorMsg = errorMsg.encode("ascii", errors="replace")
68+
errorMsg = errorMsg.decode("ascii", errors="replace")
69+
print("\n"+errorMsg+"\n")
5970
cefpython.QuitMessageLoop()
6071
cefpython.Shutdown()
61-
# So that "finally" does not execute.
6272
os._exit(1)
6373

6474
class PyGTKExample:
@@ -97,7 +107,7 @@ def __init__(self):
97107
browserSettings={"plugins_disabled": True},
98108
navigateUrl="file://"+GetApplicationPath("cefsimple.html"))
99109

100-
# Must be show_all() for VBox otherwise browser doesn't
110+
# Must be show_all() for VBox otherwise browser doesn't
101111
# appear when you just call show().
102112
self.vbox.show()
103113

@@ -145,7 +155,7 @@ def OnTimer(self):
145155

146156
def OnFocusIn(self, widget, data):
147157

148-
# This function is currently not called by any of code,
158+
# This function is currently not called by any of code,
149159
# but if you would like for browser to have automatic focus
150160
# add such line:
151161
# self.mainWindow.connect('focus-in-event', self.OnFocusIn)

cefpython/cef1/linux/binaries_64bit/wxpython.py

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,25 +49,35 @@ def GetApplicationPath(file=None):
4949
return path
5050
return str(file)
5151

52-
def ExceptHook(type, value, traceObject):
52+
def ExceptHook(excType, excValue, traceObject):
5353
import traceback, os, time
54-
# This hook does the following: in case of exception display it,
55-
# write to error.log, shutdown CEF and exit application.
56-
error = "\n".join(traceback.format_exception(type, value, traceObject))
57-
error_file = GetApplicationPath("error.log")
54+
# This hook does the following: in case of exception write it to
55+
# the "error.log" file, display it to the console, shutdown CEF
56+
# and exit application immediately by ignoring "finally" (_exit()).
57+
errorMsg = "\n".join(traceback.format_exception(excType, excValue,
58+
traceObject))
59+
logFile = GetApplicationPath("error.log")
5860
try:
59-
with open(error_file, "a") as file:
60-
file.write("\n[%s] %s\n" % (time.strftime("%Y-%m-%d %H:%M:%S"), error))
61+
appEncoding = cefpython.g_applicationSettings["string_encoding"]
62+
except:
63+
appEncoding = "utf-8"
64+
if type(errorMsg) == bytes:
65+
errorMsg = errorMsg.decode(encoding=appEncoding, errors="replace")
66+
try:
67+
with open(logFile, "a", encoding=appEncoding) as fp:
68+
fp.write("\n[%s] %s\n" % (
69+
time.strftime("%Y-%m-%d %H:%M:%S"), errorMsg))
6170
except:
62-
# If this is an example run from
63-
# /usr/local/lib/python2.7/dist-packages/cefpython1/examples/
64-
# then we might have not permission to write to that directory.
6571
print("cefpython: WARNING: failed writing to error file: %s" % (
6672
error_file))
67-
print("\n"+error+"\n")
73+
# Convert error message to ascii before printing, otherwise
74+
# you may get error like this:
75+
# | UnicodeEncodeError: 'charmap' codec can't encode characters
76+
errorMsg = errorMsg.encode("ascii", errors="replace")
77+
errorMsg = errorMsg.decode("ascii", errors="replace")
78+
print("\n"+errorMsg+"\n")
6879
cefpython.QuitMessageLoop()
6980
cefpython.Shutdown()
70-
# So that "finally" does not execute.
7181
os._exit(1)
7282

7383
class MainFrame(wx.Frame):

cefpython/cef1/linux/setup/setup.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,6 @@
1212
# Stop on first error, otherwise hundreds of errors appear in the console.
1313
Options.fast_fail = True
1414

15-
# Since Cython 0.18 it is required to set string encoding
16-
if sys.version_info.major < 3:
17-
C_STRING_TYPE = "str"
18-
C_STRING_ENCODING = "utf8"
19-
else:
20-
C_STRING_TYPE = "unicode"
21-
C_STRING_ENCODING = "utf8"
22-
2315
# Written to cython_includes/compile_time_constants.pxi
2416
CEF_VERSION = 1
2517

@@ -34,6 +26,7 @@ def CompileTimeConstants():
3426
# A way around Python 3.2 bug: UNAME_SYSNAME is not set.
3527
fd.write('DEF UNAME_SYSNAME = "%s"\n' % platform.uname()[0])
3628
fd.write('DEF CEF_VERSION = %s\n' % CEF_VERSION)
29+
fd.write('DEF PY_MAJOR_VERSION = %s\n' % sys.version_info.major)
3730

3831
CompileTimeConstants()
3932

@@ -43,8 +36,9 @@ def CompileTimeConstants():
4336
["cefpython.pyx"],
4437

4538
cython_directives={
46-
"c_string_type": C_STRING_TYPE,
47-
"c_string_encoding": C_STRING_ENCODING,
39+
# Any conversion to unicode must be explicit using .decode().
40+
"c_string_type": "bytes",
41+
"c_string_encoding": "utf-8",
4842
},
4943

5044
language='c++',
@@ -105,4 +99,4 @@ def CompileTimeConstants():
10599
name = 'cefpython_py%s' % PYTHON_VERSION,
106100
cmdclass = {'build_ext': build_ext},
107101
ext_modules = ext_modules
108-
)
102+
)

cefpython/cef1/windows/binaries/cefadvanced.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ <h3>Basic authentication</h3>
171171

172172
<h3>Frame.ExecuteJavascript()</h3>
173173

174-
<textarea id=jscode>alert('test me')</textarea><br>
174+
<textarea id=jscode cols=50 rows=2>alert('test me [unicode: ąś]')</textarea><br>
175175
<a href="javascript:python.ExecuteJavascript(jscode.value)">python.ExecuteJavascript(jscode.value)</a> - execute javascript from the textarea above.
176176

177177
<h3>Frames</h3>
@@ -186,7 +186,7 @@ <h3>Javascript bindings</h3>
186186
<h4>Passing arguments</h4>
187187

188188
<a href="javascript:alert('Return value from python.Test1: '+python.Test1(100))">python.Test1(100)</a><br>
189-
<a href="javascript:alert('Return value from python.Test2: '+JSON.stringify(python.Test2(100, 'This string was passed from javascript', '')))">python.Test2(100, 'This string was passed from javascript', '')</a> - python.Test2() should return: [1,2, [2.1, {'3': 3, '4': [5,6]}]]
189+
<a href="javascript:alert('Return value from python.Test2: '+JSON.stringify(python.Test2(100, 'This string was passed from javascript [unicode: ąś]', '')))">python.Test2(100, 'This string was passed from javascript [unicode: ąś]', '')</a> - python.Test2() should return: [1,2, [2.1, {'3': 3, '4': [5,6]}]]
190190
<br><br>
191191

192192
<script>var array = [1]; array[100] = 100.01;</script>
@@ -210,9 +210,9 @@ <h4>Passing arguments</h4>
210210
<h3>Javasript callbacks</h3>
211211

212212
<script>
213-
function MyJSCallback(arg1, arg2, arg3, arg4)
213+
function MyJSCallback(arg1, arg2, arg3, arg4, arg5)
214214
{
215-
alert("MyJSCallback() called\narg1="+JSON.stringify(arg1)+"\narg2="+JSON.stringify(arg2)+"\narg3="+JSON.stringify(arg3)+"\narg4="+JSON.stringify(arg4))
215+
alert("MyJSCallback() called\narg1="+JSON.stringify(arg1)+"\narg2="+JSON.stringify(arg2)+"\narg3="+JSON.stringify(arg3)+"\narg4="+JSON.stringify(arg4)+"\narg5="+JSON.stringify(arg5))
216216
}
217217
</script>
218218

0 commit comments

Comments
 (0)
X Tutup