File: pyi_subprocess_environment_inheritance.py

package info (click to toggle)
pyinstaller 6.18.0%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,820 kB
  • sloc: python: 41,828; ansic: 12,123; makefile: 171; sh: 131; xml: 19
file content (103 lines) | stat: -rw-r--r-- 3,937 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#-----------------------------------------------------------------------------
# Copyright (c) 2024, PyInstaller Development Team.
#
# Distributed under the terms of the GNU General Public License (version 2
# or later) with exception for distributing the bootloader.
#
# The full license is in the file COPYING.txt, distributed with this software.
#
# SPDX-License-Identifier: (GPL-2.0-or-later WITH Bootloader-exception)
#-----------------------------------------------------------------------------

import argparse
import os
import sys
import subprocess

if __name__ == '__main__':
    # Argument parser
    parser = argparse.ArgumentParser(description="Sub-process environment inheritance test")
    subparsers = parser.add_subparsers(dest="process_type", help="Process type.")

    parser_parent = subparsers.add_parser("parent", help="Parent process.")
    parser_parent.add_argument(
        "child_executable",
        type=str,
        help="Path to executable to spawn as a child process.",
    )
    parser_parent.add_argument(
        "--force-independent",
        action="store_true",
        help="Spawn the child process as an independent instance.",
    )

    parser_child = subparsers.add_parser("child", help="Child process.")
    parser_child.add_argument(
        "mode",
        type=str,
        choices={"same", "different"},
        help="Child mode - whether executable is the same as parent process or not.",
    )
    parser_child.add_argument(
        "parent_app_dir",
        type=str,
        help="Top-level application directory of the parent process.",
    )

    args = parser.parse_args()

    if args.process_type is None:
        # Process type not specified - exit early.
        print("Process type not specified.", file=sys.stderr)
    elif args.process_type == "parent":
        # Parent process.
        print("Running as parent process!", file=sys.stderr)
        print(f"Child executable: {args.child_executable}", file=sys.stderr)
        print(f"Force independent instance: {args.force_independent}", file=sys.stderr)

        env = os.environ.copy()

        if (
            args.child_executable == "sys.executable"
            or os.path.realpath(args.child_executable) == os.path.realpath(sys.executable)
        ):
            subprocess_args = [
                sys.executable,
                "child",
                "different" if args.force_independent else "same",
                sys._MEIPASS,
            ]

            if args.force_independent:
                env["PYINSTALLER_RESET_ENVIRONMENT"] = "1"
        else:
            subprocess_args = [
                args.child_executable,
                "child",
                "different",
                sys._MEIPASS,
            ]

        print(f"Running child process with arguments: {subprocess_args!r}", file=sys.stderr)
        subprocess.run(subprocess_args, check=True, env=env)
    else:
        # Child process.
        print("Running as child process!", file=sys.stderr)
        print(f"Mode: {args.mode}", file=sys.stderr)
        print(f"Our top-level directory: {sys._MEIPASS}", file=sys.stderr)
        print(f"Parent top-level directory: {args.parent_app_dir}", file=sys.stderr)

        if args.mode == "same":
            # Raise error if directories are different.
            if sys._MEIPASS != args.parent_app_dir:
                raise SystemExit(
                    f"Expected top-level directory ({sys._MEIPASS}) to be SAME as that of the parent process "
                    f"({args.parent_app_dir}), but it is not!"
                )
        else:
            # Raise error if directories are the same.
            if sys._MEIPASS == args.parent_app_dir:
                raise SystemExit(
                    f"Expected top-level directory ({sys._MEIPASS}) to be DIFFERENT from that of the parent process "
                    f"({args.parent_app_dir}), but it is not!"
                )