BEntos
BEntos

Reputation: 31

An import error when using Py2app

I'm using py2app to pack up my python script as an .app document on mac but find an import error:

Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.7/bin/py2applet", line 7, in <module>
from py2app.script_py2applet import main
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/py2app/script_py2applet.py", line 13, in <module>
from plistlib import Plist
ImportError: cannot import name 'Plist' from 'plistlib' (/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/plistlib.py)

And I am try to search this kind of error through google found out no one has ask the same question as mine. Is there any error with my own setting?

Upvotes: 3

Views: 3357

Answers (1)

user669132
user669132

Reputation: 199

This is a temporary fix until the new update is released, some time later this month.

Find path to the py2app directory as you will need to change some lines of code in a few files in this directory.

If you have terminal you can find the directory with:

find ~/ -type f -name “*py2app*”

FILE 1

py2app/build_app.py (line 614)

Replace:

if isinstance(self.plist, plistlib.Dict):

    self.plist = dict(self.plist.__dict__)

else:

  self.plist = dict(self.plist)

With the following:

if not isinstance(self.plist, dict):

    self.plist = dict(self.plist)

FILE 2

py2app/create_appbundle.py (line 26)

Replace:

dirs = [contents, resources, platdir]

plist = plistlib.Plist()

plist.update(kw)

plistPath = os.path.join(contents, 'Info.plist')

if os.path.exists(plistPath):

    if plist != plistlib.Plist.fromFile(plistPath):

        for d in dirs:

            shutil.rmtree(d, ignore_errors=True)

for d in dirs:

    makedirs(d)

plist.write(plistPath)

With the following:

dirs = [contents, resources, platdir]

plistPath = os.path.join(contents, 'Info.plist')

if os.path.exists(plistPath):

    for d in dirs:

        shutil.rmtree(d, ignore_errors=True)

for d in dirs:

    makedirs(d)

plistlib.writePlist(kw, plistPath)

FILE 3

py2app/script_py2applet.py (line 13)

Replace:

from plistlib import Plist

With the following:

import plistlib

Also, replace (line 115)

plist = Plist.fromFile(fn)

With the following:

plist = plistlib.fromFile(fn)

Then you can finally create the setup.py file in your app directory with:

py2applet --make-setup my_project.py

And build the standalone app with:

python setup.py py2app -A

Contribution to this guy for most of the code above.

The reason for this issue is due to Plist being depreciated in python3.7. See python docs

Upvotes: 6

Related Questions