Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Python 3.10 support #5693

Closed
ickk opened this issue Apr 2, 2021 · 22 comments · Fixed by #5694
Closed

feat: Python 3.10 support #5693

ickk opened this issue Apr 2, 2021 · 22 comments · Fixed by #5694
Labels
bug feature Feature request

Comments

@ickk
Copy link

ickk commented Apr 2, 2021

Python 3.10 is coming. The new match,case stuff is particularly exciting to a developer coming from Rust or Haskell.

PyInstaller is a great tool for the developer when she wants to distribute a software application to the end-user without requiring the end-user to have any particular version of python installed. This is can simplify the developer's maintenance efforts - rather than trying to keep her software compatible across multiple versions of Python - and can allow her to take advantage of newer language features, like those found in the newest version of Python.

It would be a great addition for PyInstaller to add support for Python 3.10.

What I have tried:
I have tried, naively, to run PyInstaller against python 3.10.0a6 but immediately ran into at least one issue:

  • _bootlocale has been removed in cPython 3.10 and has been replaced with a new _locale._get_locale_encoding()
    excluding _bootlocale from PY3_BASE_MODULES for python 3.10 in PyInstaller/compat.py allows PyInstaller to generate an executable, however from here I kept running into issues when running the resulting binary.

It is not obvious to me what needs to be done to support python 3.10, That said, if desirable I am perfectly happy to do what I can with a little direction.

@ickk ickk added the feature Feature request label Apr 2, 2021
@bwoodsend
Copy link
Member

I can get a functional executable on Linux if I:

  • Replace _bootlocale with _locale as you said in compat.PY3_BASE_MODULES
  • Add struct to compat.PY3_BASE_MODULES
  • Copy/paste the importer/loader runtime scripts from PyInstaller/loader straight into the built application's root.

Number 3 is a hack - we'll need to work out why the original approach to inject those runtime modules isn't working.

@bwoodsend bwoodsend added the bug label Apr 2, 2021
@rokm
Copy link
Member

rokm commented Apr 2, 2021

Number 3 is a hack - we'll need to work out why the original approach to inject those runtime modules isn't working.

Because PI_PyObject_CallFunction calls are erroring out with PY_SSIZE_T_CLEAN macro must be defined for '#' formats. It might be enough to have our PI_PyObject_CallFunction point to _PyObject_CallFunction_SizeT instead of PyObject_CallFunction for Python 3.10...

@rokm
Copy link
Member

rokm commented Apr 2, 2021

We'll need to address pyvers field in COOKIE becoming 40 under python 3.10... for example, encoding it as

pyvers = sys.version_info[0] * 100 + sys.version_info[1]

instead of

pyvers = sys.version_info[0] * 10 + sys.version_info[1]

(it's a 32-bit int, so there's no shortage of space...).

@SLBIAM
Copy link

SLBIAM commented Jul 22, 2021

The issue is NOT resolved fully.

I have Beta 4 of Python 10 installed on my (Windows 10) PC (which I must use because I really need pattern matching feature only available in v3.10):

C:\Users\myname\Documents\Projects\Project Migration\SeleniumExamplePy>py -3 --version
Python 3.10.0b4

and I made sure my pyinstaller is up to date:

    C:\Users\myname\Documents\Projects\Project Migration\SeleniumExamplePy>pip install --upgrade pyinstaller
Requirement already satisfied: pyinstaller in c:\users\myname\appdata\local\programs\python\python310\lib\site-packages (4.4)
Requirement already satisfied: pefile>=2017.8.1 in c:\users\myname\appdata\local\programs\python\python310\lib\site-packages (from pyinstaller) (2021.5.24)
Requirement already satisfied: pyinstaller-hooks-contrib>=2020.6 in c:\users\myname\appdata\local\programs\python\python310\lib\site-packages (from pyinstaller) (2021.2)
Requirement already satisfied: pywin32-ctypes>=0.2.0 in c:\users\myname\appdata\local\programs\python\python310\lib\site-packages (from pyinstaller) (0.2.0)
Requirement already satisfied: setuptools in c:\users\myname\appdata\local\programs\python\python310\lib\site-packages (from pyinstaller) (56.0.0)
Requirement already satisfied: altgraph in c:\users\myname\appdata\local\programs\python\python310\lib\site-packages (from pyinstaller) (0.17)
Requirement already satisfied: future in c:\users\myname\appdata\local\programs\python\python310\lib\site-packages (from pefile>=2017.8.1->pyinstaller) (0.18.2)

