FYI for those people upgrading from earlier versions (v13 and earlier).
Scenario
- You have a DocField with a datatype of either
'Date'
or'DateTime'
. - One of your documents has a value for this DocField that is blank/empty/null.
Earlier Versions of Frappe Framework:
some_date = frappe.db.get_single_value("MyDocType", "my_docfield")
The value of ‘some_date’ is a Python 'None'
(NoneType)
Newer Versions of Frappe
(Version 15 definitely, perhaps 14 too. It’s hard to tell because of all the backporting that happens)
some_date = frappe.db.get_single_value("MyDocType", "my_docfield")
The value of ‘result’ is a Python Date type , with a value of 0001-01-01
(January 1st 1900)
Problems:
Consider the following code.
if not some_date: # if the value is null ...
do_stuff()
This code block will execute in V13. But it will not execute in V15.
This is because a Python Date 0001-01-01
will not coerce to a boolean False.
- This Framework behavior is very surprising (which is why I’m writing my 10th forum topic)
- It’s very non-Pythonic and wrong, imo.
Python has a standard 'NoneType'
for a reason: to help developers deal with the concept of ‘null’. Substituting the value “January 1st 1900” was always a workaround we made in previous decades, when we worked on older software that lacked proper typing for dates. January 1st 1900 is a legitimate date in history: it’s not a substitute for empty / blank / none / null / N/A, etc.
Anyhow, if this surprises anyone, I suggest you audit your custom code for any if not datefield:
kind of evaluations.
(when I’m finished with my upgrade, I may to try reverting the Frappe code back to the old None
behavior. see what breaks. and try to fix it. if I’m successful, I’ll shared my forked code.)