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

ImportError in multithreaded context with cx_Logging [works with Python 3.10] #1632

Open
deymundson opened this issue Oct 7, 2022 · 7 comments

Comments

@deymundson
Copy link

Describe the bug
"Just in time" imports using the form from foo import bar intermittently fail with an ImportError. When running the Python scripts directly the imports always succeed.

The behavior shows up when two or more threads are attempting to import a given module at the same time. In order for the bug to manifest itself, the following must be true:

  • The program is run from a frozen executable.
  • The module is being imported from more than one thread simultaneously.
  • The module is being imported "just in time" and all threads are importing the module for the first time.
  • The thread must make a call to cx_Logging before attempting to import the module.
  • The module being imported must import cProfile or pstats. It likely isn't constrained to just these modules, but in the scenario in which I encountered the bug, these imports were involved.

To Reproduce
main.py

import cx_Logging
import threading


def import_test():
    # Thread must write with cx_Logging before importing module
    cx_Logging.Trace("import_test(): start")
    try:
        # Import needs to be "from x import y", not "import x"
        from module import Module
    except ImportError:
        cx_Logging.Trace("import_test(): import failed")
    cx_Logging.Trace("import_test(): end")


if __name__ == "__main__":
    cx_Logging.StartLoggingStdout(20, prefix="%t [%i]")

    cx_Logging.Trace("run_test(): Round 1")
    threads1 = [threading.Thread(target=import_test) for i in range(3)]
    for thread in threads1:
        thread.start()
    for thread in threads1:
        thread.join()

    cx_Logging.Trace("run_test(): Round 2")
    threads2 = [threading.Thread(target=import_test) for i in range(3)]
    for thread in threads2:
        thread.start()
    for thread in threads2:
        thread.join()

module.py

# Module needs to import cProfile or pstats
import cProfile


class Module(object):
    pass

Freeze Command

cxfreeze.exe --includes cx_Logging -c main.py

Sample Output

15:58:45.986 [27604] run_test(): Round 1
15:58:45.988 [27532] import_test(): start
15:58:45.990 [21256] import_test(): start
15:58:45.991 [23600] import_test(): start
15:58:45.992 [23600] import_test(): import failed
15:58:45.993 [27532] import_test(): end
15:58:45.994 [21256] import_test(): end
15:58:45.995 [23600] import_test(): end
15:58:45.997 [27604] run_test(): Round 2
15:58:45.998 [04608] import_test(): start
15:58:45.998 [23008] import_test(): start
15:58:45.999 [04608] import_test(): end
15:58:46.000 [12200] import_test(): start
15:58:46.001 [23008] import_test(): end
15:58:46.001 [12200] import_test(): end

Round 1 shows that the initial attempt to import the module fails for one of the threads. Round 2 shows that the import succeeds for all threads after the module was initially loaded.

Expected behavior
As is the case when running the Python scripts directly, the imports should succeed.

Desktop (please complete the following information):

  • Platform information: Windows 10.0.19044
  • OS architecture: amd64
  • cx_Freeze version: 6.11.1
  • Python version: 3.8
@marcelotduarte marcelotduarte modified the milestone: kdir 1632 Oct 8, 2022
@marcelotduarte
Copy link
Owner

marcelotduarte commented Oct 8, 2022

I tested w/ py 3.8.10 and confirm.
I tested also installing cx_Freeze and cx_Logging from my packages*:
pip install --pre --extra-index-url https://marcelotduarte.github.io/packages/ cx_Logging
pip install --pre --extra-index-url https://marcelotduarte.github.io/packages/ cx_Freeze

and its works.
With py 3.10 it worked for me w/ cx_Freeze 6.11.1 and the cx_Logging from my packages.

@marcelotduarte
Copy link
Owner

Can you test with the latest version of cx_Freeze and cx_Logging 3.1?

@marcelotduarte
Copy link
Owner

Can I close this issue?

@deymundson
Copy link
Author

deymundson commented Jul 10, 2023

Sorry for the delay on getting back to this. I tested with Python 3.8.10, cx_Freeze 6.15.3, and cx_Logging 3.1.0 and I am still getting the issue.

@marcelotduarte
Copy link
Owner

Can you test with Python 3.10?

@deymundson
Copy link
Author

Tested with Python 3.10.11 and I no longer get the issue.

@marcelotduarte marcelotduarte changed the title ImportError in multithreaded context with cx_Logging ImportError in multithreaded context with cx_Logging [works with Python 3.10] Jul 10, 2023
@marcelotduarte
Copy link
Owner

marcelotduarte commented Jul 13, 2023

I discovered that if you put a time.sleep(0.1) before the `thread.start() in round 1, it runs without problems with Python 3.8.10/64.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants