[Python-modules-commits] [mysql-connector-python] 01/09: Import mysql-connector-python_2.1.5.orig.tar.gz

Sandro Tosi morph at moszumanska.debian.org
Sun Dec 18 00:56:09 UTC 2016


This is an automated email from the git hooks/post-receive script.

morph pushed a commit to branch master
in repository mysql-connector-python.

commit 31f67d0a752c5bfcd89f949ff5e1c34e2223e8aa
Author: Sandro Tosi <morph at debian.org>
Date:   Sat Dec 17 16:18:57 2016 -0500

    Import mysql-connector-python_2.1.5.orig.tar.gz
---
 CHANGES.txt                                     |    28 +-
 PKG-INFO                                        |     2 +-
 README.txt                                      |     4 +-
 lib/cpy_distutils.py                            |    18 +-
 lib/mysql/connector/__init__.py                 |     4 +-
 lib/mysql/connector/abstracts.py                |     6 +-
 lib/mysql/connector/connection.py               |    20 +-
 lib/mysql/connector/connection_cext.py          |     9 +-
 lib/mysql/connector/constants.py                |    13 +-
 lib/mysql/connector/conversion.py               |     4 +-
 lib/mysql/connector/cursor.py                   |    53 +-
 lib/mysql/connector/errorcode.py                |    56 +-
 lib/mysql/connector/locales/eng/client_error.py |     4 +-
 lib/mysql/connector/network.py                  |    97 +-
 lib/mysql/connector/optionfiles.py              |    36 +-
 lib/mysql/connector/protocol.py                 |    22 +-
 lib/mysql/connector/version.py                  |     4 +-
 src/mysql_capi.c                                |    99 +-
 tests/__init__.py                               |    10 +-
 tests/cext/test_cext_api.py                     |    27 +-
 tests/cext/test_cext_connection.py              |    14 +-
 tests/data/option_files/my.cnf                  |     1 +
 tests/data/random_big_bin.csv                   | 11535 ++++++++++++++++++++++
 tests/issues/__init__.py                        |     0
 tests/issues/test_bug21449207.py                |    80 +
 tests/issues/test_bug21449996.py                |    59 +
 tests/issues/test_bug21879859.py                |    76 +
 tests/issues/test_bug21879914.py                |    58 +
 tests/issues/test_bug22545879.py                |    71 +
 tests/test_abstracts.py                         |     7 +-
 tests/test_bugs.py                              |   349 +-
 tests/test_connection.py                        |     8 +-
 tests/test_conversion.py                        |    10 +-
 tests/test_cursor.py                            |    46 +-
 tests/test_network.py                           |    49 +-
 tests/test_optionfiles.py                       |     8 +-
 tests/test_protocol.py                          |     4 +-
 37 files changed, 12634 insertions(+), 257 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index 54e1219..18112d1 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -3,11 +3,36 @@ MySQL Connector/Python 2.1 - Release Notes & Changes
 ====================================================
 
 MySQL Connector/Python
-Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
 
 Full release notes:
  http://dev.mysql.com/doc/relnotes/connector-python/en/
 
+v2.1.5
+======
+
+- BUG#25111218: Fix duplicate logic for reading EOF packet
+- BUG#21656282: Connection fails using unicode passwords with C extension
+- BUG#21530841: Select statement fails for results with more than 4096 columns
+- BUG#21530100: Fix reading option files
+- BUG#21477493: Fix RE_SQL_INSERT_STMT to correctly match Insert Statement
+- BUG#21476495: Fix set_charset_collation() for an invalid charset provided
+
+v2.1.4
+======
+
+- BUG#22873551: Fix cleartext authentication issue
+- BUG#22545879: Fix usage of --ssl-cipher option
+- BUG#22529828: Fix potencial SQL injection
+- BUG#21881038: Fix duplicate entry in CHANGES.txt
+- BUG#21879914: Fix using SSL without key or certificate using C/Ext
+- BUG#21879859: Fix consuming results after calling procedure
+- BUG#21498719: Fix conversion of Python bytearray
+- BUG#21449996: Fix LOAD DATA with compression turned on
+- BUG#20834643: Attribute Error while promoting servers using MySQL Fabric
+- BUG#20811802: Fix buffered named tuple cursor with CExtension
+- BUG#20217174: Fix install command honouring --install-lib when given
+
 v2.1.3
 ======
 
@@ -29,7 +54,6 @@ v2.1.3
 - BUG#21490865: Fix compiling CExtension with relocated libmysqlclient
 - BUG#21492428: Fix using passwords with leading/trailing whitespaces
 - BUG#21541244: Fix running unit tests for MySQL server 5.5
-- BUG#21782246: Fix Install check of bitness of libmysql c client fails
 
 v2.1.2b1
 ========
diff --git a/PKG-INFO b/PKG-INFO
index 2ab16ed..4af4d6f 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.0
 Name: mysql-connector-python
-Version: 2.1.3
+Version: 2.1.5
 Summary: MySQL driver written in Python
 Home-page: http://dev.mysql.com/doc/connector-python/en/index.html
 Author: Oracle and/or its affiliates
diff --git a/README.txt b/README.txt
index 8d4cc3d..773af0b 100644
--- a/README.txt
+++ b/README.txt
@@ -3,7 +3,7 @@ MySQL Connector/Python 2.1
 ==========================
 
 MySQL Connector/Python
-Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
 
 License information can be found in the LICENSE.txt file.
 
@@ -28,7 +28,7 @@ doubt, this particular copy of the software is released
 under the version 2 of the GNU General Public License.
 MySQL Connector/Python is brought to you by Oracle.
 
-Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
 
 License information can be found in the LICENSE.txt file.
 
diff --git a/lib/cpy_distutils.py b/lib/cpy_distutils.py
index fbddc84..e944ce6 100644
--- a/lib/cpy_distutils.py
+++ b/lib/cpy_distutils.py
@@ -1,7 +1,6 @@
 # MySQL Connector/Python - MySQL driver written in Python.
 # Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
 
-
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
 # MySQL Connectors. There are special exceptions to the terms and
@@ -170,7 +169,6 @@ def get_mysql_config_info(mysql_config):
     log.debug("# info['libs']: ")
     for lib in info['libs']:
         log.debug("#   {0}".format(lib))
-    log.error("# info['libs']: {0}".format(info['libs']))
     libs = shlex.split(info['libs_r'])
     info['lib_r_dir'] = libs[0].replace('-L', '')
     info['libs_r'] = [ lib.replace('-l', '') for lib in libs[1:] ]
@@ -182,9 +180,6 @@ def get_mysql_config_info(mysql_config):
     if os.name == 'posix':
         pathname = os.path.join(info['lib_dir'], 'lib' + info['libs'][0]) + '*'
         libs = glob(pathname)
-        log.debug("# libs: {0}".format(libs))
-        for lib in libs:
-            log.debug("#-   {0}".format(lib))
         mysqlclient_libs = []
         for filepath in libs:
             _, filename = os.path.split(filepath)
@@ -473,13 +468,19 @@ class BuildExtStatic(BuildExtDynamic):
             log.error("MySQL C API should be a directory")
             sys.exit(1)
 
+        log.info("Copying MySQL libraries")
         copy_tree(os.path.join(connc_loc, 'lib'), self.connc_lib)
+        log.info("Copying MySQL header files")
         copy_tree(os.path.join(connc_loc, 'include'), self.connc_include)
 
         # Remove all but static libraries to force static linking
-        for lib_file in os.listdir(self.connc_lib):
-            if os.name == 'posix' and not lib_file.endswith('.a'):
-                os.unlink(os.path.join(self.connc_lib, lib_file))
+        if os.name == 'posix':
+            log.info("Removing non-static MySQL libraries from %s" % self.connc_lib)
+            for lib_file in os.listdir(self.connc_lib):
+                lib_file_path = os.path.join(self.connc_lib, lib_file)
+                if os.path.isfile(lib_file_path) and not lib_file.endswith('.a'):
+                    os.unlink(os.path.join(self.connc_lib, lib_file))
+
 
     def fix_compiler(self):
         BuildExtDynamic.fix_compiler(self)
@@ -557,6 +558,7 @@ class Install(install):
 
     def finalize_options(self):
         if self.static:
+            log.info("Linking CExtension statically with MySQL libraries")
             self.distribution.cmdclass['build_ext'] = BuildExtStatic
 
         if self.byte_code_only is None:
diff --git a/lib/mysql/connector/__init__.py b/lib/mysql/connector/__init__.py
index 464030a..8a2428e 100644
--- a/lib/mysql/connector/__init__.py
+++ b/lib/mysql/connector/__init__.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -42,7 +42,7 @@ from .errors import (  # pylint: disable=W0622
 from .constants import FieldFlag, FieldType, CharacterSet, \
     RefreshOption, ClientFlag
 from .dbapi import (
-    Date, Time, Timestamp, Binary, DateFromTicks, DateFromTicks,
+    Date, Time, Timestamp, Binary, DateFromTicks,
     TimestampFromTicks, TimeFromTicks,
     STRING, BINARY, NUMBER, DATETIME, ROWID,
     apilevel, threadsafety, paramstyle)
diff --git a/lib/mysql/connector/abstracts.py b/lib/mysql/connector/abstracts.py
index 9aa4ac9..c83a527 100644
--- a/lib/mysql/connector/abstracts.py
+++ b/lib/mysql/connector/abstracts.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -23,9 +23,6 @@
 
 """Module gathering all abstract base classes"""
 
-# Issue with pylint and NotImplementedError
-# pylint: disable=R0921
-
 from abc import ABCMeta, abstractmethod, abstractproperty
 import re
 import time
@@ -637,7 +634,6 @@ class MySQLConnectionAbstract(object):
         """
         if charset:
             if isinstance(charset, int):
-                self._charset_id = charset
                 (self._charset_id, charset_name, collation_name) = \
                     CharacterSet.get_charset_info(charset)
             elif isinstance(charset, str):
diff --git a/lib/mysql/connector/connection.py b/lib/mysql/connector/connection.py
index 0aaa78c..453c73e 100644
--- a/lib/mysql/connector/connection.py
+++ b/lib/mysql/connector/connection.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -237,7 +237,7 @@ class MySQLConnection(MySQLConnectionAbstract):
     disconnect = close
 
     def _send_cmd(self, command, argument=None, packet_number=0, packet=None,
-                  expect_response=True):
+                  expect_response=True, compressed_packet_number=0):
         """Send a command to the MySQL server
 
         This method sends a command with an optional argument.
@@ -258,7 +258,7 @@ class MySQLConnection(MySQLConnectionAbstract):
         try:
             self._socket.send(
                 self._protocol.make_command(command, packet or argument),
-                packet_number)
+                packet_number, compressed_packet_number)
         except AttributeError:
             raise errors.OperationalError("MySQL Connection not available.")
 
