Skip to content

Commit

Permalink
WL13194: Add support for Python 3.8
Browse files Browse the repository at this point in the history
  • Loading branch information
nmariz committed Aug 23, 2019
1 parent 1a54dfa commit 7820919
Show file tree
Hide file tree
Showing 16 changed files with 142 additions and 41 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -2,6 +2,7 @@
.coverage
.DS_Store
*__pycache__*
.python-version
.idea/
.vscode/
commit.txt
Expand Down
2 changes: 1 addition & 1 deletion cpyint
6 changes: 3 additions & 3 deletions lib/mysql/connector/connection.py
@@ -1,4 +1,4 @@
# Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, version 2.0, as
Expand Down Expand Up @@ -51,7 +51,7 @@
MySQLCursorBufferedNamedTuple)
from .network import MySQLUnixSocket, MySQLTCPSocket
from .protocol import MySQLProtocol
from .utils import int4store
from .utils import int4store, linux_distribution
from .abstracts import MySQLConnectionAbstract


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

license_chunks = version.LICENSE.split(" ")
if license_chunks[0] == "GPLv2":
Expand Down
110 changes: 105 additions & 5 deletions lib/mysql/connector/utils.py
@@ -1,4 +1,4 @@
# Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, version 2.0, as
Expand Down Expand Up @@ -29,13 +29,16 @@
"""Utilities
"""

from __future__ import print_function
import os
import subprocess
import struct
import sys

__MYSQL_DEBUG__ = False
from .catch23 import struct_unpack, PY2

import struct

from .catch23 import struct_unpack
__MYSQL_DEBUG__ = False


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


def print_buffer(abuffer, prefix=None, limit=30):
"""Debug function printing output of _digest_buffer()"""
if prefix:
Expand All @@ -340,3 +344,99 @@ def print_buffer(abuffer, prefix=None, limit=30):
print(prefix + ': ' + digest)
else:
print(_digest_buffer(abuffer))


def _parse_os_release():
"""Parse the contents of /etc/os-release file.
Returns:
A dictionary containing release information.
"""
distro = {}
os_release_file = os.path.join("/etc", "os-release")
if not os.path.exists(os_release_file):
return distro
with open(os_release_file) as file_obj:
for line in file_obj:
key_value = line.split("=")
if len(key_value) != 2:
continue
key = key_value[0].lower()
value = key_value[1].rstrip("\n").strip('"')
distro[key] = value
return distro


def _parse_lsb_release():
"""Parse the contents of /etc/lsb-release file.
Returns:
A dictionary containing release information.
"""
distro = {}
lsb_release_file = os.path.join("/etc", "lsb-release")
if os.path.exists(lsb_release_file):
with open(lsb_release_file) as file_obj:
for line in file_obj:
key_value = line.split("=")
if len(key_value) != 2:
continue
key = key_value[0].lower()
value = key_value[1].rstrip("\n").strip('"')
distro[key] = value
return distro


def _parse_lsb_release_command():
"""Parse the output of the lsb_release command.
Returns:
A dictionary containing release information.
"""
distro = {}
with open(os.devnull, "w") as devnull:
try:
stdout = subprocess.check_output(
("lsb_release", "-a"), stderr=devnull)
except OSError:
return None
lines = stdout.decode(sys.getfilesystemencoding()).splitlines()
for line in lines:
key_value = line.split(":")
if len(key_value) != 2:
continue
key = key_value[0].replace(" ", "_").lower()
value = key_value[1].strip("\t")
distro[key] = value.encode("utf-8") if PY2 else value
return distro


def linux_distribution():
"""Tries to determine the name of the Linux OS distribution name.
First tries to get information from ``/etc/os-release`` file.
If fails, tries to get the information of ``/etc/lsb-release`` file.
And finally the information of ``lsb-release`` command.
Returns:
A tuple with (`name`, `version`, `codename`)
"""
distro = _parse_lsb_release()
if distro:
return (distro.get("distrib_id", ""),
distro.get("distrib_release", ""),
distro.get("distrib_codename", ""))

distro = _parse_lsb_release_command()
if distro:
return (distro.get("distributor_id", ""),
distro.get("release", ""),
distro.get("codename", ""))

distro = _parse_os_release()
if distro:
return (distro.get("name", ""),
distro.get("version_id", ""),
distro.get("version_codename", ""))

