0

I've cloned a Python project I was working on on MacOS to a new Ubuntu (virtual) machine.

I've managed to get it to run, but the program crashes at the following line:

ujson.dumps(plist_as_file) # crash

The error is:

TypeError: � is not JSON serializable

I have no idea which character that is, nor where it's found. The plist_as_file is a mac *.plist file, opened with this line:

with open(plist_path, 'rb') as plist_as_file:

It might be that git messed something up, but since both MacOS and Ubuntu are Unix based, I don't really see how.

Any ideas?

Gino Mempin
  • 25,369
  • 29
  • 96
  • 135
Karlovsky120
  • 6,212
  • 8
  • 41
  • 94
  • 1
    What do you mean by it works on MacOS? You mean it can read the .plist file as JSON? The problem here is that plist files are like XML rather than JSON, so ujson is not the appropriate tool here. I'm doubting that what you have is an actual plist format. I think it's better to use something like Python's built-in [plistlib](https://docs.python.org/dev/library/plistlib.html#module-plistlib). – Gino Mempin Mar 20 '20 at 06:40

2 Answers2

0

I don't think that code will work on both MacOS or on Ubuntu, because Apple's macOS and iOS .plist files are not JSON. They follow more of an XML format, and they even say this in the docs:

The file itself is typically encoded using the Unicode UTF-8 encoding and the contents are structured using XML.

Running your code on a Mac or on Ubuntu:

import ujson

with open("Info.plist", 'r') as plist_as_file:
    ujson.dumps(plist_as_file)

will result in:

Traceback (most recent call last):
  File "test.py", line 4, in <module>
    ujson.dumps(plist_as_file)
TypeError: <_io.BufferedReader name='Info.plist'> is not JSON serializable

If, for some reason, you can successfully open the .plist and you don't get that error, then what you have isn't an actual .plist file. The error is same whether the file open mode is r or rb.

You said you got:

TypeError: � is not JSON serializable

and I think that's the same error, but for some reason, it's not printing out correctly. So, ujson is really not the appropriate tool to use here, and it's not a problem with Git.

Python offers a built-in module for reading/writing .plist files: plistlib.

It has the same dump/dumps and load/loads methods as the json (or the ujson) module.

import plistlib

with open("Info.plist", 'rb') as plist_as_file:
    plist_data = plistlib.load(plist_as_file)

# The entire contents is stored as a dict
print(plist_data)

# Access specific content as a dict
print(plist_data["CFBundleShortVersionString"])
print(plist_data["UIMainStoryboardFile"])
Gino Mempin
  • 25,369
  • 29
  • 96
  • 135
  • You have missed the point completely, but it's not your fault, I left out some details out of my explanation. Plistlib is significantly slower than ujson. I was using ujson to quickly read the file and generate a unique identifier with xxhash. This was then further used for caching the result of plistlib load operation. – Karlovsky120 Mar 22 '20 at 15:14
  • Now that I've written it out loud, I don't know why I'm even using ujson, I could just feed the raw list of strings to xxhash. I'll have to reconsider it. – Karlovsky120 Mar 22 '20 at 15:15
0

It turns out that ujson version on MacOS was 1.35, while the one on Linux was 2.0.1. The module was changed for whatever reason and the version 2.0.1 no longer supports serialization of that type.

However, if I write:

ujson.dumps(plist_as_file.readlines())

it works. Since I only need it as an unique identifier, I can use this instead.

Karlovsky120
  • 6,212
  • 8
  • 41
  • 94