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

Kivy 2.1.0 with Pyinstaller 5.7.0 kivy\logger.py RecursionError #8074

Closed
Marcinosoft opened this issue Dec 17, 2022 · 17 comments
Closed

Kivy 2.1.0 with Pyinstaller 5.7.0 kivy\logger.py RecursionError #8074

Marcinosoft opened this issue Dec 17, 2022 · 17 comments

Comments

@Marcinosoft
Copy link

Marcinosoft commented Dec 17, 2022

I did upgrade from Pyinstaller 5.6.2 to 5.7.0 to make exe of Kivy 2.1.0 project based on Python 3.8 on Windows 10 x64 Pro.

pip install -U pyinstaller==5.7.0
pip install -U pyinstaller-hooks-contrib==2022.14

Exe produced by Pyinstaller 5.7.0 ends with following exceptions after run:
244 times:

Traceback (most recent call last):
  File "logging\__init__.py", line 1088, in emit
AttributeError: 'NoneType' object has no attribute 'write'

During handling of the above exception, another exception occurred:

then:

File "main.py", line 1, in <module>
File "<frozen importlib._bootstrap>", line 991, in _find_and_load
File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
File "PyInstaller\loader\pyimod02_importers.py", line 499, in exec_module
File "kivy\__init__.py", line 509, in <module>
File "logging\__init__.py", line 1446, in info
File "logging\__init__.py", line 1589, in _log
File "logging\__init__.py", line 1599, in handle
File "logging\__init__.py", line 1661, in callHandlers
File "logging\__init__.py", line 954, in handle
File "kivy\logger.py", line 257, in emit

then 242 times:

File "kivy\logger.py", line 338, in write
File "logging\__init__.py", line 1458, in warning
File "logging\__init__.py", line 1589, in _log
File "logging\__init__.py", line 1599, in handle
File "logging\__init__.py", line 1661, in callHandlers
File "logging\__init__.py", line 954, in handle
File "logging\__init__.py", line 1093, in emit
File "logging\__init__.py", line 1006, in handleError

and the end of exception is:

File "kivy\logger.py", line 291, in format
File "copy.py", line 172, in deepcopy
File "copy.py", line 264, in _reconstruct
RecursionError: maximum recursion depth exceeded

My main.spec file:

# -*- mode: python ; coding: utf-8 -*-
from kivy_deps import sdl2, glew, gstreamer

block_cipher = None


a = Analysis(
	['main.py'],
	pathex=[],
	binaries=[],
	datas=[],
	hiddenimports=[],
	hookspath=[],
	hooksconfig={},
	runtime_hooks=[],
	excludes=['kivy.core.video.video_gstplayer', 'kivy.lib.gstplayer', 'kivy.core.audio.audio_gstplayer'],
	win_no_prefer_redirects=False,
	win_private_assemblies=False,
	cipher=block_cipher,
	noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
	pyz,
	a.scripts,
	a.binaries,
	a.zipfiles,
	a.datas,
	*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
	[],
	name='main',
	debug=False,
	bootloader_ignore_signals=False,
	strip=False,
	upx=True,
	upx_exclude=[],
	runtime_tmpdir=None,
	console=False,
	disable_windowed_traceback=False,
	argv_emulation=False,
	target_arch=None,
	codesign_identity=None,
	entitlements_file=None,
)

My main.py:

from kivy.app import App
import os
import sys
from kivy.resources import resource_add_path, resource_find

if hasattr(sys, '_MEIPASS'):
	resource_add_path(os.path.join(sys._MEIPASS))


class MyApp(App):
	pass


MyApp().run()

Requirements:

pip install -U kivy[full]==2.1.0 pyinstaller==5.7.0 pyinstaller-hooks-contrib==2022.14

Exactly same Kivy project exe run's fine after downgrade Pyinstaller to:

pip install -U pyinstaller==5.6.2
pip install -U pyinstaller-hooks-contrib==2022.13

or by change:

console=True,

within spec file.

BTW. Increasing recursion limit using sys.setrecursionlimit() doesn't help. Same issue no matter how huge limit is set.

Based on this reply it's Kivy bug:

pyinstaller/pyinstaller#7329 (comment)

This is because PyInstaller no longer creates a fake sys.stdout/sys.stderr in windowed mode. Instead, both are left as None which matches what pythonw.exe does. If kivy.logger blindly writes to sys.stderr without first checking that it's there then this is kivy's bug.

@iamazeem
Copy link

@Marcinosoft: Were you able to resolve this? Any workaround?
I'm getting the same issue on Windows 10 and 11.

@Marcinosoft
Copy link
Author

@Marcinosoft: Were you able to resolve this? Any workaround? I'm getting the same issue on Windows 10 and 11.

Yes, by downgrading PyInstaller to 5.6.2 using:

pip install pyinstaller==5.6.2 pyinstaller-hooks-contrib==2022.13

or using latest PyInstaller 5.7.0 with following addon on top of main Python program:

import os
import sys
if hasattr(sys, '_MEIPASS'):
    os.environ['KIVY_NO_CONSOLELOG'] = '1'

or

import os
import sys
if sys.__stdout__ is None or sys.__stderr__ is None:
    os.environ['KIVY_NO_CONSOLELOG'] = '1'

I hope Kivy will include stdout/err check within logger.py soon to be compatible with PyInstaller 5.7.0+.