return ("", "", "")
6 changes: 2 additions & 4 deletions lib/mysqlx/__init__.py
Expand Up @@ -363,10 +363,8 @@ def _get_connection_settings(*args, **kwargs):
for key, val in args[0].items():
settings[key.replace("_", "-")] = val
elif kwargs:
settings.update(kwargs)
for key in settings:
if "_" in key:
settings[key.replace("_", "-")] = settings.pop(key)
for key, val in kwargs.items():
settings[key.replace("_", "-")] = val

if not settings:
raise InterfaceError("Settings not provided")
Expand Down
7 changes: 3 additions & 4 deletions lib/mysqlx/connection.py
Expand Up @@ -61,6 +61,7 @@

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


Expand Down Expand Up @@ -480,8 +481,7 @@ def _handle_capabilities(self):

is_ol7 = False
if platform.system() == "Linux":
# pylint: disable=W1505
distname, version, _ = platform.linux_distribution()
distname, version, _ = linux_distribution()
try:
is_ol7 = "Oracle Linux" in distname and \
version.split(".")[0] == "7"
Expand Down Expand Up @@ -1406,8 +1406,7 @@ def _init_attributes(self):
if platform.system() == "Darwin":
os_ver = "{}-{}".format("macOS", platform.mac_ver()[0])
else:
os_ver = "-".join(
platform.linux_distribution()[0:2]) # pylint: disable=W1505
os_ver = "-".join(linux_distribution()[0:2])

license_chunks = LICENSE.split(' ')
if license_chunks[0] == "GPLv2":
Expand Down
2 changes: 1 addition & 1 deletion lib/mysqlx/expr.py
Expand Up @@ -973,7 +973,7 @@ def cast_data_type_dimension(self, decimal=False):
dimension.append(self.consume_token(TokenType.LNUM))
self.consume_token(TokenType.RPAREN)

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

def star_operator(self):
Expand Down
2 changes: 1 addition & 1 deletion lib/mysqlx/statement.py
Expand Up @@ -119,7 +119,7 @@ def parse_table_name(default_schema, table_name, sql_mode=""):
quote = '"' if "ANSI_QUOTES" in sql_mode else "`"
delimiter = ".{0}".format(quote) if quote in table_name else "."
temp = table_name.split(delimiter, 1)
return (default_schema if len(temp) is 1 else temp[0].strip(quote),
return (default_schema if len(temp) == 1 else temp[0].strip(quote),
temp[-1].strip(quote),)


Expand Down
3 changes: 2 additions & 1 deletion setupinfo.py
Expand Up @@ -115,7 +115,7 @@
maintainer = 'Nuno Mariz'
maintainer_email = 'nuno.mariz@oracle.com'
cpy_gpl_license = "GNU GPLv2 (with FOSS License Exception)"
keywords = "mysql db",
keywords = "mysql db"
url = 'http://dev.mysql.com/doc/connector-python/en/index.html'
download_url = 'http://dev.mysql.com/downloads/connector/python/'
classifiers = [
Expand All @@ -133,6 +133,7 @@
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Topic :: Database',
'Topic :: Software Development',
'Topic :: Software Development :: Libraries :: Application Frameworks',
Expand Down
22 changes: 10 additions & 12 deletions src/mysql_capi.c
Expand Up @@ -1107,6 +1107,7 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
}

mysql_init(&self->session);
Py_END_ALLOW_THREADS

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

#ifdef PY3
Py_END_ALLOW_THREADS
charset_name= PyUnicode_AsASCIIString(self->charset_name);
Py_BEGIN_ALLOW_THREADS
if (NULL == charset_name)
{
return NULL;
Expand Down Expand Up @@ -1198,7 +1197,6 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
#endif
}

Py_END_ALLOW_THREADS
if (PyString_Check(self->auth_plugin)) {
auth_plugin= PyStringAsString(self->auth_plugin);
mysql_options(&self->session, MYSQL_DEFAULT_AUTH, auth_plugin);
Expand Down Expand Up @@ -1226,7 +1224,6 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
(char*)&abool);
}
}
Py_BEGIN_ALLOW_THREADS

