Skip to content

Commit 9240c8e

Browse files
committed
add initial support of python 3.13
1 parent 99dafa7 commit 9240c8e

18 files changed

Lines changed: 115 additions & 60 deletions

src/browser.pyx

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,17 @@ cdef class PyBrowser:
231231
if self.imageBuffer:
232232
free(self.imageBuffer)
233233

234-
cpdef py_void SetClientCallback(self, py_string name, object callback):
234+
cpdef py_void SetClientCallback(self, object cname, object callback):
235+
cdef bytes name_bytes
236+
cdef str name_str
237+
238+
if isinstance(cname, bytes):
239+
name_bytes = cname
240+
name_str = name_bytes.decode("utf-8", "replace")
241+
else:
242+
name_str = str(cname)
243+
name_bytes = name_str.encode("utf-8", "replace")
244+
235245
if not self.allowedClientCallbacks:
236246
# DisplayHandler
237247
self.allowedClientCallbacks += [
@@ -287,10 +297,10 @@ cdef class PyBrowser:
287297
"OnBeforeDownload",
288298
"OnDownloadUpdated"]
289299

290-
if name not in self.allowedClientCallbacks:
300+
if name_str not in self.allowedClientCallbacks:
291301
raise Exception("Browser.SetClientCallback() failed: unknown "
292-
"callback: %s" % name)
293-
self.clientCallbacks[name] = callback
302+
"callback: %s" % name_str)
303+
self.clientCallbacks[name_bytes] = callback
294304

295305
cpdef py_void SetClientHandler(self, object clientHandler):
296306
if not hasattr(clientHandler, "__class__"):
@@ -307,7 +317,13 @@ cdef class PyBrowser:
307317
if key and key[0] != '_':
308318
self.SetClientCallback(key, method)
309319

310-
cpdef object GetClientCallback(self, py_string name):
320+
cpdef object GetClientCallback(self, object cname):
321+
cdef bytes name
322+
if isinstance(cname, bytes):
323+
name = cname
324+
else:
325+
name = str(cname).encode("utf-8", "replace")
326+
311327
if name in self.clientCallbacks:
312328
return self.clientCallbacks[name]
313329

@@ -353,8 +369,15 @@ cdef class PyBrowser:
353369
NonCriticalError("GetImage not implemented on this platform")
354370
return None
355371

356-
cpdef object GetSetting(self, py_string key):
372+
cpdef object GetSetting(self, object okey):
357373
cdef int browser_id = self.GetIdentifier()
374+
375+
cdef bytes key
376+
if isinstance(okey, bytes):
377+
key = okey
378+
else:
379+
key = str(okey).encode("utf-8", "replace")
380+
358381
if browser_id in g_browser_settings:
359382
if key in g_browser_settings[browser_id]:
360383
return g_browser_settings[browser_id][key]
@@ -421,7 +444,7 @@ cdef class PyBrowser:
421444
self.GetMainFrame().ExecuteFunction(*args)
422445

423446
cpdef py_void ExecuteJavascript(self, py_string jsCode,
424-
py_string scriptUrl="", int startLine=1):
447+
py_string scriptUrl=str(None), int startLine=1):
425448
self.GetMainFrame().ExecuteJavascript(jsCode, scriptUrl, startLine)
426449