I even tried installing the latest dev build:

pip install https://github.com/pyinstaller/pyinstaller/archive/develop.zip
Collecting https://github.com/pyinstaller/pyinstaller/archive/develop.zip
  Downloading https://github.com/pyinstaller/pyinstaller/archive/develop.zip
     / 4.0 MB 2.2 MB/s
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
    Preparing wheel metadata ... done
Requirement already satisfied: pyinstaller-hooks-contrib>=2020.6 in c:\users\myname\appdata\local\programs\python\python310\lib\site-packages (from pyinstaller==5.0.dev0) (2021.2)
Requirement already satisfied: pefile>=2017.8.1 in c:\users\myname\appdata\local\programs\python\python310\lib\site-packages (from pyinstaller==5.0.dev0) (2021.5.24)
Requirement already satisfied: altgraph in c:\users\myname\appdata\local\programs\python\python310\lib\site-packages (from pyinstaller==5.0.dev0) (0.17)
Requirement already satisfied: pywin32-ctypes>=0.2.0 in c:\users\myname\appdata\local\programs\python\python310\lib\site-packages (from pyinstaller==5.0.dev0) (0.2.0)
Requirement already satisfied: setuptools in c:\users\myname\appdata\local\programs\python\python310\lib\site-packages (from pyinstaller==5.0.dev0) (56.0.0)
Requirement already satisfied: future in c:\users\myname\appdata\local\programs\python\python310\lib\site-packages (from pefile>=2017.8.1->pyinstaller==5.0.dev0) (0.18.2)
Building wheels for collected packages: pyinstaller
  Building wheel for pyinstaller (PEP 517) ... done
  Created wheel for pyinstaller: filename=pyinstaller-5.0.dev0-py3-none-any.whl size=2670672 sha256=d7b490f711282e8b635300a5eb2ebf47d78b7aa21dacc518fdf1ee8606a4aac0
  Stored in directory: C:\Users\myname\AppData\Local\Temp\pip-ephem-wheel-cache-rseun6wp\wheels\d6\02\6d\a387c4f56a9895d41bc6868742c7f6ad092c79ffce4b680952
Successfully built pyinstaller
Installing collected packages: pyinstaller
  Attempting uninstall: pyinstaller
    Found existing installation: pyinstaller 4.4
    Uninstalling pyinstaller-4.4:
      Successfully uninstalled pyinstaller-4.4
Successfully installed pyinstaller-5.0.dev0

I am still getting ImportError: No module named _bootlocale error while trying to convert my python code (that I thoroughly tested) to executable:

C:\Users\myname\Documents\Projects\Project Migration\SeleniumExamplePy>pyinstaller --onefile --clean ExtractRules.spec
83 INFO: PyInstaller: 4.4
83 INFO: Python: 3.10.0b4
100 INFO: Platform: Windows-10-10.0.18363-SP0
110 INFO: UPX is not available.
110 INFO: Removing temporary files and cleaning cache in C:\Users\myname\AppData\Local\pyinstaller
113 INFO: Extending PYTHONPATH with paths
['C:\\Users\\myname\\Documents\\Projects\\Project '
 'Migration\\SeleniumExamplePy',
 'C:\\Users\\myname\\Documents\\Projects\\Project '
 'Migration\\SeleniumExamplePy']