if (database && strlen(database) == 0)
{
Expand All @@ -1246,7 +1243,7 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
if (conn_attrs != NULL)
{
while (PyDict_Next(conn_attrs, &pos, &key, &value)) {
char* attr_name;
const char* attr_name;
#ifdef PY3
PyObject *str_name = PyObject_Str(key);
if (!str_name)
Expand All @@ -1266,7 +1263,7 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
attr_name= PyString_AsString(key);
}
#endif
char* attr_value;
const char* attr_value;
#ifdef PY3
PyObject *str_value = PyObject_Str(value);
if (!str_value)
Expand Down Expand Up @@ -1305,8 +1302,10 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
}

#ifdef PY3
Py_BEGIN_ALLOW_THREADS
res= mysql_real_connect(&self->session, host, user, password, database,
port, unix_socket, client_flags);
Py_END_ALLOW_THREADS
#else
{
char* c_password;
Expand All @@ -1320,13 +1319,13 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
{
c_password= PyString_AsString(password);
}
Py_BEGIN_ALLOW_THREADS
res= mysql_real_connect(&self->session, host, user, c_password, database,
port, unix_socket, client_flags);
Py_END_ALLOW_THREADS
}
#endif

Py_END_ALLOW_THREADS

if (!res)
{
raise_with_session(&self->session, NULL);
Expand Down Expand Up @@ -1431,11 +1430,9 @@ MySQL_escape_string(MySQL *self, PyObject *value)
to= BytesFromStringAndSize(NULL, from_size * 2 + 1);
to_str= PyBytesAsString(to);

Py_BEGIN_ALLOW_THREADS
escaped_size= (Py_ssize_t)mysql_real_escape_string(&self->session, to_str,
from_str,
(unsigned long)from_size);
Py_END_ALLOW_THREADS

BytesResize(&to, escaped_size);
Py_XDECREF(from);
Expand Down Expand Up @@ -3232,7 +3229,7 @@ MySQLPrepStmt_execute(MySQLPrepStmt *self, PyObject *args)
PyObject*
MySQLPrepStmt_handle_result(MySQLPrepStmt *self)
{
int i= 0;
unsigned int i= 0;

Py_BEGIN_ALLOW_THREADS
self->res = mysql_stmt_result_metadata(self->stmt);
Expand Down Expand Up @@ -3346,7 +3343,8 @@ MySQLPrepStmt_fetch_row(MySQLPrepStmt *self)
PyObject *field_info;
PyObject *mod_decimal, *decimal, *dec_args;
unsigned long field_flags;
int i= 0, fetch= 0;
unsigned int i= 0;
int fetch= 0;

row= PyTuple_New(self->column_count);

Expand Down
7 changes: 4 additions & 3 deletions src/mysqlxpb/mysqlxpb.cc
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
Expand Down Expand Up @@ -831,8 +831,9 @@ static const char* GetMessageNameByTypeId(Mysqlx::ServerMessages::Type type) {
case Mysqlx::ServerMessages::RESULTSET_FETCH_DONE: {
return "Mysqlx.Resultset.FetchDone";
}
// TODO: Unused, enable in the future.
// case Mysqlx::ServerMessages::RESULTSET_FETCH_SUSPENDED: { return ""; }
case Mysqlx::ServerMessages::RESULTSET_FETCH_SUSPENDED: {
return "Mysqlx.Resultset.FetchSuspended";
}
case Mysqlx::ServerMessages::RESULTSET_FETCH_DONE_MORE_RESULTSETS: {
return "Mysqlx.Resultset.FetchDoneMoreResultsets";
}
Expand Down
3 changes: 2 additions & 1 deletion tests/test_connection.py
Expand Up @@ -53,6 +53,7 @@
from mysql.connector import (connect, connection, network, errors,
constants, cursor, abstracts, catch23)
from mysql.connector.optionfiles import read_option_files
from mysql.connector.utils import linux_distribution
from mysql.connector.version import VERSION, LICENSE

LOGGER = logging.getLogger(tests.LOGGER_NAME)
Expand Down Expand Up @@ -1809,7 +1810,7 @@ def test_connection_attributes_defaults(self):
if platform.system() == "Darwin":
os_ver = "{}-{}".format("macOS", platform.mac_ver()[0])
else:
os_ver = "-".join(platform.linux_distribution()[0:2])
os_ver = "-".join(linux_distribution()[0:2])

license_chunks = LICENSE.split(" ")
if license_chunks[0] == "GPLv2":
Expand Down

0 comments on commit 7820919

Please sign in to comment.