execnet icon indicating copy to clipboard operation
execnet copied to clipboard

Add frozen environment support

Open AlexPaiva opened this issue 1 year ago • 5 comments

Fixes #237

Fixes pytest-dev/pytest-xdist#991

Adds support for frozen environments such as pyinstaller, with proper imports on the pyinstaller side this change will work, tested with pytest and pytest-xdist.

Extra documentation available on both the mentioned issues.

AlexPaiva avatar Dec 28 '23 20:12 AlexPaiva

Any idea how we could test this in automation, it may easily break if we have no test for it

Yes, let me explain how it would differenciate for regular testing:

For a 'normal' run (meaning it would run perfectly without this PR and with the PR also works perfectly still) just create any test you want in a separate file (insert prints or write to files inside of them so you can debug if they ran or not), then pip install pytest xdist then start from a main.py file a call to pytest.main such as: pytest.main(["-n","2",relative_to_assets('test.py')]) where relative_to_assets() is a function that returns the correct path depending if it's a frozen env or not:

def relative_to_assets(relative_path):
    try:
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.dirname(__file__)
    return os.path.join(base_path, relative_path)

Run via command line as usual with python main.py It should work as it normally would.

The issue then arises when you compile into a pyinstaller single .exe where it no longer works, the expected debug print/file write will not happen and errors will arise, usually it opens a second .exe instead (related to trying to open sys.executable I assume). Basically just open the .exe and it should execute the code of main.py and it does but the pytest.main'' call doesn't execute properly as you will be able to test yourself.

For a run with this PR if you run normally it will still work without any kind of issues and the difference comes when ran with the pyinstaller single .exe, it will work perfectly aswell just by changing the execnet source code with this PR and without making any other changes.

To compile the main.py and according files properly into an .exe you will need this main.spec or similiar configuration for pyinstaller (assuming the main.spec and main.py are in the same directory, replace the execnet path in the .spec file with the path to the source code of the installed execnet on the test machine at the C:/Users/AA/AppData/Local/Programs/Python/Python310/Lib/site-packages/execnet path located in the datas), download all the files here: https://we.tl/t-tYpHw527Kw

On there the pytest-xdist folder is just a copy of: https://github.com/pytest-dev/pytest-xdist/tree/master/src/xdist so feel free to download yourself if you want.

On that directory run python main.py to test it normally, then run pyinstaller main.spec to build the .exe, then on the dist folder that is created should be a main.exe, just start it and a console will open and run the test. If you have the original execnet it should give errors or not run, if you have my PR it will run without any issues. Inside the test.py feel free to add any other tests you want.

Let me know if you need any extra details.

AlexPaiva avatar Dec 31 '23 12:12 AlexPaiva

@AlexPaiva I think @RonnyPfannschmidt just meant that we need to add tests to execnet to ensure the behavior this PR is adding does not break in the future.

For that, we need some tests:

  • We just need to spawn a sub interpreter and make sure the EXECNET_SPAWNING_SUBPROCESS is set appropriately.
  • I would say the same about PYTHON_EXECUTABLE, but it is not clear to me if we need this variable at all.

nicoddemus avatar Jan 04 '24 21:01 nicoddemus

Sorry on the late reply, was very busy! You mean, why not use sys.executable directly correct?

AlexPaiva avatar Mar 05 '24 21:03 AlexPaiva

You mean, why not use sys.executable directly correct?

Yes. 👍

nicoddemus avatar Mar 05 '24 23:03 nicoddemus

The goal was to leave the entire thing as it was and only change when it's a frozen env, especially for testing. But agreed that it can be simplified.

AlexPaiva avatar Mar 06 '24 12:03 AlexPaiva