Skip to content

Commit 7820919

Browse files
committed
WL13194: Add support for Python 3.8
1 parent 1a54dfa commit 7820919

16 files changed

+142
-41
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
.coverage
33
.DS_Store
44
*__pycache__*
5+
.python-version
56
.idea/
67
.vscode/
78
commit.txt

cpyint

lib/mysql/connector/connection.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
22
#
33
# This program is free software; you can redistribute it and/or modify
44
# it under the terms of the GNU General Public License, version 2.0, as
@@ -51,7 +51,7 @@
5151
MySQLCursorBufferedNamedTuple)
5252
from .network import MySQLUnixSocket, MySQLTCPSocket
5353
from .protocol import MySQLProtocol
54-
from .utils import int4store
54+
from .utils import int4store, linux_distribution
5555
from .abstracts import MySQLConnectionAbstract
5656

5757

@@ -123,7 +123,7 @@ def _add_default_conn_attrs(self):
123123
if platform.system() == "Darwin":
124124
os_ver = "{}-{}".format("macOS", platform.mac_ver()[0])
125125
else:
126-
os_ver = "-".join(platform.linux_distribution()[0:2]) # pylint: disable=W1505
126+
os_ver = "-".join(linux_distribution()[0:2])
127127

128128
license_chunks = version.LICENSE.split(" ")
129129
if license_chunks[0] == "GPLv2":

lib/mysql/connector/utils.py

Lines changed: 105 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
22
#
33
# This program is free software; you can redistribute it and/or modify
44
# it under the terms of the GNU General Public License, version 2.0, as
@@ -29,13 +29,16 @@
2929
"""Utilities
3030
"""
3131

32-
from __future__ import print_function
32+
import os
33+
import subprocess
34+
import struct
35+
import sys
3336

34-
__MYSQL_DEBUG__ = False
37+
from .catch23 import struct_unpack, PY2
3538

36-
import struct
3739

38-
from .catch23 import struct_unpack
40+
__MYSQL_DEBUG__ = False
41+
3942

4043
def intread(buf):
4144
"""Unpacks the given buffer to an integer"""
@@ -330,6 +333,7 @@ def _digest_buffer(buf):
330333
return ''.join(["\\x%02x" % c for c in buf])
331334
return ''.join(["\\x%02x" % ord(c) for c in buf])
332335