@@ -325,7 +325,7 @@ class MySQLConnection(MySQLConnectionAbstract):
         """
         if packet[4] == 0:
             ok_pkt = self._protocol.parse_ok(packet)
-            self._handle_server_status(ok_pkt['server_status'])
+            self._handle_server_status(ok_pkt['status_flag'])
             return ok_pkt
         elif packet[4] == 255:
             raise errors.get_exception(packet)
@@ -440,12 +440,14 @@ class MySQLConnection(MySQLConnectionAbstract):
                 rows = self._protocol.read_binary_result(
                     self._socket, columns, count)
             else:
-                rows = self._protocol.read_text_result(self._socket, count)
+                rows = self._protocol.read_text_result(self._socket, self._server_version, count=count)
         except errors.Error as err:
             self.unread_result = False
             raise err
+
         if rows[-1] is not None:
-            self._handle_server_status(rows[-1]['status_flag'])
+            ek = rows[-1] # OK or EOF
+            self._handle_server_status(ek['status_flag'] if 'status_flag' in ek else ek['server_status'])
             self.unread_result = False
 
         return rows
@@ -553,7 +555,7 @@ class MySQLConnection(MySQLConnectionAbstract):
         self.handle_unread_result()
 
         packet = self._protocol.make_command(ServerCmd.QUIT)
-        self._socket.send(packet, 0)
+        self._socket.send(packet, 0, 0)
         return packet
 
     def cmd_shutdown(self, shutdown_type=None):
@@ -587,7 +589,7 @@ class MySQLConnection(MySQLConnectionAbstract):
         self.handle_unread_result()
 
         packet = self._protocol.make_command(ServerCmd.STATISTICS)
-        self._socket.send(packet, 0)
+        self._socket.send(packet, 0, 0)
         return self._protocol.parse_statistics(self._socket.recv())
 
     def cmd_process_kill(self, mysql_pid):
@@ -646,7 +648,7 @@ class MySQLConnection(MySQLConnectionAbstract):
             charset=charset, client_flags=self._client_flags,
             ssl_enabled=self._ssl_active,
             auth_plugin=self._auth_plugin)
-        self._socket.send(packet, 0)
+        self._socket.send(packet, 0, 0)
 
         ok_packet = self._auth_switch_request(username, password)
 
diff --git a/lib/mysql/connector/connection_cext.py b/lib/mysql/connector/connection_cext.py
index 473f6bd..9c00a9a 100644
--- a/lib/mysql/connector/connection_cext.py
+++ b/lib/mysql/connector/connection_cext.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -36,8 +36,9 @@ from .abstracts import MySQLConnectionAbstract, MySQLCursorAbstract
 from .protocol import MySQLProtocol
 
 HAVE_CMYSQL = False
+# pylint: disable=F0401,C0413
 try:
-    import _mysql_connector  # pylint: disable=F0401
+    import _mysql_connector
     from .cursor_cext import (
         CMySQLCursor, CMySQLCursorRaw,
         CMySQLCursorBuffered, CMySQLCursorBufferedRaw, CMySQLCursorPrepared,
@@ -51,7 +52,7 @@ except ImportError as exc:
         ))
 else:
     HAVE_CMYSQL = True
-
+# pylint: enable=F0401,C0413
 
 class CMySQLConnection(MySQLConnectionAbstract):
 
@@ -210,7 +211,7 @@ class CMySQLConnection(MySQLConnectionAbstract):
         try:
             connected = self._cmysql.ping()
         except AttributeError:
-          pass  # Raise or reconnect later
+            pass  # Raise or reconnect later
         else:
             if connected:
                 return
diff --git a/lib/mysql/connector/constants.py b/lib/mysql/connector/constants.py
index 79dc178..8d27cb0 100644
--- a/lib/mysql/connector/constants.py
+++ b/lib/mysql/connector/constants.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -56,6 +56,7 @@ DEFAULT_CONFIGURATION = {
     'ssl_cert': None,
     'ssl_key': None,
     'ssl_verify_cert': False,
+    'ssl_cipher': None,
     'passwd': None,
     'db': None,
     'connect_timeout': None,
@@ -397,6 +398,8 @@ class ClientFlag(_Flags):
     CONNECT_ARGS = 1 << 20
     PLUGIN_AUTH_LENENC_CLIENT_DATA = 1 << 21
     CAN_HANDLE_EXPIRED_PASSWORDS = 1 << 22
+    SESION_TRACK = 1 << 23
+    DEPRECATE_EOF = 1 << 24
     SSL_VERIFY_SERVER_CERT = 1 << 30
     REMEMBER_OPTIONS = 1 << 31
 
@@ -419,6 +422,14 @@ class ClientFlag(_Flags):
         'SECURE_CONNECTION': (1 << 15, 'New 4.1 authentication'),
         'MULTI_STATEMENTS': (1 << 16, 'Enable/disable multi-stmt support'),
         'MULTI_RESULTS': (1 << 17, 'Enable/disable multi-results'),
+        'PS_MULTI_RESULTS': (1 << 18, 'Multi-results in PS-protocol'),
+        'PLUGIN_AUTH': (1 << 19, 'Client supports plugin authentication'),
+        'CONNECT_ARGS': (1 << 20, 'Client supports connection attributes'),
+        'PLUGIN_AUTH_LENENC_CLIENT_DATA': (1 << 21,
+                                           'Enable authentication response packet to be larger than 255 bytes'),
+        'CAN_HANDLE_EXPIRED_PASSWORDS': (1 << 22, "Don't close the connection for a connection with expired password"),
+        'SESION_TRACK': (1 << 23, 'Capable of handling server state change information'),
+        'DEPRECATE_EOF': (1 << 24, 'Client no longer needs EOF packet'),
         'SSL_VERIFY_SERVER_CERT': (1 << 30, ''),
         'REMEMBER_OPTIONS': (1 << 31, ''),
     }
diff --git a/lib/mysql/connector/conversion.py b/lib/mysql/connector/conversion.py
index 07bed43..d94e9e9 100644
--- a/lib/mysql/connector/conversion.py
+++ b/lib/mysql/connector/conversion.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -251,7 +251,7 @@ class MySQLConverter(MySQLConverterBase):
 
     def _bytearray_to_mysql(self, value):
         """Convert value to bytes"""
-        return str(value)
+        return bytes(value)
 
     def _bool_to_mysql(self, value):
         """Convert value to boolean"""
diff --git a/lib/mysql/connector/cursor.py b/lib/mysql/connector/cursor.py
index 7cc7362..09b7b54 100644
--- a/lib/mysql/connector/cursor.py
+++ b/lib/mysql/connector/cursor.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -40,10 +40,19 @@ RE_SQL_ON_DUPLICATE = re.compile(
     r'''\s*ON\s+DUPLICATE\s+KEY(?:[^"'`]*["'`][^"'`]*["'`])*[^"'`]*$''',
     re.I | re.M | re.S)
 RE_SQL_INSERT_STMT = re.compile(
-    r"({0}|\s)*INSERT({0}|\s)*INTO.+VALUES.*".format(SQL_COMMENT),
+    r"({0}|\s)*INSERT({0}|\s)*INTO\s+[`'\"]?.+[`'\"]?(?:\.[`'\"]?.+[`'\"]?)"
+     "{{0,2}}\s+VALUES\s*\(.+(?:\s*,.+)*\)".format(SQL_COMMENT),
     re.I | re.M | re.S)
 RE_SQL_INSERT_VALUES = re.compile(r'.*VALUES\s*(\(.*\)).*', re.I | re.M | re.S)
 RE_PY_PARAM = re.compile(b'(%s)')
+RE_PY_MAPPING_PARAM = re.compile(
+    br'''
+    %
+    \((?P<mapping_key>[^)]+)\)
+    (?P<conversion_type>[diouxXeEfFgGcrs%])
+    ''',
+    re.X
+)
 RE_SQL_SPLIT_STMTS = re.compile(
     b''';(?=(?:[^"'`]*["'`][^"'`]*["'`])*[^"'`]*$)''')
 RE_SQL_FIND_PARAM = re.compile(
@@ -75,6 +84,34 @@ class _ParamSubstitutor(object):
         return len(self.params) - self.index
 
 
+def _bytestr_format_dict(bytestr, value_dict):
+    """
+    >>> _bytestr_format_dict(b'%(a)s', {b'a': b'foobar'})
+    b'foobar
+    >>> _bytestr_format_dict(b'%%(a)s', {b'a': b'foobar'})
+    b'%%(a)s'
+    >>> _bytestr_format_dict(b'%%%(a)s', {b'a': b'foobar'})
+    b'%%foobar'
+    >>> _bytestr_format_dict(b'%(x)s %(y)s',
+    ...                      {b'x': b'x=%(y)s', b'y': b'y=%(x)s'})
+    b'x=%(y)s y=%(x)s'
+    """
+    def replace(matchobj):
+        value = None
+        groups = matchobj.groupdict()
+        if groups["conversion_type"] == b"%":
+            value = b"%"
+        if groups["conversion_type"] == b"s":
+            key = groups["mapping_key"].encode("utf-8") \
+                  if PY2 else groups["mapping_key"]
+            value = value_dict[key]
+        if value is None:
+            raise ValueError("Unsupported conversion_type: {0}"
+                             "".format(groups["conversion_type"]))
+        return value.decode("utf-8") if PY2 else value
+    return RE_PY_MAPPING_PARAM.sub(replace, bytestr.decode("utf-8")
+                                   if PY2 else bytestr)
+
 class CursorBase(MySQLCursorAbstract):
     """
     Base for defining MySQLCursor. This class is a skeleton and defines
