djangodjango-haystackwhoosh

Haystack/Whoosh convert string to bytes-like object? "Cannot use a string pattern on a bytes-like object" error


On my Django (2.2.7, Python 3.7) project, I use Haystack(2.8.1) and Whoosh(2.7.4) for fulltext search.

When searching, I always get Cannot use a string pattern on a bytes-like object error.

I know, in general, why this error happens, but I don't know hot to avoid it. I pass a proper string keyword to haystack/whoosh functions, but it gets probably converted to bytes-like object somewhere inside the above libraries.

E.g. I give it a string somestring, but it becomes b'somestring' in the file "/usr/local/lib/python3.7/site-packages/haystack/inputs.py" in self.exact_match_re.findall(query_string) function.

Local vars at that moment:

__class__   
<class 'haystack.inputs.AutoQuery'>
query_obj   
<haystack.backends.whoosh_backend.WhooshSearchQuery object at 0x7fea4c19c550>
query_string    
b'somestring'
self    
<AutoQuery 'somestring'>

The whole stack trace:

ERROR 2019-11-23 01:17:51,136 middlewares 5013 140644284933888 http://www.my_project.loc/hledat?q=ATIKA&x=3&y=16
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python3.7/site-packages/haystack/views.py", line 51, in __call__
    return self.create_response()
  File "/my_project/search/views.py", line 57, in create_response
    for item in self.results:
  File "/usr/local/lib/python3.7/site-packages/haystack/query.py", line 154, in _manual_iter
    if not self._fill_cache(current_position, current_position + ITERATOR_LOAD_PER_QUERY):
  File "/usr/local/lib/python3.7/site-packages/haystack/query.py", line 231, in _fill_cache
    results = self.query.get_results(**kwargs)
  File "/usr/local/lib/python3.7/site-packages/haystack/backends/__init__.py", line 638, in get_results
    self.run(**kwargs)
  File "/usr/local/lib/python3.7/site-packages/haystack/backends/__init__.py", line 550, in run
    final_query = self.build_query()
  File "/usr/local/lib/python3.7/site-packages/haystack/backends/__init__.py", line 693, in build_query
    final_query = self.query_filter.as_query_string(self.build_query_fragment)
  File "/usr/local/lib/python3.7/site-packages/haystack/backends/__init__.py", line 381, in as_query_string
    result.append(query_fragment_callback(field, filter_type, value))
  File "/usr/local/lib/python3.7/site-packages/haystack/backends/whoosh_backend.py", line 801, in build_query_fragment
    prepared_value = value.prepare(self)
  File "/usr/local/lib/python3.7/site-packages/haystack/inputs.py", line 105, in prepare
    exacts = self.exact_match_re.findall(query_string)
TypeError: cannot use a string pattern on a bytes-like object

Thank you.


Solution

  • Ok, found it!

    I was using my own class to customize a Search query set (searchqueryset=MyClass).

    Purpose of the class is to remove accents from query strings. There were a function:

    textutil.strip_accents(query_string)

    inside the class, that always returned a byte like object.

    I added a decoding to fix the problem:

    textutil.strip_accents(query_string).decode('utf-8')
    

    Thank you.