https://github.com/python/cpython/commit/e20ca6d1b006674be23d16083f273e8a7b8f77b6 commit: e20ca6d1b006674be23d16083f273e8a7b8f77b6 branch: main author: Steve Dower <steve.do...@python.org> committer: zooba <steve.do...@microsoft.com> date: 2025-04-28T13:57:47+01:00 summary:
gh-132930: Implement PEP 773 (GH-132931) This change to the core CPython repo: * Adds PyManager support to PC/layout * Adds a warning message to the legacy py.exe if subcommands are invoked * Add deprecation message to traditional installer * Updates using/windows docs files: A Misc/NEWS.d/next/Windows/2025-04-25-13-34-27.gh-issue-132930.6MJumW.rst A PC/layout/support/pymanager.py M Doc/using/windows.rst M PC/launcher2.c M PC/layout/main.py M PC/layout/support/options.py M Tools/msi/bundle/Default.thm M Tools/msi/bundle/Default.wxl diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index 1a6322d72341ff..57c6062ee43a22 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -1,441 +1,781 @@ .. highlight:: none +.. _python.org/downloads: https://www.python.org/downloads/ + +.. _Microsoft Store app: https://apps.microsoft.com/detail/9NQ7512CXL7T + .. _using-on-windows: ************************* Using Python on Windows ************************* -.. sectionauthor:: Robert Lehmann <lehman...@gmail.com> -.. sectionauthor:: Steve Dower <steve.do...@microsoft.com> +.. sectionauthor:: Steve Dower <steve.do...@python.org> This document aims to give an overview of Windows-specific behaviour you should know about when using Python on Microsoft Windows. Unlike most Unix systems and services, Windows does not include a system -supported installation of Python. To make Python available, the CPython team -has compiled Windows installers with every `release -<https://www.python.org/downloads/>`_ for many years. These installers -are primarily intended to add a per-user installation of Python, with the -core interpreter and library being used by a single user. The installer is also -able to install for all users of a single machine, and a separate ZIP file is -available for application-local distributions. +supported installation of Python. Instead, Python can be obtained from a number +of distributors, including directly from the CPython team. Each Python +distribution will have its own benefits and drawbacks, however, consistency with +other tools you are using is generally a worthwhile benefit. Before committing +to the process described here, we recommend investigating your existing tools to +see if they can provide Python directly. + +To obtain Python from the CPython team, use the Python Install Manager. This +is a standalone tool that makes Python available as global commands on your +Windows machine, integrates with the system, and supports updates over time. You +can download the Python Install Manager from `python.org/downloads`_ or through +the `Microsoft Store app`_. + +Once you have installed the Python Install Manager, the global ``python`` +command can be used from any terminal to launch your current latest version of +Python. This version may change over time as you add or remove different +versions, and the ``py list`` command will show which is current. + +In general, we recommend that you create a :ref:`virtual environment <tut-venv>` +for each project and run ``<env>\Scripts\Activate`` in your terminal to use it. +This provides isolation between projects, consistency over time, and ensures +that additional commands added by packages are also available in your session. +Create a virtual environment using ``python -m venv <env path>``. + +If the ``python`` or ``py`` commands do not seem to be working, please see the +:ref:`Troubleshooting <pymanager-troubleshoot>` section below. There are +sometimes additional manual steps required to configure your PC. + +Apart from using the Python install manager, Python can also be obtained as +NuGet packages. See :ref:`windows-nuget` below for more information on these +packages. + +The embeddable distros are minimal packages of Python suitable for embedding +into larger applications. They can be installed using the Python install +manager. See :ref:`windows-embeddable` below for more information on these +packages. + + +.. _pymanager: +.. _windows-store: +.. _setting-envvars: +.. _windows-path-mod: +.. _launcher: -As specified in :pep:`11`, a Python release only supports a Windows platform -while Microsoft considers the platform under extended support. This means that -Python |version| supports Windows 10 and newer. If you require Windows 7 -support, please install Python 3.8. If you require Windows 8.1 support, -please install Python 3.12. +Python Install Manager +====================== -There are a number of different installers available for Windows, each with -certain benefits and downsides. +Installation +------------ -:ref:`windows-full` contains all components and is the best option for -developers using Python for any kind of project. +The Python install manager can be installed from the `Microsoft Store app`_ +or downloaded and installed from `python.org/downloads`_. The two versions are +identical. -:ref:`windows-store` is a simple installation of Python that is suitable for -running scripts and packages, and using IDLE or other development environments. -It requires Windows 10 and above, but can be safely installed without corrupting other -programs. It also provides many convenient commands for launching Python and -its tools. +To install through the Store, simply click "Install". After it has completed, +open a terminal and type ``python`` to get started. -:ref:`windows-nuget` are lightweight installations intended for continuous -integration systems. It can be used to build Python packages or run scripts, -but is not updateable and has no user interface tools. +To install the file downloaded from python.org, either double-click and select +"Install", or run ``Add-AppxPackage <path to MSIX>`` in Windows Powershell. -:ref:`windows-embeddable` is a minimal package of Python suitable for -embedding into a larger application. +After installation, the ``python``, ``py``, and ``pymanager`` commands should be +available. If they are not, click Start and search for "Manage app execution +aliases". This settings page will let you enable the relevant commands. They +will be labelled "Python (default)", "Python (default windowed)", and "Python +install manager". +If you have existing installations of Python, or you have modified your +:envvar:`PATH` variable, you may need to remove them or undo the modifications +in order for the commands to work. Old versions of Python can be reinstalled +using the Python install manager. -.. _windows-full: +When you first install a runtime, you will likely be prompted to add a directory +to your :envvar:`PATH`. This is optional, if you prefer to use the ``py`` +command, but is offered for those who prefer the full range of aliases (such +as ``python3.14.exe``) to be available. The directory will be +:file:`%LocalAppData%\Python\bin` by default, but may be customized by an +administrator. Click Start and search for "Edit environment variables for your +account" for the system settings page to add the path. -The full installer -================== +The Python install manager will be automatically updated to new releases. This +does not affect any installs of Python runtimes. Uninstalling the Python install +manager does not uninstall any Python runtimes. -Installation steps ------------------- +If you are not able to install an MSIX in your context, for example, you are +using automated deployment software that does not support it, please see +:ref:`pymanager-advancedinstall` below for more information. -Four Python |version| installers are available for download - two each for the -32-bit and 64-bit versions of the interpreter. The *web installer* is a small -initial download, and it will automatically download the required components as -necessary. The *offline installer* includes the components necessary for a -default installation and only requires an internet connection for optional -features. See :ref:`install-layout-option` for other ways to avoid downloading -during installation. -After starting the installer, one of two options may be selected: +Basic Use +--------- -.. image:: win_installer.png +The recommended command for launching Python is ``python``, which will either +launch the version requested by the script being launched, an active virtual +environment, or the default installed version, which will be the latest stable +release unless configured otherwise. If no version is specifically requested and +no runtimes are installed at all, the current latest release will be installed +automatically. + +For all scenarios involving multiple runtime versions, the recommended command +is ``py``. This may be used anywhere in place of ``python`` or the older +``py.exe`` launcher. By default, ``py`` matches the behaviour of ``python``, but +also allows command line options to select a specific version as well as +subcommands to manage installations. These are detailed below. + +Because the ``py`` command may already be taken by the previous version, there +is also an unambiguous ``pymanager`` command. Scripted installs that are +intending to use Python install manager should consider using ``pymanager``, due +to the lower chance of encountering a conflict with existing installs. The only +difference between the two commands is when running without any arguments: +``py`` will install and launch your default interpreter, while ``pymanager`` +will display help (``pymanager exec ...`` provides equivalent behaviour to +``py ...``). + +Each of these commands also has a windowed version that avoids creating a +console window. These are ``pyw``, ``pythonw`` and ``pymanagerw``. A ``python3`` +command is also included that mimics the ``python`` command. It is intended to +catch accidental uses of the typical POSIX command on Windows, but is not meant +to be widely used or recommended. + +To launch your default runtime, run ``python`` or ``py`` with the arguments you +want to be passed to the runtime (such as script files or the module to launch): + +.. code:: + + $> py + ... + $> python my-script.py + ... + $> py -m this + ... + +To launch a specific runtime, the ``py`` command accepts a ``-V:<TAG>`` option. +This option must be specified before any others. The tag is part or all of the +identifier for the runtime; for those from the CPython team, it looks like the +version, potentially with the platform. For compatibility, the ``V:`` may be +omitted in cases where the tag refers to an official release and starts with +``3``. + +.. code:: + + $> py -V:3.14 ... + $> py -V:3-arm64 ... + +Runtimes from other distributors may require the *company* to be included as +well. This should be separated from the tag by a slash, and may be a prefix. +Specifying the company is optional when it is ``PythonCore``, and specifying the +tag is optional (but not the slash) when you want the latest release from a +specific company. + +.. code:: + + $> py -V:Distributor\1.0 ... + $> py -V:distrib/ ... + +If no version is specified, but a script file is passed, the script will be +inspected for a *shebang line*. This is a special format for the first line in +a file that allows overriding the command. See :ref:`pymanager-shebang` for more +information. When there is no shebang line, or it cannot be resolved, the script +will be launched with the default runtime. + +If you are running in an active virtual environment, have not requested a +particular version, and there is no shebang line, the default runtime will be +that virtual environment. In this scenario, the ``python`` command was likely +already overridden and none of these checks occurred. However, this behaviour +ensures that the ``py`` command can be used interchangeably. + +When you launch either ``python`` or ``py`` but do not have any runtimes +installed, and the requested version is the default, it will be installed +automatically and then launched. Otherwise, the requested version will be +installed if automatic installation is configured (most likely by setting +``PYTHON_MANAGER_AUTOMATIC_INSTALL`` to ``true``), or if the ``py exec`` or +``pymanager exec`` forms of the command were used. + + +Command Help +------------ -If you select "Install Now": +The ``py help`` command will display the full list of supported commands, along +with their options. Any command may be passed the ``-?`` option to display its +help, or its name passed to ``py help``. -* You will *not* need to be an administrator (unless a system update for the - C Runtime Library is required or you install the :ref:`launcher` for all - users) -* Python will be installed into your user directory -* The :ref:`launcher` will be installed according to the option at the bottom - of the first page -* The standard library, test suite, launcher and pip will be installed -* If selected, the install directory will be added to your :envvar:`PATH` -* Shortcuts will only be visible for the current user +.. code:: -Selecting "Customize installation" will allow you to select the features to -install, the installation location and other options or post-install actions. -To install debugging symbols or binaries, you will need to use this option. + $> py help + $> py help install + $> py install /? -To perform an all-users installation, you should select "Customize -installation". In this case: -* You may be required to provide administrative credentials or approval -* Python will be installed into the Program Files directory -* The :ref:`launcher` will be installed into the Windows directory -* Optional features may be selected during installation -* The standard library can be pre-compiled to bytecode -* If selected, the install directory will be added to the system :envvar:`PATH` -* Shortcuts are available for all users +All commands support some common options, which will be shown by ``py help``. +These options must be specified after any subcommand. Specifying ``-v`` or +``--verbose`` will increase the amount of output shown, and ``-vv`` will +increase it further for debugging purposes. Passing ``-q`` or ``--quiet`` will +reduce output, and ``-qq`` will reduce it further. -.. _max-path: +The ``--config=<PATH>`` option allows specifying a configuration file to +override multiple settings at once. See :ref:`pymanager-config` below for more +information about these files. -Removing the MAX_PATH Limitation --------------------------------- -Windows historically has limited path lengths to 260 characters. This meant that -paths longer than this would not resolve and errors would result. +Listing Runtimes +---------------- -In the latest versions of Windows, this limitation can be expanded to -approximately 32,000 characters. Your administrator will need to activate the -"Enable Win32 long paths" group policy, or set ``LongPathsEnabled`` to ``1`` -in the registry key -``HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem``. +.. code:: -This allows the :func:`open` function, the :mod:`os` module and most other -path functionality to accept and return paths longer than 260 characters. + $> py list [-f=|--format=<FMT>] [-1|--one] [--online|-s=|--source=<URL>] [<TAG>...] -After changing the above option, no further configuration is required. +The list of installed runtimes can be seen using ``py list``. A filter may be +added in the form of one or more tags (with or without company specifier), and +each may include a ``<``, ``<=``, ``>=`` or ``>`` prefix to restrict to a range. -.. versionchanged:: 3.6 +A range of formats are supported, and can be passed as the ``--format=<FMT>`` or +``-f <FMT>`` option. Formats include ``table`` (a user friendly table view), +``csv`` (comma-separated table), ``json`` (a single JSON blob), ``jsonl`` (one +JSON blob per result), ``exe`` (just the executable path), ``prefix`` (just the +prefix path). - Support for long paths was enabled in Python. +The ``--one`` or ``-1`` option only displays a single result. If the default +runtime is included, it will be the one. Otherwise, the "best" result is shown +("best" is deliberately vaguely defined, but will usually be the most recent +version). The result shown by ``py list --one <TAG>`` will match the runtime +that would be launched by ``py -V:<TAG>``. -.. _install-quiet-option: +The ``--only-managed`` option excludes results that were not installed by the +Python install manager. This is useful when determining which runtimes may be +updated or uninstalled through the ``py`` command. -Installing Without UI ---------------------- +The ``--online`` option is short for passing ``--source=<URL>`` with the default +source. Passing either of these options will search the online index for +runtimes that can be installed. The result shown by ``py list --online --one +<TAG>`` will match the runtime that would be installed by ``py install <TAG>``. -All of the options available in the installer UI can also be specified from the -command line, allowing scripted installers to replicate an installation on many -machines without user interaction. These options may also be set without -suppressing the UI in order to change some of the defaults. +.. code:: -The following options (found by executing the installer with ``/?``) can be -passed into the installer: + $> py list --online 3.14 -+---------------------+--------------------------------------------------------+ -| Name | Description | -+=====================+========================================================+ -| /passive | to display progress without requiring user interaction | -+---------------------+--------------------------------------------------------+ -| /quiet | to install/uninstall without displaying any UI | -+---------------------+--------------------------------------------------------+ -| /simple | to prevent user customization | -+---------------------+--------------------------------------------------------+ -| /uninstall | to remove Python (without confirmation) | -+---------------------+--------------------------------------------------------+ -| /layout [directory] | to pre-download all components | -+---------------------+--------------------------------------------------------+ -| /log [filename] | to specify log files location | -+---------------------+--------------------------------------------------------+ +For compatibility with the old launcher, the ``--list``, ``--list-paths``, +``-0`` and ``-0p`` commands (e.g. ``py -0p``) are retained. They do not allow +additional options, and will produce legacy formatted output. -All other options are passed as ``name=value``, where the value is usually -``0`` to disable a feature, ``1`` to enable a feature, or a path. The full list -of available options is shown below. -+---------------------------+--------------------------------------+--------------------------+ -| Name | Description | Default | -+===========================+======================================+==========================+ -| InstallAllUsers | Perform a system-wide installation. | 0 | -+---------------------------+--------------------------------------+--------------------------+ -| TargetDir | The installation directory | Selected based on | -| | | InstallAllUsers | -+---------------------------+--------------------------------------+--------------------------+ -| DefaultAllUsersTargetDir | The default installation directory | :file:`%ProgramFiles%\\\ | -| | for all-user installs | Python X.Y` or :file:`\ | -| | | %ProgramFiles(x86)%\\\ | -| | | Python X.Y` | -+---------------------------+--------------------------------------+--------------------------+ -| DefaultJustForMeTargetDir | The default install directory for | :file:`%LocalAppData%\\\ | -| | just-for-me installs | Programs\\Python\\\ | -| | | PythonXY` or | -| | | :file:`%LocalAppData%\\\ | -| | | Programs\\Python\\\ | -| | | PythonXY-32` or | -| | | :file:`%LocalAppData%\\\ | -| | | Programs\\Python\\\ | -| | | PythonXY-64` | -+---------------------------+--------------------------------------+--------------------------+ -| DefaultCustomTargetDir | The default custom install directory | (empty) | -| | displayed in the UI | | -+---------------------------+--------------------------------------+--------------------------+ -| AssociateFiles | Create file associations if the | 1 | -| | launcher is also installed. | | -+---------------------------+--------------------------------------+--------------------------+ -| CompileAll | Compile all ``.py`` files to | 0 | -| | ``.pyc``. | | -+---------------------------+--------------------------------------+--------------------------+ -| PrependPath | Prepend install and Scripts | 0 | -| | directories to :envvar:`PATH` and | | -| | add ``.PY`` to :envvar:`PATHEXT` | | -+---------------------------+--------------------------------------+--------------------------+ -| AppendPath | Append install and Scripts | 0 | -| | directories to :envvar:`PATH` and | | -| | add ``.PY`` to :envvar:`PATHEXT` | | -+---------------------------+--------------------------------------+--------------------------+ -| Shortcuts | Create shortcuts for the interpreter,| 1 | -| | documentation and IDLE if installed. | | -+---------------------------+--------------------------------------+--------------------------+ -| Include_doc | Install Python manual | 1 | -+---------------------------+--------------------------------------+--------------------------+ -| Include_debug | Install debug binaries | 0 | -+---------------------------+--------------------------------------+--------------------------+ -| Include_dev | Install developer headers and | 1 | -| | libraries. Omitting this may lead to | | -| | an unusable installation. | | -+---------------------------+--------------------------------------+--------------------------+ -| Include_exe | Install :file:`python.exe` and | 1 | -| | related files. Omitting this may | | -| | lead to an unusable installation. | | -+---------------------------+--------------------------------------+--------------------------+ -| Include_launcher | Install :ref:`launcher`. | 1 | -+---------------------------+--------------------------------------+--------------------------+ -| InstallLauncherAllUsers | Installs the launcher for all | 1 | -| | users. Also requires | | -| | ``Include_launcher`` to be set to 1 | | -+---------------------------+--------------------------------------+--------------------------+ -| Include_lib | Install standard library and | 1 | -| | extension modules. Omitting this may | | -| | lead to an unusable installation. | | -+---------------------------+--------------------------------------+--------------------------+ -| Include_pip | Install bundled pip and setuptools | 1 | -+---------------------------+--------------------------------------+--------------------------+ -| Include_symbols | Install debugging symbols (``*.pdb``)| 0 | -+---------------------------+--------------------------------------+--------------------------+ -| Include_tcltk | Install Tcl/Tk support and IDLE | 1 | -+---------------------------+--------------------------------------+--------------------------+ -| Include_test | Install standard library test suite | 1 | -+---------------------------+--------------------------------------+--------------------------+ -| Include_tools | Install utility scripts | 1 | -+---------------------------+--------------------------------------+--------------------------+ -| LauncherOnly | Only installs the launcher. This | 0 | -| | will override most other options. | | -+---------------------------+--------------------------------------+--------------------------+ -| SimpleInstall | Disable most install UI | 0 | -+---------------------------+--------------------------------------+--------------------------+ -| SimpleInstallDescription | A custom message to display when the | (empty) | -| | simplified install UI is used. | | -+---------------------------+--------------------------------------+--------------------------+ +Installing Runtimes +------------------- -For example, to silently install a default, system-wide Python installation, -you could use the following command (from an elevated command prompt):: +.. code:: - python-3.9.0.exe /quiet InstallAllUsers=1 PrependPath=1 Include_test=0 + $> py install [-s=|--source=<URL>] [-f|--force] [-u|--update] [--dry-run] [<TAG>...] -To allow users to easily install a personal copy of Python without the test -suite, you could provide a shortcut with the following command. This will -display a simplified initial page and disallow customization:: +New runtime versions may be added using ``py install``. One or more tags may be +specified, and the special tag ``default`` may be used to select the default. +Ranges are not supported for installation. - python-3.9.0.exe InstallAllUsers=0 Include_launcher=0 Include_test=0 - SimpleInstall=1 SimpleInstallDescription="Just for me, no test suite." +The ``--source=<URL>`` option allows overriding the online index that is used to +obtain runtimes. This may be used with an offline index, as shown in +:ref:`pymanager-offline`. -(Note that omitting the launcher also omits file associations, and is only -recommended for per-user installs when there is also a system-wide installation -that included the launcher.) +Passing ``--force`` will ignore any cached files and remove any existing install +to replace it with the specified one. -The options listed above can also be provided in a file named ``unattend.xml`` -alongside the executable. This file specifies a list of options and values. -When a value is provided as an attribute, it will be converted to a number if -possible. Values provided as element text are always left as strings. This -example file sets the same options as the previous example: +Passing ``--update`` will replace existing installs if the new version is newer. +Otherwise, they will be left. If no tags are provided with ``--update``, all +installs managed by the Python install manager will be updated if newer versions +are available. Updates will remove any modifications made to the install, +including globally installed packages, but virtual environments will continue to +work. -.. code-block:: xml +Passing ``--dry-run`` will generate output and logs, but will not modify any +installs. - <Options> - <Option Name="InstallAllUsers" Value="no" /> - <Option Name="Include_launcher" Value="0" /> - <Option Name="Include_test" Value="no" /> - <Option Name="SimpleInstall" Value="yes" /> - <Option Name="SimpleInstallDescription">Just for me, no test suite</Option> - </Options> +In addition to the above options, the ``--target`` option will extract the +runtime to the specified directory instead of doing a normal install. This is +useful for embedding runtimes into larger applications. -.. _install-layout-option: +.. code:: -Installing Without Downloading ------------------------------- + $> py install ... [-t=|--target=<PATH>] <TAG> -As some features of Python are not included in the initial installer download, -selecting those features may require an internet connection. To avoid this -need, all possible components may be downloaded on-demand to create a complete -*layout* that will no longer require an internet connection regardless of the -selected features. Note that this download may be bigger than required, but -where a large number of installations are going to be performed it is very -useful to have a locally cached copy. -Execute the following command from Command Prompt to download all possible -required files. Remember to substitute ``python-3.9.0.exe`` for the actual -name of your installer, and to create layouts in their own directories to -avoid collisions between files with the same name. +.. _pymanager-offline: -:: +Offline Installs +---------------- - python-3.9.0.exe /layout [optional target directory] +To perform offline installs of Python, you will need to first create an offline +index on a machine that has network access. -You may also specify the ``/quiet`` option to hide the progress display. +.. code:: -Modifying an install --------------------- + $> py install --download=<PATH> ... <TAG>... -Once Python has been installed, you can add or remove features through the -Programs and Features tool that is part of Windows. Select the Python entry and -choose "Uninstall/Change" to open the installer in maintenance mode. +The ``--download=<PATH>`` option will download the packages for the listed tags +and create a directory containing them and an ``index.json`` file suitable for +later installation. This entire directory can be moved to the offline machine +and used to install one or more of the bundled runtimes: -"Modify" allows you to add or remove features by modifying the checkboxes - -unchanged checkboxes will not install or remove anything. Some options cannot be -changed in this mode, such as the install directory; to modify these, you will -need to remove and then reinstall Python completely. +.. code:: -"Repair" will verify all the files that should be installed using the current -settings and replace any that have been removed or modified. + $> py install --source="<PATH>\index.json" <TAG>... -"Uninstall" will remove Python entirely, with the exception of the -:ref:`launcher`, which has its own entry in Programs and Features. +The Python install manager can be installed by downloading its installer and +moving it to another machine before installing. -.. _install-freethreaded-windows: +Alternatively, the ZIP files in an offline index directory can simply be +transferred to another machine and extracted. This will not register the install +in any way, and so it must be launched by directly referencing the executables +in the extracted directory, but it is sometimes a preferable approach in cases +where installing the Python install manager is not possible or convenient. -Installing Free-threaded Binaries ---------------------------------- +In this way, Python runtimes can be installed and managed on a machine without +access to the internet. -.. versionadded:: 3.13 (Experimental) -.. note:: +Uninstalling Runtimes +--------------------- - Everything described in this section is considered experimental, - and should be expected to change in future releases. +.. code:: -To install pre-built binaries with free-threading enabled (see :pep:`703`), you -should select "Customize installation". The second page of options includes the -"Download free-threaded binaries" checkbox. + $> py uninstall [-y|--yes] <TAG>... -.. image:: win_install_freethreaded.png +Runtimes may be removed using the ``py uninstall`` command. One or more tags +must be specified. Ranges are not supported here. -Selecting this option will download and install additional binaries to the same -location as the main Python install. The main executable is called -``python3.13t.exe``, and other binaries either receive a ``t`` suffix or a full -ABI suffix. Python source files and bundled third-party dependencies are shared -with the main install. +The ``--yes`` option bypasses the confirmation prompt before uninstalling. -The free-threaded version is registered as a regular Python install with the -tag ``3.13t`` (with a ``-32`` or ``-arm64`` suffix as normal for those -platforms). This allows tools to discover it, and for the :ref:`launcher` to -support ``py.exe -3.13t``. Note that the launcher will interpret ``py.exe -3`` -(or a ``python3`` shebang) as "the latest 3.x install", which will prefer the -free-threaded binaries over the regular ones, while ``py.exe -3.13`` will not. -If you use the short style of option, you may prefer to not install the -free-threaded binaries at this time. +Instead of passing tags individually, the ``--purge`` option may be specified. +This will remove all runtimes managed by the Python install manager, including +cleaning up the Start menu, registry, and any download caches. Runtimes that +were not installed by the Python install manager will not be impacted, and +neither will manually created configuration files. -To specify the install option at the command line, use -``Include_freethreaded=1``. See :ref:`install-layout-option` for instructions on -pre-emptively downloading the additional binaries for offline install. The -options to include debug symbols and binaries also apply to the free-threaded -builds. +.. code:: -Free-threaded binaries are also available :ref:`on nuget.org <windows-nuget>`. + $> py uninstall [-y|--yes] --purge -.. _windows-store: +The Python install manager can be uninstalled through the Windows "Installed +apps" settings page. This does not remove any runtimes, and they will still be +usable, though the global ``python`` and ``py`` commands will be removed. +Reinstalling the Python install manager will allow you to manage these runtimes +again. To completely clean up all Python runtimes, run with ``--purge`` before +uninstalling the Python install manager. -The Microsoft Store package -=========================== +.. _pymanager-config: -.. versionadded:: 3.7.2 +Configuration +------------- -The Microsoft Store package is an easily installable Python interpreter that -is intended mainly for interactive use, for example, by students. +Python install manager is configured with a hierarchy of configuration files, +environment variables, command-line options, and registry settings. In general, +configuration files have the ability to configure everything, including the +location of other configuration files, while registry settings are +administrator-only and will override configuration files. Command-line options +override all other settings, but not every option is available. + +This section will describe the defaults, but be aware that modified or +overridden installs may resolve settings differently. + +A global configuration file may be configured by an administrator, and would be +read first. The user configuration file is stored at +:file:`%AppData%\\Python\\pymanager.json` (by default) and is read next, +overwriting any settings from earlier files. An additional configuration file +may be specified as the ``PYTHON_MANAGER_CONFIG`` environment variable or the +``--config`` command line option (but not both). + +The following settings are those that are considered likely to be modified in +normal use. Later sections list those that are intended for administrative +customization. + +.. csv-table:: Standard configuration options + :header: "Config Key", "Environment Variable", "Description" + :widths: 2, 2, 4 + + ``default_tag``,``PYTHON_MANAGER_DEFAULT``,"The preferred default + version to launch or install. By default, this is interpreted as the most + recent non-prerelease version from the CPython team. + " + ``default_platform``,``PYTHON_MANAGER_DEFAULT_PLATFORM``,"The preferred + default platform to launch or install. This is treated as a suffix to the + specified tag, such that ``py -V:3.14`` would prefer an install for + ``3.14-64`` if it exists (and ``default_platform`` is ``-64``), but will use + ``3.14`` if no tagged install exists. + " + ``logs_dir``,``PYTHON_MANAGER_LOGS``,"The location where log files are + written. By default, :file:`%TEMP%`. + " + ``automatic_install``,``PYTHON_MANAGER_AUTOMATIC_INSTALL``,"True to + allow automatic installs when specifying a particular runtime to launch. + By default, true. + " + ``include_unmanaged``,``PYTHON_MANAGER_INCLUDE_UNMANAGED``,"True to + allow listing and launching runtimes that were not installed by the Python + install manager, or false to exclude them. By default, true. + " + ``shebang_can_run_anything``,"``PYTHON_MANAGER_SHEBANG_CAN_RUN_ANYTHING`` + ","True to allow shebangs in ``.py`` files to launch applications other than + Python runtimes, or false to prevent it. By default, true. + " + ``log_level``,"``PYMANAGER_VERBOSE``, ``PYMANAGER_DEBUG``","Set + the default level of output (0-50) By default, 20. Lower values produce more + output. The environment variables are boolean, and may produce additional + output during startup that is later suppressed by other configuration. + " + ``confirm``,``PYTHON_MANAGER_CONFIRM``,"True to confirm certain actions + before taking them (such as uninstall), or false to skip the confirmation. By + default, true. + " + ``install.source``,``PYTHON_MANAGER_SOURCE_URL``,"Override the index + feed to obtain new installs from. + " + ``list.format``,``PYTHON_MANAGER_LIST_FORMAT``,"Specify the default + format used by the ``py list`` command. By default, ``table``. + " + +Dotted names should be nested inside JSON objects, for example, ``list.format`` +would be specified as ``{"list": {"format": "table"}}``. + +.. _pymanager-shebang: + +Shebang lines +------------- -To install the package, ensure you have the latest Windows 10 updates and -search the Microsoft Store app for "Python |version|". Ensure that the app -you select is published by the Python Software Foundation, and install it. +If the first line of a script file starts with ``#!``, it is known as a +"shebang" line. Linux and other Unix like operating systems have native +support for such lines and they are commonly used on such systems to indicate +how a script should be executed. The ``python`` and ``py`` commands allow the +same facilities to be used with Python scripts on Windows. -.. warning:: - Python will always be available for free on the Microsoft Store. If you - are asked to pay for it, you have not selected the correct package. +To allow shebang lines in Python scripts to be portable between Unix and +Windows, a number of 'virtual' commands are supported to specify which +interpreter to use. The supported virtual commands are: -After installation, Python may be launched by finding it in Start. -Alternatively, it will be available from any Command Prompt or PowerShell -session by typing ``python``. Further, pip and IDLE may be used by typing -``pip`` or ``idle``. IDLE can also be found in Start. +* ``/usr/bin/env <ALIAS>`` +* ``/usr/bin/env -S <ALIAS>`` +* ``/usr/bin/<ALIAS>`` +* ``/usr/local/bin/<ALIAS>`` +* ``<ALIAS>`` -All three commands are also available with version number suffixes, for -example, as ``python3.exe`` and ``python3.x.exe`` as well as -``python.exe`` (where ``3.x`` is the specific version you want to launch, -such as |version|). Open "Manage App Execution Aliases" through Start to -select which version of Python is associated with each command. It is -recommended to make sure that ``pip`` and ``idle`` are consistent with -whichever version of ``python`` is selected. +For example, if the first line of your script starts with -Virtual environments can be created with ``python -m venv`` and activated -and used as normal. +.. code-block:: sh -If you have installed another version of Python and added it to your -``PATH`` variable, it will be available as ``python.exe`` rather than the -one from the Microsoft Store. To access the new installation, use -``python3.exe`` or ``python3.x.exe``. + #! /usr/bin/python -The ``py.exe`` launcher will detect this Python installation, but will prefer -installations from the traditional installer. +The default Python or an active virtual environment will be located and used. +As many Python scripts written to work on Unix will already have this line, +you should find these scripts can be used by the launcher without modification. +If you are writing a new script on Windows which you hope will be useful on +Unix, you should use one of the shebang lines starting with ``/usr``. -To remove Python, open Settings and use Apps and Features, or else find -Python in Start and right-click to select Uninstall. Uninstalling will -remove all packages you installed directly into this Python installation, but -will not remove any virtual environments +Any of the above virtual commands can have ``<ALIAS>`` replaced by an alias from +an installed runtime. That is, any command generated in the global aliases +directory (which you may have added to your :envvar:`PATH` environment variable) +can be used in a shebang, even if it is not on your :envvar:`PATH`. This allows +the use of shebangs like ``/usr/bin/python3.12`` to select a particular runtime. + +The ``/usr/bin/env`` form of shebang line will also search the :envvar:`PATH` +environment variable for unrecognized commands. This corresponds to the +behaviour of the Unix ``env`` program, which performs the same search, but +prefers launching known Python commands. A warning may be displayed when +searching for arbitrary executables, and this search may be disabled by the +``shebang_can_run_anything`` configuration option. + +Shebang lines that do not match any of patterns are treated as *Windows* +executable paths that are absolute or relative to the directory containing the +script file. This is a convenience for Windows-only scripts, such as those +generated by an installer, since the behavior is not compatible with Unix-style +shells. These paths may be quoted, and may include multiple arguments, after +which the path to the script and any additional arguments will be appended. +This functionality may be disabled by the ``shebang_can_run_anything`` +configuration option. + +.. note: + + The behaviour of shebangs in the Python install manager is subtly different + from the previous ``py.exe`` launcher, and the old configuration options no + longer apply. If you are specifically reliant on the old behaviour or + configuration, we recommend keeping the legacy launcher. It may be + `downloaded independently <https://www.python.org/ftp/python/3.13.1/win32/launcher.msi>`_ + and installed on its own. The legacy launcher's ``py`` command will override + PyManager's one, and you will need to use ``pymanager`` commands for + installing and uninstalling. + + +.. _pymanager-advancedinstall: + +Advanced Installation +--------------------- -Known issues ------------- +For situations where an MSIX cannot be installed, such as some older +administrative distribution platforms, there is an MSI available from the +python.org downloads page. This MSI has no user interface, and can only perform +per-machine installs to its default location in Program Files. It will attempt +to modify the system :envvar:`PATH` environment variable to include this install +location, but be sure to validate this on your configuration. + +Be aware that the MSI package does not bundle any runtimes, and so is not +suitable for installs into offline environments without also creating an offline +install index. See :ref:`pymanager-offline` and :ref:`pymanager-admin-config` +for information on handling these scenarios. + +Runtimes installed by the MSI are shared with those installed by the MSIX, and +are all per-user only. The Python install manager does not support installing +runtimes per-machine. To emulate a per-machine install, you can use ``py install +--target=<shared location>`` as administrator and add your own system-wide +modifications to :envvar:`PATH`, the registry, or the Start menu. + +When the MSIX is installed, but commands are not available in the :envvar:`PATH` +environment variable, they can be found under +:file:`%LocalAppData%\\Microsoft\\WindowsApps\\PythonSoftwareFoundation.PythonManager_3847v3x7pw1km` +or +:file:`%LocalAppData%\\Microsoft\\WindowsApps\\PythonSoftwareFoundation.PythonManager_qbz5n2kfra8p0`, +depending on whether it was installed from python.org or through the Windows +Store. Attempting to run the executable directly from Program Files is not +recommended. + + +.. _pymanager-admin-config: + +Administrative Configuration +---------------------------- + +There are a number of options that may be useful for administrators to override +configuration of the Python install manager. These can be used to provide local +caching, disable certain shortcut types, override bundled content. All of the +above configuration options may be set, as well as those below. + +Configuration options may be overridden in the registry by setting values under +:file:`HKEY_LOCAL_MACHINE\\Software\\Policies\\Python\\PyManager`, where the +value name matches the configuration key and the value type is ``REG_SZ``. Note +that this key can itself be customized, but only by modifying the core config +file distributed with the Python install manager. We recommend, however, that +registry values are used only to set ``base_config`` to a JSON file containing +the full set of overrides. Registry key overrides will replace any other +configured setting, while ``base_config`` allows users to further modify +settings they may need. + +Note that most settings with environment variables support those variables +because their default setting specifies the variable. If you override them, the +environment variable will no longer work, unless you override it with another +one. For example, the default value of ``confirm`` is literally +``%PYTHON_MANAGER_CONFIRM%``, which will resolve the variable at load time. If +you override the value to ``yes``, then the environment variable will no longer +be used. If you override the value to ``%CONFIRM%``, then that environment +variable will be used instead. + +Configuration settings that are paths are interpreted as relative to the +directory containing the configuration file that specified them. + +.. csv-table:: Administrative configuration options + :header: "Config Key", "Description" + :widths: 1, 4 + + ``base_config``,"The highest priority configuration file to read. Note that + only the built-in configuration file and the registry can modify this + setting. + " + ``user_config``,"The second configuration file to read. + " + ``additional_config``,"The third configuration file to read. + " + ``registry_override_key``,"Registry location to check for overrides. Note + that only the built-in configuration file can modify this setting. + " + ``bundled_dir``,"Read-only directory containing locally cached files. + " + ``install.fallback_source``,"Path or URL to an index to consult when the + main index cannot be accessed. + " + ``install.enable_shortcut_kinds``,"Comma-separated list of shortcut kinds + to allow (e.g. ``""pep514,start""``). Enabled shortcuts may still be disabled + by ``disable_shortcut_kinds``. + " + ``install.disable_shortcut_kinds``,"Comma-separated list of shortcut kinds + to exclude (e.g. ``""pep514,start""``). Disabled shortcuts are not + reactivated by ``enable_shortcut_kinds``. + " + ``pep514_root``,"Registry location to read and write PEP 514 entries into. + By default, :file:`HKEY_CURRENT_USER\\Software\\Python`. + " + ``start_folder``,"Start menu folder to write shortcuts into. By default, + ``Python``. This path is relative to the user's Programs folder. + " + ``virtual_env``,"Path to the active virtual environment. By default, this + is ``%VIRTUAL_ENV%``, but may be set empty to disable venv detection. + " + ``shebang_can_run_anything_silently``,"True to suppress visible warnings + when a shebang launches an application other than a Python runtime. + " -Redirection of local data, registry, and temporary paths -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. _install-freethreaded-windows: -Because of restrictions on Microsoft Store apps, Python scripts may not have -full write access to shared locations such as :envvar:`TEMP` and the registry. -Instead, it will write to a private copy. If your scripts must modify the -shared locations, you will need to install the full installer. +Installing Free-threaded Binaries +--------------------------------- -At runtime, Python will use a private copy of well-known Windows folders and the registry. -For example, if the environment variable :envvar:`%APPDATA%` is :file:`c:\\Users\\<user>\\AppData\\`, -then when writing to :file:`C:\\Users\\<user>\\AppData\\Local` will write to -:file:`C:\\Users\\<user>\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\\LocalCache\\Local\\`. +.. versionadded:: 3.13 (Experimental) -When reading files, Windows will return the file from the private folder, or if that does not exist, the -real Windows directory. For example reading :file:`C:\\Windows\\System32` returns the contents of :file:`C:\\Windows\\System32` -plus the contents of :file:`C:\\Program Files\\WindowsApps\\package_name\\VFS\\SystemX86`. +.. note:: -You can find the real path of any existing file using :func:`os.path.realpath`: + Everything described in this section is considered experimental, + and should be expected to change in future releases. -.. code-block:: python +Pre-built distributions of the experimental free-threaded build are available +by installing tags with the ``t`` suffix. + +.. code:: + + $> py install 3.14t + $> py install 3.14t-arm64 + $> py install 3.14t-32 + +This will install and register as normal. If you have no other runtimes +installed, then ``python`` will launch this one. Otherwise, you will need to use +``py -V:3.14t ...`` or, if you have added the global aliases directory to your +:envvar:`PATH` environment variable, the ``python3.14t.exe`` commands. + +.. _pymanager-troubleshoot: + +Troubleshooting +--------------- + +If your Python install manager does not seem to be working correctly, please +work through these tests and fixes to see if it helps. If not, please report an +issue at `our bug tracker <https://github.com/python/cpython/issues>`_, +including any relevant log files (written to your :file:`%TEMP%` directory by +default). + +.. csv-table:: Troubleshooting + :header: "Symptom", "Things to try" + :widths: 1, 1 + + "``python`` gives me a ""command not found"" error or opens the Store app + when I type it in my terminal.", "Did you :ref:`install the Python install + manager <pymanager>`? + " + "", "Click Start, open ""Manage app execution aliases"", and check that the + aliases for ""Python (default)"" are enabled. If they already are, try + disabling and re-enabling to refresh the command. The ""Python (default + windowed)"" and ""Python install manager"" commands may also need refreshing. + " + "", "Check that the ``py`` and ``pymanager`` commands work. + " + "``py`` gives me a ""command not found"" error when I type it in my + terminal.","Did you :ref:`install the Python install manager <pymanager>`? + " + "", "Click Start, open ""Manage app execution aliases"", and check that the + aliases for ""Python install manager"" are enabled. If they already are, try + disabling and re-enabling to refresh the command. The ""Python (default + windowed)"" and ""Python install manager"" commands may also need refreshing. + " + "``py`` gives me a ""can't open file"" error when I type commands in my + terminal.", "This usually means you have the legacy launcher installed and it + has priority over the Python install manager. To remove, click Start, open + ""Installed apps"", search for ""Python launcher"" and uninstall it. + " + "``python`` doesn't launch the same runtime as ``py``", "Click Start, open + ""Installed apps"", look for any existing Python runtimes, and either remove + them or Modify and disable the :envvar:`PATH` options. + " + "", "Click Start, open ""Manage app execution aliases"", and check that your + ``python.exe`` alias is set to ""Python (default)"" + " + "``python`` and ``py`` don't launch the runtime I expect", "Check your + ``PYTHON_MANAGER_DEFAULT`` environment variable or ``default_tag`` + configuration. The ``py list`` command will show your default based on these + settings. + " + "", "Installs that are managed by the Python install manager will be chosen + ahead of unmanaged installs. Use ``py install`` to install the runtime you + expect, or configure your default tag. + " + "", "Prerelease and experimental installs that are not managed by the Python + install manager may be chosen ahead of stable releases. Configure your + default tag or uninstall the prerelease runtime and reinstall using ``py + install``. + " + "``pythonw`` or ``pyw`` don't launch the same runtime as ``python`` or + ``py``","Click Start, open ""Manage app execution aliases"", and check that + your ``pythonw.exe`` and ``pyw.exe`` aliases are consistent with your + others. + " + + +.. _windows-embeddable: + +The embeddable package +====================== + +.. versionadded:: 3.5 + +The embedded distribution is a ZIP file containing a minimal Python environment. +It is intended for acting as part of another application, rather than being +directly accessed by end-users. + +To install an embedded distribution, we recommend using ``py install`` with the +``--target`` option: + +.. code:: + + $> py install 3.14-embed --target=runtime + +When extracted, the embedded distribution is (almost) fully isolated from the +user's system, including environment variables, system registry settings, and +installed packages. The standard library is included as pre-compiled and +optimized ``.pyc`` files in a ZIP, and ``python3.dll``, ``python313.dll``, +``python.exe`` and ``pythonw.exe`` are all provided. Tcl/tk (including all +dependents, such as Idle), pip and the Python documentation are not included. + +A default ``._pth`` file is included, which further restricts the default search +paths (as described below in :ref:`windows_finding_modules`). This file is +intended for embedders to modify as necessary. + +Third-party packages should be installed by the application installer alongside +the embedded distribution. Using pip to manage dependencies as for a regular +Python installation is not supported with this distribution, though with some +care it may be possible to include and use pip for automatic updates. In +general, third-party packages should be treated as part of the application +("vendoring") so that the developer can ensure compatibility with newer +versions before providing updates to users. + +The two recommended use cases for this distribution are described below. + +Python Application +------------------ + +An application written in Python does not necessarily require users to be aware +of that fact. The embedded distribution may be used in this case to include a +private version of Python in an install package. Depending on how transparent it +should be (or conversely, how professional it should appear), there are two +options. - >>> import os - >>> test_file = 'C:\\Users\\example\\AppData\\Local\\test.txt' - >>> os.path.realpath(test_file) - 'C:\\Users\\example\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\\LocalCache\\Local\\test.txt' +Using a specialized executable as a launcher requires some coding, but provides +the most transparent experience for users. With a customized launcher, there are +no obvious indications that the program is running on Python: icons can be +customized, company and version information can be specified, and file +associations behave properly. In most cases, a custom launcher should simply be +able to call ``Py_Main`` with a hard-coded command line. + +The simpler approach is to provide a batch file or generated shortcut that +directly calls the ``python.exe`` or ``pythonw.exe`` with the required +command-line arguments. In this case, the application will appear to be Python +and not its actual name, and users may have trouble distinguishing it from other +running Python processes or file associations. + +With the latter approach, packages should be installed as directories alongside +the Python executable to ensure they are available on the path. With the +specialized launcher, packages can be located in other locations as there is an +opportunity to specify the search path before launching the application. -When writing to the Windows Registry, the following behaviors exist: +Embedding Python +---------------- -* Reading from ``HKLM\\Software`` is allowed and results are merged with the :file:`registry.dat` file in the package. -* Writing to ``HKLM\\Software`` is not allowed if the corresponding key/value exists, i.e. modifying existing keys. -* Writing to ``HKLM\\Software`` is allowed as long as a corresponding key/value does not exist in the package - and the user has the correct access permissions. +Applications written in native code often require some form of scripting +language, and the embedded Python distribution can be used for this purpose. In +general, the majority of the application is in native code, and some part will +either invoke ``python.exe`` or directly use ``python3.dll``. For either case, +extracting the embedded distribution to a subdirectory of the application +installation is sufficient to provide a loadable Python interpreter. -For more detail on the technical basis for these limitations, please consult -Microsoft's documentation on packaged full-trust apps, currently available at -`docs.microsoft.com/en-us/windows/msix/desktop/desktop-to-uwp-behind-the-scenes -<https://learn.microsoft.com/windows/msix/desktop/desktop-to-uwp-behind-the-scenes>`_ +As with the application use, packages can be installed to any location as there +is an opportunity to specify search paths before initializing the interpreter. +Otherwise, there is no fundamental differences between using the embedded +distribution and a regular installation. .. _windows-nuget: @@ -515,85 +855,6 @@ version, and `pythonarm64-freethreaded version. These packages contain both the ``python3.13t.exe`` and ``python.exe`` entry points, both of which run free threaded. -.. _windows-embeddable: - -The embeddable package -====================== - -.. versionadded:: 3.5 - -The embedded distribution is a ZIP file containing a minimal Python environment. -It is intended for acting as part of another application, rather than being -directly accessed by end-users. - -When extracted, the embedded distribution is (almost) fully isolated from the -user's system, including environment variables, system registry settings, and -installed packages. The standard library is included as pre-compiled and -optimized ``.pyc`` files in a ZIP, and ``python3.dll``, ``python37.dll``, -``python.exe`` and ``pythonw.exe`` are all provided. Tcl/tk (including all -dependents, such as Idle), pip and the Python documentation are not included. - -.. note:: - - The embedded distribution does not include the `Microsoft C Runtime - <https://learn.microsoft.com/cpp/windows/latest-supported-vc-redist#visual-studio-2015-2017-2019-and-2022>`_ and it is - the responsibility of the application installer to provide this. The - runtime may have already been installed on a user's system previously or - automatically via Windows Update, and can be detected by finding - ``ucrtbase.dll`` in the system directory. - -Third-party packages should be installed by the application installer alongside -the embedded distribution. Using pip to manage dependencies as for a regular -Python installation is not supported with this distribution, though with some -care it may be possible to include and use pip for automatic updates. In -general, third-party packages should be treated as part of the application -("vendoring") so that the developer can ensure compatibility with newer -versions before providing updates to users. - -The two recommended use cases for this distribution are described below. - -Python Application ------------------- - -An application written in Python does not necessarily require users to be aware -of that fact. The embedded distribution may be used in this case to include a -private version of Python in an install package. Depending on how transparent it -should be (or conversely, how professional it should appear), there are two -options. - -Using a specialized executable as a launcher requires some coding, but provides -the most transparent experience for users. With a customized launcher, there are -no obvious indications that the program is running on Python: icons can be -customized, company and version information can be specified, and file -associations behave properly. In most cases, a custom launcher should simply be -able to call ``Py_Main`` with a hard-coded command line. - -The simpler approach is to provide a batch file or generated shortcut that -directly calls the ``python.exe`` or ``pythonw.exe`` with the required -command-line arguments. In this case, the application will appear to be Python -and not its actual name, and users may have trouble distinguishing it from other -running Python processes or file associations. - -With the latter approach, packages should be installed as directories alongside -the Python executable to ensure they are available on the path. With the -specialized launcher, packages can be located in other locations as there is an -opportunity to specify the search path before launching the application. - -Embedding Python ----------------- - -Applications written in native code often require some form of scripting -language, and the embedded Python distribution can be used for this purpose. In -general, the majority of the application is in native code, and some part will -either invoke ``python.exe`` or directly use ``python3.dll``. For either case, -extracting the embedded distribution to a subdirectory of the application -installation is sufficient to provide a loadable Python interpreter. - -As with the application use, packages can be installed to any location as there -is an opportunity to specify search paths before initializing the interpreter. -Otherwise, there is no fundamental differences between using the embedded -distribution and a regular installation. - Alternative bundles =================== @@ -623,142 +884,560 @@ Note that these packages may not include the latest versions of Python or other libraries, and are not maintained or supported by the core Python team. +Supported Windows versions +========================== + +As specified in :pep:`11`, a Python release only supports a Windows platform +while Microsoft considers the platform under extended support. This means that +Python |version| supports Windows 10 and newer. If you require Windows 7 +support, please install Python 3.8. If you require Windows 8.1 support, +please install Python 3.12. -Configuring Python -================== -To run Python conveniently from a command prompt, you might consider changing -some default environment variables in Windows. While the installer provides an -option to configure the PATH and PATHEXT variables for you, this is only -reliable for a single, system-wide installation. If you regularly use multiple -versions of Python, consider using the :ref:`launcher`. +.. _max-path: +Removing the MAX_PATH Limitation +================================ -.. _setting-envvars: +Windows historically has limited path lengths to 260 characters. This meant that +paths longer than this would not resolve and errors would result. -Excursus: Setting environment variables ---------------------------------------- +In the latest versions of Windows, this limitation can be expanded to over +32,000 characters. Your administrator will need to activate the "Enable Win32 +long paths" group policy, or set ``LongPathsEnabled`` to ``1`` in the registry +key ``HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem``. -Windows allows environment variables to be configured permanently at both the -User level and the System level, or temporarily in a command prompt. +This allows the :func:`open` function, the :mod:`os` module and most other +path functionality to accept and return paths longer than 260 characters. -To temporarily set environment variables, open Command Prompt and use the -:command:`set` command: +After changing the above option and rebooting, no further configuration is +required. -.. code-block:: doscon - C:\>set PATH=C:\Program Files\Python 3.9;%PATH% - C:\>set PYTHONPATH=%PYTHONPATH%;C:\My_python_lib - C:\>python +.. _win-utf8-mode: + +UTF-8 mode +========== + +.. versionadded:: 3.7 + +Windows still uses legacy encodings for the system encoding (the ANSI Code +Page). Python uses it for the default encoding of text files (e.g. +:func:`locale.getencoding`). + +This may cause issues because UTF-8 is widely used on the internet +and most Unix systems, including WSL (Windows Subsystem for Linux). -These changes will apply to any further commands executed in that console, and -will be inherited by any applications started from the console. +You can use the :ref:`Python UTF-8 Mode <utf8-mode>` to change the default text +encoding to UTF-8. You can enable the :ref:`Python UTF-8 Mode <utf8-mode>` via +the ``-X utf8`` command line option, or the ``PYTHONUTF8=1`` environment +variable. See :envvar:`PYTHONUTF8` for enabling UTF-8 mode, and +:ref:`setting-envvars` for how to modify environment variables. -Including the variable name within percent signs will expand to the existing -value, allowing you to add your new value at either the start or the end. -Modifying :envvar:`PATH` by adding the directory containing -:program:`python.exe` to the start is a common way to ensure the correct version -of Python is launched. +When the :ref:`Python UTF-8 Mode <utf8-mode>` is enabled, you can still use the +system encoding (the ANSI Code Page) via the "mbcs" codec. -To permanently modify the default environment variables, click Start and search -for 'edit environment variables', or open System properties, :guilabel:`Advanced -system settings` and click the :guilabel:`Environment Variables` button. -In this dialog, you can add or modify User and System variables. To change -System variables, you need non-restricted access to your machine -(i.e. Administrator rights). +Note that adding ``PYTHONUTF8=1`` to the default environment variables +will affect all Python 3.7+ applications on your system. +If you have any Python 3.7+ applications which rely on the legacy +system encoding, it is recommended to set the environment variable +temporarily or use the ``-X utf8`` command line option. .. note:: + Even when UTF-8 mode is disabled, Python uses UTF-8 by default + on Windows for: + + * Console I/O including standard I/O (see :pep:`528` for details). + * The :term:`filesystem encoding <filesystem encoding and error handler>` + (see :pep:`529` for details). + - Windows will concatenate User variables *after* System variables, which may - cause unexpected results when modifying :envvar:`PATH`. +.. _windows_finding_modules: - The :envvar:`PYTHONPATH` variable is used by all versions of Python, - so you should not permanently configure it unless the listed paths - only include code that is compatible with all of your installed Python - versions. +Finding modules +=============== -.. seealso:: +These notes supplement the description at :ref:`sys-path-init` with +detailed Windows notes. + +When no ``._pth`` file is found, this is how :data:`sys.path` is populated on +Windows: + +* An empty entry is added at the start, which corresponds to the current + directory. + +* If the environment variable :envvar:`PYTHONPATH` exists, as described in + :ref:`using-on-envvars`, its entries are added next. Note that on Windows, + paths in this variable must be separated by semicolons, to distinguish them + from the colon used in drive identifiers (``C:\`` etc.). + +* Additional "application paths" can be added in the registry as subkeys of + :samp:`\\SOFTWARE\\Python\\PythonCore\\{version}\\PythonPath` under both the + ``HKEY_CURRENT_USER`` and ``HKEY_LOCAL_MACHINE`` hives. Subkeys which have + semicolon-delimited path strings as their default value will cause each path + to be added to :data:`sys.path`. (Note that all known installers only use + HKLM, so HKCU is typically empty.) + +* If the environment variable :envvar:`PYTHONHOME` is set, it is assumed as + "Python Home". Otherwise, the path of the main Python executable is used to + locate a "landmark file" (either ``Lib\os.py`` or ``pythonXY.zip``) to deduce + the "Python Home". If a Python home is found, the relevant sub-directories + added to :data:`sys.path` (``Lib``, ``plat-win``, etc) are based on that + folder. Otherwise, the core Python path is constructed from the PythonPath + stored in the registry. + +* If the Python Home cannot be located, no :envvar:`PYTHONPATH` is specified in + the environment, and no registry entries can be found, a default path with + relative entries is used (e.g. ``.\Lib;.\plat-win``, etc). + +If a ``pyvenv.cfg`` file is found alongside the main executable or in the +directory one level above the executable, the following variations apply: + +* If ``home`` is an absolute path and :envvar:`PYTHONHOME` is not set, this + path is used instead of the path to the main executable when deducing the + home location. + +The end result of all this is: + +* When running :file:`python.exe`, or any other .exe in the main Python + directory (either an installed version, or directly from the PCbuild + directory), the core path is deduced, and the core paths in the registry are + ignored. Other "application paths" in the registry are always read. + +* When Python is hosted in another .exe (different directory, embedded via COM, + etc), the "Python Home" will not be deduced, so the core path from the + registry is used. Other "application paths" in the registry are always read. + +* If Python can't find its home and there are no registry value (frozen .exe, + some very strange installation setup) you get a path with some default, but + relative, paths. + +For those who want to bundle Python into their application or distribution, the +following advice will prevent conflicts with other installations: + +* Include a ``._pth`` file alongside your executable containing the + directories to include. This will ignore paths listed in the registry and + environment variables, and also ignore :mod:`site` unless ``import site`` is + listed. + +* If you are loading :file:`python3.dll` or :file:`python37.dll` in your own + executable, explicitly set :c:member:`PyConfig.module_search_paths` before + :c:func:`Py_InitializeFromConfig`. + +* Clear and/or overwrite :envvar:`PYTHONPATH` and set :envvar:`PYTHONHOME` + before launching :file:`python.exe` from your application. + +* If you cannot use the previous suggestions (for example, you are a + distribution that allows people to run :file:`python.exe` directly), ensure + that the landmark file (:file:`Lib\\os.py`) exists in your install directory. + (Note that it will not be detected inside a ZIP file, but a correctly named + ZIP file will be detected instead.) + +These will ensure that the files in a system-wide installation will not take +precedence over the copy of the standard library bundled with your application. +Otherwise, your users may experience problems using your application. Note that +the first suggestion is the best, as the others may still be susceptible to +non-standard paths in the registry and user site-packages. + +.. versionchanged:: 3.6 + + Add ``._pth`` file support and removes ``applocal`` option from + ``pyvenv.cfg``. + +.. versionchanged:: 3.6 + + Add :file:`python{XX}.zip` as a potential landmark when directly adjacent + to the executable. + +.. deprecated:: 3.6 + + Modules specified in the registry under ``Modules`` (not ``PythonPath``) + may be imported by :class:`importlib.machinery.WindowsRegistryFinder`. + This finder is enabled on Windows in 3.6.0 and earlier, but may need to + be explicitly added to :data:`sys.meta_path` in the future. + +Additional modules +================== + +Even though Python aims to be portable among all platforms, there are features +that are unique to Windows. A couple of modules, both in the standard library +and external, and snippets exist to use these features. + +The Windows-specific standard modules are documented in +:ref:`mswin-specific-services`. + +PyWin32 +------- + +The :pypi:`PyWin32` module by Mark Hammond +is a collection of modules for advanced Windows-specific support. This includes +utilities for: + +* `Component Object Model + <https://learn.microsoft.com/windows/win32/com/component-object-model--com--portal>`_ + (COM) +* Win32 API calls +* Registry +* Event log +* `Microsoft Foundation Classes + <https://learn.microsoft.com/cpp/mfc/mfc-desktop-applications>`_ + (MFC) user interfaces + +`PythonWin <https://web.archive.org/web/20060524042422/ +https://www.python.org/windows/pythonwin/>`_ is a sample MFC application +shipped with PyWin32. It is an embeddable IDE with a built-in debugger. + +.. seealso:: + + `Win32 How Do I...? <https://timgolden.me.uk/python/win32_how_do_i.html>`_ + by Tim Golden + + `Python and COM <https://www.boddie.org.uk/python/COM.html>`_ + by David and Paul Boddie + + +cx_Freeze +--------- + +`cx_Freeze <https://cx-freeze.readthedocs.io/en/latest/>`_ +wraps Python scripts into executable Windows programs +(:file:`{*}.exe` files). When you have done this, you can distribute your +application without requiring your users to install Python. + + +Compiling Python on Windows +=========================== + +If you want to compile CPython yourself, first thing you should do is get the +`source <https://www.python.org/downloads/source/>`_. You can download either the +latest release's source or just grab a fresh `checkout +<https://devguide.python.org/setup/#get-the-source-code>`_. + +The source tree contains a build solution and project files for Microsoft +Visual Studio, which is the compiler used to build the official Python +releases. These files are in the :file:`PCbuild` directory. + +Check :file:`PCbuild/readme.txt` for general information on the build process. + +For extension modules, consult :ref:`building-on-windows`. + + + +.. _windows-full: + +The full installer (deprecated) +=============================== + +.. deprecated:: 3.14 + + This installer is deprecated since 3.14 and will not be produced for Python + 3.16 or later. See :ref:`pymanager` for the modern installer. + + +Installation steps +------------------ + +Four Python |version| installers are available for download - two each for the +32-bit and 64-bit versions of the interpreter. The *web installer* is a small +initial download, and it will automatically download the required components as +necessary. The *offline installer* includes the components necessary for a +default installation and only requires an internet connection for optional +features. See :ref:`install-layout-option` for other ways to avoid downloading +during installation. + +After starting the installer, one of two options may be selected: + +.. image:: win_installer.png + +If you select "Install Now": + +* You will *not* need to be an administrator (unless a system update for the + C Runtime Library is required or you install the :ref:`launcher` for all + users) +* Python will be installed into your user directory +* The :ref:`launcher` will be installed according to the option at the bottom + of the first page +* The standard library, test suite, launcher and pip will be installed +* If selected, the install directory will be added to your :envvar:`PATH` +* Shortcuts will only be visible for the current user + +Selecting "Customize installation" will allow you to select the features to +install, the installation location and other options or post-install actions. +To install debugging symbols or binaries, you will need to use this option. + +To perform an all-users installation, you should select "Customize +installation". In this case: + +* You may be required to provide administrative credentials or approval +* Python will be installed into the Program Files directory +* The :ref:`launcher` will be installed into the Windows directory +* Optional features may be selected during installation +* The standard library can be pre-compiled to bytecode +* If selected, the install directory will be added to the system :envvar:`PATH` +* Shortcuts are available for all users + + +Removing the MAX_PATH Limitation +-------------------------------- + +Windows historically has limited path lengths to 260 characters. This meant that +paths longer than this would not resolve and errors would result. + +In the latest versions of Windows, this limitation can be expanded to +approximately 32,000 characters. Your administrator will need to activate the +"Enable Win32 long paths" group policy, or set ``LongPathsEnabled`` to ``1`` +in the registry key +``HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem``. + +This allows the :func:`open` function, the :mod:`os` module and most other +path functionality to accept and return paths longer than 260 characters. + +After changing the above option, no further configuration is required. + +.. versionchanged:: 3.6 + + Support for long paths was enabled in Python. + +.. _install-quiet-option: + +Installing Without UI +--------------------- + +All of the options available in the installer UI can also be specified from the +command line, allowing scripted installers to replicate an installation on many +machines without user interaction. These options may also be set without +suppressing the UI in order to change some of the defaults. + +The following options (found by executing the installer with ``/?``) can be +passed into the installer: + ++---------------------+--------------------------------------------------------+ +| Name | Description | ++=====================+========================================================+ +| /passive | to display progress without requiring user interaction | ++---------------------+--------------------------------------------------------+ +| /quiet | to install/uninstall without displaying any UI | ++---------------------+--------------------------------------------------------+ +| /simple | to prevent user customization | ++---------------------+--------------------------------------------------------+ +| /uninstall | to remove Python (without confirmation) | ++---------------------+--------------------------------------------------------+ +| /layout [directory] | to pre-download all components | ++---------------------+--------------------------------------------------------+ +| /log [filename] | to specify log files location | ++---------------------+--------------------------------------------------------+ + +All other options are passed as ``name=value``, where the value is usually +``0`` to disable a feature, ``1`` to enable a feature, or a path. The full list +of available options is shown below. + ++---------------------------+--------------------------------------+--------------------------+ +| Name | Description | Default | ++===========================+======================================+==========================+ +| InstallAllUsers | Perform a system-wide installation. | 0 | ++---------------------------+--------------------------------------+--------------------------+ +| TargetDir | The installation directory | Selected based on | +| | | InstallAllUsers | ++---------------------------+--------------------------------------+--------------------------+ +| DefaultAllUsersTargetDir | The default installation directory | :file:`%ProgramFiles%\\\ | +| | for all-user installs | Python X.Y` or :file:`\ | +| | | %ProgramFiles(x86)%\\\ | +| | | Python X.Y` | ++---------------------------+--------------------------------------+--------------------------+ +| DefaultJustForMeTargetDir | The default install directory for | :file:`%LocalAppData%\\\ | +| | just-for-me installs | Programs\\Python\\\ | +| | | PythonXY` or | +| | | :file:`%LocalAppData%\\\ | +| | | Programs\\Python\\\ | +| | | PythonXY-32` or | +| | | :file:`%LocalAppData%\\\ | +| | | Programs\\Python\\\ | +| | | PythonXY-64` | ++---------------------------+--------------------------------------+--------------------------+ +| DefaultCustomTargetDir | The default custom install directory | (empty) | +| | displayed in the UI | | ++---------------------------+--------------------------------------+--------------------------+ +| AssociateFiles | Create file associations if the | 1 | +| | launcher is also installed. | | ++---------------------------+--------------------------------------+--------------------------+ +| CompileAll | Compile all ``.py`` files to | 0 | +| | ``.pyc``. | | ++---------------------------+--------------------------------------+--------------------------+ +| PrependPath | Prepend install and Scripts | 0 | +| | directories to :envvar:`PATH` and | | +| | add ``.PY`` to :envvar:`PATHEXT` | | ++---------------------------+--------------------------------------+--------------------------+ +| AppendPath | Append install and Scripts | 0 | +| | directories to :envvar:`PATH` and | | +| | add ``.PY`` to :envvar:`PATHEXT` | | ++---------------------------+--------------------------------------+--------------------------+ +| Shortcuts | Create shortcuts for the interpreter,| 1 | +| | documentation and IDLE if installed. | | ++---------------------------+--------------------------------------+--------------------------+ +| Include_doc | Install Python manual | 1 | ++---------------------------+--------------------------------------+--------------------------+ +| Include_debug | Install debug binaries | 0 | ++---------------------------+--------------------------------------+--------------------------+ +| Include_dev | Install developer headers and | 1 | +| | libraries. Omitting this may lead to | | +| | an unusable installation. | | ++---------------------------+--------------------------------------+--------------------------+ +| Include_exe | Install :file:`python.exe` and | 1 | +| | related files. Omitting this may | | +| | lead to an unusable installation. | | ++---------------------------+--------------------------------------+--------------------------+ +| Include_launcher | Install :ref:`launcher`. | 1 | ++---------------------------+--------------------------------------+--------------------------+ +| InstallLauncherAllUsers | Installs the launcher for all | 1 | +| | users. Also requires | | +| | ``Include_launcher`` to be set to 1 | | ++---------------------------+--------------------------------------+--------------------------+ +| Include_lib | Install standard library and | 1 | +| | extension modules. Omitting this may | | +| | lead to an unusable installation. | | ++---------------------------+--------------------------------------+--------------------------+ +| Include_pip | Install bundled pip and setuptools | 1 | ++---------------------------+--------------------------------------+--------------------------+ +| Include_symbols | Install debugging symbols (``*.pdb``)| 0 | ++---------------------------+--------------------------------------+--------------------------+ +| Include_tcltk | Install Tcl/Tk support and IDLE | 1 | ++---------------------------+--------------------------------------+--------------------------+ +| Include_test | Install standard library test suite | 1 | ++---------------------------+--------------------------------------+--------------------------+ +| Include_tools | Install utility scripts | 1 | ++---------------------------+--------------------------------------+--------------------------+ +| LauncherOnly | Only installs the launcher. This | 0 | +| | will override most other options. | | ++---------------------------+--------------------------------------+--------------------------+ +| SimpleInstall | Disable most install UI | 0 | ++---------------------------+--------------------------------------+--------------------------+ +| SimpleInstallDescription | A custom message to display when the | (empty) | +| | simplified install UI is used. | | ++---------------------------+--------------------------------------+--------------------------+ + +For example, to silently install a default, system-wide Python installation, +you could use the following command (from an elevated command prompt):: + + python-3.9.0.exe /quiet InstallAllUsers=1 PrependPath=1 Include_test=0 + +To allow users to easily install a personal copy of Python without the test +suite, you could provide a shortcut with the following command. This will +display a simplified initial page and disallow customization:: + + python-3.9.0.exe InstallAllUsers=0 Include_launcher=0 Include_test=0 + SimpleInstall=1 SimpleInstallDescription="Just for me, no test suite." + +(Note that omitting the launcher also omits file associations, and is only +recommended for per-user installs when there is also a system-wide installation +that included the launcher.) + +The options listed above can also be provided in a file named ``unattend.xml`` +alongside the executable. This file specifies a list of options and values. +When a value is provided as an attribute, it will be converted to a number if +possible. Values provided as element text are always left as strings. This +example file sets the same options as the previous example: + +.. code-block:: xml + + <Options> + <Option Name="InstallAllUsers" Value="no" /> + <Option Name="Include_launcher" Value="0" /> + <Option Name="Include_test" Value="no" /> + <Option Name="SimpleInstall" Value="yes" /> + <Option Name="SimpleInstallDescription">Just for me, no test suite</Option> + </Options> + +.. _install-layout-option: + +Installing Without Downloading +------------------------------ + +As some features of Python are not included in the initial installer download, +selecting those features may require an internet connection. To avoid this +need, all possible components may be downloaded on-demand to create a complete +*layout* that will no longer require an internet connection regardless of the +selected features. Note that this download may be bigger than required, but +where a large number of installations are going to be performed it is very +useful to have a locally cached copy. - https://learn.microsoft.com/windows/win32/procthread/environment-variables - Overview of environment variables on Windows +Execute the following command from Command Prompt to download all possible +required files. Remember to substitute ``python-3.9.0.exe`` for the actual +name of your installer, and to create layouts in their own directories to +avoid collisions between files with the same name. - https://learn.microsoft.com/windows-server/administration/windows-commands/set_1 - The ``set`` command, for temporarily modifying environment variables +:: - https://learn.microsoft.com/windows-server/administration/windows-commands/setx - The ``setx`` command, for permanently modifying environment variables + python-3.9.0.exe /layout [optional target directory] +You may also specify the ``/quiet`` option to hide the progress display. -.. _windows-path-mod: +Modifying an install +-------------------- -Finding the Python executable ------------------------------ +Once Python has been installed, you can add or remove features through the +Programs and Features tool that is part of Windows. Select the Python entry and +choose "Uninstall/Change" to open the installer in maintenance mode. -.. versionchanged:: 3.5 +"Modify" allows you to add or remove features by modifying the checkboxes - +unchanged checkboxes will not install or remove anything. Some options cannot be +changed in this mode, such as the install directory; to modify these, you will +need to remove and then reinstall Python completely. -Besides using the automatically created start menu entry for the Python -interpreter, you might want to start Python in the command prompt. The -installer has an option to set that up for you. +"Repair" will verify all the files that should be installed using the current +settings and replace any that have been removed or modified. -On the first page of the installer, an option labelled "Add Python to PATH" -may be selected to have the installer add the install location into the -:envvar:`PATH`. The location of the :file:`Scripts\\` folder is also added. -This allows you to type :command:`python` to run the interpreter, and -:command:`pip` for the package installer. Thus, you can also execute your -scripts with command line options, see :ref:`using-on-cmdline` documentation. +"Uninstall" will remove Python entirely, with the exception of the +:ref:`launcher`, which has its own entry in Programs and Features. -If you don't enable this option at install time, you can always re-run the -installer, select Modify, and enable it. Alternatively, you can manually -modify the :envvar:`PATH` using the directions in :ref:`setting-envvars`. You -need to set your :envvar:`PATH` environment variable to include the directory -of your Python installation, delimited by a semicolon from other entries. An -example variable could look like this (assuming the first two entries already -existed):: - C:\WINDOWS\system32;C:\WINDOWS;C:\Program Files\Python 3.9 +Installing Free-threaded Binaries +--------------------------------- -.. _win-utf8-mode: +.. versionadded:: 3.13 (Experimental) -UTF-8 mode -========== +.. note:: -.. versionadded:: 3.7 + Everything described in this section is considered experimental, + and should be expected to change in future releases. -Windows still uses legacy encodings for the system encoding (the ANSI Code -Page). Python uses it for the default encoding of text files (e.g. -:func:`locale.getencoding`). +To install pre-built binaries with free-threading enabled (see :pep:`703`), you +should select "Customize installation". The second page of options includes the +"Download free-threaded binaries" checkbox. -This may cause issues because UTF-8 is widely used on the internet -and most Unix systems, including WSL (Windows Subsystem for Linux). +.. image:: win_install_freethreaded.png -You can use the :ref:`Python UTF-8 Mode <utf8-mode>` to change the default text -encoding to UTF-8. You can enable the :ref:`Python UTF-8 Mode <utf8-mode>` via -the ``-X utf8`` command line option, or the ``PYTHONUTF8=1`` environment -variable. See :envvar:`PYTHONUTF8` for enabling UTF-8 mode, and -:ref:`setting-envvars` for how to modify environment variables. +Selecting this option will download and install additional binaries to the same +location as the main Python install. The main executable is called +``python3.13t.exe``, and other binaries either receive a ``t`` suffix or a full +ABI suffix. Python source files and bundled third-party dependencies are shared +with the main install. -When the :ref:`Python UTF-8 Mode <utf8-mode>` is enabled, you can still use the -system encoding (the ANSI Code Page) via the "mbcs" codec. +The free-threaded version is registered as a regular Python install with the +tag ``3.13t`` (with a ``-32`` or ``-arm64`` suffix as normal for those +platforms). This allows tools to discover it, and for the :ref:`launcher` to +support ``py.exe -3.13t``. Note that the launcher will interpret ``py.exe -3`` +(or a ``python3`` shebang) as "the latest 3.x install", which will prefer the +free-threaded binaries over the regular ones, while ``py.exe -3.13`` will not. +If you use the short style of option, you may prefer to not install the +free-threaded binaries at this time. -Note that adding ``PYTHONUTF8=1`` to the default environment variables -will affect all Python 3.7+ applications on your system. -If you have any Python 3.7+ applications which rely on the legacy -system encoding, it is recommended to set the environment variable -temporarily or use the ``-X utf8`` command line option. +To specify the install option at the command line, use +``Include_freethreaded=1``. See :ref:`install-layout-option` for instructions on +pre-emptively downloading the additional binaries for offline install. The +options to include debug symbols and binaries also apply to the free-threaded +builds. -.. note:: - Even when UTF-8 mode is disabled, Python uses UTF-8 by default - on Windows for: +Free-threaded binaries are also available :ref:`on nuget.org <windows-nuget>`. - * Console I/O including standard I/O (see :pep:`528` for details). - * The :term:`filesystem encoding <filesystem encoding and error handler>` - (see :pep:`529` for details). +Python Launcher for Windows (Deprecated) +======================================== -.. _launcher: +.. deprecated:: 3.14 -Python Launcher for Windows -=========================== + The launcher and this documentation have been superseded by the Python + Install Manager described above. This is preserved temporarily for historical + interest. .. versionadded:: 3.3 @@ -1168,190 +1847,3 @@ listed in alphabetical order of names. | | | found. | +-------------------+-------+-----------------------------------------------+ - -.. _windows_finding_modules: - -Finding modules -=============== - -These notes supplement the description at :ref:`sys-path-init` with -detailed Windows notes. - -When no ``._pth`` file is found, this is how :data:`sys.path` is populated on -Windows: - -* An empty entry is added at the start, which corresponds to the current - directory. - -* If the environment variable :envvar:`PYTHONPATH` exists, as described in - :ref:`using-on-envvars`, its entries are added next. Note that on Windows, - paths in this variable must be separated by semicolons, to distinguish them - from the colon used in drive identifiers (``C:\`` etc.). - -* Additional "application paths" can be added in the registry as subkeys of - :samp:`\\SOFTWARE\\Python\\PythonCore\\{version}\\PythonPath` under both the - ``HKEY_CURRENT_USER`` and ``HKEY_LOCAL_MACHINE`` hives. Subkeys which have - semicolon-delimited path strings as their default value will cause each path - to be added to :data:`sys.path`. (Note that all known installers only use - HKLM, so HKCU is typically empty.) - -* If the environment variable :envvar:`PYTHONHOME` is set, it is assumed as - "Python Home". Otherwise, the path of the main Python executable is used to - locate a "landmark file" (either ``Lib\os.py`` or ``pythonXY.zip``) to deduce - the "Python Home". If a Python home is found, the relevant sub-directories - added to :data:`sys.path` (``Lib``, ``plat-win``, etc) are based on that - folder. Otherwise, the core Python path is constructed from the PythonPath - stored in the registry. - -* If the Python Home cannot be located, no :envvar:`PYTHONPATH` is specified in - the environment, and no registry entries can be found, a default path with - relative entries is used (e.g. ``.\Lib;.\plat-win``, etc). - -If a ``pyvenv.cfg`` file is found alongside the main executable or in the -directory one level above the executable, the following variations apply: - -* If ``home`` is an absolute path and :envvar:`PYTHONHOME` is not set, this - path is used instead of the path to the main executable when deducing the - home location. - -The end result of all this is: - -* When running :file:`python.exe`, or any other .exe in the main Python - directory (either an installed version, or directly from the PCbuild - directory), the core path is deduced, and the core paths in the registry are - ignored. Other "application paths" in the registry are always read. - -* When Python is hosted in another .exe (different directory, embedded via COM, - etc), the "Python Home" will not be deduced, so the core path from the - registry is used. Other "application paths" in the registry are always read. - -* If Python can't find its home and there are no registry value (frozen .exe, - some very strange installation setup) you get a path with some default, but - relative, paths. - -For those who want to bundle Python into their application or distribution, the -following advice will prevent conflicts with other installations: - -* Include a ``._pth`` file alongside your executable containing the - directories to include. This will ignore paths listed in the registry and - environment variables, and also ignore :mod:`site` unless ``import site`` is - listed. - -* If you are loading :file:`python3.dll` or :file:`python37.dll` in your own - executable, explicitly set :c:member:`PyConfig.module_search_paths` before - :c:func:`Py_InitializeFromConfig`. - -* Clear and/or overwrite :envvar:`PYTHONPATH` and set :envvar:`PYTHONHOME` - before launching :file:`python.exe` from your application. - -* If you cannot use the previous suggestions (for example, you are a - distribution that allows people to run :file:`python.exe` directly), ensure - that the landmark file (:file:`Lib\\os.py`) exists in your install directory. - (Note that it will not be detected inside a ZIP file, but a correctly named - ZIP file will be detected instead.) - -These will ensure that the files in a system-wide installation will not take -precedence over the copy of the standard library bundled with your application. -Otherwise, your users may experience problems using your application. Note that -the first suggestion is the best, as the others may still be susceptible to -non-standard paths in the registry and user site-packages. - -.. versionchanged:: 3.6 - - Add ``._pth`` file support and removes ``applocal`` option from - ``pyvenv.cfg``. - -.. versionchanged:: 3.6 - - Add :file:`python{XX}.zip` as a potential landmark when directly adjacent - to the executable. - -.. deprecated:: 3.6 - - Modules specified in the registry under ``Modules`` (not ``PythonPath``) - may be imported by :class:`importlib.machinery.WindowsRegistryFinder`. - This finder is enabled on Windows in 3.6.0 and earlier, but may need to - be explicitly added to :data:`sys.meta_path` in the future. - -Additional modules -================== - -Even though Python aims to be portable among all platforms, there are features -that are unique to Windows. A couple of modules, both in the standard library -and external, and snippets exist to use these features. - -The Windows-specific standard modules are documented in -:ref:`mswin-specific-services`. - -PyWin32 -------- - -The :pypi:`PyWin32` module by Mark Hammond -is a collection of modules for advanced Windows-specific support. This includes -utilities for: - -* `Component Object Model - <https://learn.microsoft.com/windows/win32/com/component-object-model--com--portal>`_ - (COM) -* Win32 API calls -* Registry -* Event log -* `Microsoft Foundation Classes - <https://learn.microsoft.com/cpp/mfc/mfc-desktop-applications>`_ - (MFC) user interfaces - -`PythonWin <https://web.archive.org/web/20060524042422/ -https://www.python.org/windows/pythonwin/>`_ is a sample MFC application -shipped with PyWin32. It is an embeddable IDE with a built-in debugger. - -.. seealso:: - - `Win32 How Do I...? <https://timgolden.me.uk/python/win32_how_do_i.html>`_ - by Tim Golden - - `Python and COM <https://www.boddie.org.uk/python/COM.html>`_ - by David and Paul Boddie - - -cx_Freeze ---------- - -`cx_Freeze <https://cx-freeze.readthedocs.io/en/latest/>`_ -wraps Python scripts into executable Windows programs -(:file:`{*}.exe` files). When you have done this, you can distribute your -application without requiring your users to install Python. - - -Compiling Python on Windows -=========================== - -If you want to compile CPython yourself, first thing you should do is get the -`source <https://www.python.org/downloads/source/>`_. You can download either the -latest release's source or just grab a fresh `checkout -<https://devguide.python.org/setup/#get-the-source-code>`_. - -The source tree contains a build solution and project files for Microsoft -Visual Studio, which is the compiler used to build the official Python -releases. These files are in the :file:`PCbuild` directory. - -Check :file:`PCbuild/readme.txt` for general information on the build process. - -For extension modules, consult :ref:`building-on-windows`. - - -Other Platforms -=============== - -With ongoing development of Python, some platforms that used to be supported -earlier are no longer supported (due to the lack of users or developers). -Check :pep:`11` for details on all unsupported platforms. - -* `Windows CE <https://pythonce.sourceforge.net/>`_ is - `no longer supported <https://github.com/python/cpython/issues/71542>`__ - since Python 3 (if it ever was). -* The `Cygwin <https://cygwin.com/>`_ installer offers to install the - `Python interpreter <https://cygwin.com/packages/summary/python3.html>`__ - as well - -See `Python for Windows <https://www.python.org/downloads/windows/>`_ -for detailed information about platforms with pre-compiled installers. diff --git a/Misc/NEWS.d/next/Windows/2025-04-25-13-34-27.gh-issue-132930.6MJumW.rst b/Misc/NEWS.d/next/Windows/2025-04-25-13-34-27.gh-issue-132930.6MJumW.rst new file mode 100644 index 00000000000000..bdf6cca26588a8 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2025-04-25-13-34-27.gh-issue-132930.6MJumW.rst @@ -0,0 +1,2 @@ +Marks the installer for Windows as deprecated and updates documentation to +cover the new Python install manager. diff --git a/PC/launcher2.c b/PC/launcher2.c index 02ab417bb27ece..832935c5cc6c1c 100644 --- a/PC/launcher2.c +++ b/PC/launcher2.c @@ -1058,7 +1058,7 @@ checkShebang(SearchInfo *search) debug(L"# Failed to open %s for shebang parsing (0x%08X)\n", scriptFile, GetLastError()); free(scriptFile); - return 0; + return RC_NO_SCRIPT; } DWORD bytesRead = 0; @@ -2665,6 +2665,21 @@ performSearch(SearchInfo *search, EnvironmentInfo **envs) case RC_NO_SHEBANG: case RC_RECURSIVE_SHEBANG: break; + case RC_NO_SCRIPT: + if (!_comparePath(search->scriptFile, search->scriptFileLength, L"install", -1) || + !_comparePath(search->scriptFile, search->scriptFileLength, L"uninstall", -1) || + !_comparePath(search->scriptFile, search->scriptFileLength, L"list", -1) || + !_comparePath(search->scriptFile, search->scriptFileLength, L"help", -1)) { + fprintf( + stderr, + "WARNING: The '%.*ls' command is unavailable because this is the legacy py.exe command.\n" + "If you have already installed the Python install manager, open Installed Apps and " + "remove 'Python Launcher' to enable the new py.exe command.\n", + search->scriptFileLength, + search->scriptFile + ); + } + break; default: return exitCode; } diff --git a/PC/layout/main.py b/PC/layout/main.py index 6321c33b3f780a..7324a135133b66 100644 --- a/PC/layout/main.py +++ b/PC/layout/main.py @@ -8,6 +8,7 @@ __version__ = "3.8" import argparse +import json import os import shutil import sys @@ -28,6 +29,7 @@ from .support.options import * from .support.pip import * from .support.props import * +from .support.pymanager import * from .support.nuspec import * TEST_PYDS_ONLY = FileStemSet("xxlimited", "xxlimited_35", "_ctypes_test", "_test*") @@ -265,7 +267,12 @@ def _c(d): if ns.include_dev: for dest, src in rglob(ns.source / "Include", "**/*.h"): yield "include/{}".format(dest), src - yield "include/pyconfig.h", ns.build / "pyconfig.h" + # Support for layout of new and old releases. + pc = ns.source / "PC" + if (pc / "pyconfig.h.in").is_file(): + yield "include/pyconfig.h", ns.build / "pyconfig.h" + else: + yield "include/pyconfig.h", pc / "pyconfig.h" for dest, src in get_tcltk_lib(ns): yield dest, src @@ -303,6 +310,9 @@ def _c(d): else: yield "DLLs/{}".format(ns.include_cat.name), ns.include_cat + if ns.include_install_json or ns.include_install_embed_json or ns.include_install_test_json: + yield "__install__.json", ns.temp / "__install__.json" + def _compile_one_py(src, dest, name, optimize, checked=True): import py_compile @@ -394,6 +404,22 @@ def generate_source_files(ns): log_info("Extracting pip") extract_pip_files(ns) + if ns.include_install_json: + log_info("Generating __install__.json in {}", ns.temp) + ns.temp.mkdir(parents=True, exist_ok=True) + with open(ns.temp / "__install__.json", "w", encoding="utf-8") as f: + json.dump(calculate_install_json(ns), f, indent=2) + elif ns.include_install_embed_json: + log_info("Generating embeddable __install__.json in {}", ns.temp) + ns.temp.mkdir(parents=True, exist_ok=True) + with open(ns.temp / "__install__.json", "w", encoding="utf-8") as f: + json.dump(calculate_install_json(ns, for_embed=True), f, indent=2) + elif ns.include_install_test_json: + log_info("Generating test __install__.json in {}", ns.temp) + ns.temp.mkdir(parents=True, exist_ok=True) + with open(ns.temp / "__install__.json", "w", encoding="utf-8") as f: + json.dump(calculate_install_json(ns, for_test=True), f, indent=2) + def _create_zip_file(ns): if not ns.zip: @@ -627,6 +653,7 @@ def main(): if ns.include_cat and not ns.include_cat.is_absolute(): ns.include_cat = (Path.cwd() / ns.include_cat).resolve() if not ns.arch: + # TODO: Calculate arch from files in ns.build instead if sys.winver.endswith("-arm64"): ns.arch = "arm64" elif sys.winver.endswith("-32"): diff --git a/PC/layout/support/options.py b/PC/layout/support/options.py index f1a8eb0b317744..e8c393385425e7 100644 --- a/PC/layout/support/options.py +++ b/PC/layout/support/options.py @@ -36,6 +36,9 @@ def public(f): "alias": {"help": "aliased python.exe entry-point binaries"}, "alias3": {"help": "aliased python3.exe entry-point binaries"}, "alias3x": {"help": "aliased python3.x.exe entry-point binaries"}, + "install-json": {"help": "a PyManager __install__.json file"}, + "install-embed-json": {"help": "a PyManager __install__.json file for embeddable distro"}, + "install-test-json": {"help": "a PyManager __install__.json for the test distro"}, } @@ -95,6 +98,34 @@ def public(f): "precompile", ], }, + "pymanager": { + "help": "PyManager package", + "options": [ + "stable", + "pip", + "tcltk", + "idle", + "venv", + "dev", + "html-doc", + "install-json", + ], + }, + "pymanager-test": { + "help": "PyManager test package", + "options": [ + "stable", + "pip", + "tcltk", + "idle", + "venv", + "dev", + "html-doc", + "symbols", + "tests", + "install-test-json", + ], + }, } diff --git a/PC/layout/support/pymanager.py b/PC/layout/support/pymanager.py new file mode 100644 index 00000000000000..d7bdefadb242b7 --- /dev/null +++ b/PC/layout/support/pymanager.py @@ -0,0 +1,249 @@ +from .constants import * + +URL_BASE = "https://www.python.org/ftp/python/" + +XYZ_VERSION = f"{VER_MAJOR}.{VER_MINOR}.{VER_MICRO}" +WIN32_VERSION = f"{VER_MAJOR}.{VER_MINOR}.{VER_MICRO}.{VER_FIELD4}" +FULL_VERSION = f"{VER_MAJOR}.{VER_MINOR}.{VER_MICRO}{VER_SUFFIX}" + + +def _not_empty(n, key=None): + result = [] + for i in n: + if key: + i_l = i[key] + else: + i_l = i + if not i_l: + continue + result.append(i) + return result + + +def calculate_install_json(ns, *, for_embed=False, for_test=False): + TARGET = "python.exe" + TARGETW = "pythonw.exe" + + SYS_ARCH = { + "win32": "32bit", + "amd64": "64bit", + "arm64": "64bit", # Unfortunate, but this is how it's spec'd + }[ns.arch] + TAG_ARCH = { + "win32": "-32", + "amd64": "-64", + "arm64": "-arm64", + }[ns.arch] + + COMPANY = "PythonCore" + DISPLAY_NAME = "Python" + TAG_SUFFIX = "" + ALIAS_PREFIX = "python" + ALIAS_WPREFIX = "pythonw" + FILE_PREFIX = "python-" + FILE_SUFFIX = f"-{ns.arch}" + DISPLAY_TAGS = [{ + "win32": "32-bit", + "amd64": "", + "arm64": "ARM64", + }[ns.arch]] + + if for_test: + # Packages with the test suite come under a different Company + COMPANY = "PythonTest" + DISPLAY_TAGS.append("with tests") + FILE_SUFFIX = f"-test-{ns.arch}" + if for_embed: + # Embeddable distro comes under a different Company + COMPANY = "PythonEmbed" + TARGETW = None + ALIAS_PREFIX = None + DISPLAY_TAGS.append("embeddable") + # Deliberately name the file differently from the existing distro + # so we can republish old versions without replacing files. + FILE_SUFFIX = f"-embeddable-{ns.arch}" + if ns.include_freethreaded: + # Free-threaded distro comes with a tag suffix + TAG_SUFFIX = "t" + TARGET = f"python{VER_MAJOR}.{VER_MINOR}t.exe" + TARGETW = f"pythonw{VER_MAJOR}.{VER_MINOR}t.exe" + DISPLAY_TAGS.append("freethreaded") + FILE_SUFFIX = f"t-{ns.arch}" + + FULL_TAG = f"{VER_MAJOR}.{VER_MINOR}.{VER_MICRO}{VER_SUFFIX}{TAG_SUFFIX}" + FULL_ARCH_TAG = f"{FULL_TAG}{TAG_ARCH}" + XY_TAG = f"{VER_MAJOR}.{VER_MINOR}{TAG_SUFFIX}" + XY_ARCH_TAG = f"{XY_TAG}{TAG_ARCH}" + X_TAG = f"{VER_MAJOR}{TAG_SUFFIX}" + X_ARCH_TAG = f"{X_TAG}{TAG_ARCH}" + + # Tag used in runtime ID (for side-by-side install/updates) + ID_TAG = XY_ARCH_TAG + # Tag shown in 'py list' output + DISPLAY_TAG = f"{XY_TAG}-dev{TAG_ARCH}" if VER_SUFFIX else XY_ARCH_TAG + + DISPLAY_SUFFIX = ", ".join(i for i in DISPLAY_TAGS if i) + if DISPLAY_SUFFIX: + DISPLAY_SUFFIX = f" ({DISPLAY_SUFFIX})" + DISPLAY_VERSION = f"{XYZ_VERSION}{VER_SUFFIX}{DISPLAY_SUFFIX}" + + STD_RUN_FOR = [] + STD_ALIAS = [] + STD_PEP514 = [] + STD_START = [] + STD_UNINSTALL = [] + + # The list of 'py install <TAG>' tags that will match this runtime. + # Architecture should always be included here because PyManager will add it. + INSTALL_TAGS = [ + FULL_ARCH_TAG, + XY_ARCH_TAG, + X_ARCH_TAG, + # X_TAG and XY_TAG doesn't include VER_SUFFIX, so create -dev versions + f"{XY_TAG}-dev{TAG_ARCH}" if XY_TAG and VER_SUFFIX else "", + f"{X_TAG}-dev{TAG_ARCH}" if X_TAG and VER_SUFFIX else "", + ] + + # Generate run-for entries for each target. + # Again, include architecture because PyManager will add it. + for base in [ + {"target": TARGET}, + {"target": TARGETW, "windowed": 1}, + ]: + if not base["target"]: + continue + STD_RUN_FOR.append({**base, "tag": FULL_ARCH_TAG}) + if XY_TAG: + STD_RUN_FOR.append({**base, "tag": XY_ARCH_TAG}) + if X_TAG: + STD_RUN_FOR.append({**base, "tag": X_ARCH_TAG}) + if VER_SUFFIX: + STD_RUN_FOR.extend([ + {**base, "tag": f"{XY_TAG}-dev{TAG_ARCH}" if XY_TAG else ""}, + {**base, "tag": f"{X_TAG}-dev{TAG_ARCH}" if X_TAG else ""}, + ]) + + # Generate alias entries for each target. We need both arch and non-arch + # versions as well as windowed/non-windowed versions to make sure that all + # necessary aliases are created. + if ALIAS_PREFIX: + for prefix, base in [ + (ALIAS_PREFIX, {"target": TARGET}), + (f"{ALIAS_PREFIX}w", {"target": TARGETW, "windowed": 1}), + ]: + if not base["target"]: + continue + if XY_TAG: + STD_ALIAS.extend([ + {**base, "name": f"{prefix}{XY_TAG}.exe"}, + {**base, "name": f"{prefix}{XY_ARCH_TAG}.exe"}, + ]) + if X_TAG: + STD_ALIAS.extend([ + {**base, "name": f"{prefix}{X_TAG}.exe"}, + {**base, "name": f"{prefix}{X_ARCH_TAG}.exe"}, + ]) + + STD_PEP514.append({ + "kind": "pep514", + "Key": rf"{COMPANY}\{ID_TAG}", + "DisplayName": f"{DISPLAY_NAME} {DISPLAY_VERSION}", + "SupportUrl": "https://www.python.org/", + "SysArchitecture": SYS_ARCH, + "SysVersion": VER_DOT, + "Version": FULL_VERSION, + "InstallPath": { + "_": "%PREFIX%", + "ExecutablePath": f"%PREFIX%{TARGET}", + # WindowedExecutablePath is added below + }, + "Help": { + "Online Python Documentation": { + "_": f"https://docs.python.org/{VER_DOT}/" + }, + }, + }) + + STD_START.append({ + "kind": "start", + "Name": f"{DISPLAY_NAME} {VER_DOT}{DISPLAY_SUFFIX}", + "Items": [ + { + "Name": f"{DISPLAY_NAME} {VER_DOT}{DISPLAY_SUFFIX}", + "Target": f"%PREFIX%{TARGET}", + "Icon": f"%PREFIX%{TARGET}", + }, + { + "Name": f"{DISPLAY_NAME} {VER_DOT} Online Documentation", + "Icon": r"%SystemRoot%\System32\SHELL32.dll", + "IconIndex": 13, + "Target": f"https://docs.python.org/{VER_DOT}/", + }, + # IDLE and local documentation items are added below + ], + }) + + if TARGETW: + STD_PEP514[0]["InstallPath"]["WindowedExecutablePath"] = f"%PREFIX%{TARGETW}" + + if ns.include_idle: + STD_START[0]["Items"].append({ + "Name": f"IDLE {VER_DOT}{DISPLAY_SUFFIX}", + "Target": f"%PREFIX%{TARGETW or TARGET}", + "Arguments": r'"%PREFIX%Lib\idlelib\idle.pyw"', + "Icon": r"%PREFIX%Lib\idlelib\Icons\idle.ico", + "IconIndex": 0, + }) + STD_START[0]["Items"].append({ + "Name": f"PyDoc {VER_DOT}{DISPLAY_SUFFIX}", + "Target": f"%PREFIX%{TARGET}", + "Arguments": "-m pydoc -b", + "Icon": r"%PREFIX%Lib\idlelib\Icons\idle.ico", + "IconIndex": 0, + }) + + if ns.include_html_doc: + STD_PEP514[0]["Help"]["Main Python Documentation"] = { + "_": rf"%PREFIX%Doc\html\index.html", + } + STD_START[0]["Items"].append({ + "Name": f"{DISPLAY_NAME} {VER_DOT} Manuals{DISPLAY_SUFFIX}", + "Target": r"%PREFIX%Doc\html\index.html", + }) + elif ns.include_chm: + STD_PEP514[0]["Help"]["Main Python Documentation"] = { + "_": rf"%PREFIX%Doc\{PYTHON_CHM_NAME}", + } + STD_START[0]["Items"].append({ + "Name": f"{DISPLAY_NAME} {VER_DOT} Manuals{DISPLAY_SUFFIX}", + "Target": "%WINDIR%hhc.exe", + "Arguments": rf"%PREFIX%Doc\{PYTHON_CHM_NAME}", + }) + + STD_UNINSTALL.append({ + "kind": "uninstall", + # Other settings will pick up sensible defaults + "Publisher": "Python Software Foundation", + "HelpLink": f"https://docs.python.org/{VER_DOT}/", + }) + + data = { + "schema": 1, + "id": f"{COMPANY.lower()}-{ID_TAG}", + "sort-version": FULL_VERSION, + "company": COMPANY, + "tag": DISPLAY_TAG, + "install-for": _not_empty(INSTALL_TAGS), + "run-for": _not_empty(STD_RUN_FOR, "tag"), + "alias": _not_empty(STD_ALIAS, "name"), + "shortcuts": [ + *STD_PEP514, + *STD_START, + *STD_UNINSTALL, + ], + "display-name": f"{DISPLAY_NAME} {DISPLAY_VERSION}", + "executable": rf".\{TARGET}", + "url": f"{URL_BASE}{XYZ_VERSION}/{FILE_PREFIX}{FULL_VERSION}{FILE_SUFFIX}.zip" + } + + return data diff --git a/Tools/msi/bundle/Default.thm b/Tools/msi/bundle/Default.thm index 471d37acc33b3d..6e908ac373442d 100644 --- a/Tools/msi/bundle/Default.thm +++ b/Tools/msi/bundle/Default.thm @@ -1,12 +1,13 @@ <?xml version="1.0" encoding="utf-8"?> <Theme xmlns="http://wixtoolset.org/schemas/thmutil/2010"> - <Window Width="670" Height="412" HexStyle="100a0000" FontId="0">#(loc.Caption)</Window> + <Window Width="670" Height="422" HexStyle="100a0000" FontId="0">#(loc.Caption)</Window> <Font Id="0" Height="-14" Weight="500" Foreground="000000" Background="ffffff">Segoe UI</Font> <Font Id="1" Height="-26" Weight="500" Foreground="000000" Background="ffffff">Segoe UI</Font> <Font Id="2" Height="-24" Weight="500" Foreground="808080" Background="ffffff">Segoe UI</Font> <Font Id="3" Height="-14" Weight="500" Foreground="000000" Background="ffffff">Segoe UI</Font> <Font Id="4" Height="-14" Weight="500" Foreground="ff0000" Background="ffffff" Underline="yes">Segoe UI</Font> <Font Id="5" Height="-14" Weight="500" Foreground="808080" Background="ffffff">Segoe UI</Font> + <Font Id="6" Height="-14" Weight="700" Foreground="000000" Background="ffffff">Segoe UI</Font> <Page Name="Help"> <Text X="185" Y="11" Width="-11" Height="36" FontId="1" DisablePrefix="yes">#(loc.HelpHeader)</Text> @@ -21,8 +22,10 @@ <Text X="185" Y="50" Width="-11" Height="50" FontId="3" TabStop="yes">#(loc.InstallMessage)</Text> - <Button Name="InstallButton" X="185" Y="101" Width="-11" Height="109" TabStop="yes" FontId="3" HexStyle="0xE">#(loc.InstallButton)</Button> - <Button Name="InstallCustomButton" X="185" Y="221" Width="-11" Height="59" TabStop="yes" FontId="3" HexStyle="0xE">#(loc.InstallCustomButton)</Button> + <Hypertext X="185" Y="100" Width="-11" Height="40" FontId="6" DisablePrefix="yes">#(loc.DeprecationMessage)</Hypertext> + + <Button Name="InstallButton" X="185" Y="141" Width="-11" Height="109" TabStop="yes" FontId="3" HexStyle="0xE">#(loc.InstallButton)</Button> + <Button Name="InstallCustomButton" X="185" Y="251" Width="-11" Height="59" TabStop="yes" FontId="3" HexStyle="0xE">#(loc.InstallCustomButton)</Button> <Checkbox Name="InstallLauncherAllUsers" X="185" Y="-37" Width="-100" Height="24" TabStop="yes" FontId="3">#(loc.ShortInstallLauncherAllUsersLabel)</Checkbox> <Checkbox Name="PrependPath" X="185" Y="-13" Width="-100" Height="24" TabStop="yes" FontId="3">#(loc.ShortPrependPathLabel)</Checkbox> diff --git a/Tools/msi/bundle/Default.wxl b/Tools/msi/bundle/Default.wxl index 7208d83ddae61b..0bd3644b58b747 100644 --- a/Tools/msi/bundle/Default.wxl +++ b/Tools/msi/bundle/Default.wxl @@ -128,4 +128,6 @@ Feel free to post at <a href="https://discuss.python.org/c/users/7">discus Visit <a href="https://www.python.org/downloads/">python.org</a> to download an earlier version of Python.</String> <String Id="SuccessMaxPathButton">Disable path length limit</String> <String Id="SuccessMaxPathButtonNote">Changes your machine configuration to allow programs, including Python, to bypass the 260 character "MAX_PATH" limitation.</String> + + <String Id="DeprecationMessage">NOTE: This installer is being retired and will no longer be available after Python 3.15. <a href="https://docs.python.org/using/windows">More info</a></String> </WixLocalization> _______________________________________________ Python-checkins mailing list -- python-checkins@python.org To unsubscribe send an email to python-checkins-le...@python.org https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: arch...@mail-archive.com