Q:

paho.mqtt + python TypeError: a bytes-like object is required, not 'str'

Two paho.mqtt clients (client1 and client2) are created in Python, which connects to mosquitto brokers. Two clients subscribe to different topics. client1 runs loop_forever(), and client2 runs loop_start(). client1's on_message() callback stores the message in MySQL database. client2's on_message() callback runs a simple test.
The test contains a test method which uses mock object paho.mqtt.client.MQTTMessage. For client2, I am publishing the message from mosquitto_pub in a command line. when I receive the message to run the test, the test runs successfully. But after that I get this below error message. when I comment the test method which uses this mock object paho.mqtt.client.MQTTMessage for test, I don't get this error message.
Is this error coming from Python or paho.mqtt? or is it from client1.loop_forever() method?
File "/usr/local/lib/python3.6/site-packages/paho_mqtt-1.3.1-py3.6.egg/paho/mqtt/client.py", line 1481, in loop_forever
rc = self.loop(timeout, max_packets)
File "/usr/local/lib/python3.6/site-packages/paho_mqtt-1.3.1-py3.6.egg/paho/mqtt/client.py", line 1003, in loop
rc = self.loop_read(max_packets)
File "/usr/local/lib/python3.6/site-packages/paho_mqtt-1.3.1-py3.6.egg/paho/mqtt/client.py", line 1284, in loop_read
rc = self._packet_read()
File "/usr/local/lib/python3.6/site-packages/paho_mqtt-1.3.1-py3.6.egg/paho/mqtt/client.py", line 1849, in _packet_read
rc = self._packet_handle()
File "/usr/local/lib/python3.6/site-packages/paho_mqtt-1.3.1-py3.6.egg/paho/mqtt/client.py", line 2305, in _packet_handle
return self._handle_publish()
File "/usr/local/lib/python3.6/site-packages/paho_mqtt-1.3.1-py3.6.egg/paho/mqtt/client.py", line 2500, in _handle_publish
self._handle_on_message(message)
File "/usr/local/lib/python3.6/site-packages/paho_mqtt-1.3.1-py3.6.egg/paho/mqtt/client.py", line 2640, in _handle_on_message
for callback in self._on_message_filtered.iter_match(message.topic):
File "/usr/local/lib/python3.6/site-packages/paho_mqtt-1.3.1-py3.6.egg/paho/mqtt/matcher.py", line 60, in iter_match
lst = topic.split('/')
TypeError: a bytes-like object is required, not 'str'

A:

As mentioned in the paho documentation, your topic must be of type bytes:
class MQTTMessage(object):
""" This is a class that describes an incoming or outgoing message. It is
passed to the on_message callback as the message parameter.

Members:

topic : String/bytes. topic that the message was published on.
payload : String/bytes the message payload.
qos : Integer. The message Quality of Service 0, 1 or 2.
retain : Boolean. If true, the message is a retained message and not fresh.
mid : Integer. The message id.

On Python 3, topic must be bytes.
"""

__slots__ = 'timestamp', 'state', 'dup', 'mid', '_topic', 'payload', 'qos', 'retain', 'info'

def __init__(self, mid=0, topic=b""):
    self.timestamp = 0
    self.state = mqtt_ms_invalid
    self.dup = False
    self.mid = mid
    self._topic = topic
    self.payload = b""
    self.qos = 0
    self.retain = False
    self.info = MQTTMessageInfo(mid)

def __eq__(self, other):
    """Override the default Equals behavior"""
    if isinstance(other, self.__class__):
        return self.mid == other.mid
    return False

def __ne__(self, other):
    """Define a non-equality test"""
    return not self.__eq__(other)

@property
def topic(self):
    if sys.version_info[0] >= 3:
        return self._topic.decode('utf-8')
    else:
        return self._topic

@topic.setter
def topic(self, value):
    self._topic = value

-> On Python 3, topic must be bytes. 
So ensure that your topic is a bytes object, then it should work
BTW, here a short example for string and byte converting:
mystring = 'hello_string'
b1 = bytes(mystring, 'utf-8')
b2 = str(b1, 'utf-8')
print(b1)
print(b2)

output is:
b'hello_string'
hello_string

