Description:
If your password includes a @, it is not possible to create a session using the X DevAPI (mysqlx) with an URI. Attempting to connect causes an error for invalid user or password:
mysqlx.errors.InterfaceError: Invalid user or password
The issue is that the @ character is used to split the user info from the rest of the URI. However, there is no way to encode @ as Connector/Python does not decode the values retrieved from the URI before adding them to the settings dictionary.
Other restrictions that apply:
* The username can't have a : or @
* The hostname, socket, port, and schema can't have a ?
* The hostname, socket, and port can't have a /
These are less likely to be an issue though.
How to repeat:
See the _parse_connection_uri() function in __init__ for mysqlx:
userinfo, temp = temp.partition("@")[::2]
...
settings["user"], settings["password"] = userinfo.split(":", 1)
It can also be demonstrated with a simple test:
import mysqlx
uri = "mysqlx://{0}:{1}@{2}:{3}/{4}".format(
'pyuser',
'Py@pp4Demo',
'127.0.0.1',
33060,
'world_x'
)
print("URI: {0}".format(uri))
db = mysqlx.get_session(uri)
This prints the URI:
mysqlx://pyuser:Py@pp4Demo@127.0.0.1:33060/world_x
Or alternatively try to percent encode the password (as per http://dev.mysql.com/doc/refman/8.0/en/mysql-shell-connection-using-uri.html ):
import mysqlx
import urllib
uri = "mysqlx://{0}:{1}@{2}:{3}/{4}".format(
'pyuser',
urllib.parse.quote('Py@pp4Demo', safe=''),
'127.0.0.1',
33060,
'world_x'
)
print("URI: {0}".format(uri))
db = mysqlx.get_session(uri)
This prints the URI:
mysqlx://pyuser:Py%40pp4Demo@127.0.0.1:33060/world_x
This URI works with MySQL Shell and would also be what I expect to work in MySQL Connector/Python.
Suggested fix:
Support encoding of the parameters in the URI.