Skip to content

Commit 2998c26

Browse files
committed
BUG20736339: Expect multiple include directories from mysql_config
Patch is provided by the bug reporter. Tests added for regression.
1 parent 3408dca commit 2998c26

File tree

2 files changed

+60
-23
lines changed

2 files changed

+60
-23
lines changed

lib/cpy_distutils.py

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# MySQL Connector/Python - MySQL driver written in Python.
2-
# Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
2+
# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
33

44
# MySQL Connector/Python is licensed under the terms of the GPLv2
55
# <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -136,21 +136,7 @@ def unix_lib_is64bit(lib_file):
136136
return False
137137

138138

139-
def get_mysql_config_info(mysql_config):
140-
"""Get MySQL information using mysql_config tool
141-
142-
Returns a dict.
143-
"""
144-
options = ['cflags', 'include', 'libs', 'libs_r', 'plugindir', 'version']
145-
146-
cmd = [mysql_config] + [ "--{0}".format(opt) for opt in options ]
147-
148-
try:
149-
proc = Popen(cmd, stdout=PIPE, universal_newlines=True)
150-
stdout, _ = proc.communicate()
151-
except OSError as exc:
152-
raise DistutilsExecError("Failed executing mysql_config: {0}".format(
153-
str(exc)))
139+
def parse_mysql_config_info(options, stdout):
154140
log.debug("# stdout: {0}".format(stdout))
155141
info = {}
156142
for option, line in zip(options, stdout.split('\n')):
@@ -173,7 +159,28 @@ def get_mysql_config_info(mysql_config):
173159
info['lib_r_dir'] = libs[0].replace('-L', '')
174160
info['libs_r'] = [ lib.replace('-l', '') for lib in libs[1:] ]
175161

176-
info['include'] = info['include'].replace('-I', '')
162+
info['include'] = [x.strip() for x in info['include'].split('-I')[1:]]
163+
164+
return info
165+
166+
167+
def get_mysql_config_info(mysql_config):
168+
"""Get MySQL information using mysql_config tool
169+
170+
Returns a dict.
171+
"""
172+
options = ['cflags', 'include', 'libs', 'libs_r', 'plugindir', 'version']
173+
174+
cmd = [mysql_config] + [ "--{0}".format(opt) for opt in options ]
175+
176+
try:
177+
proc = Popen(cmd, stdout=PIPE, universal_newlines=True)
178+
stdout, _ = proc.communicate()
179+
except OSError as exc:
180+
raise DistutilsExecError("Failed executing mysql_config: {0}".format(
181+
str(exc)))
182+
183+
info = parse_mysql_config_info(options, stdout)
177184

178185
# Try to figure out the architecture
179186
info['arch'] = None
@@ -316,7 +323,7 @@ def _finalize_connector_c(self, connc_loc):
316323
else:
317324
raise OSError("Unsupported platform: %s" % os.name)
318325

319-
include_dir = os.path.join(connc_loc, 'include')
326+
include_dirs = [os.path.join(connc_loc, 'include')]
320327
if os.name == 'nt':
321328
libraries = ['libmysql']
322329
else:
@@ -341,19 +348,20 @@ def _finalize_connector_c(self, connc_loc):
341348
log.error(err_version)
342349
sys.exit(1)
343350

344-
include_dir = myc_info['include']
351+
include_dirs = myc_info['include']
345352
libraries = myc_info['libs']
346353
library_dirs = myc_info['lib_dir']
347354
self._mysql_config_info = myc_info
348355
self.arch = self._mysql_config_info['arch']
349356
connc_64bit = self.arch == 'x86_64'
350357

351-
if not os.path.exists(include_dir):
352-
log.error(err_invalid_loc, connc_loc)
353-
sys.exit(1)
358+
for include_dir in include_dirs:
359+
if not os.path.exists(include_dir):
360+
log.error(err_invalid_loc, connc_loc)
361+
sys.exit(1)
354362

355363
# Set up the build_ext class
356-
self.include_dirs.append(include_dir)
364+
self.include_dirs.extend(include_dirs)
357365
self.libraries.extend(libraries)
358366
self.library_dirs.append(library_dirs)
359367

tests/test_bugs.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
errors, constants, pooling)
5454
from mysql.connector.optionfiles import read_option_files
5555
import mysql.connector
56+
import cpy_distutils
5657

5758
try:
5859
from mysql.connector.connection_cext import CMySQLConnection
@@ -4369,3 +4370,31 @@ def test_pure_cnx(self):
43694370
del config["connection_timeout"]
43704371
cursor_class = mysql.connector.cursor.MySQLCursorBufferedRaw
43714372
self._long_query(config, cursor_class)
4373+
4374+
4375+
class BugOra20736339(tests.MySQLConnectorTests):
4376+
"""BUG#20736339: C EXTENSION FAILS TO COMPILE IF MYSQL_CONFIG RETURN MORE
4377+
THAN ONE INCLUDE DIR
4378+
"""
4379+
def test_parse_mysql_config(self):
4380+
options = ['cflags', 'include', 'libs', 'libs_r', 'plugindir', 'version']
4381+
includes = ["/mysql/include", "/mysql/another_include"]
4382+
config = """
4383+
-I/mysql/include -fabi-version=2 -fno-omit-frame-pointer
4384+
-I{0}
4385+
-L/mysql/lib -lmysqlclient -lpthread -lm -lrt -lssl -lcrypto -ldl
4386+
-L/mysql/lib -lmysqlclient -lpthread -lm -lrt -lssl -lcrypto -ldl
4387+
/mysql/lib/plugin
4388+
5.7.17
4389+
"""
4390+
4391+
info = cpy_distutils.parse_mysql_config_info(options,
4392+
config.strip().format(includes[0]))
4393+
self.assertEqual(1, len(info["include"]))
4394+
self.assertEqual(includes[0], info["include"][0])
4395+
4396+
info = cpy_distutils.parse_mysql_config_info(options,
4397+
config.strip().format(" -I".join(includes)))
4398+
self.assertEqual(2, len(info["include"]))
4399+
self.assertEqual(includes[0], info["include"][0])
4400+
self.assertEqual(includes[1], info["include"][1])

0 commit comments

Comments
 (0)