427450
cpdef py_void Find(self, py_string searchText,

src/cefpython.pyx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,14 +1007,26 @@ cpdef py_void SetGlobalClientHandler(object clientHandler):
10071007
if key and key[0:2] != '__':
10081008
SetGlobalClientCallback(key, method)
10091009

1010-
cpdef object GetGlobalClientCallback(py_string name):
1010+
cpdef object GetGlobalClientCallback(object cname):
1011+
cdef bytes name
1012+
if isinstance(cname, bytes):
1013+
name = cname
1014+
else:
1015+
name = str(cname).encode("utf-8", "replace")
1016+
10111017
global g_globalClientCallbacks
10121018
if name in g_globalClientCallbacks:
10131019
return g_globalClientCallbacks[name]
10141020
else:
10151021
return None
10161022

1017-
cpdef object GetAppSetting(py_string key):
1023+
cpdef object GetAppSetting(object skey):
1024+
cdef bytes key
1025+
if isinstance(skey, bytes):
1026+
key = skey
1027+
else:
1028+
key = str(skey).encode("utf-8", "replace")
1029+
10181030
global g_applicationSettings
10191031
if key in g_applicationSettings:
10201032
return g_applicationSettings[key]

src/common/cefpython_public_api.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@
5757
#include "../../build/build_cefpython/cefpython_py311_fixed.h"
5858
#elif PY_MINOR_VERSION == 12
5959
#include "../../build/build_cefpython/cefpython_py312_fixed.h"
60+
#elif PY_MINOR_VERSION == 13
61+
#include "../../build/build_cefpython/cefpython_py313_fixed.h"
6062
#endif // PY_MINOR_VERSION
6163
#endif // PY_MAJOR_VERSION
6264

src/frame.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ cdef class PyFrame:
164164
self.ExecuteJavascript(code)
165165

166166
cpdef py_void ExecuteJavascript(self, py_string jsCode,
167-
py_string scriptUrl="", int startLine=1):
167+
py_string scriptUrl=str(""), int startLine=1):
168168
self.GetCefFrame().get().ExecuteJavaScript(PyToCefStringValue(jsCode),
169169
PyToCefStringValue(scriptUrl), startLine)
170170