336+
333337
def print_buffer(abuffer, prefix=None, limit=30):
334338
"""Debug function printing output of _digest_buffer()"""
335339
if prefix:
@@ -340,3 +344,99 @@ def print_buffer(abuffer, prefix=None, limit=30):
340344
print(prefix + ': ' + digest)
341345
else:
342346
print(_digest_buffer(abuffer))
347+
348+
349+
def _parse_os_release():
350+
"""Parse the contents of /etc/os-release file.
351+
352+
Returns:
353+
A dictionary containing release information.
354+
"""
355+
distro = {}
356+
os_release_file = os.path.join("/etc", "os-release")
357+
if not os.path.exists(os_release_file):
358+
return distro
359+
with open(os_release_file) as file_obj:
360+
for line in file_obj:
361+
key_value = line.split("=")
362+
if len(key_value) != 2:
363+
continue
364+
key = key_value[0].lower()
365+
value = key_value[1].rstrip("\n").strip('"')
366+
distro[key] = value
367+
return distro
368+
369+
370+
def _parse_lsb_release():
371+
"""Parse the contents of /etc/lsb-release file.
372+
373+
Returns:
374+
A dictionary containing release information.
375+
"""
376+
distro = {}
377+
lsb_release_file = os.path.join("/etc", "lsb-release")
378+
if os.path.exists(lsb_release_file):
379+
with open(lsb_release_file) as file_obj:
380+
for line in file_obj:
381+
key_value = line.split("=")
382+
if len(key_value) != 2:
383+
continue
384+
key = key_value[0].lower()
385+
value = key_value[1].rstrip("\n").strip('"')
386+
distro[key] = value
387+
return distro
388+
389+
390+
def _parse_lsb_release_command():
391+
"""Parse the output of the lsb_release command.
392+
393+
Returns:
394+
A dictionary containing release information.
395+
"""
396+
distro = {}
397+
with open(os.devnull, "w") as devnull:
398+
try:
399+
stdout = subprocess.check_output(
400+
("lsb_release", "-a"), stderr=devnull)
401+
except OSError:
402+
return None
403+
lines = stdout.decode(sys.getfilesystemencoding()).splitlines()
404+
for line in lines:
405+
key_value = line.split(":")
406+
if len(key_value) != 2:
407+
continue
408+
key = key_value[0].replace(" ", "_").lower()
409+
value = key_value[1].strip("\t")
410+
distro[key] = value.encode("utf-8") if PY2 else value
411+
return distro
412+
413+
414+
def linux_distribution():
415+
"""Tries to determine the name of the Linux OS distribution name.
416+
417+
First tries to get information from ``/etc/os-release`` file.
418+
If fails, tries to get the information of ``/etc/lsb-release`` file.
419+
And finally the information of ``lsb-release`` command.
420+
421+
Returns:
422+
A tuple with (`name`, `version`, `codename`)
423+
"""
424+
distro = _parse_lsb_release()
425+
if distro:
426+
return (distro.get("distrib_id", ""),
427+
distro.get("distrib_release", ""),
428+
distro.get("distrib_codename", ""))
429+
430+
distro = _parse_lsb_release_command()
431+
if distro:
432+
return (distro.get("distributor_id", ""),
433+
distro.get("release", ""),
434+
distro.get("codename", ""))
435+
436+
distro = _parse_os_release()
437+
if distro:
438+
return (distro.get("name", ""),
439+
distro.get("version_id", ""),
440+
distro.get("version_codename", ""))
441+
442+
return ("", "", "")

lib/mysqlx/__init__.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -363,10 +363,8 @@ def _get_connection_settings(*args, **kwargs):
363363
for key, val in args[0].items():
364364
settings[key.replace("_", "-")] = val
365365
elif kwargs:
366-
settings.update(kwargs)
367-
for key in settings:
368-
if "_" in key:
369-
settings[key.replace("_", "-")] = settings.pop(key)
366+
for key, val in kwargs.items():
367+
settings[key.replace("_", "-")] = val
370368

371369
if not settings:
372370
raise InterfaceError("Settings not provided")

lib/mysqlx/connection.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161

6262
# pylint: disable=C0411,C0413
6363
sys.path.append("..")
64+
from mysql.connector.utils import linux_distribution
6465
from mysql.connector.version import VERSION, LICENSE
6566

6667

@@ -480,8 +481,7 @@ def _handle_capabilities(self):
480481

481482
is_ol7 = False
482483
if platform.system() == "Linux":
483-
# pylint: disable=W1505
484-
distname, version, _ = platform.linux_distribution()
484+
distname, version, _ = linux_distribution()
485485
try:
486486
is_ol7 = "Oracle Linux" in distname and \
487487
version.split(".")[0] == "7"
@@ -1406,8 +1406,7 @@ def _init_attributes(self):
14061406
if platform.system() == "Darwin":
14071407
os_ver = "{}-{}".format("macOS", platform.mac_ver()[0])
14081408
else:
1409-
os_ver = "-".join(
1410-
platform.linux_distribution()[0:2]) # pylint: disable=W1505
1409+
os_ver = "-".join(linux_distribution()[0:2])
14111410

14121411
license_chunks = LICENSE.split(' ')
14131412
if license_chunks[0] == "GPLv2":

lib/mysqlx/expr.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,7 @@ def cast_data_type_dimension(self, decimal=False):
973973
dimension.append(self.consume_token(TokenType.LNUM))
974974
self.consume_token(TokenType.RPAREN)
975975

976-
return "({0})".format(dimension[0]) if len(dimension) is 1 else \
976+
return "({0})".format(dimension[0]) if len(dimension) == 1 else \
977977
"({0},{1})".format(*dimension)
978978

