This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: plist handling of real data type
Type: behavior Stage: resolved
Components: Versions: Python 3.8
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: David Nicolson, ned.deily, ronaldoussoren, serhiy.storchaka
Priority: normal Keywords:

Created on 2019-11-12 11:08 by David Nicolson, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (4)
msg356440 - (view) Author: David Nicolson (David Nicolson) Date: 2019-11-12 11:08
Converting float values stored as strings with the real data type can result in an integer value or a rounding error.

import plistlib

xml = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>FloatExample</key>
<real>100.0</real>
<key>FloatExample2</key>
<real>0.1</real>
</dict>
</plist>
"""

pl = plistlib.loads(str.encode(xml), fmt=plistlib.FMT_XML)
with open('test.plist', 'wb') as fp:
  plistlib.dump(pl, fp, fmt=plistlib.FMT_BINARY)

cat test.plist | plutil -convert xml1 -o - -- -
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>FloatExample</key>
	<real>100</real>
	<key>FloatExample2</key>
	<real>0.10000000000000001</real>
</dict>
</plist>

This might be related to the following issue:

https://bugs.python.org/issue14896
msg356443 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2019-11-12 11:26
This looks like a plutil issue.
msg356468 - (view) Author: Ronald Oussoren (ronaldoussoren) * (Python committer) Date: 2019-11-12 15:05
I don't think this is a bug. The value's in the plutil output are correct, and marked up with the correct type in both cases. 

The difference between 0.1 and 0.10000000000000001 is the usual problem with floating point representation (see the python.org FAQ).  Plutil uses a different algorithm for printing float's than Python, but both evaluate to the same binary representation for the float value.
msg356474 - (view) Author: David Nicolson (David Nicolson) Date: 2019-11-12 17:01
It looks like it's just inconsistency in plutil that is causing the confusion.

/usr/libexec/PlistBuddy -c Print test.plist
Dict {
    FloatExample2 = 0.100000
    FloatExample3 = 100.000000
    FloatExample = 0.000000
}

cat test.plist | plutil -convert xml1 -o - -- -
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>FloatExample</key>
	<real>0.0</real>
	<key>FloatExample2</key>
	<real>0.10000000000000001</real>
	<key>FloatExample3</key>
	<real>100</real>
</dict>
</plist>
History
Date User Action Args
2022-04-11 14:59:23adminsetgithub: 82958
2019-11-12 17:01:34David Nicolsonsetstatus: open -> closed
resolution: not a bug
messages: + msg356474

stage: resolved
2019-11-12 15:05:56ronaldoussorensetmessages: + msg356468
2019-11-12 11:26:46serhiy.storchakasetnosy: + serhiy.storchaka, ronaldoussoren
messages: + msg356443
2019-11-12 11:22:24xtreaksetnosy: + ned.deily
2019-11-12 11:08:52David Nicolsoncreate