@@ -360,9 +397,9 @@ class MySQLCursor(CursorBase):
                 conv = escape(conv)
                 conv = quote(conv)
                 if PY2:
-                    res["%({0})s".format(key)] = conv
+                    res[key] = conv
                 else:
-                    res["%({0})s".format(key).encode()] = conv
+                    res[key.encode()] = conv
         except Exception as err:
             raise errors.ProgrammingError(
                 "Failed processing pyformat-parameters; %s" % err)
@@ -497,8 +534,8 @@ class MySQLCursor(CursorBase):
 
         if params is not None:
             if isinstance(params, dict):
-                for key, value in self._process_params_dict(params).items():
-                    stmt = stmt.replace(key, value)
+                stmt = _bytestr_format_dict(
+                    stmt, self._process_params_dict(params))
             elif isinstance(params, (list, tuple)):
                 psub = _ParamSubstitutor(self._process_params(params))
                 stmt = RE_PY_PARAM.sub(psub, stmt)
@@ -551,8 +588,8 @@ class MySQLCursor(CursorBase):
             for params in seq_params:
                 tmp = fmt
                 if isinstance(params, dict):
-                    for key, value in self._process_params_dict(params).items():
-                        tmp = tmp.replace(key, value)
+                    tmp = _bytestr_format_dict(
+                        tmp, self._process_params_dict(params))
                 else:
                     psub = _ParamSubstitutor(self._process_params(params))
                     tmp = RE_PY_PARAM.sub(psub, tmp)
