[AttributeError: 'array.array' object has no attribute 'fromstring'] When using setup.py

Hello,

I am trying to compile main.py into an executable program, but setup.py would throw out this odd error to me:

AttributeError: ‘array.array’ object has no attribute ‘fromstring’

I have two additional files besides main.py and its resource folder, requirements.txt and setup.py. For requirements.txt, it simply has the name panda3d on it. While for setup.py:

from setuptools import setup

setup(
    name = "Panda3D Another Works",
    options = {
        "build_apps" : {
            "include_patterns" : [
                "**/*.png",
                "**/*.mp3",
                "**/*.egg",
                "resources/*"
            ],
            "gui_apps" : {
                "Panda3D Another Works" : "main.py"
            },
            "plugins" : [
                "pandagl",
                "p3openal_audio"
            ],
            "platforms" : [
                "win_amd64"
            ]
        }
    }
)

I do not understand what I have done wrong. Here its log when attempting to compile it through CMD:

D:\Personal\Programming\Python\Panda3D\Panda3DAnotherWorks>python setup.py bdist_apps
running bdist_apps
running build_apps
Building platforms: win_amd64
Gathering wheels for platform: win_amd64
Looking in indexes: Simple index, Simple Index, Simple Index
Collecting panda3d
File was already downloaded d:\personal\programming\python\panda3d\panda3danotherworks\build_whl_cache_\win_amd64_cp39\panda3d-1.10.7+opt-cp39-cp39-win_amd64.whl
Successfully downloaded panda3d
Building runtime for platform: win_amd64
There are some missing modules: [‘builtin’, 'posixsubprocess’, ‘grp’, ‘pep517’, ‘zipimport’]
Traceback (most recent call last):
File “D:\Personal\Programming\Python\Panda3D\Panda3DAnotherWorks\setup.py”, line 3, in
setup(
File "D:\Programs\Python39\lib\site-packages\setuptools_init
.py", line 165, in setup
return distutils.core.setup(**attrs)
File “D:\Programs\Python39\lib\distutils\core.py”, line 148, in setup
dist.run_commands()
File “D:\Programs\Python39\lib\distutils\dist.py”, line 966, in run_commands
self.run_command(cmd)
File “D:\Programs\Python39\lib\distutils\dist.py”, line 985, in run_command
cmd_obj.run()
File “D:\Programs\Panda3D-1.10.7-x64\direct\dist\commands.py”, line 1474, in run
self.run_command(‘build_apps’)
File “D:\Programs\Python39\lib\distutils\cmd.py”, line 313, in run_command
self.distribution.run_command(command)
File “D:\Programs\Python39\lib\distutils\dist.py”, line 985, in run_command
cmd_obj.run()
File “D:\Programs\Panda3D-1.10.7-x64\direct\dist\commands.py”, line 398, in run
self.build_runtimes(platform, True)
File “D:\Programs\Panda3D-1.10.7-x64\direct\dist\commands.py”, line 772, in build_runtimes
create_runtime(appname, scriptname, False)
File “D:\Programs\Panda3D-1.10.7-x64\direct\dist\commands.py”, line 759, in create_runtime
self.copy_dependencies(target_path, builddir, search_path, stub_name)
File “D:\Programs\Panda3D-1.10.7-x64\direct\dist\commands.py”, line 1127, in copy_dependencies
self.add_dependency(dep, target_dir, search_path, referenced_by)
File “D:\Programs\Panda3D-1.10.7-x64\direct\dist\commands.py”, line 1021, in add_dependency
self.copy_with_dependencies(source_path, target_path, search_path)
File “D:\Programs\Panda3D-1.10.7-x64\direct\dist\commands.py”, line 1086, in copy_with_dependencies
self.copy_dependencies(target_path, target_dir, search_path, base)
File “D:\Programs\Panda3D-1.10.7-x64\direct\dist\commands.py”, line 1099, in copy_dependencies
pe.read(fp)
File “D:\Programs\Panda3D-1.10.7-x64\direct\dist\pefile.py”, line 602, in read
self.resources.unpack_from(self.vmem, self.res_rva.addr)
File “D:\Programs\Panda3D-1.10.7-x64\direct\dist\pefile.py”, line 468, in unpack_from
entry.unpack_from(mem, addr, data & 0x7fffffff)
File “D:\Programs\Panda3D-1.10.7-x64\direct\dist\pefile.py”, line 468, in unpack_from
entry.unpack_from(mem, addr, data & 0x7fffffff)
File “D:\Programs\Panda3D-1.10.7-x64\direct\dist\pefile.py”, line 470, in unpack_from
entry = self._unpack_data_entry(mem, addr + data, ident=self._ident+(id,))
File “D:\Programs\Panda3D-1.10.7-x64\direct\dist\pefile.py”, line 484, in _unpack_data_entry
entry.unpack_from(data)
File “D:\Programs\Panda3D-1.10.7-x64\direct\dist\pefile.py”, line 249, in unpack_from
dwords.fromstring(bytes(data[40:offset]))
AttributeError: ‘array.array’ object has no attribute ‘fromstring’

It looks like Python 3.9 removed fromstring(). You could manually fix the file in question or try Python 3.8.

We need to fix this in the next version of Panda3D.

I can confirm that by replacing fromstring to frombytes does fix the issue for Python 3.9.0. there. Of course, this also works for 3.8 (I am using 3.8.3 on Anaconda since 3.8.7’s installation is acting funny to me).

At this point, two different error appears, depending on what Python version is it being used.

For Python 3.8.3:

warning: build_apps: could not find dependency CRYPT32.dll (referenced by _ssl.pyd)

This also appears if the platform is being compiled to manylinux1_x86_64.

For Python 3.9.0:

warning: build_apps: could not find dependency api-ms-win-core-path-l1-1-0.dll (referenced by python39.dll)

Those are warnings. You can ignore them.

Does the resulting binary work?

Strangely enough, it will only work if it has a log_filename in setup.py. Without that, it will simply outright refuse to start when running the executable without any messages, even on CMD.

One could say that my question is fixed, and that would be true. But I want to know two things:

  1. If I had to assume the cause of fromstring() in pefile.py is being there without saying it was overlooked, I would say that it was possibly still there for backwards compatibility.
  2. Is there a way to omnit the log_filename without, for example, using CMD?
  1. Yes, Panda 1.10 still supports Python 2.7, and therefore it uses fromstring, which worked until Python 3.9.

  2. That’s strange. It sounds like a bug. Unfortunately it’s a bit of a catch-22 situation since it’s hard to figure out what’s going wrong without a log file. You could try using console_apps instead of gui_apps which will force output to be on the command-prompt.