src/javascript_bindings.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ cdef class JavascriptBindings:
105105
methods[methodName] = None
106106
objects[objectName] = methods
107107
pyBrowser.GetMainFrame().SendProcessMessage(cef_types.PID_RENDERER,
108-
0, "DoJavascriptBindings", [{
108+
0, str("DoJavascriptBindings"), [{
109109
"functions": functions,
110110
"properties": properties,
111111
"objects": objects,

src/javascript_callback.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ cdef class JavascriptCallback:
3333
browser.GetMainFrame().SendProcessMessage(
3434
cef_types.PID_RENDERER,
3535
self.frame.GetIdentifier(),
36-
"ExecuteJavascriptCallback",
36+
str("ExecuteJavascriptCallback"),
3737
[self.callbackId] + list(args))
3838
else:
3939
# This code probably ain't needed

src/process_message_utils.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ cdef object CheckForCefPythonMessageHash(CefRefPtr[CefBrowser] cefBrowser,
2222
# TODO: this could be sent using CefBinaryNamedString in the future,
2323
# see this topic "Sending custom data types using process messaging":
2424
# http://www.magpcss.org/ceforum/viewtopic.php?f=6&t=10881
25-
cdef py_string cefPythonMessageHash = "####cefpython####"
25+
cdef py_string cefPythonMessageHash = str("####cefpython####")
2626
cdef JavascriptCallback jsCallback
2727
cdef py_string jsonData
2828
cdef object message

src/string_utils.pyx

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,13 @@ BYTES_DECODE_ERRORS = "replace"
2626

2727

2828
cdef py_string AnyToPyString(object value):
29-
cdef object valueType = type(value)
30-
if valueType == str or valueType == bytes:
31-
return value
32-
elif PY_MAJOR_VERSION < 3 and valueType == unicode:
33-
# The unicode type is not defined in Python 3
29+
if isinstance(value, str):
3430
return value
31+
elif isinstance(value, bytes):
32+
# Decode bytes to str using utf-8 with replacement for errors
33+
return value.decode("utf-8", "replace")
3534
else:
36-
return ""
35+
return str("")
3736

3837
cdef py_string CharToPyString(
3938
const char* charString):
@@ -77,22 +76,23 @@ cdef bytes PyStringToChar(py_string pyString):
7776
# return cppString
7877
# ---
7978

80-
cdef py_string CefToPyString(
81-
ConstCefString& cefString):
79+
cdef py_string CefToPyString(ConstCefString& cefString):
8280
cdef cpp_string cppString
8381
if cefString.empty():
84-
return ""
82+
return str("")
8583
IF UNAME_SYSNAME == "Windows":
8684
cdef wchar_t* wcharstr = <wchar_t*> cefString.c_str()
8785
return WidecharToPyString(wcharstr)
8886
ELSE:
8987
cppString = cefString.ToString()
90-
if PY_MAJOR_VERSION < 3:
91-
return <bytes>cppString
88+
value = <bytes>cppString
89+
# Only decode if value is bytes (Python 3)
90+
if isinstance(value, bytes):
91+
return value.decode(
92+
g_applicationSettings["string_encoding"],
93+
errors=BYTES_DECODE_ERRORS)
9294
else:
93-
return <unicode>((<bytes>cppString).decode(
94-
g_applicationSettings["string_encoding"],
95-
errors=BYTES_DECODE_ERRORS))
95+
return value
9696

9797
cdef bytes CefToPyBytes(
9898
ConstCefString& cefString):
@@ -118,11 +118,14 @@ cdef void PyToCefString(
118118
# when a non-ascii character is encountered.
119119
cefString.FromString(cppString)
120120

121-
cdef CefString PyToCefStringValue(
122-
py_string pyString
123-
) except *:
121+
cdef CefString PyToCefStringValue(object astring) except *:
122+
cdef bytes string
123+
if isinstance(astring, bytes):
124+
string = astring
125+
else:
126+
string = str(astring).encode("utf-8", "replace")
124127
cdef CefString cefString
125-
PyToCefString(pyString, cefString)
128+
PyToCefString(string, cefString)
126129
return cefString
127130

128131
cdef void PyToCefStringPointer(

src/utils.pyx

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -42,29 +42,33 @@ cpdef py_bool IsThread(int threadID):
4242
# unicode strings and writing them to file (codecs.open).
4343
# This change is required to work with Cython 0.20.
4444

45-
cpdef object Debug(py_string msg):
45+
cpdef bytes toBytes(object input):
46+
""" Convert input to bytes string."""
47+
if input is None:
48+
return b""
49+
elif isinstance(input, bytes):
50+
return input
51+
else:
52+
return str(input).encode("utf-8", "replace")
53+
54+
cpdef object Debug(object message):
4655
"""Print debug message. Will be shown only when settings.debug=True."""
47-
# In Python 3 str or bytes may be passed
48-
if type(msg) != str and type(msg) == bytes:
49-
msg = msg.decode("utf-8", "replace")
50-
# Convert to str in case other kind of object was passed
51-
msg = str(msg)
52-
msg = "[Browser process] " + msg
53-
# CEF logging is initialized only after CEF was initialized.
54-
# Otherwise the default is LOGSEVERITY_INFO and log_file is
55-
# none.
56+
cdef bytes msg_bytes
57+
msg_bytes = toBytes(message)
58+
msg_bytes = b"[Browser process] " + msg_bytes
5659
if g_cef_initialized or g_debug:
57-
cef_log_info(PyStringToChar(msg))
60+
cef_log_info(msg_bytes)
61+
return None
5862

59-
cdef void NonCriticalError(py_string msg) except *:
63+
cdef void NonCriticalError(object msg) except *:
6064
"""Notify about error gently. Does not terminate application."""
61-
# In Python 3 str or bytes may be passed
62-
if type(msg) != str and type(msg) == bytes:
63-
msg = msg.decode("utf-8", "replace")
64-
# Convert to str in case other kind of object was passed
65-
msg = str(msg)
66-
msg = "[Browser process] " + msg
67-
cef_log_error(PyStringToChar(msg))
65+
cdef bytes msg_bytes
66+
if isinstance(msg, bytes):
67+
msg_bytes = msg
68+
else:
69+
msg_bytes = str(msg).encode("utf-8", "replace")
70+
msg_bytes = b"[Browser process] " + msg_bytes
71+
cef_log_error(msg_bytes)
6872

6973
cpdef str GetSystemError():
7074
IF UNAME_SYSNAME == "Windows":

src/window_info.pyx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ cdef class WindowInfo:
8282
cdef public py_string windowName
8383

8484
def __init__(self, title=""):
85-
self.windowName = ""
85+
self.windowName = str("")
8686
if title:
8787
self.windowName = title
8888

@@ -94,7 +94,7 @@ cdef class WindowInfo:
9494
# On Windows when parent window handle is 0 then SetAsPopup()
9595
# must be called instead.
9696
if parentWindowHandle == 0:
97-
self.SetAsPopup(parentWindowHandle, "")
97+
self.SetAsPopup(parentWindowHandle, str(""))
9898
return
9999
if parentWindowHandle != 0\
100100
and not WindowUtils.IsWindowHandle(parentWindowHandle):

0 commit comments

Comments
 (0)