# Remove bdist\_wininst command

**URL:** <https://discuss.python.org/t/remove-bdist-wininst-command/6434>\
**Category:** Packaging\
**Created:** [January 1, 2021, 3:09pm UTC](https://discuss.python.org/t/remove-bdist-wininst-command/6434 "2021-01-01T15:09:42Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![vstinner](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/vstinner/32/15130_2.png) [@vstinner](https://discuss.python.org/u/vstinner)\
**Post date:** [January 1, 2021, 3:09pm UTC](https://discuss.python.org/t/remove-bdist-wininst-command/6434/1 "2021-01-01T15:09:42Z")

</div>

Hi,

After deprecating the distutils bdist\_wininst command in Python 3.8 and fixing setuptools to handle a missing bdist\_wininst command, I now propose the remove the command:  
[https://bugs.python.org/issue42802](https://bugs.python.org/issue42802)

In July 2019, it was said that only wheel packages should be accepted on PyPI:

> [@Deprecate bdist\_wininst](https://discuss.python.org/t/deprecate-bdist-wininst/1929):
>
> Hi, bdist\_wininst uses the mbcs encoding which is only available on Windows. There is an issue open for 8 years to suggest to use UTF-8 or use the Unicode (wide character) flavor of the Windows API to support running bdist\_wininst on non-Windows platforms and to be able to distribute binaries which don’t depend on the ANSI code page: [https://bugs.python.org/issue10945](https://bugs.python.org/issue10945) When I look at numpy or Cython: they don’t distribute .exe installers, but binary wheel packages for Windows. I understood the …

People are free to distribute wininst installer programs outside PyPI, but it’s a pain to maintain the “wininst” code base (the installer itself and the distutils command), there are 19 open bdist\_wininst issues and most are inactive for between 1 year 1/2 and 10 years.

Do you see any good reason to keep the bdist\_wininst command?

Victor

---

<div class="post-metadata">

**Author:** ![pradyunsg](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pradyunsg/32/206_2.png) [@pradyunsg](https://discuss.python.org/u/pradyunsg)\
**Post date:** [January 1, 2021, 4:52pm UTC](https://discuss.python.org/t/remove-bdist-wininst-command/6434/2 "2021-01-01T16:52:52Z")

</div>

I don’t see any good reasons to be maintaining this support, given that nearly all of Python Packaging tooling is moving toward standardising around wheels and, IIUC, no automated installer supports installing using this format from a package index.

I’m on board for removing this unless someone has a valid use case that simply cannot be satisfied without this, and that someone also steps up to actively maintain this and work on existing issues. 🙂

---

<div class="post-metadata">

**Author:** ![vstinner](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/vstinner/32/15130_2.png) [@vstinner](https://discuss.python.org/u/vstinner)\
**Post date:** [January 1, 2021, 6:38pm UTC](https://discuss.python.org/t/remove-bdist-wininst-command/6434/3 "2021-01-01T18:38:21Z")

</div>

> [@pradyunsg](#):
>
> and that someone also steps up to actively maintain this and work on existing issues. 🙂

🤣 🤣 🤣

---

<div class="post-metadata">

**Author:** ![steve.dower](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/steve.dower/32/56_2.png) [@steve.dower](https://discuss.python.org/u/steve.dower)\
**Post date:** [January 2, 2021, 9:57am UTC](https://discuss.python.org/t/remove-bdist-wininst-command/6434/4 "2021-01-02T09:57:12Z")

</div>

Yeah, time to remove it. Hopefully setuptools has stopped unconditionally importing it already, but if not, it probably makes sense to replace it with a nearly empty stub file, as I’ve already done for some of the release (look under PC/layout). That solves the maintenance burden, but only actually breaks people who try and use it, rather than importing something that wants to monkeypatch it.

---

<div class="post-metadata">

**Author:** ![vstinner](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/vstinner/32/15130_2.png) [@vstinner](https://discuss.python.org/u/vstinner)\
**Post date:** [January 2, 2021, 10:10pm UTC](https://discuss.python.org/t/remove-bdist-wininst-command/6434/5 "2021-01-02T22:10:34Z")

</div>

> [@steve.dower](#):
>
> Hopefully setuptools has stopped unconditionally importing it already

Copy of my message on the issue.

FYI last year, I fixed setuptools v45.2 (released in February 2020) when bdist\_wininst is missing:

> <https://github.com/pypa/setuptools/commit/5d17586a56077dfa3109a5861cf0ff579095a42e>
>
> Fix install\_scripts() if bdist\_wininst is missing

But I didn’t try setuptools with [bpo-42802: Remove distutils bdist\_wininst command by vstinner · Pull Request #24043 · python/cpython · GitHub](https://github.com/python/cpython/pull/24043) to double check.

---

<div class="post-metadata">

**Author:** ![mhammond](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/mhammond/32/76_2.png) [@mhammond](https://discuss.python.org/u/mhammond)\
**Post date:** [January 4, 2021, 11:14pm UTC](https://discuss.python.org/t/remove-bdist-wininst-command/6434/6 "2021-01-04T23:14:38Z")

</div>

We should be clear that this will completely break extensions which rely on the features it supports and which aren’t supported by wheels. pywin32 is one such package - many pywin32 things work from wheels, but many things (such as services, COM servers, etc) do not.

> [@vstinner](#):
>
> > [@pradyunsg](#):
> >
> > and that someone also steps up to actively maintain this and work on existing issues. 🙂
> 
> 🤣 🤣

FWIW, bdist\_wininst is currently broken on 3.8+, and a PR has languished for over 3 months - but people can work around that by applying the patch to the python version that builds the distribution.

Honestly, just because “most” packages don’t use bdist\_wininst doesn’t mean that it’s OK to break packages that do when there’s no possible way for those packages to “modernize” and keep the existing functionality. I don’t see how the fact that there are open issues for bdist\_wininst justifies killing it entirely without any way to replace the lost functionality (and as above, the fact that issues remain open aren’t just because they don’t have a PR)

---

<div class="post-metadata">

**Author:** ![mhammond](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/mhammond/32/76_2.png) [@mhammond](https://discuss.python.org/u/mhammond)\
**Post date:** [January 4, 2021, 11:15pm UTC](https://discuss.python.org/t/remove-bdist-wininst-command/6434/7 "2021-01-04T23:15:27Z")

</div>

Oops - I meant to link to [Issue 41771: bdist\_wininst doesn't execute postinstall script - Python tracker](https://bugs.python.org/issue41771)

---

<div class="post-metadata">

**Author:** ![vstinner](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/vstinner/32/15130_2.png) [@vstinner](https://discuss.python.org/u/vstinner)\
**Post date:** [January 5, 2021, 9:00am UTC](https://discuss.python.org/t/remove-bdist-wininst-command/6434/8 "2021-01-05T09:00:55Z")

</div>

Technically, is it possible to maintain bdist\_wininst outside CPython code base? I don’t know if setuptools/distutils allows “pluggins”.

I’m not surprised that there is at least one project which still rely on bdist\_wininst. But the question is if CPython core developers (which is a small team) should continue to maintain this code base. It’s a matter of maintenance burden and who is going to maintain the code.

Moreover, wininst seems to be very specific. Why not using MSI which is better integrated with Windows for example?

> [@mhammond](#):
>
> pywin32 is one such package - many pywin32 things work from wheels, but many things (such as services, COM servers, etc) do not.

Would you mind to elaborate how the fact that pywin32 would be distributed a wheel package (which is basically a ZIP file) prevents to use services and COM servers on Windows?

---

<div class="post-metadata">

**Author:** ![vstinner](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/vstinner/32/15130_2.png) [@vstinner](https://discuss.python.org/u/vstinner)\
**Post date:** [January 5, 2021, 9:05am UTC](https://discuss.python.org/t/remove-bdist-wininst-command/6434/9 "2021-01-05T09:05:25Z")

</div>

> [@vstinner](#):
>
> In July 2019, it was said that only wheel packages should be accepted on PyPI: (…)

pywin32 only distributes wheel packages on PyPI: [pywin32 · PyPI](https://pypi.org/project/pywin32/#files)

The README says:

> [@](#):
>
> Note that if you want to use pywin32 for “system wide” features, such as registering COM objects or implementing Windows Services, then you must run the following command from an elevated command prompt:
> 
> ```
> python Scripts/pywin32_postinstall.py -install
> 
> ```

It sounds like an acceptable tradeoff, no?

---

<div class="post-metadata">

**Author:** ![steve.dower](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/steve.dower/32/56_2.png) [@steve.dower](https://discuss.python.org/u/steve.dower)\
**Post date:** [January 5, 2021, 5:22pm UTC](https://discuss.python.org/t/remove-bdist-wininst-command/6434/10 "2021-01-05T17:22:40Z")

</div>

The primary reason for dropping bdist\_wininst and bdist\_msi right now is that they don’t support virtual environments, and it seems unlikely that they ever reasonably could (they can’t really support multiple installs on the same machine, for example). Packaging in general is moving toward self-contained, side-effect free installation, rather than system-wide (or user-wide) installs.

There is also absolutely no reason why they need to live in core, and it would be entirely reasonable (once the deprecation is formalised) for someone to take it on as a standalone project, even retaining the same setup.py commands. That would allow the few projects that benefit from them to keep producing and distributing them, as well as actually improving them. But as long as they live in the core repo, that is much too hard.

Ultimately, this kind of cleanup process is going to force those who continue using them out of habit to evaluate whether they really want to be using it or not. If they really do, there are options for continued maintenance. But if it’s cheaper/easier to move to something else, that is also a totally valid solution. Leaving it unmaintained while we repeatedly release “new” versions is not viable long-term.

---

<div class="post-metadata">

**Author:** ![vstinner](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/vstinner/32/15130_2.png) [@vstinner](https://discuss.python.org/u/vstinner)\
**Post date:** [January 8, 2021, 11:34pm UTC](https://discuss.python.org/t/remove-bdist-wininst-command/6434/11 "2021-01-08T23:34:26Z")

</div>

I ran the setuptools test suite on a Python without bdist\_wininst. I had to remove setuptools/command/bdist\_wininst.py file to be able to run tests. Result: 1 failed, 665 passed, 17 skipped, 5 xfailed, 1 xpassed, 3 errors.

Errors and warnings:

- test\_distutils\_stdlib
- test\_distutils\_local\_with\_setuptools
- test\_distutils\_local
- test\_bdist\_wininst\_warning

I understand that almost everything works in setuptools, unless a few specific tests which expect bdist\_wininst command to exist. It sounds doable to fix 4 tests.

---

<div class="post-metadata">

**Author:** ![vstinner](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/vstinner/32/15130_2.png) [@vstinner](https://discuss.python.org/u/vstinner)\
**Post date:** [January 8, 2021, 11:37pm UTC](https://discuss.python.org/t/remove-bdist-wininst-command/6434/12 "2021-01-08T23:37:54Z")

</div>

I removed the command: [bpo-42802: Remove distutils bdist\_wininst command (GH-24043) · python/cpython@0e2a0f7 · GitHub](https://github.com/python/cpython/commit/0e2a0f72cc9af0899eacb5604e44a563c0b06110)

Follow-up issue in setuptools: [distutils bdist\_wininst command has been removed in Python 3.10 · Issue #2527 · pypa/setuptools · GitHub](https://github.com/pypa/setuptools/issues/2527)

---

<div class="post-metadata">

**Author:** ![vstinner](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/vstinner/32/15130_2.png) [@vstinner](https://discuss.python.org/u/vstinner)\
**Post date:** [January 8, 2021, 11:39pm UTC](https://discuss.python.org/t/remove-bdist-wininst-command/6434/13 "2021-01-08T23:39:34Z")

</div>

I agree with Steve that the bdist\_wininst maintenance can continue as a third party module. It would be easy to contribute to a third party project than CPython itself.

---

<div class="post-metadata">

**Author:** ![jkloth](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/jkloth/32/253_2.png) [@jkloth](https://discuss.python.org/u/jkloth)\
**Post date:** [January 9, 2021, 2:43am UTC](https://discuss.python.org/t/remove-bdist-wininst-command/6434/14 "2021-01-09T02:43:13Z")

</div>

Well, I started to look at the backlog of issues for wininst as soon as the top post went out. I ran into unrelated issues running the test suite, so last weekend was consumed by that. I was looking forward to getting into the _actual_ issues this weekend, but apparently, that is something that isn’t wanted anymore.

\< rant \>  
At what point, in a volunteer project, is 1 week deemed more than enough time for non-core developers to analyze and resolve issues? On one of the python mailing lists, I remember that 30 days was considered a polite amount of time for responses in a distributed collaboration model, like Python’s development is.

I’ve been contributing to Python, in some form, on and off now for 20+ years. I started the first win64 buildbot nearly a decade ago. My Real Life doesn’t allot me as much time as I was once able to commit, but I do still enjoy as least following the discussions. I am lucky to be able to dedicate a few hours a weekend (sometimes even up to 8!) to **all** development tasks I have going on.

This particular occasion isn’t all that aggreges, but it seems to be the straw that broke the camel’s back. It seems that unless you can dedicate a ton of time, mostly immediately, your contributions are not wanted in this development community. I would think that for a small team, which apparently wants to grow, alienating old hats with robust understanding of parts (or most) of the Python codebase in favor of rookies with loads of free time isn’t necessarily a good thing. It’s not that rookies cannot grow into pros and fresh blood is truly needed to maintain project health, but to chase away contributors that do not need any training time seems wasteful.  
\< /rant \>

I guess this is just my frustration of seeing things continually being eliminated without true replacements in place. The “once its gone, then they’ll make something _better_” strategy doesn’t cut it, IMO. It should be, "we have something that improves upon `thing`, let’s remove the old `thing`".

If you think that the current state of packaging has suitable replacements for what is provided by the wininst installers, please do enlighten me. A 1-1 listing of features would suffice.

FWIW, one of my first contributions to Python was to improve the extensibility of Distutils as our company one of the first adopters (anyone remember the `make Setup` fun-ness?)

---

<div class="post-metadata">

**Author:** ![daniele](https://avatars.discourse-cdn.com/v4/letter/d/dfb087/32.png) [@daniele](https://discuss.python.org/u/daniele)\
**Post date:** [January 9, 2021, 12:47pm UTC](https://discuss.python.org/t/remove-bdist-wininst-command/6434/15 "2021-01-09T12:47:19Z")

</div>

I was also very surprised to see the code removed as it did not look like there was consensus on this move and, at least, it would have made sense to fix the setuptools tests before removing the code, not leaving setuptools in a broken state. I don’t understand what is the rush in removing code that does not do any harm, other than magically solving a bunch of old bugs as invalid.

Anyhow, it should be easy to resurrect the `bdist_wininst` code into its own little package. If you like, I can bootstrap the effort and hand over the package to you once it implements the status quo ante. However, I will not be able to do more than check that the code runs. What do you thing of `setuptoools_wininst` as package name?

---

<div class="post-metadata">

**Author:** ![uranusjr](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/uranusjr/32/103_2.png) [@uranusjr](https://discuss.python.org/u/uranusjr)\
**Post date:** [January 9, 2021, 3:14pm UTC](https://discuss.python.org/t/remove-bdist-wininst-command/6434/16 "2021-01-09T15:14:25Z")

</div>

> [@daniele](#):
>
> Anyhow, it should be easy to resurrect the `bdist_wininst` code into its own little package. If you like, I can bootstrap the effort and hand over the package to you once it implements the status quo ante. However, I will not be able to do more than check that the code runs. What do you thing of `setuptoools_wininst` as package name?

I was wondering about this before reading your comment. It definitely makes sense IMO, although I cannot speak about the hand over part since I dont have any real-world usage of the command myself either. It would make perfect sense for anyone assuming maintenance of the package to propose it joining PyPA as well, if they wish to.

Another off-topic thought I have on this: Would it be a good idea for other distutils commands to be moved out of stdlib without too much effort?

---

<div class="post-metadata">

**Author:** ![steve.dower](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/steve.dower/32/56_2.png) [@steve.dower](https://discuss.python.org/u/steve.dower)\
**Post date:** [January 10, 2021, 12:13pm UTC](https://discuss.python.org/t/remove-bdist-wininst-command/6434/17 "2021-01-10T12:13:38Z")

</div>

> [@uranusjr](#):
>
> Another off-topic thought I have on this: Would it be a good idea for other distutils commands to be moved out of stdlib without too much effort?

All the commands have already moved into setuptools… so… yes? The main thing we gain from removing wininst from the next release is fewer people having their installs blocked by bad AV.

I agree it was a quick move from this post to final result, but then this post is not the first time it’s come up. So rather than saying you need to be actively working on stuff every week (a simple “I’m looking at it” post doesn’t take a week, BTW, and would have been enough), we are really lacking any kind of central coordination or even a central discussion location that some people aren’t ignoring for any of a variety of reasons. That fracturing is probably our biggest problem right now, which I think is why most of us are trying to just twiddle little things at the edges and avoid involving too many people.

The fact that I’m posting this in the packaging category and not a core dev category kinda emphasises my point, I think.

---

<div class="post-metadata">

**Author:** ![vstinner](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/vstinner/32/15130_2.png) [@vstinner](https://discuss.python.org/u/vstinner)\
**Post date:** [January 11, 2021, 12:49pm UTC](https://discuss.python.org/t/remove-bdist-wininst-command/6434/18 "2021-01-11T12:49:29Z")

</div>

Hi,

About the timeline:

- There are 19 open issues on wininst: 13 issues are between 4 and 10 years old. The fact that wininst is not maintained is not a new fact.
- 2016: PEP 527 was approved, it disallows to upload files other than source (sdist: tarball, ZIP) and wheel packages (bdist\_wheel) to PyPI.
- July 2019: I created [Deprecate bdist\_wininst](https://discuss.python.org/t/deprecate-bdist-wininst/1929) discussion to propose to deprecate distutils bdist\_wininst command, there was a consensus to deprecate it.
- January 2021: I created this discussion to actually remove the deprecated command. I saw that people who work on packaging still agree to remove the command, so I removed it.

For me, there is now a clear consensus that wheel binary packages is the way to go according to developers who work on Python packaging.

The What’s New Python 3.10 entry clearly suggests to replace bdist\_wininst with wheel. Some wininst features are not supported by wheel packages. It has been discussed that pywin32 requires to run a manual step to support Windows Services. IMO it’s an acceptable trade-off compared to wheel package advantages (ex: support virtual environments).

It has also been said that it’s perfectly fine if wininst installer and distutils bdist\_wininst command development continues as a third-party project. People are also free to offer download of wininst EXE installers on their website (but not on PyPI: PEP 527).

I removed bdist\_wininst to reduce the Python maintenance burden.

---

<div class="post-metadata">

**Author:** ![pf\_moore](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pf_moore/32/35_2.png) [@pf\_moore](https://discuss.python.org/u/pf_moore)\
**Post date:** [January 11, 2021, 12:59pm UTC](https://discuss.python.org/t/remove-bdist-wininst-command/6434/19 "2021-01-11T12:59:04Z")

</div>

It’s also worth noting that while wheels don’t offer a means to automatically run post-install commands, that is a limitation that has been discussed and acknowledged in the past. It’s possible for an update to the wheel format to be proposed which adds such a capability, but to my knowledge, no-one has done so. There are a number of problems which any such proposal would have to address, because one of the key principles of the existing packaging ecosystem is to move away from running arbitrary code at install time, but that’s something that can be discussed as part of any proposal.

So in short, yes wheels are not currently a complete feature-by-feature replacement for wininst, but no-one has so far seemed interested in fixing that.

---

<div class="post-metadata">

**Author:** ![vstinner](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/vstinner/32/15130_2.png) [@vstinner](https://discuss.python.org/u/vstinner)\
**Post date:** [January 11, 2021, 1:05pm UTC](https://discuss.python.org/t/remove-bdist-wininst-command/6434/20 "2021-01-11T13:05:43Z")

</div>

People who work on PyPI are fighting against typosquatting packages: malwares which steal secrets like SSH private keys. There are 1 to 50 packages that should be manually removed. It’s a lot of work. Automating the detection of malwares is an even larger project, it seems like some people are working on that.

I like the fact that wheel packages **cannot** run arbitrary (Python) code. For me, it’s a great argument for stronger security. I would even suggest to require a command line option to opt-in for source installation (run “legacy” setup.py).

pip is a generic package manager. Companies can build more specialized installers for their own needs. But I would recommend against making pip too complicated, and focus on the most common use cases. pip cannot solve all problems. The team working on pip is too small.

[Next page](https://discuss.python.org/t/remove-bdist-wininst-command/6434.md?page=2)
