Repository navigation
Closed
Labels
Description
Info:
Linux 4.15.0-24-generic #26-Ubuntu SMP Wed Jun 13 08:44:47 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
Python 3.7.0b3
>>> import dateparser
>>> dateparser.__version__
'0.7.0'
Code to reproduce error:
import dateparser
from concurrent.futures.thread import ThreadPoolExecutor
fs = []
with ThreadPoolExecutor(16) as executor:
for _ in range(100):
fs.append(executor.submit(lambda: dateparser.parse('tomorrow')))
for f in fs:
print(f.result())
Error:
Traceback (most recent call last):
File "test.py", line 10, in <module>
print(f.result())
File "/usr/lib/python3.7/concurrent/futures/_base.py", line 425, in result
return self.__get_result()
File "/usr/lib/python3.7/concurrent/futures/_base.py", line 384, in __get_result
raise self._exception
File "/usr/lib/python3.7/concurrent/futures/thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "test.py", line 7, in <lambda>
fs.append(executor.submit(lambda: dateparser.parse('tomorrow')))
File "/home/egor/Projects/rekko/.env/lib/python3.7/site-packages/dateparser/conf.py", line 81, in wrapper
return f(*args, **kwargs)
File "/home/egor/Projects/rekko/.env/lib/python3.7/site-packages/dateparser/__init__.py", line 53, in parse
data = parser.get_date_data(date_string, date_formats)
File "/home/egor/Projects/rekko/.env/lib/python3.7/site-packages/dateparser/date.py", line 404, in get_date_data
locale, date_string, date_formats, settings=self._settings)
File "/home/egor/Projects/rekko/.env/lib/python3.7/site-packages/dateparser/date.py", line 177, in parse
return instance._parse()
File "/home/egor/Projects/rekko/.env/lib/python3.7/site-packages/dateparser/date.py", line 187, in _parse
date_obj = parser()
File "/home/egor/Projects/rekko/.env/lib/python3.7/site-packages/dateparser/date.py", line 200, in _try_freshness_parser
return freshness_date_parser.get_date_data(self._get_translated_date(), self._settings)
File "/home/egor/Projects/rekko/.env/lib/python3.7/site-packages/dateparser/freshness_date_parser.py", line 147, in get_date_data
date, period = self.parse(date_string, settings)
File "/home/egor/Projects/rekko/.env/lib/python3.7/site-packages/dateparser/freshness_date_parser.py", line 96, in parse
date, period = self._parse_date(date_string)
File "/home/egor/Projects/rekko/.env/lib/python3.7/site-packages/dateparser/freshness_date_parser.py", line 130, in _parse_date
date = self.now + td
Reacted by Nur Lan, thomasO, Stepan and Andrey Gusev
Activity
lopuhin commentedon Aug 7, 2018
Good catch! FWIW the exception message is
TypeError: unsupported operand type(s) for +: 'NoneType' and 'relativedelta'wRAR commentedon Sep 19, 2018
This particular test detects only one concurrency problem, so I cannot be sure there is none else. Still, this one is pretty clear.
dateparser.freshness_date_parser.freshness_date_parseris a singleton with internal state and it is used concurrently in_DateLocaleParser._try_freshness_parser()in different threads. The shared state isFreshnessDateDataParser.now, read in_parse_date()and written inparse(), and putting it intothreading.local()fixes this particular problem and allows the test to pass (I'm not saying this is a correct solution though).Actually, I don't understand why this var is needed as it's used only once, right after its setting (though in a separate private method), and cleared after that. It's also not documented as a public attribute. The git history shows a lot of changes to the handling of this var but the current code seems strange to me.
I've also noticed there is a lock in pytz acquired inside
FreshnessDateDataParser.get_local_tz().bzamecnik commentedon Oct 17, 2018
Another error possibly caused by thread non-safety:
The app was running in Flask in uwsgi with 8 threads.
bzamecnik commentedon Oct 17, 2018
Possibly we could change
dateparser._default_parserfrom a plain module variable to a thread-local variable.Gallaecio commentedon Dec 12, 2019
Related to #276
mprzydatek commentedon Apr 23, 2020
Is this going to get fixed?
sheikware commentedon Jun 24, 2020
There are other concurrency issues when multi-threading and having some invalid datetime strings. This causes
Expected output (which you can get if you thread lock the call):
Error output:
nex2hex commentedon Jul 2, 2020
not yet, just replace
dateparser.parse()call with custom functionzegerius commentedon Jul 11, 2020
@nex2hex I tried using the custom function, but had the same issues as before (
TypeError: unsupported operand type(s) for +: 'NoneType' and 'relativedelta'). I resorted to storing the records in Redis and processing them serially.doctaphred commentedon Feb 15, 2021
To expand on the above reports, the concurrency issues don't just cause exceptions, they cause wrong results:
Looks like this behavior is already being fixed and verified by
TestConcurrencyin #834, but FYI to future confused devs attempting to diagnose data errors.