Well, it's still what you do every time you create a new project.
> It is mandatory in quite a lot of package managers.
Ok but many packages won't be installable at all anymore, because people pin different versions instead of maintaining their packages by continuously integrating upstream releases.
> You can't live at latest release with software coming from wildly different developers, with wildly different policies on compatibility, versioning, breaking changes, bugs...
Well I didn't know can't so I did.
> I can't just take the latest numpy and patch it for Python 3.6.
Instead, you should be upgrading your code to support the newer numpy version. Seriously, try it out, you'll be spending less effort at the end of the year.
> You also spend time doing maintenance and debugging on new installations to debug and fix compatibility issues, when those upgrades might not bring any value to the product.
I spend less time and more spread over the year, bringing value to the whole ecosystem of packages which are bringing value to my product, and bringing value to myself as I develop new products with the dependencies I like and support as such.
> In my case, I do that debugging and fixing in a controlled environment
I wait for CI or users to report that a new release isn't compatible so I can fix it as soon as possible, in which case we temporarily pin versions, instead of piling up tech debt until it's so huge the whole project becomes trash.
That's what I call taking responsibility with the dependencies that you include in your product.