diff --git a/lib/mysql/connector/errorcode.py b/lib/mysql/connector/errorcode.py
index 7a11a16..6304811 100644
--- a/lib/mysql/connector/errorcode.py
+++ b/lib/mysql/connector/errorcode.py
@@ -24,8 +24,8 @@
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 
 
 # This file was auto-generated.
-_GENERATED_ON = '2015-07-02'
-_MYSQL_VERSION = (5, 7, 7)
+_GENERATED_ON = '2015-12-13'
+_MYSQL_VERSION = (5, 7, 10)
 
 """This module contains the MySQL Server and Client error codes"""
 
@@ -641,7 +641,7 @@ ER_CANT_CREATE_SROUTINE = 1607
 ER_NEVER_USED = 1608
 ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT = 1609
 ER_SLAVE_CORRUPT_EVENT = 1610
-ER_LOAD_DATA_INVALID_COLUMN = 1611
+ER_LOAD_DATA_INVALID_COLUMN_UNUSED = 1611
 ER_LOG_PURGE_NO_FILE = 1612
 ER_XA_RBTIMEOUT = 1613
 ER_XA_RBDEADLOCK = 1614
@@ -1019,7 +1019,7 @@ ER_PREVENTS_VARIABLE_WITHOUT_RBR = 3099
 ER_RUN_HOOK_ERROR = 3100
 ER_TRANSACTION_ROLLBACK_DURING_COMMIT = 3101
 ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED = 3102
-ER_KEY_BASED_ON_GENERATED_COLUMN = 3103
+ER_UNSUPPORTED_ALTER_INPLACE_ON_VIRTUAL_COLUMN = 3103
 ER_WRONG_FK_OPTION_FOR_GENERATED_COLUMN = 3104
 ER_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN = 3105
 ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN = 3106
@@ -1045,7 +1045,53 @@ ER_WARN_UNSUPPORTED_MAX_EXECUTION_TIME = 3125
 ER_WARN_CONFLICTING_HINT = 3126
 ER_WARN_UNKNOWN_QB_NAME = 3127
 ER_UNRESOLVED_HINT_NAME = 3128
-ER_WARN_DEPRECATED_SQLMODE_UNSET = 3129
+ER_WARN_ON_MODIFYING_GTID_EXECUTED_TABLE = 3129
+ER_PLUGGABLE_PROTOCOL_COMMAND_NOT_SUPPORTED = 3130
+ER_LOCKING_SERVICE_WRONG_NAME = 3131
+ER_LOCKING_SERVICE_DEADLOCK = 3132
+ER_LOCKING_SERVICE_TIMEOUT = 3133
+ER_GIS_MAX_POINTS_IN_GEOMETRY_OVERFLOWED = 3134
+ER_SQL_MODE_MERGED = 3135
+ER_VTOKEN_PLUGIN_TOKEN_MISMATCH = 3136
+ER_VTOKEN_PLUGIN_TOKEN_NOT_FOUND = 3137
+ER_CANT_SET_VARIABLE_WHEN_OWNING_GTID = 3138
+ER_SLAVE_CHANNEL_OPERATION_NOT_ALLOWED = 3139
+ER_INVALID_JSON_TEXT = 3140
+ER_INVALID_JSON_TEXT_IN_PARAM = 3141
+ER_INVALID_JSON_BINARY_DATA = 3142
+ER_INVALID_JSON_PATH = 3143
+ER_INVALID_JSON_CHARSET = 3144
+ER_INVALID_JSON_CHARSET_IN_FUNCTION = 3145
+ER_INVALID_TYPE_FOR_JSON = 3146
+ER_INVALID_CAST_TO_JSON = 3147
+ER_INVALID_JSON_PATH_CHARSET = 3148
+ER_INVALID_JSON_PATH_WILDCARD = 3149
+ER_JSON_VALUE_TOO_BIG = 3150
+ER_JSON_KEY_TOO_BIG = 3151
+ER_JSON_USED_AS_KEY = 3152
+ER_JSON_VACUOUS_PATH = 3153
+ER_JSON_BAD_ONE_OR_ALL_ARG = 3154
+ER_NUMERIC_JSON_VALUE_OUT_OF_RANGE = 3155
+ER_INVALID_JSON_VALUE_FOR_CAST = 3156
+ER_JSON_DOCUMENT_TOO_DEEP = 3157
+ER_JSON_DOCUMENT_NULL_KEY = 3158
+ER_SECURE_TRANSPORT_REQUIRED = 3159
+ER_NO_SECURE_TRANSPORTS_CONFIGURED = 3160
+ER_DISABLED_STORAGE_ENGINE = 3161
+ER_USER_DOES_NOT_EXIST = 3162
+ER_USER_ALREADY_EXISTS = 3163
+ER_AUDIT_API_ABORT = 3164
+ER_INVALID_JSON_PATH_ARRAY_CELL = 3165
+ER_BUFPOOL_RESIZE_INPROGRESS = 3166
+ER_FEATURE_DISABLED_SEE_DOC = 3167
+ER_SERVER_ISNT_AVAILABLE = 3168
+ER_SESSION_WAS_KILLED = 3169
+ER_CAPACITY_EXCEEDED = 3170
+ER_CAPACITY_EXCEEDED_IN_RANGE_OPTIMIZER = 3171
+ER_TABLE_NEEDS_UPG_PART = 3172
+ER_CANT_WAIT_FOR_EXECUTED_GTID_SET_WHILE_OWNING_A_GTID = 3173
+ER_CANNOT_ADD_FOREIGN_BASE_COL_VIRTUAL = 3174
+ER_CANNOT_CREATE_VIRTUAL_INDEX_CONSTRAINT = 3175
 CR_UNKNOWN_ERROR = 2000
 CR_SOCKET_CREATE_ERROR = 2001
 CR_CONNECTION_ERROR = 2002