979979
def star_operator(self):

lib/mysqlx/statement.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def parse_table_name(default_schema, table_name, sql_mode=""):
119119
quote = '"' if "ANSI_QUOTES" in sql_mode else "`"
120120
delimiter = ".{0}".format(quote) if quote in table_name else "."
121121
temp = table_name.split(delimiter, 1)
122-
return (default_schema if len(temp) is 1 else temp[0].strip(quote),
122+
return (default_schema if len(temp) == 1 else temp[0].strip(quote),
123123
temp[-1].strip(quote),)
124124

125125

setupinfo.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@
115115
maintainer = 'Nuno Mariz'
116116
maintainer_email = 'nuno.mariz@oracle.com'
117117
cpy_gpl_license = "GNU GPLv2 (with FOSS License Exception)"
118-
keywords = "mysql db",
118+
keywords = "mysql db"
119119
url = 'http://dev.mysql.com/doc/connector-python/en/index.html'
120120
download_url = 'http://dev.mysql.com/downloads/connector/python/'
121121
classifiers = [
@@ -133,6 +133,7 @@
133133
'Programming Language :: Python :: 3.5',
134134
'Programming Language :: Python :: 3.6',
135135
'Programming Language :: Python :: 3.7',
136+
'Programming Language :: Python :: 3.8',
136137
'Topic :: Database',
137138
'Topic :: Software Development',
138139
'Topic :: Software Development :: Libraries :: Application Frameworks',

src/mysql_capi.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,6 +1107,7 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
11071107
}
11081108

11091109
mysql_init(&self->session);
1110+
Py_END_ALLOW_THREADS
11101111

11111112
#ifdef MS_WINDOWS
11121113
if (NULL == host)
@@ -1130,9 +1131,7 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
11301131
}
11311132

11321133
#ifdef PY3
1133-
Py_END_ALLOW_THREADS
11341134
charset_name= PyUnicode_AsASCIIString(self->charset_name);
1135-
Py_BEGIN_ALLOW_THREADS
11361135
if (NULL == charset_name)
11371136
{
11381137
return NULL;
@@ -1198,7 +1197,6 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
11981197
#endif
11991198
}
12001199

1201-
Py_END_ALLOW_THREADS
12021200
if (PyString_Check(self->auth_plugin)) {
12031201
auth_plugin= PyStringAsString(self->auth_plugin);
12041202
mysql_options(&self->session, MYSQL_DEFAULT_AUTH, auth_plugin);
@@ -1226,7 +1224,6 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
12261224
(char*)&abool);
12271225
}
12281226
}
1229-
Py_BEGIN_ALLOW_THREADS
12301227