126 INFO: checking Analysis
126 INFO: Building Analysis because Analysis-00.toc is non existent
126 INFO: Initializing module dependency graph...
126 INFO: Caching module graph hooks...
139 INFO: Analyzing base_library.zip ...
3449 INFO: Processing pre-find module path hook distutils from 'c:\\users\\myname\\appdata\\local\\programs\\python\\python310\\lib\\site-packages\\PyInstaller\\hooks\\pre_find_module_path\\hook-distutils.py'.
3449 INFO: distutils: retargeting to non-venv dir 'c:\\users\\myname\\appdata\\local\\programs\\python\\python310\\lib'
Traceback (most recent call last):
  File "c:\users\myname\appdata\local\programs\python\python310\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "c:\users\myname\appdata\local\programs\python\python310\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "C:\Users\myname\AppData\Local\Programs\Python\Python310\Scripts\pyinstaller.exe\__main__.py", line 7, in <module>
  File "c:\users\myname\appdata\local\programs\python\python310\lib\site-packages\PyInstaller\__main__.py", line 126, in run
    run_build(pyi_config, spec_file, **vars(args))
  File "c:\users\myname\appdata\local\programs\python\python310\lib\site-packages\PyInstaller\__main__.py", line 65, in run_build
    PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
  File "c:\users\myname\appdata\local\programs\python\python310\lib\site-packages\PyInstaller\building\build_main.py", line 758, in main
    build(specfile, kw.get('distpath'), kw.get('workpath'), kw.get('clean_build'))
  File "c:\users\myname\appdata\local\programs\python\python310\lib\site-packages\PyInstaller\building\build_main.py", line 705, in build
    exec(code, spec_namespace)
  File "ExtractRules.spec", line 7, in <module>
    a = Analysis(['ExtractRules.py'],
  File "c:\users\myname\appdata\local\programs\python\python310\lib\site-packages\PyInstaller\building\build_main.py", line 254, in __init__
    self.__postinit__()
  File "c:\users\myname\appdata\local\programs\python\python310\lib\site-packages\PyInstaller\building\datastruct.py", line 159, in __postinit__
    self.assemble()
  File "c:\users\myname\appdata\local\programs\python\python310\lib\site-packages\PyInstaller\building\build_main.py", line 354, in assemble
    self.graph = initialize_modgraph(
  File "c:\users\myname\appdata\local\programs\python\python310\lib\site-packages\PyInstaller\depend\analysis.py", line 882, in initialize_modgraph
    graph = PyiModuleGraph(
  File "c:\users\myname\appdata\local\programs\python\python310\lib\site-packages\PyInstaller\depend\analysis.py", line 122, in __init__
    self._analyze_base_modules()
  File "c:\users\myname\appdata\local\programs\python\python310\lib\site-packages\PyInstaller\depend\analysis.py", line 289, in _analyze_base_modules
    self._base_modules = [mod
  File "c:\users\myname\appdata\local\programs\python\python310\lib\site-packages\PyInstaller\depend\analysis.py", line 291, in <listcomp>
    for mod in self.import_hook(req)]
  File "c:\users\myname\appdata\local\programs\python\python310\lib\site-packages\PyInstaller\lib\modulegraph\modulegraph.py", line 1505, in import_hook
    target_package, target_module_partname = self._find_head_package(
  File "c:\users\myname\appdata\local\programs\python\python310\lib\site-packages\PyInstaller\lib\modulegraph\modulegraph.py", line 1711, in _find_head_package
    raise ImportError("No module named " + target_package_name)
ImportError: No module named _bootlocale

I was able to resolve the issue and build the executable by following only the first step of the bwoodsend's comment above
"Replace _bootlocale with _locale as you said in compat.PY3_BASE_MODULES"
I did not need to do steps 2 and 3, but wanted to let you know that the problem is still not fully resolved without editing compat.py module file manually.

@rokm
Copy link
Member

rokm commented Jul 22, 2021

The issue is NOT resolved fully.

Do note that the linked PR has not been merged yet nor has this issue been marked as resolved... and it likely won't be until the stable 3.10 release and the python packages that our CI tests against release compatible wheels.

@bwoodsend
Copy link
Member

Use:

pip install https://github.com/rokm/pyinstaller/archive/refs/heads/python-3.10.zip

to get the 3.10 support branch.

@rokm
Copy link
Member

rokm commented Jul 22, 2021

Hmm, think I'll rebase and push it again, to see how the tests turn out this time. I see that failing test with 3.10 on Linux and macOS was that recursion test that we removed the other day...

@rokm
Copy link
Member

rokm commented Jul 22, 2021

Use:

pip install https://github.com/rokm/pyinstaller/archive/refs/heads/python-3.10.zip

to get the 3.10 support branch.

This branch requires bootloader to be rebuilt (due to pyvers change).

@bwoodsend
Copy link
Member

In that case you'll have to do a proper git clone, build the bootloaders, then locally install. Don't use the oneliner because it won't work.

@SLBIAM
Copy link

SLBIAM commented Jul 22, 2021

I appreciate quick responses folks. Given that simple small change that I described resolved an immediate issue for me, in the interest of saving time I will refrain from going the whole distance for now ("do a proper git clone, build the bootloaders, then locally install"). I just wanted to bring the issue to your attention to give back to the community. I did not realize that linked PR has not been merged yet--hopefully that will resolve the issue permanently when done.

@eric15342335
Copy link
Contributor

do we have a timeline for this?

@bwoodsend
Copy link
Member

Not really. We'll merge the pull request once 3.10 is officially released and try to do a v4.6 release as soon as possible afterwards. I'll give the PR another rebase now to see if anything new has changed.

@jay0lee
Copy link

jay0lee commented Oct 4, 2021

just pinging this now that 3.10.0 is official:

https://pythoninsider.blogspot.com/2021/10/python-3100-is-available.html

@michaelkozakovsc
Copy link

3.10 is also the default release on Travis CI on windows, which results in broken builds that involve pyinstaller

@anibal2j
Copy link

anibal2j commented Oct 5, 2021

Also looking for an update in regards to this. I just installed 3.10 on a Windows 10 workstation and need to get pyinstaller to work but can't. Any ETA will be greatly appreciated.

@rokm
Copy link
Member

rokm commented Oct 5, 2021

Also looking for an update in regards to this. I just installed 3.10 on a Windows 10 workstation and need to get pyinstaller to work but can't. Any ETA will be greatly appreciated.

You can always use #5694 (v.5/develop branch) or #6274 (v.4 branch) if you absolutely need to use python 3.10 a day after it was released... (but you need to do an actual git checkout, rebuild the bootloader, and then install from the modified checkout).

@zetaloop
Copy link

zetaloop commented Oct 6, 2021

I tried --exclude-module _bootlocale and it worked for me properly

@anibal2j
Copy link

I tried as well with the --exclude-module _bootlocale and it worked with a simple Hello world program. However, with a slightly more complex program I'm now getting this:

Traceback (most recent call last):
  File "main.py", line 7, in <module>
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "PyInstaller\loader\pyimod03_importers.py", line 546, in exec_module
  File "requests\__init__.py", line 133, in <module>
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "PyInstaller\loader\pyimod03_importers.py", line 546, in exec_module
  File "requests\utils.py", line 41, in <module>
  File "certifi\core.py", line 37, in where
  File "contextlib.py", line 135, in __enter__
  File "importlib\_common.py", line 87, in _tempfile
  File "tempfile.py", line 337, in mkstemp
  File "tempfile.py", line 249, in _mkstemp_inner
TypeError: can only concatenate str (not "method") to str
[5848] Failed to execute script 'main' due to unhandled exception!

I'm using these Python libraries:

  1. from prettytable import PrettyTable
  2. import requests
  3. from tqdm import tqdm

Could that be the reason? Any way to get around this?

@rokm
Copy link
Member

rokm commented Oct 14, 2021

Could that be the reason? Any way to get around this?

Packages that use importlib.resources (in your case, requests) are incompatible with PyInstaller under python 3.10 unless a custom PyInstaller-compatible importlib.resources reader is implemented. So you need to use a branch with proper 3.10 support (or back-port the importlib.resources PR to your 4.5.1 installation).

@ickk
Copy link
Author

ickk commented Oct 15, 2021

🎉

@Davido17
Copy link

i

I tried --exclude-module _bootlocale and it worked for me properly

I used that as well, it made the exe file but the app is not working. it just pops up n goes on its own

@Legorooj
Copy link
Member

I've just release PyInstaller 4.6 onto PyPI. This release includes support for Python 3.10.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug feature Feature request
Projects
None yet
Development

Successfully merging a pull request may close this issue.