diff --git a/lib/mysql/connector/locales/eng/client_error.py b/lib/mysql/connector/locales/eng/client_error.py
index de5ed30..d145a17 100644
--- a/lib/mysql/connector/locales/eng/client_error.py
+++ b/lib/mysql/connector/locales/eng/client_error.py
@@ -24,8 +24,8 @@
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 
 
 # This file was auto-generated.
-_GENERATED_ON = '2015-07-02'
-_MYSQL_VERSION = (5, 7, 7)
+_GENERATED_ON = '2015-12-13'
+_MYSQL_VERSION = (5, 7, 10)
 
 # Start MySQL Error messages
 CR_UNKNOWN_ERROR = u"Unknown MySQL error"
diff --git a/lib/mysql/connector/network.py b/lib/mysql/connector/network.py
index 31f3f8c..1ef55a3 100644
--- a/lib/mysql/connector/network.py
+++ b/lib/mysql/connector/network.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -79,6 +79,7 @@ class BaseMySQLSocket(object):
         self.sock = None  # holds the socket connection
         self._connection_timeout = None
         self._packet_number = -1
+        self._compressed_packet_number = -1
         self._packet_queue = deque()
         self.recvsize = 8192
 
@@ -90,6 +91,14 @@ class BaseMySQLSocket(object):
             self._packet_number = 0
         return self._packet_number
 
+    @property
+    def next_compressed_packet_number(self):
+        """Increments the compressed packet number"""
+        self._compressed_packet_number = self._compressed_packet_number + 1
+        if self._compressed_packet_number > 255:
+            self._compressed_packet_number = 0
+        return self._compressed_packet_number
+
     def open_connection(self):
         """Open the socket"""
         raise NotImplementedError
@@ -115,7 +124,8 @@ class BaseMySQLSocket(object):
         except (socket.error, AttributeError):
             pass
 
-    def send_plain(self, buf, packet_number=None):
+    def send_plain(self, buf, packet_number=None,
+                   compressed_packet_number=None):
         """Send packets to the MySQL server"""
         if packet_number is None:
             self.next_packet_number  # pylint: disable=W0104
@@ -136,12 +146,18 @@ class BaseMySQLSocket(object):
 
     send = send_plain
 
-    def send_compressed(self, buf, packet_number=None):
+    def send_compressed(self, buf, packet_number=None,
+                        compressed_packet_number=None):
         """Send compressed packets to the MySQL server"""
         if packet_number is None:
             self.next_packet_number  # pylint: disable=W0104
         else:
             self._packet_number = packet_number
+        if compressed_packet_number is None:
+            self.next_compressed_packet_number  # pylint: disable=W0104
+        else:
+            self._compressed_packet_number = compressed_packet_number
+
         pktnr = self._packet_number
         pllen = len(buf)
         zpkts = []
@@ -156,32 +172,31 @@ class BaseMySQLSocket(object):
             else:
                 tmpbuf = b''.join(pkts)
             del pkts
-            seqid = 0
             zbuf = zlib.compress(tmpbuf[:16384])
             header = (struct.pack('<I', len(zbuf))[0:3]
-                      + struct.pack('<B', seqid)
+                      + struct.pack('<B', self._compressed_packet_number)
                       + b'\x00\x40\x00')
             if PY2:
                 header = buffer(header)  # pylint: disable=E0602
             zpkts.append(header + zbuf)
             tmpbuf = tmpbuf[16384:]
             pllen = len(tmpbuf)
-            seqid = seqid + 1
+            self.next_compressed_packet_number
             while pllen > maxpktlen:
                 zbuf = zlib.compress(tmpbuf[:maxpktlen])
                 header = (struct.pack('<I', len(zbuf))[0:3]
-                          + struct.pack('<B', seqid)
+                          + struct.pack('<B', self._compressed_packet_number)
                           + b'\xff\xff\xff')
                 if PY2:
                     header = buffer(header)  # pylint: disable=E0602
                 zpkts.append(header + zbuf)
                 tmpbuf = tmpbuf[maxpktlen:]
                 pllen = len(tmpbuf)