12311228
if (database && strlen(database) == 0)
12321229
{
@@ -1246,7 +1243,7 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
12461243
if (conn_attrs != NULL)
12471244
{
12481245
while (PyDict_Next(conn_attrs, &pos, &key, &value)) {
1249-
char* attr_name;
1246+
const char* attr_name;
12501247
#ifdef PY3
12511248
PyObject *str_name = PyObject_Str(key);
12521249
if (!str_name)
@@ -1266,7 +1263,7 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
12661263
attr_name= PyString_AsString(key);
12671264
}
12681265
#endif
1269-
char* attr_value;
1266+
const char* attr_value;
12701267
#ifdef PY3
12711268
PyObject *str_value = PyObject_Str(value);
12721269
if (!str_value)
@@ -1305,8 +1302,10 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
13051302
}
13061303

13071304
#ifdef PY3
1305+
Py_BEGIN_ALLOW_THREADS
13081306
res= mysql_real_connect(&self->session, host, user, password, database,
13091307
port, unix_socket, client_flags);
1308+
Py_END_ALLOW_THREADS
13101309
#else
13111310
{
13121311
char* c_password;
@@ -1320,13 +1319,13 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
13201319
{
13211320
c_password= PyString_AsString(password);
13221321
}
1322+
Py_BEGIN_ALLOW_THREADS
13231323
res= mysql_real_connect(&self->session, host, user, c_password, database,
13241324
port, unix_socket, client_flags);
1325+
Py_END_ALLOW_THREADS
13251326
}
13261327
#endif
13271328

1328-
Py_END_ALLOW_THREADS
1329-
13301329
if (!res)
13311330
{
13321331
raise_with_session(&self->session, NULL);
@@ -1431,11 +1430,9 @@ MySQL_escape_string(MySQL *self, PyObject *value)
14311430
to= BytesFromStringAndSize(NULL, from_size * 2 + 1);
14321431
to_str= PyBytesAsString(to);
14331432

1434-
Py_BEGIN_ALLOW_THREADS
14351433
escaped_size= (Py_ssize_t)mysql_real_escape_string(&self->session, to_str,
14361434
from_str,
14371435
(unsigned long)from_size);
1438-
Py_END_ALLOW_THREADS
14391436

14401437
BytesResize(&to, escaped_size);
14411438
Py_XDECREF(from);
@@ -3232,7 +3229,7 @@ MySQLPrepStmt_execute(MySQLPrepStmt *self, PyObject *args)
32323229
PyObject*
32333230
MySQLPrepStmt_handle_result(MySQLPrepStmt *self)
32343231
{
3235-
int i= 0;
3232+
unsigned int i= 0;
32363233

32373234
Py_BEGIN_ALLOW_THREADS
32383235
self->res = mysql_stmt_result_metadata(self->stmt);
@@ -3346,7 +3343,8 @@ MySQLPrepStmt_fetch_row(MySQLPrepStmt *self)
33463343
PyObject *field_info;
33473344
PyObject *mod_decimal, *decimal, *dec_args;
33483345
unsigned long field_flags;
3349-
int i= 0, fetch= 0;
3346+
unsigned int i= 0;
3347+
int fetch= 0;
33503348

33513349
row= PyTuple_New(self->column_count);
33523350

src/mysqlxpb/mysqlxpb.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program is free software; you can redistribute it and/or modify
55
* it under the terms of the GNU General Public License, version 2.0, as
@@ -831,8 +831,9 @@ static const char* GetMessageNameByTypeId(Mysqlx::ServerMessages::Type type) {
831831
case Mysqlx::ServerMessages::RESULTSET_FETCH_DONE: {
832832
return "Mysqlx.Resultset.FetchDone";
833833
}
834-
// TODO: Unused, enable in the future.
835-
// case Mysqlx::ServerMessages::RESULTSET_FETCH_SUSPENDED: { return ""; }
834+
case Mysqlx::ServerMessages::RESULTSET_FETCH_SUSPENDED: {
835+
return "Mysqlx.Resultset.FetchSuspended";
836+
}
836837
case Mysqlx::ServerMessages::RESULTSET_FETCH_DONE_MORE_RESULTSETS: {
837838
return "Mysqlx.Resultset.FetchDoneMoreResultsets";
838839
}

tests/test_connection.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
from mysql.connector import (connect, connection, network, errors,
5454
constants, cursor, abstracts, catch23)
5555
from mysql.connector.optionfiles import read_option_files
56+
from mysql.connector.utils import linux_distribution
5657
from mysql.connector.version import VERSION, LICENSE
5758

5859
LOGGER = logging.getLogger(tests.LOGGER_NAME)
@@ -1809,7 +1810,7 @@ def test_connection_attributes_defaults(self):
18091810
if platform.system() == "Darwin":
18101811
os_ver = "{}-{}".format("macOS", platform.mac_ver()[0])
18111812
else:
1812-
os_ver = "-".join(platform.linux_distribution()[0:2])
1813+
os_ver = "-".join(linux_distribution()[0:2])
18131814

18141815
license_chunks = LICENSE.split(" ")
18151816
if license_chunks[0] == "GPLv2":

0 commit comments

Comments
 (0)