@iamazeem
Copy link

@Marcinosoft: Thank you! 😄 👍
I hope so too that it'll be fixed soon.
Apparently, it looks like a trivial issue. 🤔
For now, either of the above workarounds are fine.

@jimmieliu
Copy link

Same problem here, and solved with os.environ['KIVY_NO_CONSOLELOG'] = '1'. Thank you all.

@misl6
Copy link
Member

misl6 commented Jan 9, 2023

Hi everyone!

Since we had a lot of improvements to Kivy logging system , did you tried to use Kivy from the master branch?

@misl6 misl6 added the awaiting-reply Waiting for reply from issue opener, will be closed if no reply label Jan 9, 2023
@Marcinosoft
Copy link
Author

Hi everyone!

Since we had a lot of improvements to Kivy logging system , did you tried to use Kivy from the master branch?

In my case I used latest released Kivy 2.1.0 installed by:
pip install kivy[full]
so not the latest from the sources (master branch).

@github-actions github-actions bot removed the awaiting-reply Waiting for reply from issue opener, will be closed if no reply label Jan 10, 2023
@Neizvestnyj
Copy link

In master branch same error

@Marcinosoft
Copy link
Author

Marcinosoft commented Apr 2, 2023

Hi everyone!

Since we had a lot of improvements to Kivy logging system , did you tried to use Kivy from the master branch?

Yes. Same issue with Kivy 2.2.0.dev0 and latest PyInstaller 5.9.0

Kivy 2.2.0.dev0 installed by:

python -m pip install -U kivy --pre --no-deps --index-url https://kivy.org/downloads/simple/
python -m pip install -U "kivy[base]" --pre --extra-index-url https://kivy.org/downloads/simple/

@peterstavrou
Copy link

I'm also getting the same error with PyInstaller 5.9.0 with kivy[base] v2.1.0 and kivy[full].

The below solution did not work for me.

import os
import sys
if hasattr(sys, '_MEIPASS'):
    os.environ['KIVY_NO_CONSOLELOG'] = '1'
import os
import sys
if sys.__stdout__ is None or sys.__stderr__ is None:
    os.environ['KIVY_NO_CONSOLELOG'] = '1'

@Marcinosoft
Copy link
Author

I'm also getting the same error with PyInstaller 5.9.0 with kivy[base] v2.1.0 and kivy[full].

The below solution did not work for me.

import os
import sys
if hasattr(sys, '_MEIPASS'):
    os.environ['KIVY_NO_CONSOLELOG'] = '1'
import os
import sys
if sys.__stdout__ is None or sys.__stderr__ is None:
    os.environ['KIVY_NO_CONSOLELOG'] = '1'

It works but it have to be placed on very top of your python file, before any kivy import

@peterstavrou
Copy link

It works but it have to be placed on very top of your python file, before any kivy import

ah that did the trick.

@apartale
Copy link

apartale commented Jul 4, 2023

The Problem still exists, but the workaround works perfect.
Hopefully it will be fixed soon.

@aamirawan7584
Copy link

so in this workaround we will not get the kivy app logs can anyone guide me how to redirect those logs to my own logger. thank you

@Marcinosoft
Copy link
Author

Marcinosoft commented Jul 24, 2023

so in this workaround we will not get the kivy app logs can anyone guide me how to redirect those logs to my own logger. thank you

Workaround won't output into console only while console is not available, so It's fair enough.
It do not disable file output. To disable logging to file you can set KIVY_NO_FILELOG to 1.
See all env options here: https://kivy.org/doc/stable/guide/environment.html

By default on Windows log files are stored within %USERPROFILE%\.kivy\logs\ folder. Look for KIVY_HOME environment variable to get or change kivy's root folder containing config.ini with log files folder and files naming.

In my opinion these log files are not very valuable and it's good choice to disable it. By default last 100 log files are kept. Same for Android.

You can change log folder, log names and retention by changing Kivy configuration: https://kivy.org/doc/stable/guide/config.html
You can do it via config.ini file or at code level: https://kivy.org/doc/stable/api-kivy.config.html#module-kivy.config

@ElliotGarbus
Copy link
Contributor

From the response in the pyinstaller issues: pyinstaller/pyinstaller#7329 (comment)

"PyInstaller no longer creates a fake sys.stdout/sys.stderr in windowed mode. Instead, both are left as None which matches what pythonw.exe does. If kivy.logger blindly writes to sys.stderr without first checking that it's there then this is kivy's bug."

Anyone working on a PR? I've just started looking to find the error...

@ElliotGarbus
Copy link
Contributor

I have a fix, just need to get a PR done - hopefully in the next few days.
The details:
Under pythonw or pyinstaller 5.7 sys.stderr is set to None. Therefore, writes to sys.stderr will result in an AttributeError.
The solution is to modify the add_kivy_handlers() function in kivy's logger.py file such that the ConsoleHandler() is not added to the logger if sys.stderr is None. This is like automatically setting KIVY_NO_CONSOLELOG.

This fixes the pythonw and pyinstaller issue and preserves the behavior that any writes to sys.stderr are written to the logfile as warning messages.

@misl6
Copy link
Member

misl6 commented Oct 8, 2023

Fixed via #8345

@misl6 misl6 closed this as completed Oct 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

No branches or pull requests

9 participants