-                seqid = seqid + 1
+                self.next_compressed_packet_number
             if tmpbuf:
                 zbuf = zlib.compress(tmpbuf)
                 header = (struct.pack('<I', len(zbuf))[0:3]
-                          + struct.pack('<B', seqid)
+                          + struct.pack('<B', self._compressed_packet_number)
                           + struct.pack('<I', pllen)[0:3])
                 if PY2:
                     header = buffer(header)  # pylint: disable=E0602
@@ -196,12 +211,12 @@ class BaseMySQLSocket(object):
             if pllen > 50:
                 zbuf = zlib.compress(pkt)
                 zpkts.append(struct.pack('<I', len(zbuf))[0:3]
-                             + struct.pack('<B', 0)
+                             + struct.pack('<B', self._compressed_packet_number)
                              + struct.pack('<I', pllen)[0:3]
                              + zbuf)
             else:
                 header = (struct.pack('<I', pllen)[0:3]
-                          + struct.pack('<B', 0)
+                          + struct.pack('<B', self._compressed_packet_number)
                           + struct.pack('<I', 0)[0:3])
                 if PY2:
                     header = buffer(header)  # pylint: disable=E0602
@@ -294,15 +309,22 @@ class BaseMySQLSocket(object):
     def _split_zipped_payload(self, packet_bunch):
         """Split compressed payload"""
         while packet_bunch:
-            payload_length = struct_unpack("<I",
-                                           packet_bunch[0:3] + b'\x00')[0]
+            if PY2:
+                payload_length = struct.unpack_from(
+                    "<I",
+                    packet_bunch[0:3] + b'\x00')[0]  # pylint: disable=E0602
+            else:
+                payload_length = struct.unpack("<I", packet_bunch[0:3] + b'\x00')[0]
+
             self._packet_queue.append(packet_bunch[0:payload_length + 4])
             packet_bunch = packet_bunch[payload_length + 4:]
 
     def recv_compressed(self):
         """Receive compressed packets from the MySQL server"""
         try:
-            return self._packet_queue.popleft()
+            pkt = self._packet_queue.popleft()
+            self._packet_number = pkt[3]
+            return pkt
         except IndexError:
             pass
 
@@ -316,9 +338,15 @@ class BaseMySQLSocket(object):
             while header:
                 if len(header) < 7:
                     raise errors.InterfaceError(errno=2013)
+
+                # Get length of compressed packet
                 zip_payload_length = struct_unpack("<I",
                                                    header[0:3] + b'\x00')[0]
+                self._compressed_packet_number = header[3]
+
+                # Get payload length before compression
                 payload_length = struct_unpack("<I", header[4:7] + b'\x00')[0]
+
                 zip_payload = init_bytearray(abyte)
                 while len(zip_payload) < zip_payload_length:
                     chunk = self.sock.recv(zip_payload_length
@@ -326,38 +354,47 @@ class BaseMySQLSocket(object):
                     if len(chunk) == 0:
                         raise errors.InterfaceError(errno=2013)
                     zip_payload = zip_payload + chunk
+
+                # Payload was not compressed
                 if payload_length == 0:
                     self._split_zipped_payload(zip_payload)
-                    return self._packet_queue.popleft()
-                packets.append(header + zip_payload)
-                if payload_length != 16384:
+                    pkt = self._packet_queue.popleft()
+                    self._packet_number = pkt[3]
+                    return pkt
+
+                packets.append((payload_length, zip_payload))
+
+                if zip_payload_length <= 16384:
+                    # We received the full compressed packet
                     break
+
+                # Get next compressed packet
                 header = init_bytearray(b'')
                 abyte = self.sock.recv(1)
                 while abyte and len(header) < 7:
                     header += abyte
                     abyte = self.sock.recv(1)
+
         except IOError as err:
             raise errors.OperationalError(
                 errno=2055, values=(self.get_address(), _strioerror(err)))
 
+        # Compressed packet can contain more than 1 MySQL packets
+        # We decompress and make one so we can split it up
         tmp = init_bytearray(b'')
-        for packet in packets:
-            payload_length = struct_unpack("<I", header[4:7] + b'\x00')[0]
-            if payload_length == 0:
-                tmp.append(packet[7:])
+        for payload_length, payload in packets:
+            # payload_length can not be 0; this was previously handled
+            if PY2:
+                tmp += zlib.decompress(buffer(payload))  # pylint: disable=E0602
             else:
-                if PY2:
-                    tmp += zlib.decompress(
-                        buffer(packet[7:]))  # pylint: disable=E0602
-                else:
-                    tmp += zlib.decompress(packet[7:])
-
+                tmp += zlib.decompress(payload)
         self._split_zipped_payload(tmp)
         del tmp
 
         try:
-            return self._packet_queue.popleft()
+            pkt = self._packet_queue.popleft()
+            self._packet_number = pkt[3]
+            return pkt
         except IndexError:
             pass
 
@@ -366,7 +403,7 @@ class BaseMySQLSocket(object):
         self._connection_timeout = timeout
 
     # pylint: disable=C0103
-    def switch_to_ssl(self, ca, cert, key, verify_cert=False):
+    def switch_to_ssl(self, ca, cert, key, verify_cert=False, cipher=None):
         """Switch the socket to use SSL"""
         if not self.sock:
             raise errors.InterfaceError(errno=2048)
@@ -380,7 +417,7 @@ class BaseMySQLSocket(object):
             self.sock = ssl.wrap_socket(
                 self.sock, keyfile=key, certfile=cert, ca_certs=ca,
                 cert_reqs=cert_reqs, do_handshake_on_connect=False,
-                ssl_version=ssl.PROTOCOL_TLSv1)
+                ssl_version=ssl.PROTOCOL_TLSv1, ciphers=cipher)
             self.sock.do_handshake()
         except NameError:
             raise errors.NotSupportedError(
diff --git a/lib/mysql/connector/optionfiles.py b/lib/mysql/connector/optionfiles.py
index 4334481..d4e9c58 100644
--- a/lib/mysql/connector/optionfiles.py
+++ b/lib/mysql/connector/optionfiles.py
@@ -286,19 +286,19 @@ class MySQLOptionsParser(SafeConfigParser):  # pylint: disable=R0901
             args = self._options_dict.keys()
 
         options = {}
+        priority = {}
         for group in args:
             try:
-                for option, value in self._options_dict[group].items():
-                    if option not in options or options[option][1] <= value[1]:
-                        options[option] = value
+                for option, value in [(key, value,) for key, value in
+                                      self._options_dict[group].items() if
+                                      key != "__name__" and
+                                      not key.startswith("!")]:
+                    if option not in options or priority[option] <= value[1]:
+                        priority[option] = value[1]
+                        options[option] = value[0]
             except KeyError:
                 pass
 
-        for key in options.keys():
-            if key == '__name__' or key.startswith('!'):
-                del options[key]
-            else:
-                options[key] = options[key][0]
         return options
 
     def get_groups_as_dict_with_priority(self, *args): # pylint: disable=C0103
@@ -321,14 +321,13 @@ class MySQLOptionsParser(SafeConfigParser):  # pylint: disable=R0901
         options = dict()
         for group in args:
             try:
-                options[group] = dict(self._options_dict[group])
+                options[group] = dict((key, value,) for key, value in
+                                      self._options_dict[group].items() if
+                                      key != "__name__" and
+                                      not key.startswith("!"))
             except KeyError:
                 pass
 
-        for group in options.keys():
-            for key in options[group].keys():
-                if key == '__name__' or key.startswith('!'):
-                    del options[group][key]
         return options
 
     def get_groups_as_dict(self, *args):
@@ -347,14 +346,11 @@ class MySQLOptionsParser(SafeConfigParser):  # pylint: disable=R0901
         options = dict()
         for group in args:
             try:
-                options[group] = dict(self._options_dict[group])
+                options[group] = dict((key, value[0],) for key, value in
+                                      self._options_dict[group].items() if
+                                      key != "__name__" and
+                                      not key.startswith("!"))
             except KeyError:
                 pass
 
-        for group in options.keys():
-            for key in options[group].keys():
-                if key == '__name__' or key.startswith('!'):
-                    del options[group][key]
-                else:
-                    options[group][key] = options[group][key][0]
         return options
diff --git a/lib/mysql/connector/protocol.py b/lib/mysql/connector/protocol.py
index d61bc48..6c75a0a 100644
--- a/lib/mysql/connector/protocol.py
+++ b/lib/mysql/connector/protocol.py
@@ -1,5 +1,5 @@
 # MySQL Connector/Python - MySQL driver written in Python.
-# Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
 
 # MySQL Connector/Python is licensed under the terms of the GPLv2
 # <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -206,14 +206,14 @@ class MySQLProtocol(object):
     def parse_ok(self, packet):
         """Parse a MySQL OK-packet"""
         if not packet[4] == 0:
-            raise errors.InterfaceError("Failed parsing OK packet.")
+            raise errors.InterfaceError("Failed parsing OK packet (invalid).")
 
         ok_packet = {}
         try:
             ok_packet['field_count'] = struct_unpack('<xxxxB', packet[0:5])[0]
             (packet, ok_packet['affected_rows']) = utils.read_lc_int(packet[5:])
             (packet, ok_packet['insert_id']) = utils.read_lc_int(packet)
-            (ok_packet['server_status'],
+            (ok_packet['status_flag'],
              ok_packet['warning_count']) = struct_unpack('<HH', packet[0:4])
             packet = packet[4:]
             if packet:
@@ -227,8 +227,6 @@ class MySQLProtocol(object):
         """Parse a MySQL packet with the number of columns in result set"""
         try:
             count = utils.read_lc_int(packet[4:])[1]
-            if count > MAX_MYSQL_TABLE_COLUMNS:
-                return None
             return count
         except (struct.error, ValueError):
             raise errors.InterfaceError("Failed parsing column count")
@@ -261,6 +259,10 @@ class MySQLProtocol(object):
 
     def parse_eof(self, packet):
         """Parse a MySQL EOF-packet"""
+        if packet[4] == 0:
+            # EOF packet deprecation
+            return self.parse_ok(packet)
+
         err_msg = "Failed parsing EOF packet."
         res = {}
         try:
@@ -302,7 +304,7 @@ class MySQLProtocol(object):
                         "{0} ({1}:{2}).".format(errmsg, lbl, val))
         return res
 
-    def read_text_result(self, sock, count=1):
+    def read_text_result(self, sock, version, count=1):
         """Read MySQL text result
 
         Reads all or given number of rows from the socket.
@@ -315,9 +317,7 @@ class MySQLProtocol(object):
         rowdata = None
         i = 0
         while True:
-            if eof is not None:
-                break
... 57941 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/mysql-connector-python.git



More information about the Python-modules-commits mailing list