#setuptools
1 messages · Page 2 of 1
Automatically exported from code.google.com/p/graffle2svg - dbremner/graffle2svg
The project is 14 years not updated, might be broken. Try pip install ., but I am not hopeful
is there any method to make it modern?
Fork it and fix issues. Judging by the age, it is probably focused on Python 2, so code might even be incompatible with modern Python versions
yeah, at that point 3.x barely existed and had quite poor adoption. and nobody distributing their code was thinking in terms of the "ecosystem" we have today. they weren't even thinking in terms of "setuptools can release new versions and that could possibly cause a problem"
however, I don't see a license here (let alone any PyPI distribution), so....
to do things properly you'll have to start by emailing the author
the project was developed in google codes era, all Github repos are just archives
idk do those developers active in Github
There's no hurry as I've already been sitting on it for a while. Just wanted to mention that next time there's a pypa/distutils sync to pypa/setuptools, that'll unblock removing a bunch of jank from typeshed's setuptools stubs: https://github.com/python/typeshed/pull/13627
Is this a setuptools bug, or.. is it more complicated? https://github.com/astral-sh/uv/issues/9559#issuecomment-3275424142
It seems like it's not producing the android wheel?
Hello! Is there a way to control the location of the build directory? We're trying to clean up this part of our distribution process https://github.com/jcrist/msgspec/blob/836d71ff2fd39a21f98b1c2c1cc211e4e224734e/.github/workflows/ci.yml#L47-L55
Since builds are isolated in a temporary directory when building from the source distribution I was hoping to set an absolute path.
I tried the following:
uv build --config-setting=...=/build --config-setting=...=/build
with --build-lib/--build-temp, build-lib/build-temp and build_lib/build_temp
This is outside my expertise, but I think the frontend installer tells the backend what directory to build the wheel, as we just changed this in pip: https://github.com/pypa/pip/pull/13541
Is it possible to configure the editable_mode behavior in pyproject.toml?
<@&815744082823348274> ^ spam
Ban hammer has been used.
I'm trying to ship a .pth file with coverage.py. pytest-cov used to do it, so I'm trying to follow its old-code example, but I think it has some things wrong. The documentation for extending setuptools is a bit confusing to me, and has some gaps. For example, I can't tell what commands in cmdclass will be used when running pip install -e .. Are these described somewhere that I've missed?
Doing some reverse engineering, these are the keys looked up in cmdclass when doing pip install -e .:
looking for cmdclass['egg_info']
looking for cmdclass['egg_info']
looking for cmdclass['build']
looking for cmdclass['build_ext']
looking for cmdclass['dist_info']
looking for cmdclass['dist_info']
looking for cmdclass['build']
looking for cmdclass['build_ext']
looking for cmdclass['bdist']
looking for cmdclass['editable_wheel']
looking for cmdclass['editable_wheel']
looking for cmdclass['build']
looking for cmdclass['build_ext']
looking for cmdclass['bdist']
looking for cmdclass['build_scripts']
looking for cmdclass['install_lib']
what is the reason for custom .pth files actually?
to start coverage measurement of spawned subprocesses.
BTW, that page has some odd sentences:
Between these mandatory methods, are listed: initialize_options(), finalize_options() and run().
and:
Subcommands SHOULD take advantage of editable_mode=True to adequate its behaviour or perform optimisations.
Messing with those is pretty fragile, can't you just add it as package data?
I don't use setuptools on my projects (too slow and don't like the error messages), but I'm pretty sure I added a pth file for a project I was helping and that probably was setuptools, I know it wasn't hard, didn't have to resort to setup.py.
I tried using package data, but the .pth file has to go in one of four specific places, not in the coverage/ directory. Using a data_file works as long as the Python version that built the wheel is the same as the version installing it. The version is in the file path (see https://inspector.pypi.io/project/coverage/7.12.1b1/packages/1b/1b/cd5c3391a04a101767961e3e3ccf5a0c987b08d8434d97073dbbd132a049/coverage-7.12.1b1-py3-none-any.whl/), so environments that use py3-none-any (like PyPy or 3.15.0a2) don't work properly.
That's not the right place for the .pth file. Those go at the top level, just like if you had a <package>.py file (single file module).
I'll make a PR showing you what I mean.
Thanks, i'll take a look soon. The 7.12.1b1 code was putting the .pth in the correct place for binary wheels, but not for the non-binary wheels. I've had a fascinating session with Claude reverse-engineering setuptools. I had been looking at how pytest-cov managed it, and it seems like their code was outdated.
No, it happens to go to the right spot if site-packages is in the most common location. It only goes in the right spot in a specific (though common) case. It must be placed in the correct location in the wheel, in purelib/platlib, not assuming python was built without passing the --site-packages configure flag.
sorry, you are right, the 7.12.1b1 wheel has the wrong (hard-coded) path. My latest code (not published) has the same path your fix does (./coverage.pth), but with more code to get it done.
i have to decide what to do about -e installs. the pytest-cov code for that doesn't work.
In the off chance this isn't resolved... See https://stackoverflow.com/a/71137790
thanks. @unkempt birch gave me a simpler solution:
package_data={
"coverage": [
"htmlfiles/*.*",
"py.typed",
"../coverage.pth",
],
},
and i got editable installs working also. just a few coverage-within-coverage details to iron out.
Aye nice! I'll look into updating the answer w/ credits then, assuming I can find my SO credentials right now. 😅
I'm a little surprised that ../ works there, but it seems to.
wait, is coverage.pth in a folder above the pyproject.toml? o_O
(actually, ISTR something about a giant Apache monorepo having that use case....)
(for Airflow I guess?)
Is there any new info about pkg_resources removal?
Came here to check on this too ^^
Past the due date and no movement on https://github.com/pypa/setuptools/pull/5007
PBR still had reliance on pkg_resources, but that seems to have been solved: https://bugs.launchpad.net/pbr/+bug/2111459/comments/6
Remove pkg_resources
Remove assertion that 'import pkg_resources' works; it's no longer an invariant.
Mark pbr integration test as xfail.
Mark namespace tests as xfail. Supp...
@jaraco I think this should be resolved now. Running the same tests, I now see:
❯ tox -e py39 -- -p no:cov -p no:xdist -k pbr_integration -v
.pkg-cpython39: _optional_hooks> python /usr/lib/python3.13/site-packages/pyproject_api/_backend.py True setuptools.build_meta
.pkg-cpython39: get_requires_for_build_editable> python /usr/lib/python...
Actually there's been almost no movement on distutils/setuptools in a few months other than CI fixes. I believe Jason got a new job, probably related.
I've been patiently waiting on a distutils sync to do some cleanup in typeshed. I'm also so, so close to making setuptools' type annotations complete enough to be first-party (all the changes I still need have a PR open).
wonders if top_level.txt still serves any pupose post-eggs
Even if it had any use, PEP 794 should provide a complete replacement (and some more)
Yeah
I'm looking at some misbehaviour of a Debian Python package where the upstream had:
[tool.setuptools.packages.find]
where = ["."]
Which leads to all sorts of non-reproducible junk in top_level.txt. And debating how much effort I want to spend on fixing this systematically.
Just deleting top_level.txt should probably be fine?
it does
importlib.metadata uses it
PEP 794 isn't supported yet if I am correct
That is at least used in a context where missing is probably better than present and incorrect.
i don't think an stdlib module should be reading single-tool non-spec files at all
(I tried to dig into importlib_metadata once and the architecture of it just seemed really strange overall. Like, just organic and not designed with forethought)
(so I'm not surprised that it would be doing something like that, though I agree it's not a good idea)
there are much worse sins being committed there 😅
it preceded PEP 517, so it makes sense
kinda, there is a decent deal of thought that goes into the design, but it had to grow quickly to fill the use-cases of pkg_resources
deleting it blindly would cause more trouble than it's worth
and if you are fixing the package manually anyway, you could just fix it instead, but it's your call
also, I am struggling to see how that setuptools setting might be causing issues with reproducibility unless you are not building from clean sources
i focused the issue on improving the docs for that
That's exactly the issue. Two builds one after another, that generate different metadata
i think it's worth though documenting top_level.txt as some form of unsupported/deprecated, if just to avoid users building on top of broken workflows
how are you building? are you using python -m build -n?
that'd be my recommendation as it builds the sdist first, which may not include the problematic build artifacts you will have in the second build
building a wheel directly from source is a footgun with some backends
anyway, this is definitely a setuptools bug, so worth reporting
Yeah. Roughly.
https://salsa.debian.org/python-team/tools/dh-python/-/blob/master/dhpython/build/plugin_pyproject.py?ref_type=heads
doesn't seem so
the key thing in the command I mentioned is that it builds an sdist, unpacks it, and builds a wheel from that source
I would recommend you to do the same
building directly from source jumps over https://setuptools.pypa.io/en/latest/userguide/miscellaneous.html
setuptools, and some other backends, are not designed to work like that, they are designed to build the wheel from the sdist
setuptools is usually the most problematic one, in the others issues mostly come from dirty development trees, etc
do this
I'll look into that. I want to make some other changes to this code, to run tests away from the code that we'll install.
I still see https://setuptools.pypa.io/en/stable/pkg_resources.html being in the docs despite pkg_resources having been nixed yesterday – oops?
gotcha
and here is the issue I expected to find: https://github.com/pypa/setuptools/issues/5174
why is it that people continue blindly updating through major versions and expect no backwards compat issues?
and ignoring DeprecationWarnings and UserWarnings and not pinning...
My way of fixing this in the scientific ecosystem has been to get more and better docs for meson and meson-python written
I read the issue more thoroughly and the problem seems more nuanced than I first thought
the problem seems to be legacy dependencies that still assume setuptools has pkg_resources
with build isolation this becomes a problem
you get strong pushback when you suggest upper bounds on build backends
this isn't even a problem for projects that release wheels
and my criticism, whether deserved or not, was aimed at app developers who have the ability to pin their dependencies
as far as I can tell, because their tooling defaults to the updates and the issues are not something they considered in the first place
https://lwn.net/Articles/1020576/ seems relevant
In late March, version 78.0.1 of Setuptools — an important Python packaging tool — was released [...]
(FD: that's me. Writing for LWN is fun and not as stressful as you'd think, despite that they're even more nitpicky than you'd guess)
generally speaking open ended version ranges behave better
at least until they don't 🙃
Given metadata for anything shipped on PyPI is immutable, if people were pessimistic about their upper bounds, you'd quickly end up where a large majority of PyPI couldn't be installed alongside each other
for build backends it's less of a problem, given they're (typically) run in isolation
If PyPI had metadata patching, pessimistic upper bounds would function better, since you could patch your metadata to bump the upper bound after you've tested the new release-- but that presumes people would actually do that across all of PyPI, which is unlikely! So even with metadata patching, optimistic would tend to be better, but at least you could patch to respond to breakage 🙂
setuptools releases major versions way too often to cap it. And you need newer versions for newer Pythons, newer OSs, etc. Anything with capped setuptools would likely be broken already from other things.
I don't understand the insistence that changing setuptools should require a PEP in that issue
This only affects Python 3.9+ (would maybe have been nice to have dropped 3.9 first, as that reduces impact on older Pythons, but 3.9+ does have importlib.resources.files and such)
Wouldn't this download a file, and then do something weird on installation since the included metadata is different?
Well it doesn't exist so it's impossible to know exactly how it would work 😉 but presumably either installers would treat the repo level metadata as authoritative or it would be implemented as separate "patch" (in concept, not the patch tool) files that the installer is expected to apply to the metadata before reading it (and maybe PyPI pre-applies those for the metadata that it lifts out of the artifact-- or maybe it doesn't and tools just have to apply thoes patches to the metadata to get the correct behavior)
or something like that
https://prefix.dev/blog/repodata_patching conda has repodata patching, so it's just patching (afaik) the repository level metadata, and I think it leaves the artifacts alone, but tbh I don't really know if that's true (or if conda artifacts even have metadata inside them like python packages do)
if it was part of pip or some other standard toolchain, it would probably be doable for people
Oh yea, adding it would be a PEP that would need the installers to support it for sure
there is also a matter of local caches of wheels that would have to understand that
Patchable metadata is massive undertaking. It's been discussed a bit, but it would touch a lot and require changes everywhere. And security can be an issue depending on what you wanted to allow patching for. And you'll need something for mass updates on PyPI. Etc.
some distutils CI fixes: https://github.com/pypa/distutils/pull/398 maybe someone with merge rights can have a look, feedback welcome
Added one small comment, nothing major though, looks good. 🙂
I just ran into https://github.com/pypa/setuptools/issues/2688 again, where our DEFAULT_EXCLUDE list doesn't include any sub-packages, so doesn't do a whole lot of excluding... I'd forgotten how painful setuptools finders can be.
The context for me is building Python modules multiple times from one source tree and getting build directories inside the result wheel.
@quaint jolt: You previously advised building wheels from sdists, rather than directly from the source tree, I guess that's the best solution for me here...
this is for debian or ubuntu or whatever? I suspect building from sdists to be the right answer, but I recognize that sometimes sdists contain built artifacts (generated files typically) that sometimes the source tree doesn't.. .hopefully that's less of a problem with 517/518? Dunno though
Seeing this with 517/518. But it also happened before 517/518
sorry I just mean hopefully less people will include pre-generated files in their sdists because IIRC that was commonly done to avoid bootstrapping dependency issues 😅
I'm worried that going via sdist is going to break lots of fragile test setups etc. But the only way we'll find out is by implementing it...
I'm just shaking my head wondering how DEFAULT_EXCLUDE was ever supposed to work
(And I have a sneaky feeling I've been there before)
my guess is someone made an arbitrary choice 20 years ago and changing it is scary 😛
My position too 😛
my recommendation was to build an sdist from source, and then use it to build a wheel
👍 that's good practice anyway (at least according to build)
Deeply confused about how the Py_LIMITED_API macro ends up being defines in builds managed by setuptools. I see how that’s controlled via the distutils bdist_wheel command’s py-limited-api argument, but then I don’t see how that leads to any macros being defined in extension builds. Anyone have the foggiest idea how that works? Context is I’m working on https://github.com/Quansight-Labs/stable-abi-testing and want to get the setuptools support I’ve hacked together into a more mergeable state.
If PEP 803 were accepted, does it make sense to have a new Extension keyword argument that allows manually toggling an abi3t build? Or should it require a free-threaded interpreter?
uh
distutils/setuptools has a way to inject macro definitions into the build
is the method in distutils, not sure if that get moved out if distutils or if that part is still used
I don't think setuptools actually sets the macro for you though, I think you're expected to set the macro yourself using those mechanisms (or another)
changelog for 25.4.0 says:
Add Extension(py_limited_api=True). When set to a truthy value, that extension gets a filename appropriate for code using Py_LIMITED_API. When used correctly this allows a single compiled extension to work on all future versions of CPython 3. The py_limited_api argument only controls the filename. To be compatible with multiple versions of Python 3, the C extension will also need to set -DPy_LIMITED_API=... and be modified to use only the functions in the limited API.
no problem!
Hi! We got a request in the PEP 803 packaging thread to get input from setuptools maintainers on the possibility of a new ABI tag. I have a draft PR open that implements support for the new ABI tag in setuptools: https://github.com/pypa/setuptools/pull/5193. I'd appreciate feedback there and on the packaging discourse thread if any setuptools maintainers have some time to weigh in. https://discuss.python.org/t/pep-803-stable-abi-for-free-threaded-builds-packaging-thread/104976/75
@lusty dome I had a look at the distutils adoption
setuptools will adopt the distutils module as it is currently in cpython, right? or will the implementation be somewhat replaced?
my take considering the Linux distro issue, is that it should be adopted as-is, but deprecated
then the Linux distros that need to, can apply their patches
some people might also be relying on implementation details of the distutils module, so I think this would cause less breakage
I am probably still missing some context though, because overall it seems pretty straight-forward to me
Indeed it is more complicated. Setuptools has already adopted distutils, but it’s protected by a flag flip currently disabled by default. The problem with applying the patches is that distros can’t apply their patches reliably to third party packages... and they can’t apply them to the adopted code without affecting other platforms. They need a hook or mechanism to apply their settings anytime Setuptools is installed on their platform. The approach we settled on is they will override sysconfig (root package) and distutils will honor those settings. The devils in the details.
Maybe we could meet Friday or Sat and I could give you a tour and answer questions.
yes, that is fine by me
@lusty dome any thoughts on https://github.com/pypa/build/issues/255 ?
My project exists in a directory like so: /c/users/b/projects/repo/foo/foo-py With my setup.py and pyproject.toml residing in /c/users/b/projects/repo/foo, and the source code under that in foo-py/...
@lusty dome I am available for the rest of the day, let me know if you want to have a chat
How about in 25 minutes. At :45 ?
works for me
@lusty dome can you talk in the next few days?
I just have some final details to run by you and some questions about the process
It's been quite a week for me, and I'm on-call this weekend, but maybe Saturday. Does that work for you?
I'm going to make a coffee, then I'll be on the voice channel.
I am available now
I've been taking notes in our hackmd: https://hackmd.io/r-iOdmM_TGSiYpyGKp-cFg?edit
@lusty dome https://github.com/jaraco/zipp/issues/71 this seems like a setuptools bug to me 🤔
it's almost like setuptools is not able to generate metadata for pip to evaluate the python_requires without loading the namespace
The packages = find_namespace: line in setup.cfg looks out of place to me. zipp doesn’t seem to have a namespace package, so setuptools is probably just confused.
importlib-metadata depends on zipp, and virtualenv/pytest/tox depends on importlib-metadata, so this bug breaks the entire python 2 CI at my company 😄
@river oak do you know how to check why pip picks a given package? for some reason on my local machine it picks 1.2.0 of zipp, but in the CI picks up 3.4.1 😐
setuptools not able to selectively load values without loading everything else is a very known problem though, this is not the first example and won’t be the last. That’s what using an interpreter (Python) for configuration gets tou, every thing is evaluated at import time so there’s no way out 🤷
actually in CI this just could be an older pip 🤔
It reads in the index page, reads data-requires-python of each link to exclude incompatible ones, and just order them by version
Yeah older pip may be a problem. IIRC Ubuntu ships with pip 9 by default as recently as 20.0 or something
I don't think it's an older pip problem. See https://github.com/jaraco/zipp/issues/70#issuecomment-814219326.
zipp/setup.cfg Line 18 in 13fad1d packages = find_namespace: this might be breaking the installation https://files.pythonhosted.org/packages/38/f9/4fa6df2753ded1bcc1ce2fdd8046f78bd240ff7647f5c9bcf5...
It could be pip 8.
@cloud sand Have you confirmed that your company is using a PEP 503 compliant index server?
FTR, I don't think there's anything wrong with find_namespace:. I use that in all my packages now as a matter of course, unless they need Python 2 compatibility.
how do you find that out? 😄 (it's running Artifactory a recent release)
It's a red herring - the problem is that some installer is pulling down packages that declare incompatibility with the target environment.
https://github.com/python-poetry/poetry/issues/2507#issuecomment-639988759 suggests that Artifactory doesn't implement PEP 503.
In that case, you're unfortunately constrained to a pre-PEP 503 world. If you recall that world, the only way to prevent installation of incompatible packages is to pin your dependencies.
So I'm being told it should be 🙂 (was released sometimes last year)
For this particular issue, I'd recommend to install zipp<2 and importlib_metadata<3 and importlib_resources<4 (possibly only for ;python_version<"3").
seems suddenly now everything passes 😐
I guess we'll come back if we can pin it down what was it, did the PEP-503 service crashed in artifactory perhaps 🤷♂️
The PEP says "A repository MAY include a data-requires-python attribute on a file link.", but a repository really SHOULD implement it if they want happy Python users.
But that should answer the question. If you want to test your repository, load the /simple/zipp/ (or similar) and inspect the HTML for anchors with data-requires-python. If it's not there, then pip can't discern either.
@lusty dome I was thinking, it would be really handy to be able to write entrypoint scripts that only use specified install schemes
this would prevent pip from shadowing modules that distro installed entrypoints are expecting to be there
what are your thoughts?
to implement this I was thinking using python -SI in the shebang and then doing something like sysconfig.enable_scheme('arch')
would this be a good idea, what do you think?
I think I understand what you're saying - if a distro installs a package with a script, you want that script to preclude the possibility that the modules that back that script could be superseded by non-distro module installs. Yes, that seems plausible to me. I'm not aware of any problems with the approach you propose, but I'm also not very familiar with installers. There are probably people better suited than me to consider the proposal. I believe it's mainly distlib and pip that implement those scripts.
I was looking forward to having it in https://github.com/pradyunsg/installer
what I described requires the addition of something like sysconfig.enable_scheme('arch')
we need a method that will add the correct paths to sys.path
it's mainly here that I want your opinion
What would enable_scheme() do? Everything in sysconfig is global and has no side effects, and probably needs to continue to be.
it would only add paths to sys.path
note this doesn't have to be in sysconfig
that's just my initial sugestion
but since it's a method that users have to run explicitly, I don't really see the issue
Oh so it adds purelib and platlib from sysconfig.get_paths(scheme='arch') to sys.path? That feels… both weird and unuseful to me.
Also there’s https://bugs.python.org/issue43312 if you’re not already aware. Instead of putting things into sys.path (which has side effects), installation tools should just not read sys.path at all, and instead relying on values returned by the “pure” sysconfig functions.
Scheme-specific console script sounds weird to me as well. IMO the scheme should decide whether it wants scripts and how, and if it doesn’t want them it can make sysconfig.get_path('scripts', scheme=scheme) return /dev/null or something (or maybe we can use None for that).
well, I presented the usefulness above
do you have any alternative suggestions?
I am not convinced it is the perfect solution, I think it is an okay solution, so I am all ears for alternatives
I am aware of that bpo, I don't think this should affect anything. we would be asking Python to enable a custom scheme, it does not affect the default scheme.
IMO the scheme should decide whether it wants scripts and how
that is fine, and in my use-case they would the same path
note there is nothing really preventing me from doing it already, I just want to streamline things so that we don't end up with another Debian-like issue
IMO this is a valid use-case
the current mechanisms were not designed exactly for this, but they were also not not designed for this
I am just trying to do the best I can to provide users the best UX
Artifactory doesn't have data-python-requires except on the newest versions.
I’m not sure I have better suggestions since I’m not really seeing the benefits here. Why is a runtime function needed? Shouldn’t this be done in the initialisation phase, maybe in site.py? Would it be a good idea to make site.py better documented and structured so distros can better configure the installation for their needs?
sure, I am open to that
I had thought about it but couldn't come up with anything particularly good
so I just proposed the simplest thing
but I am more than happy to discuss alternatives
Did they fix the #md5= to be #sha256= yet?
🤷🏻♂️
@lusty dome hey, do you have some time to go over the implementation details of the vendor config with me?
Sure. I'll have some time later today.
@quaint jolt I got occupied but free now. Joining voice
Looks like I missed you. Will check back later. Feel free to post questions in the meantime
alright
I was having dinner
@lusty dome joined voice, feel free to hop in when you can
./configure --with-vendor-config=vendor_config.py
/usr/local/lib/python3.10/_vendor_config.py
import _vendor_config
EXTRA_SITE_INSTALL_SCHEMES = {
'arch': {
'stdlib': '{installed_base}/{platlibdir}/python{py_version_short}',
'platstdlib': '{platbase}/{platlibdir}/python{py_version_short}',
'purelib': '{base}/lib/python{py_version_short}/arch-packages',
'platlib': '{platbase}/{platlibdir}/python{py_version_short}/arch-packages',
'include':
'{installed_base}/include/python{py_version_short}{abiflags}',
'platinclude':
'{installed_platbase}/include/python{py_version_short}{abiflags}',
'scripts': '{base}/bin',
'data': '{base}',
},
}
@lusty dome I have the PR ready but some people requested more feedback
acknowledged
if you have time, you can look at the code to see if there is anything you'd like to change
I see Éric has asked to discuss the design in a forum. Is that something you're prepared to do?
Probably the first thing should be to reference the prior discussions and designs and point out that this PR is an implementation of those proposals/designs.
it's a little bit tricky because this has a lot of baggage and required context, but I think so
I opened a thread on discourse
my mindset here is essentially "please point issues, or suggest and demonstrate a better alternative"
I think there is a possibility of people nitpicking the implementation, I will try to hear the suggestions but won't block progress because of that
Deadline is Monday I think. Let me look tomorrow and see how close we are. It doesn’t have to be perfect but it needs to be close to an adequate and permanent solution.
thanks
I should have fixed all the tests now
I also sent an email to Miro regarding the feedback for Fedora
I should have been quicker 😕
I have added get_preferred_schemes to the vendor config as some distributors, such as Fedora, want it
and this is better than the current approach anyway
👋
hey 🙂
@quaint jolt I'm around today. I'm going to work through the various notifications I have. I'll also be hanging out in the voice channel.
test_resource_opener and test_resource_path
Would setuptools accept wheel building for POSIX vs. Windows so my linux box does not get all the .exe ? (I have not searched for a issue - being lazy since i see the channel here) 😄
It's been requested.
Those exes are deprecated. I'd prefer to just eliminate them and rely instead on distlib.
There's an open PR that's exploring switching to distlib, if you wish to assist there.
Wow - would be very hard to relate this to deprecating .exe's in setuptools for an outsider
I'm unsure if distlib wheels have exes in it.
If distlib has exes, then that would only push the issue downstream to distlib.
Looks like it does have exes in it https://bitbucket.org/pypa/distlib/src/master/distlib/
And it uses universal wheels (https://pypi.org/project/distlib/#files).
(files(package) / normalize_path(resource)).open('rb')
self = <importlib_resources.tests.test_open.OpenZipTests testMethod=test_open_binary_FileNotFoundError>
def test_open_binary_FileNotFoundError(self):
> self.assertRaises(
FileNotFoundError, resources.open_binary, self.data, 'does-not-exist'
)
importlib_resources/tests/test_open.py:50:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
importlib_resources/_common.py:124: in open_binary
return (files(package) / normalize_path(resource)).open('rb')
/usr/lib/python3.9/zipfile.py:2306: in open
stream = self.root.open(self.at, zip_mode, pwd=pwd)
/usr/lib/python3.9/zipfile.py:1502: in open
zinfo = self.getinfo(name)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
def getinfo(self, name):
"""Return the instance of ZipInfo given 'name'."""
info = self.NameToInfo.get(name)
if info is None:
> raise KeyError(
'There is no item named %r in the archive' % name)
E KeyError: "There is no item named 'ziptestdata/does-not-exist' in the archive"
/usr/lib/python3.9/zipfile.py:1429: KeyError
@lusty dome
yo
The exe’s really need to exist, the alternative is to hand-write the binaries at runtime.
Is that terribly expensive?
It would be an extra layer of abstraction (extra step to encode when the wrappers need to change, and then extra work to decode those back to executables to generate them). I doubt the run-time cost would be a concern. How much does it benefit the use-case to have executables encoded into Python?
Correct, it's not the cost to write that's the concern, but the additional complexity involved in encoding that file in Python source and decoding it when needed.
@lusty dome im wondering, is there a sensible way to separate setuptools_scm from the core setuptools dependency, im trying to make it usable for other tools that may not want to pull in setuptools (even if the wheel is easy)
Absolutely.
I would have expected that to be the case naturally.
In hgtools, the functionality was usable independent of setuptools.
What about setuptools_scm is reliant on setuptools?
That's the beauty of entry-points - their inversion of control. They put all the control in the hands of the plugins. All a plugin needs to do is meet the consumer's protocol, and any other behavior is fully under their control.
@lusty dome the dependency is mainly there ot sort out minimal versions, the real issue is that i have to depend on setuptools to set the required version for the integration
@lusty dome so right now i dont know how to make the setuptools dependency optional without making the integration fall on too old versions
I'm inclined to suggest not to depend on Setuptools at all, but to explicitly depend on packaging (for sorting out versions). I would expect even old versions relying on setup_requires=setuptools_scm to correctly get dependencies of setuptools_scm, so it should work. What's wrong with that approach?
stuff like the finalize hook are not there in old versions, same goes for wheel support and a few other things , my current expectation is that things will blow up for users that havent pinned a minimal version as well as distros
Guessing this is timely for poetry’s new plugin system, but I’d like it for a potential future PEP 517 backend for scikit-build, too. Personally pinning a min version of setuptools In pyproject.toml is fine with me (42+ must be pinned already for good pep 517 support), but not everyone uses that, I guess.
hmm, actually, i have a idea now, will fix today - this will be a setuptools_scm 7.0
@restive talon It sounds like you want to remove the dependency on Setuptools but still enforce that if Setuptools is present that you have a suitable minimal version. For that, I'd recommend packaging and importlib.matadata. Something like
def check_requirement(req="setuptools>=42"):
"""
Return whether a present package satisfies the specified version.
"""
target = packaging.requirements.Requirement(req)
with contextlib.suppress(importlib.metadata.PackageNotFoundError):
found_str = importlib.metadata.version(target.name)
found = packaging.version.Version(found_str)
return found in target.specifier
return True
But how will that code trigger on old setuptools, it would never import setuptools_scm to begin with in a recent setup
Hmm, yikes, the file finders
This will be horrible but work as trigger
@restive talon I guess I'm not following. I don't yet fully understand the problem you're trying to solve. If nothing attempts to import setuptools_scm, then you don't have to do the check. Do you want to perform the check only when setuptools_scm is invoked from Setuptools? If that's what you're after, then yes, you would want to only enact the check in the hook(s) the plugin presents to setuptools.
@lusty dome setuptools before the finalize_dist hook batted against a project that triggers setuptools_scm importation by that hook would then not import setuptools_scm as far as i understood (as the setup keyword would only trigger import on use)
Hmm, I found a bug on https://github.com/pypa/setuptools/blob/2234e88b7b820c40f29d7ddadc182b0f130eaa1d/launcher.c#L179 where GenerateConsoleCtrlEvent silently fails and that failure isn't reported at all.
I think it is because it has wrong parameters, the first one should be one of CTRL_C_EVENT or CTRL_BREAK_EVENT https://docs.microsoft.com/en-us/windows/console/generateconsolectrlevent.
This means that if the launcher is killed the underlying python process doesn't receive that signal.
I had found it in (for context) https://github.com/msys2/msys2-runtime/pull/31#issuecomment-854019021.
will make a PR to fix them
I made https://github.com/pypa/setuptools/pull/2694 but am worried how to replace pre-build executable's?
@lusty dome Since when does setuptools use pip for handling setup_requires?
I think that changed early this year, but I can't find setuptools' changelog in the docs.
NVM, I'm blind -- it's called History and it was 52.0.0.
I use the term "History" to refer to the changelog: https://setuptools.readthedocs.io/en/latest/history.html
Looks like v42.0.0 added it https://setuptools.readthedocs.io/en/latest/history.html#v42-0-0
23 Nov 2019
Also, I'm blind too. I read your first two messages, but didn't see the third until just now.
this does not happen in build_meta, right?
but it does in the legacy backend
right?
(just confirming)
I don't recall how build_meta handles setup_requires. I seem to think build_meta still honors setup_requires but it should be a no-op if the user is supplying their build requirements in pyproject.toml.
Oh, I'm mistaken.
It does actively disable setup_requires.
cool, thanks!
@lusty dome is there something that can be done about better integrating pyproject.toml - bascially the finalize options hook will not have access to a distribution name, if the distribution config files have not bene parsed, its quite a pain at first glance - it seems setuptools_scm will have to parse setup.cfg in addition to pyproject.toml to work, and as things look, potentially the metadata from pyproject.toml as well
I agree - setuptools_scm shouldn't be responsible for parsing metadata, except maybe in a situation where there's a standard for providing that metadata (like pyproject.toml), but even then, I'm not sure why Setuptools couldn't provide that metadata parsed to its plugins.
Looking into the issue as you describe it, I can confirm that a Distribution calls .finalize_options in init, but parse_config_files is called after the Distribution is initialized. And I agree - there should be a way for plugins to hook onto the Distribution after config is fully loaded. I can see a couple of potential approaches - either add a new hook, after finalize_options and parse_config, that setuptools_scm could use instead. Or, move the config parsing ahead of finalize_options. I'd probably lean toward the latter if feasible, because that would involve less flux and enable other plugins to use the finalize_options with config loaded. What I can't tell with a cursory examination is if moving the config loading earlier would have adverse consequences.
Would you be willing to file a bug and ping me on it? And if you or someone is willing to take on the next step of the investigation and see if moving the config parsing earlier is viable (or if not, why not), that would be most appreciated.
geofft and I have been struggling to build internally to our company a number of python projects (most recently dm-tree, but also stuff like xeus and arrow) whose setuptools build scripts use a variety of mechanisms (mostly raw build_ext custom implementations, but also scikit-build exists) to call out to cmake to drive a build of c++ code, into an extension module directly (often with pybind11), sometimes into a shared library that gets linked into an extension module (cython or raw cpython or something)
our struggle often comes about because we need to pass arguments to the cmake stuff to tell it where to find its dependencies or something, and usually the custom bridging of setuptools to cmake doesn't afford passing arguments through setup.py's arguments into cmake, so we have to patch the sdist, usually for expediency just patching CMakeLists.txt
I wonder if there's any prior work you all have done, or appetite to work together on, some standardization of how setuptools invokes lower level build systems like cmake (or, I anticipate soon, meson)? We have distutils which has a known api for building c files into extension modules and surfaces things like the include path up for control by the invoker of setup.py, could we have a standard mechanism that knows about cmake conventions? Would people be in to this?
Put another way, we have setuptools-rust/maturin and these are early enough in the rust ecosystem that it's likely anyone doing python+rust will standardize on this; can/should we try to corral the python+c++ packages that exist in the ecosystem into a standard way for the build systems to cooperate?
I usually just set CFLAGS/CXXFLAGS
but that depends on the details
I can get most stuff to work using that generally
For well behaved cmake projects you can often finesse it with a carefully constructed CMAKE_PREFIX_PATH, yeah, but often you need to convince setuptools to pass some -D options to cmake or something like that, and usually when it's a custom build_ext thing, the author of setup.py hasn't bothered to plumb arguments down from setup.py's argv to cmake
https://github.com/pypa/distutils/pull/49 can I get a Code/concept review?
@jaraco thanks for the details, it seems that i have to do the parsing first in any case for compatibility
I will slot passing more details to setuptools for after i can land a workaround in setuptools_scm
@lusty dome aware of anyone working on https://www.python.org/dev/peps/pep-0621/ support for setuptools? -
Some have expressed interest. I don’t think there’s been any active development. I’m away from my computer or I’d search the issue tracker. Feel free to file one or work out a design.
i see, unfortunately im too stretched to put work into it atm
One day I'll do it 😬 if no one gets ahead of me ☺️
well, im going to merge a few prs for setuptools scm now and then work on it, the toddler dropped aslept shortly after 5
@lusty dome is there any way to integrate into commands via a entrypoint? i'd like to stop setuptools_scm from doing the write_to always and instead only do it for installs/editable installs
Setuptools allows for additional "distutills-commands", but not to hook into specific commands. @restive talon I'll need more details to describe what you're intending to accomplish.
in setuptools_scm, the write_to feauture, which writes a version.py file, runs at setup invocation time, i'd like it to run only for build/install/editable
So you wouldn't want setuptools_scm to be invoked for sdist? That sounds like a pretty big deviation from the current design - where configuration and plugins mainly affect the setup of the build, and the build acts on that configuration. That's not to say that there shouldn't maybe be a way for setuptools to solicit other behaviors at build time, but it's not obvious to me how that would work.
What's the motivation for not wanting the file to be generated earlier?
Setup.py --help triggers the write
and basically i only want it to be written into a wheel or into a sdist or inplace
Have you considered not writing the file and just letting setuptools track the version?
That's what I do and it avoids the need to write the file.
As in just writing to:
# pyproject.toml
[project]
version = ...
?
not sure what you mean, setuptools doesn't support PEP 621
Well it certainly will do eventually
@lusty dome that is the common/suggested way to track the version with setuptools_scm - however due to the relative cost of loading/finding the metadata its sometimes desirable to dump them into a file - thats how write_to was introduced - the problem - it practically needs to put actions into the build/install commands to ensure file creation at the right point in time
@lusty dome aware of a safe way to invoke parse_configuration inside of a finalize_options call? when i run the helper from setuptools.config i will end up with a recursion and i'd like to avoid creating global context-manager to handle this
i'm not aware of a way off the top of my head.
What I mean is don't supply "write-to" and just let the version be set in the distribution instance and then stored in the metadata by setuptools, not writing any file with the version (other than the metadata file).
@lusty dome the error on allow_hosts being specified on setuptools versions that use pip is a little bit of a pain , at least i could resolve it in my env quickly
@restive talon I'm not familiar with the error. Sorry to hear it's a pain.
@lusty dome basically when bisecting setuptools versions for issues, the newer ones need a pip config to disallow network, the older ones need a distutils config, however the newer ones raise a error if its given as pip doesnt support it (it might be a good idea to make it a warning
I see. Well, changing it from an error to a warning now won't help with bisecting old versions. And allowing option to be specified but ignored could cause some serious security issues (user said "don't contact any hosts but x, y, z" and then Setuptools issues a warning but then contacts "pypi" or "badpypi"). I'm open to changes that might enable the necessary patterns for testing, but I'd rather focus the little energy I have on deprecating easy_install/setup_requires entirely.
i see, in that case bisecting being a pain is a acceptable intermediate
@lusty dome why is distutils still maintained in a separate repo to setuptools?
Or is it just nobody got around to moving it?
There are a few blockers:
- Tests in distutils aren't exercised in setuptools.
- Setuptools hasn't adopted distutils by default. Because it's still opt-in and loosely integrated, it's conceivable that it might not become fully integrated.
- It may prove valuable, especially as Python 3.12 drops distutils, to have an installable package of just distutils (though I'm reserving that until there's a strong use-case).
Oh, and
pypa/distutilswas used to port commits directly from CPython, so has a historical link to the CPython history and is easier to integrate the few changes that landed in CPython since the deprecation/split.
Either way I'm looking forward to the angry comments from people still using lib2to3
@haughty bramble >150 broken ci pipelines here including deploy checks - due to pinned older coverage and jsmin
yeah
its almost funny as the fix is a 1 line change in our ci lib but the guy who merges those typically in seconds is on sick kid leave today
What's the fix?!
Probably something in setuptools should be a noop rather than crash
@restive talon ^
Wait did coveragepy need 2to3?
@haughty bramble setuptools absolutely has to error, my morning wil lbe spend with digging into the details, i just did late night bandaid about pinning low versions of setuptools
@haughty bramble https://github.com/nedbat/coveragepy/blob/v4.5.x/setup.py#L192 ^^
That's weird, it's not true by default right?
setuptools should probably support use_2to3=False
I think that was to work around an issue where setuptools failed to import lib2to3
https://github.com/pypa/setuptools/pull/2413 this thing
Summary of changes
Related to #2086
lib2to3 appears to have a problem loading the pickled pgen files, when running in parallel on pypy: https://github.com/twisted/ldaptor/runs/1205572060#step:12:10...
ah, nm, over the nighta new release allowing false was done
https://github.com/pypa/setuptools/pull/2770/files oh neato, my removal of 2to3 didn't actually change the use_2to3 flag
https://twitter.com/mitsuhiko/status/1435661088746577930?s=19 so aparantly airflow is broken
Latest setuptools removes the ability to invoke 2to3 as part of the installation. With that Flask-OpenID broke which means that Airflow broke. I don't even have the energy to fix an ancient package at this point but apparently existing airflow installations are now screwed :-/
Workaround is simple https://github.com/apache/airflow/issues/18075#issuecomment-915228611
The project has been taken over by Airflow maintainers and now have wheels
noice
maybe setuptools needs to include a 1 second sleep after raising deprecation warnings, that doubles every month
this way your build will go to an hour after one year of ignoring the warnings
IIRC warehouse did something like that a while ago and people just end up sending cryptic “I build is failing for now reason” error reports (and it’s close to impossible for maintainers to realise that brown period behaviour is the cause since users don’t connect the two)
I'm at a loss... how does one include a .pth file that resides next to setup.py?
root/
pkg/
...
patch.pth
setup.py
Include as in you want to install it?
list it as data file for the '' package ?
interesting what was the api?
@lusty dome https://bugs.python.org/issue45371 heads up on a distutils change downstream
Ahoy. Question for the maintainers: would you be willing to accept PRs that enforce that setup.py / setup.cfg files exist, in the setuptools' build backend?
https://github.com/pypa/setuptools/issues/2329 is the issue I'm thinking of.
has anybody tried bootstrapping setuptools using PEP 517?
as in, why?
As requested in #510 (comment) I'm opening a new issue. What I'd like for is that setup.py install --root=... (or a minimal equivalent) remains working as a 'low-level&#...
you can bootstrap wheel by running setuptools from source
then install it and bootstrap setuptools
ok, so you've put setuptools on path and you call build_wheel to build a wheel... what happens next?
I was able to build a wheel by generating egg info. So, the exact process is make all of _distutils_hack, pkg_resources, setuptools and wheel importable, run setup.py egg_info on setuptools, copy the egg-info folder over to your faux site packages, repeat for wheel and call the PEP 517 hook to build their wheels. dist_info won't work, it depends on bdist_wheel which is not discoverable until you run egg_info on wheel. egg_info also won't work unless you comment wheel's setup_requires out, unless pip is available in the environment - setuptools will attempt to install itself with pip.
Also if you shallow clone the setuptools repo expect your setuptools version to be mangled
Has some rough edges, but seems to be working.
Signed-off-by: Filipe Laíns lains@riseup.net
needs special handling for setuptools
but works
@quaint jolt any idea why setuptools.egg-info is created and then immediately deleted when you try to run build_sdist (or python setup.py sdist) on setuptools itself without having previously run egg_info?
it doesn't get pulled into the sdist either
I seem to recall that's a setuptools implementation detail, the egg-info is created and then used as a "template" to create the dist-info (or whatever metadata in sdist)
I managed to get it to stick by copying of all its entry points into bootstrap.egg-info
I think the next time someone asks "how do I include package data with setuptools" we should just point them to flit and be done with it
I did that without flit once, but I am not sure how exactly and if it still works https://github.com/abitrolly/ksykaitai#packaging-data-into-python-wheels
hi! i have an old package for py2.7 only, i want to use python -m build to make an sdist and a wheel, but the wheel is always marked py3 even though i have
classifiers =
Programming Language :: Python :: 2
Programming Language :: Python :: 2.7
and python_requires = <3 in my setup.cfg. what am i missing?
Did you build it with python3?
you need to enable the universal wheel setting if you want a Python 2 and 3 wheel
Did you set:
# setup.cfg
[bdist_wheel]
python-tag=py2
What's the status on using pathlib in the setuptools codebase fwiw? I'm continuing my work on adding pep 660 support to setuptools and having to use the os.* and os.path.* utilties constantly is rather annoying as all of my path manipulation experience is with pathlib :p
I took a stab at implementing PEP 660 but I can't seem to find a reliable way to query the importable base of the packages / modules (i.e. the parent directory of {name}.dist-info generated from an in-tree build). For what it's worth this is my first time working in the setuptools codebase so I'm confident there's many things wrong
my stab: https://github.com/ichard26/setuptools/commit/bbe070e735f2e4314da2228bdac1dd2c5c1705e7
blocker: https://github.com/ichard26/setuptools/commit/bbe070e735f2e4314da2228bdac1dd2c5c1705e7#r59675825
oh yes, i build with py3 and no, i didn't try a py2 tag. thanks, will try 😄
but also a universal wheel with a requires_python<=2.7 is fine really
unless you have another py3 wheel
Wow, just noticed the new docs. 🙂
I like the hammer, setuptools is used as a hammer that fixes on youryour packaging need, one big hammer to rule them all
update: it only took a runtime shim to resolve the blocker, a bit hacky yes, but it works in at least simple cases 😄 https://github.com/pypa/setuptools/compare/main...ichard26:pep-660
what does package_dir do? https://github.com/twisted/tubes/pull/89#discussion_r747318511
and is there a default [options.packages.find] exclude? https://github.com/twisted/tubes/pull/89#discussion_r747318720
what does package_dir do?
https://docs.python.org/3/distutils/setupscript.html#listing-whole-packages
so package_dir = tubes=tubes does nothing?
it produced an indentical wheel when I removed it
The default correspondence is the most obvious one, i.e. package distutils is found in the directory distutils relative to the distribution root.
ok awesome
and [options.packages.find] exclude defaults to empty?
tubes/test/__init__.py is included as expected
and include_package_data is redundant because there's no package data
great thanks a lot!
Just curious, would anyone from the setuptools developers be interested in collaborating on https://iscinumpy.gitlab.io/post/scikit-build-proposal/ ? The late-first-year phase of the proposal would include rebuilding a proper scikit-build - setuptools bridge, ideally playing nicely with setuptools rather than just trying to wrap over it as is done now. A specific letter of collaboration with setuptools might make the proposal a bit stronger.
I’ve spent the last few years trying to make it easy for anyone to extend
Python with compiled languages. I’ve worked on pybind11, a powerful C++
library that allows users to write advanced Python extensions using just C++11,
used by some of the largest projects, SciPy, PyTorch, Google, LLVM, and tens of
thousands of other libraries, down to ve...
I’ve wondered a while if we could develop an actually good build system (read: not what setuptools is currently doing) that can also be plugged into e.g. Flit and Poetry so backends can build binaries all in the same way.
This would require the build system to have some kind of agreed on API for PEP 517 backends to hook onto; probably not necessarily a PEP (because there’s no real need for interop, if the system is actually good we probably don’t want a second one?) but something useful enough for people to rely on, and standardised enough so if we really need a second such system it does not need to do the design and integration work from scratch
Is Flit interested in plugins? I know Poetry is.
Flit is interested in supporting extensions but not sure how best to approach it. So if there’s an established library that does it well I think it’d be happy to use it (likely something simpler than plugin, maybe just import detection, use that if the user lists the extension builder as a build dependency or something like that)
I have been thinking lately about this (since your first blog post).
I think in the setuptools universe, integration could be achieved as an entry-point (most of the things are).
Maybe a setuptools.externally_compiled_files or something like that... But I wonder which would be the appropriate interfaces.
Would it be enough to imagine that the entry-point value is a function with a signature similar to the following?
def external_compiled_files(language_tag, abi_tag, platform_tag, project_root) -> list[ExternallyCompiledFiles]:
...
class ExternallyCompiledFiles(Protocol):
def source_files(self) -> dict[str, Path]: ...
def compiled_files(self) -> dict[str, Path]: ...
that sounds like an interesting idea
currently all build system need to reimplement complex logic for native modules
Both Poetry and PDM currently just punt the issue and use setuptools. Not very pretty. https://stackoverflow.com/a/60163996/1376863
(IIRC there’s a documentation page on this but I can’t find it)
To build a python project managed with poetry I need to build C extensions first (an equivalent to python setup.py build). poetry is able to do this according to this github issue. But to me it's not
any tool for that shoudl aslo have things for cython, cff, hpy, mypyc
oh, and the rust libs for python interaction/boost & co as well
I would rip graph processing core from SCons for that, and maybe enscons had already done that.
And add a visualization of how graph is constructed, traversed, enriched, selected for build and processed.
The problem is that that all interactive tools for graph processing are mostly in javascript, or require heavyweight installation of binaries.
It actually doesn't matter which build system it is. The debugger for build graph is the selling point here.
@lusty dome I've released today virtualenv 20.11.0 that ships setuptools 60.1.0, which exposed a major incompatibility with pip - see https://github.com/pre-commit/pre-commit/issues/2178#issuecomment-1002163763
you might want to coordinate with pip maintainers to find a path ahead on this, because feels many people will be affected by this
Thanks Bernát. I'll investigate in https://github.com/pypa/setuptools/issues/2980
@cloud sand Initial indications are the fix does the trick. Please consider bundling this new Setuptools in a Virtualenv release or yanking the current release until you can.
Said before, the bug is not related to virtualenv and can be reproduced without it, so there's no yanking warranted here.
that being said https://github.com/pypa/virtualenv/pull/2258 🙂
Signed-off-by: Bernát Gábor gaborjbernat@gmail.com
@lusty dome is now out https://pypi.org/project/virtualenv/20.11.1/
What's the reason for setuptools using a meta path finder and a custom loader instead of shipping, let's say, setuptools/_internal/distutils and prepending _internal on the sys.path?
that would be a question towards @lusty dome
there's no path to add if the module isn't being run from disk
user could be running it from a zip for eg
nobody really should be manipulating internal paths directly on code that gets distributed
the default path finder supports zip paths but I see your point, you get to rely on import semantics this way
The main motivation is that because distutils is deprecated in the stdlib and scheduled to be removed in 3.12, Setuptools wishes to offer a replacement, but to replace situations where "import distutils" is used prior to "import setuptools", I deemed it necessary to have an import hook.
Now I realize I'm answering a different question.
I can't recall if I attempted to simply do path manipulation. I'd definitely be open to a simpler solution.
As it's currently implemented, the _distutils_hack intercepts three different imports (import setuptools, import pip, and import distutils) for different reasons/issues.
I don't see how that logic could be implemented without an import hook, but once pip removes its reliance on distutils and get-pip removes its "import setuptools" check, it may be possible to simply manipulate the sys.path.
(and of course most everybody is running those updated releases)
Why are things doing "import distutils" still now that it's deprecated?
Because the code was written ten years ago and it’s non-trivial to migrate? I literally spent a year of volunteer time to implement sysconfig support for pip and it’s still not feature-parity to distutils. It’s much more complicated than you’d imagine.
I don't know if it's intentional but the last 4 releases of setuptools haven't been published on PyPI
A piece of the workflow has been disabled (cygwin), so now the releases need to be manually uploaded.
We have a PR that fix the failing job, if anyone else would like to review it, we could confidently merge
I'm sorry, I've never used cygwin and I'm not familiar with setuptools' testing infra so I don't feel confident reviewing the PR
No problems at all. Thank you very much for pointing the problem out though!
It's more there doesn't seem to be an alternative to distutils for things that use it
There is some discussion on PEP 632 on how to replace it: https://www.python.org/dev/peps/pep-0632/#migration-advice.
I completely understand that somethings might be missing is sysconfig, but eventually we will get there 😉
Anything else not discussed in the PEP you feel that is still missing?
FWIW, @lusty dome regarding https://github.com/pypa/setuptools/issues/2971:
If you look at @kloczek's GitHub activity, you'll notice that there's almost ~300 issues filed by that user, telling (and, on occasion, demanding) projects to support setup.py build_sphinx (https://github.com/search?q=author%3Akloczek+is%3Aissue+build_sphinx&type=issues).
At some point I think (personal opinion!) Python should follow the crates.io/docs.rs pattern and standardise the documentation generation interface. But setup.py build_sphinx is of course not the way to do it.
A nice standardized docs (& tests) interface would be very nice. But I think installer is higher priority. 😉
tox -e docs 🙃
Oh yea, lemme go cut that release.
nox -s docs 😛
hatch run docs:build 😜 https://ofek.dev/hatch/latest/environment/#selection
poetry run task docs :p (for the record I don't even use poetry)
We must come up with a new standard to unify them all
I think make docs is where it's at
What is the long term plan for https://github.com/pypa/setuptools/issues/889 ? IPython has just started using this, and https://github.com/twisted/twisted/blob/trunk/setup.cfg uses this too. It's a fantastic way to shorten complex extras with lots of minimum versions, etc. You can self-reference now, but that requires Pip 21.2+, while this works with older pips. I was very exited to see it, as not being able to build 'dev' and 'all' extras is one of the main things keeping my setup.py's around (and not virtually empty), but then found it breaks setup-cfg-fmt. It's also not something that has an obvious parallel when moving to PEP 621.
Is the direction here "setup.cfg is going to be deprecated anyway", perhaps?
There seems to be some discussion in the (closed) https://github.com/pypa/setuptools/issues/1260
off topic but you can now define a (for example) "all": ".[docs,tests]" extra now and pip behaves as expected? I did not know that, but that's very nice!
I also wonder if in the context of PEP 621, something like:
...
dependencies = [
'pytest; extra == "tests" or extra == "all"'
]
[project.optional-dependencies]
tests = []
all = []
would work... (maybe even 'pytest; extra in "all tests"'?)
Problem is you can’t put this in package metadata since . is not a valid package name (interpreting it as a local path is a pip extension). IIRC the last time this was brought up the general response is something like “sounds like a good idea but someone needs to write a spec first”
No, you can't use "all": ".[docs,tests] currently, but you can use "all": "pkg[docs,tests] for a package named pkg, and pip behaves as expected (and doesn't try to download the last release or something like it used to)
name = 'pkg'
dependencies = []
[project.optional-dependencies]
tests = ['pytest']
all = ['pkg[tests]']
Works with Pip 20.2+. Ideally, .[tests] or just raw [tests] could be converted to the appropriate metadata by the backend, but at least one PEP would be affected (or a new one needed).
Hmmm, does that extra syntax work today? Looking at PEP 508 I see it mentioned (with ONLY when defined by a containing layer warning)
I don't know exactly, it would need to be checked. In theory by leaving all = [] and tests= [] in [project.optional-dependencies] the containing layer is defining the extras, right?
(specifically in setuptools I have the impression that it would fail RN because the process of handling the extras is convoluted... it first parses it as something unique to .egg-info and then it converts it back for PKG-INFO/METADATA...)
By containing layer is defining the extras I mean that the backend would produce the Provides-Extra field in the core metadata file, that would enable the extra to be used as requirement marker
It's also really a mess to use for this purpose, say if you have "tests", "dev", and "all"
But does define everything once
The in syntax would be better.
packaging.requirements.Requirement('pytest; extra in "all tests dev docs"') seems to run with no errors
I can try it out on setup.cfg
I don't know if it will work because of the internal gymnastics of .egg-info/requires.txt and PKG-INFO (but definitely an experiment would be nice to prove the theory!)
Does anyone knows if this approach 👆 works in other backends like flit?
Would this make the requirements messier in the metadata? I'm guessing the backend is not pulling these out, but just dropping them into the metadata?
@unkempt birch I like your comment in the setuptools issue. I think it would be nice to have the .[<extras>] syntax going forward since it allows specifying multiple dependencies at once. At the same time the explicit requirement marker extra can be handy for cases like extra != tests (exclusion).
The . syntax most definitely would require a PEP. The extra marker could potentially work nowadays? (It does not seem explicitly forbidden by the standards...)
Do we need a dot? what about vanilla [tests]?
Both could work. The . seems to evoke some familiarity (I use pip install -e .[all] all the time in my packages), but any of the two would work fine...
TypeError: 'in <string>' requires string as left operand, not NoneType when I try this in setup.cfg.
No, I think that is correct. "extra" is not defined if you are not "in" an extra.
Oh, that makes sense. It reminds me of a discussion somewhere about someone asking for extra to have a default value.
I guess there is no way around that right now then other than relying on pip 😅
Yeah, even when chaining them with or, extra seems to not work.
pkg_resources.extern.packaging.requirements.InvalidRequirement: Parse error at "';extra ='": Expected stringEnd
Can this error in particular be a problem with an outdated vendored version of packaging?
I tried the following:
>>> packaging.requirements.Requirement('pytest; extra == "all" or extra == "tests"')
<Requirement('pytest; extra == "all" or extra == "tests"')>
>>> packaging.requirements.Requirement('pytest; extra in "all tests"')
<Requirement('pytest; extra in "all tests"')>
And the parsing seems fine.
The bigger problem may happen when evaluating the markers, because as you pointed out extra can be undefined...
Possibly, unless I made a mistake here: https://github.com/scikit-hep/particle/pull/382/files
I am impressed that the tests passed. I was definitely not expecting that...
Are you guys also testing an editable install?
Not there, but I can try that. Also, I had to leave one item in each extra otherwise setup-cfg-format was wiping it out. Though I could try without extras.
This seems to work with empty extras too, minus setup-cfg-fmt's bug removing them.
(locally)
It is being a few months that I played with the part of setuptools that process the requirements, but what I remember is the following:
-
having the
extras_requirepart is important so setuptools will generate the correspondingProvides-Extrafield in the core metadata file (it can in theory be empty, like the one for https://github.com/pypa/setuptools_scm/blob/ccd9e7c1448044b0c832f641581738e3102ca768/setup.cfg#L72). -
I remember editable installs depending on a
.egg-info/requires.txtfile, instead of thePKG-INFO. The way this file is generated and its relationship with theRequires-Distis complicated, so it might not work for the editable install. Hopefully it is just an impression...
Wow, actually, the metadata looks pretty good.
I think requires.txt actually does put the extra in correctly.
Or, well, sortof
[metadata]
name = something
version = 1.0
[options]
packages = find:
install_requires =
pytest>=6;extra == "test"
[options.extras_require]
test =
[:extras == "tests"]?
[:extra == "test"]
pytest>=6
[test]
Hehehe, it accidentally works 😆
My mileage varies, but I opened https://github.com/asottile/setup-cfg-fmt/issues/117 🙂
Yeah, that flopped as expected.
The empty array idiom is a bit jarring, if we wanna do this we should amend PEP 621 to accept a list of strings in addition to a dictionary of lists for optional-dependencies
Or add a new property, like optional-dependency-groups
Yeeeah
I think ideally, if we are messing with PEPs, we should do it properly and allow [tests] or .[tests].
The separated extra marker does allow some other use cases though (e.g. "negative" extras or default extras)
I'm not sure if repurposing . is a good idea
This just means the current working directory when you do install .[foo] from the command line
It's going to mean something different in the spec file
Current:
dependencies = [
'pytest; extra == "tests" or extra == "all"'
]
[project.optional-dependencies]
tests = []
all = []
With dot:
dependencies = []
[project.optional-dependencies]
tests = ["pytest"]
all = [".[tests]"]
With nothing:
dependencies = []
[project.optional-dependencies]
tests = ["pytest"]
all = ["[tests]"]
Pretty sure Anthony doesn't actually read the contents of the comments, just skims them. I was literally suggesting an alternative to interpolation... Anyway, locked, so that's that.
Please someone other than Anthony write a pyproject.toml formatter. 😉 (likely, actually, as he hates toml)
I thought a lot about dependency groups for the Hatch rewrite and became confident that they only should be used for features. Deps for testing, docs, etc. should not be there but rather should be part of config for an environment manager
@robust yarrow does hatch currently supports something like
dependencies = [
'somedef; extra != "gpu"'
]
[project.optional-dependencies]
gpu = [ ... ]
? (just for curiosity)
The issue with these two is that they deviate from PEP 508. We wouldn't wanna introduce a change to that spec that'd only be applicable to pyproject.toml and we wouldn't really want to make an addendum to PEP 508 in PEP 621 either. My suggestion would be to allow referring to other extras in a sub-table, e.g. all = [{ ref = "tests" }]
I like this syntax a lot...
@dreamy urchin that would translate to a pip command and extras based on https://ofek.dev/hatch/latest/config/environment/#features
that example would be:
pip install /path/to/project[server,grpc]
Not sure I understood, but I think you are talking about using hatch to manage environments, right?
I guess my question would make more sense If I had referred to hatchling instead?
I was curious if the build backend would process that kind of project metadata and produce the corresponding Provides-Extra and Requires-Dist core metadata accordingly (or if hatchling errors when extra markers are given explicitly)
ah, no it would not error during packaging
Thank you @robust yarrow !
for checking deps of envs https://ofek.dev/hatch/latest/environment/#dependencies, this is the logic in case you're curious https://github.com/ofek/hatch/blob/master/backend/src/hatchling/dep/core.py
An idea for "negative/default" extras could be for #build - virtualenv could be the default, but using [venv] could "opt out".
I wonder if something can be done about venv being outrageously slow. What part is it that takes so long, it makes no sense that unzipping pip and setuptools should take 4 or 5 seconds?
Bit of a tangent, I'm sorry
Just use virtualenv 😂
I wonder if the installation could be performed with installer instead of pip or switch off whatever pip options are making pip take so much time
If we're going to offer venv as an option I don't see why we wouldn't try to optimise it
There can be multiple reasons why venv is slow:
- venv by default reaches out to the network to check newer version
- installing the packages is done with pip that is a generic purpose installer, starting up pip to do the useful work is 30% of the time, using installer could help
- On Windows the files are generated from a zip file, the Windows anti virus treats these operation as hostile, so there's a lot of overhead interupption by the antivirus checking each file (virtualenv works around this by extracting the file to folder, and then copying from there, this way the antivirus considers it safe, so less overhead).
venv is an option for bootstrapping, having minimal dependencies has advantages. However, most users should just use virtualenv, so making it opt out instead of opt in would be great, IMO, as long as it worked.
build is designed to have minimal dependencies so it can be bootstrapped into environments; that's why there's a venv option. CC @quaint jolt
I was kinda holding hope the default extras PEP would move forward
just made https://pypi.org/project/pyproject-validate/
I'd love some co-maintainers 🙂
I have done some effort in https://github.com/abravalheri/validate-pyproject, maybe if you would like to discuss joining forces? (probably it will still be necessary to keep 2 separated things since one aspect of validate-pyproject is to not have dependencies so it can be easily vendored, but we could discuss that)
(it is going to be fun for someone looking on PyPI: validate-pyproject and pyproject-validate 🤣 )
I've started work on a opinionated comment preserving pyproject.toml formatter, for now only supports the build-system table https://github.com/gaborbernat/pyproject-fmt/blob/main/tests/formatter/test_build_backend.py#L8, but will add project support soon too 🙂 https://pypi.org/project/pyproject-fmt/
I wish we could standardize on a TOML indentation
tomli-w does 4, others write 2, etc.
I'm in the 2 group but left it configurable 😂
me too. I opened a PR on tomli-w changing the indent with others in favor but Taneli is not very keen on it, nor making it configurable
Do you put one or two spaces before a comment?
2
Boo no config options
What would you make configurable?
if only there was a character that has the semantic meaning of “1 indentation level” 😜
blasphemy
I like to disable magic commas
fair enough 🤷
What's magic comma?
This comment refers to magic after a comma, but the comma isn't in magic position https://github.com/gaborbernat/pyproject-fmt/blob/main/tests/formatter/test_build_backend.py#L17
@cloud sand in your formatter do you explode collections that end with a trailing comma?
Or always collapse them if they fit in the column limit?
For now I always expand 🙂 but will add at some point a fit in one line of possible
That is if they are no comments, if there's a comment in the array it must always be exploded IMHO
So we have pyproject-fmt, pyproject-validate, and validate-pyproject now? 😄 To me, there are several, distinct things needed: a) validate the content of pyproject.toml to make sure it is valid, b) check for good practices like remembering certain fields, and c) formatting. I think having c separate from a/b would be fine, and I'd also be okay with all being separate tools, I can just add them all into pre-commit. 🙂
@cloud sand The hook seems to only be looking at tox.ini files... https://github.com/gaborbernat/pyproject-fmt/blob/main/.pre-commit-hooks.yaml
I'd honestly like black-style magic commas here, if it's something that gets changed a lot, I'd like it one-per-line, but requires often is very short.
Ah it's a bug
Will fix 😂
I'm looking at adding a line limit and wrapping what can fit
It's a bit WIP at the moment
I can see also having a compact and a long mode
Because I personally prefer the compact syntax instead for nested tables
e.g.
[project]
urls."Bug Tracker" = "https://github.com/gaborbernat/pyproject-fmt/issues"
urls.Documentation = "https://github.com/gaborbernat/pyproject-fmt/"
urls."Source Code" = "https://github.com/gaborbernat/pyproject-fmt"
instead of
[project.urls]
"Bug Tracker" = "https://github.com/gaborbernat/pyproject-fmt/issues"
Documentation = "https://github.com/gaborbernat/pyproject-fmt/"
"Source Code" = "https://github.com/gaborbernat/pyproject-fmt"
issues welcome though 🙂
I'd leave (nested/unnested) table structure alone, that can be a user choice.
Hence saying compact/long form
https://scikit-hep.org/developer/pep621 now has tabs for several backends, including setuptools experimental 🙂
The Scikit-HEP project is a community-driven and community-oriented project with the aim of providing Particle Physics at large with an ecosystem for data analysis in Python. The project started in Autumn 2016 and is under active development.
@lusty dome I'm proposing that Debian implement the _distutils_system_mod mechanism in https://salsa.debian.org/cpython-team/python3/-/merge_requests/16 now that setuptools essentially requires it (by bundling distutils). Sorry we didn't get to this sooner, but it's good to have motivation 😛
I do think I understand your point now, by the way, after seeing the extreme (hypermodern-python's dev environment) and the solver time and mess it causes. I don't think it's bad to have a [docs], [test], or similar extra, but not a "dev" or "all" that includes it, since it's only for use by environment setup, like readthedocs/nox/tox, etc. It's quite handy in cases were you can't reuse something like hatch (say [test] for cibuildwheel for testing the wheels)
here's an example of Hatch envs https://github.com/ofek/hatch/blob/master/hatch.toml
Hatch
I'm not getting the inverted extras to work. It says "Ignoring mplhep: markers 'extra != "noplot"' don't match your environment" then installs it anyway.
@lusty dome Is there any chance of someone convincing you that a default name+version is a bad UX for debugging setuptools issues, and worth changing?
I am convinced it's a suboptimal UX. What I don't want is a bolt-on fix that strands the legacy implementation. I'd also like to retain the degenerate behavior for use-cases where that's valuable (tests, experiments). All of that leads me to think there should be a separate layer where the validation is done. What I'd really like to see is something where user builds get the validation by default, but I haven't yet envisioned a way to make that more sophisticated use-case the default and not breaking the other use cases. The problem is also complicated by the conflation of name and version. It seems perfectly reasonable for a package to get a default version of 0, except when it happens to users that expected to get a version from elsewhere. At this stage, I have higher priority concerns on my plate (mainly distutils adoption and pkg_resources deprecation), so I'd like to defer this concern until things have settled down a bit.
Hmm... Okie, I think I finally understood what you meant now.
I think the bit where we disagree is that you want to preserve the degenerate behaviour in some cases. I don't. I think changing the behaviour to be the tests and experiments is not a big deal -- it's certainly not an unclear failure mode as long as we mention what the user needs to do in the error message. It is very different from the subtle breakages where the error messages will always be esoteric because setuptools doesn't direct control those bits. Like automation uploading to 0.0.0 to PyPI which only fails the second time.
The fix for a broken test or experiment is adding a name= or version= in the right place, in the file that the exception originates from. The fix without the clear error is the same, except you have to trace back to it from underneath all the layers of abstraction on top -- pip wrapped under poetry, in a build system invoked in a CI pipeline. After you noticed a failure in later step, which failed because you already had 0.0.0 published.
The current behaviour silently breaks things, and I think changing subtle mistakes to break loudly is a good thing.
None the less, would you be fine with reopening the issue and stating that it's not a no-go but merely low priority right now?
my two cents is that the name field should always be required
I can see value in the degenerate behavior for the version, especially because people might be relying on it
Version has a somewhat reasonable possible degenerate value (0.0), but name (UNKNOWN?) does not.
Well, an empty string, but that breaks things (as it should...)
It could pick a name like docker run does
inhibitted_halibut or something
that's worse
how about setuptools_lost_{basename(projectdir)}_{sha512_digest(projectdir)[:7]} and the default for version could be something as horrendous as YYYY.MM.DD+guessed.admirably
You don't want a default name so that an automated release procedure (or manual if you are not careful) doesn't add some weird project to pypi.
Or weird version to PyPI.
Like I recently uploaded boost-histogram 0.0.0
tbh, no need to change anything b/c pep 621 support will fix it
The idea for the name is to detect it from the packages (discussed here: https://github.com/pypa/setuptools/issues/2887#issuecomment-970708430).
For the version I agree that we should add a local version label, so twine/PyPI will halt
But pep621 requires non-dynamic name?
(I’d be tempted to pull it from CMake for scikit-build otherwise)
That is true, but adhering to PEP 621 is not mandatory
Well isn't setuptools adding PEP 621 support? Will it follow PEP 621 apart from requiring the name be declared statically?
Downstream tools, like PDM, Hatch, etc. are supposed to be able to depend on name being present in pyproject.toml if [project] is present. I don't see the point of a standard if it's not followed. Wouldn't it be better to modify the standard instead and allow name to be listed in dynamic?
There was also a suggestion for build to use the name field to detect circular dependencies ahead of time
@lusty dome : Got an issue with the _distutils_system_mod mechanism in Debian. Not sure how to make it play well with pip build isolation, so we still don't have correctly functioning editable installs.
When pip does an isolated build, it appears to the setuptools/distutils inside the isolated build that it's building for a virtualenv, so it uses the posix_prefix scheme, instead of the desired posix_local scheme. Can you think of a good way to detect that we're doing an isolated build for a system-wide install?
adhering to PEP 621 is not mandatory
why?
I'm sorry, what?
I'm going to not say much more right now (just woke up), but suffice to say: Not adhereing to a standard which one of the tool's current maintainers co-authored and other maintainers participated in the discussion of, that went through rigorous design discussions, basically feels extremely disrespectful of the work that's been put into that effort.
I think what @dreamy urchin intended to say was that you don’t need to use PEP 621 to define metadata. As in, if the backend can’t work within the scheme proposed by PEP 621, just use your own config format (like old-style Flit, setup.cfg, etc.). PEP 621 makes it easier to move the project from one backend to another, but does not force every PEP 517 backend must use it for configuration. (Plus if a backend can’t work within the PEP 621 structure, a project using it likely can’t be converted to use another build system anyway.)
Fair. All I feel strongly about is that if you use the project table for metadata, then you ought to adhere to what PEP 621 says is required/not required.
If setuptools has tool.setuptools.whatever section like flit, sure -- it can do whatever it wants there. If it, however, uses the project table -- it ought to do what the standard says. 🤷♂️
Oh no, that is not at all what I was referring to. Sorry if it was confusing, in no moment I intended to be disrespectful. I have been working for the past months in a row trying to add support to PEP621 to setuptools, I really care about it (and respect the work of the authors).
That is precisely the point. Thank you very much @river oak
This approach is also discussed in the text of the PEP:
(compared to opting-out of this PEP entirely, which is also possible).
So the backend don't need to adopt pyproject.toml for configuration or if they do, they don't need to adopt the project table.
In the case of setuptools, users also can specify the metadata in setup.py if they want to...
I am perfectly in sync with you regarding this point.
Awesome. Apologies for the somewhat spirited response earlier -- I hadn't properly woken up. 😅
If the users have the project table in pyproject.toml and don't include name, they will see a validation error message and the build will not proceed.
Ah ok thanks, I misunderstood!
After the impact my comment had, I think I made a poor choice of words 😅 (sorry for that)
Nevermind, I think I was misunderstanding the pile of bugs that were interacting with each other badly.
Ack. I appreciate that. I have seen requests for virtualenv and pip to copy that module to virtualenvs and isolated builds.
With the closure of https://github.com/pypa/distutils/milestone/1, Setuptools now should be able to re-enable its local distutils as the default.
Before releasing this change, I'd like for plat...
@dreamy urchin Do you have a ballpark figure for "soon" (days, weeks, a month, etc)? 🙂 https://github.com/pypa/setuptools/pull/2970#issuecomment-1075352330
To be sincere, my wish is to get it down to days... But we never know which other problems may appear.
My priority so far has been to reduce the risk of breaking existing packages, so I tried to test exhaustively and engage with the community for beta-testing...
Hopefully things will go right, but I am also prepared for the chances of having to revert the changes shortly after they land. Setuptools is used everywhere and therefore every single obscure aspect of its implementation is depended upon...
There are some integration tests in place for pandas, kiwisolver, brotli, sphinx, botocore, mypy, pytest and pandas... I also have been testing locally with the packages people proposed in the Discourse thread (linesep, minegauler) and the ones you helped me with (pybind, plumbum and the scikit-hep templates)...
I have my fingers crossed that things will go well
Ok, considering that my last comment in discourse had "thumbs up" from most of the people that were testing the changes before, I believe that not many people will still try the experimental branch. So I am incline to proceed with the merge today 🙂
(Lucky me... just pushed the merge but GitHub is experiencing issues with webhooks and actions)
🎉🌈🎉🌈
Thank you all for the help!
GitHub has been very unstable lately -- I had to manually merge a PR via the command line for the first time yesterday .. and I managed to mess it up (forgot to change the commit author) 😅
This PR was complicated so I was going to merge it manually anyway. But I was counting on the CI...
Now it is running! Eventually the new archive distributions will be published...
all our CI is failing on the new version, looking into it now
ignored error: ValueError - invalid pyproject.toml config: `project.license`
...
TypeError: string indices must be integers
oh, no support for pep 639
Sorry Ofek, support for PEP 639 is not implemented yet.
Temporarily you can use tool.setuptools.license-files to pass an array of glob patterns for files that should be included in the archive
(The default behaves like the usual: LICENSE*, NOTICE*, etc...)
it's super weird though, we only use setuptools for tox editable testing on py2, but tox is for some reason using the setup.py on py3 https://dev.azure.com/datadoghq/integrations-core/_build/results?buildId=94351&view=results
& neither I nor a team mate can repro locally...
Having a look on the error, it seems that the error comes from the fact that setuptools currently requires license = {text = ...} (exactly what you mentioned about PEP 639)
right but we do:
[build-system]
requires = [
"hatchling>=0.11.2",
"setuptools; python_version < '3.0'",
]
build-backend = "hatchling.build"
but tox is for some reason using the setup.py:
GLOB sdist-make: /home/vsts/work/1/s/postgres/setup.py
ERROR: invocation failed (exit code 1), logfile: /home/vsts/work/1/s/postgres/.tox/log/GLOB-0.log
================================== log start ===================================
/opt/hostedtoolcache/Python/3.8.12/x64/lib/python3.8/site-packages/setuptools/config/pyprojecttoml.py:100: _ExperimentalProjectMetadata: Support for project metadata in `pyproject.toml` is still experimental and may be removed (or change) in future releases.
warnings.warn(msg, _ExperimentalProjectMetadata)
tox 3 does to find out the name of the project
But shouldn't use it for actual packaging
looks like isolated_build = true fixes it
Yeah
I'd always use isolated_build = true, otherwise tox is not doing what pip would do. (at least if you have a pyproject.toml file)
dprint (Rust) is a pretty nice auto-formatter for TOML. Someone needs to bundle it up in a wheel and write a pre-commit hook for it. 😉 https://dprint.dev/playground/#code/NoIwrglgNgJgtAZwJ4IC4FMC2BdAUAJ3QEdJCEACAXnOF3PvICIF1UwAHVAey6gQD5KAFgCsjADR0GzVh268EAfQQBjTMG6Yo2QUIB0ARj0AmRuQDE5AMJdMmAIYV7MGOhi484aPBD2VAa3QAOxgqJhY2Th4+PS9YRUxWe0ZcXEsAFQALCAoc8ntyFVtEoNRcDWi9CLlopVUcXAB3fAgMRW4w5nwVAHoQHjRFbLQuAHN8e0wegDd0fAQILiC9diQU8vkoFaQMND0IIIhFLk5FoIQ8ZxgT1ApqWgYmOAmJJ8RMrkaoLhV7PlfGHBEKgWipUHAHPhAvMJLhAcDQeCikEAGYQUaMPC4NFQDD4Rr2fCHIKjO40RhzfBcfCvbAWazFAqETBcWbuNLkACyYFxEHYUHQ5CgB3QFCWUCQ5AgKPyqCF6EccqWgvYZGCSvw+XICEm6DgwqCgqKdnVUoo3xJuF2qHY9lQmQQlGAjGtCABmDAqGF-PQAINosxuCAA/language/toml
🙁 https://github.com/ofek/hatch/runs/5688242079?check_suite_focus=true
basically projects that use Hatchling's Mypyc build hook (which necessarily must use setuptools) now cannot use PEP 639
I guess I can do a patch release capping setuptools, but that's not ideal
Sorry @robust yarrow, PEP 639 is on my radar, but it will take some time. I want first to address all the issues with the thing we just implemented, ideally also have at least a look on PEP 660, and then I can go back to it.
If you want to submit a PR, that would be very welcomed.
Alternatively, I imagine that maybe you could temporarily rename pyproject.toml before calling setuptools? Would that work for you?
I imagine that maybe you could temporarily rename pyproject.toml before calling setuptools?
I capped it but that's a good idea thanks! I'll do that if there's a CVE before PEP 639 support
This might have already been raised in the channel here, apologies if so -- but PEP621 currently still declares that there are no POCs for a PEP621 implementation. https://peps.python.org/pep-0621/#reference-implementation Would the new implementation in setuptools >=61 qualify?
Python Enhancement Proposals (PEPs)
i think there can at least 5-7 tools be listed these days
Noted - which tools? This ~2wk old scikit-hep post (https://scikit-hep.org/developer/pep621) names Flit, Hatch, PDM, Trampolim, and Whey as supporting PEP621. Looks like poetry doesn't yet: https://github.com/python-poetry/poetry/issues/3332
Good enough to simply mention Flit and PDM, IMO
I'd personally go with Flit, Hatchling, setuptools experimental, and PDM, which I think are the major ones currently. Whey seems to be very quiet, and Trampolim too.
My inclination would be toward mentioning more rather than fewer, as long as it'll be taken as a listing of example implementations, rather than a recommendation or endorsement.
Also, that's a page (meaning it remains up to date), not a post. 😛
Ooooooo, indeed. Thx for the correction. 🙂
PEPs aren't documentation -- I'm inclined to say that it's fine to leave it as is or add, like, one or two examples there.
@nimble bridge That was the other angle I was considering -- if there's maybe value in having that part of the PEP reflect the state of the ecosystem at the time the PEP was finalized... in which case, it would be best to leave it as-is.
It seems that the Mergifyio bot needs to update some permissions (pypa/setuptools > Settings > GitHub Apps).
Does anyone have the user rights to update it? (Or is it the idea to remove this bot completely from the repo?)
I can do that.
Hi @nimble bridge, that would be helpful! Thank you very much. I do use it a lot to rebase PRs (much quicker than adding a new remote, pulling the PR and rebasing it manually...)
Done.
FWIW, I really like the GitHub CLI.
With my git aliases, doing that is as simple as:
g sync
gh pr checkout 100
g rebase main
g pushf
(I have alias g=git)
gh pr is the only subcommand I use, the rest of the command is more or less useless
I’m weird and prefer to type the URL into my browser manually instead
Thank you very much!
I still haven't got my head around gh (and @Mergifyio rebase is quite handy)...
(It is very likely that unconsciously I feel prejudice just because their documentation mentions conda as an installation method, despite of the follow up Linux-specific link... Personally I run away from conda unless absolutely necessary... Even mamba feels too slow -- Long live pip!)
I also only use gh pr checkout 100, should learn a few more but have some of my own commands:
repo is like gh repo view -w, can also do like repo pulls or repo actions to open that tab
upstream is like repo but for (surprise!) the upstream
ci opens the relevant CI webpages iff there are GHA, Travis or AppVeyor config files. can filter like ci gi to only open GHA if there's also Travis
I love gh pr checks too. Also gh pr/repo view -w, (though already mentioned above). I've also used gh release create a tiny bit. The other commands look interesting, but I guess I do center on gh pr most of the time. I just realized that gh co is a shortcut for gh pr checkout, nice. 🙂 I guess I've used gh gist a tiny bit.
This needs to bee an invite but its a link to this channel
i'm trying to implement my own finder and i'm getting crashes because setuptools expects that the Distributions returned find_distributions(self, context: DistributionFinder.Context = DistributionFinder.Context()) are instances of setuptool's vendored importlib_metadata instead of importlib.metadata
(as of python 3.8)
Example traceback, caused by virtualenv using dist.Distribution({"script_args": "--no-user-cfg"}): https://gist.github.com/konstin/b3366ba6ad4f24c21fd57a5b7f79b61f
is there some way i should get the Distribution class to use from the caller oder something else i can do to properly handle this? my current workaround is try: from setuptools._vendor.importlib_metadata import PathDistribution
Hi @crude bolt, maybe it would be better to direct this question to importlib-metadata. Am I correct to understand that this error would happen (forgetting a little bit about setuptools) if someone uses your finder together with the latest version of importlib-metadata? (Maybe this is a backwards compatibility issue?)
i don't think so, it happens because setuptools expects that the Distribution instances to have attributes the python 3.8 importlib PathDistribution does not have. if i use importlib_metadata (either installing it on my own or importing it from setuptools._vendor) it works fine. i'm also surprised that this isn't a problem with the built-in finders, so i'm not sure whether i need to change my finder or setuptools needs to accept built-in importlib
Thanks @crude bolt can you file an issue in setuptools then, with a minimal reproducer for your custom finder? I will try to have a look soon.
will do
thank you very much
@dreamy urchin Here you go: https://github.com/pypa/setuptools/issues/3319
When I use the universal2 version of Python and write an extension I don't need to specify -arch arm64 -arch x86_64 in extra_compile_args but I do need to specify them in extra_link_args but I wonder if that should be the case.
I guess if you're trying to link against an outside package there's not a way I know of to force it to install the universal2 version cleanly if they distribute platform-specific versions pip will prefer instead during a build
but that seems like an esoteric use case
@dreamy urchin I'd like to cut a release of Setuptools. Any reason to delay?
Hi Jason, no problems from my side. I merged everything I wanted to merge today
(Sorry for the delayed response)
Does anyone knows if the artefacts produced by build_clib are added to the wheel distribution at all?
I went trough the code and the old distutils docs and I have the impression that the binary files produced by build_clib are only used when extension modules produced by build_ext want to link against them...
The code for distutils/build_clib seems to place the generated files in a temporary directory...
The code for distutils/install_lib seems to only ensure that build_py and build_ext did run, not build_clib.
I am not certain but that makes sense to me
just looking at your research I'd say install_lib not ensuring build_clib is run seems like a bug
but try to make sure build_ext itself doesn't do that
Thank you very much Filipe. It seems that build_ext will check for libraries created by build_clib but not exactly ensure the command runs.
For the purposes that I am investigating right now (PEP 660) , I think I will just assume build_clib does not create any artifact that is distributed, and everything is used by build_ext... At some point I will try to test that theory for editable installs...
that sounds good 👍
@dreamy urchin @lusty dome is it intended that the finalize dist hook happens before setup.cfg metadata is parsed?
I always find this behaviour curious considering that config files do change options...
I did some investigation and find out that this hook was introduced in https://github.com/pypa/setuptools/pull/1877 as part of the finalize_options() method (which was originally stablished by distutils and intended to run at the end of Distribution.__init__).
At that point in time, the parse_config_files method already existed, so we could suppose that it was kind of intentional (but only Jason could clarify that). Maybe the naming could be improved to make it more obvious?
I don't know what would be the impacts in the ecosystem of chaging the momment we trigger the plugins. Do you have a use case in mind?
setuptools_scm has to look for the distribution name in both setup.cfg and pyproject.toml as its not set when the hook is called unless its in the setup.py
That sounds like a fair request, we could think postponing this hook or creating a different one for backward compatibility. @lusty dome do you have a suggestion?
I haven't had a chance to look into the code. I'd want to investigate whether it's likely that we could postpone the hook (or more likely, push up the config file parsing)... or if there are other dependencies (does config parsing depend on any actions in finalize_options. If parsing happens as part of finalize options, it may be possible to simply increase the priority of that finalizer so that it happens before other unprioritized hooks (such as setuptools_scm). I don't recall any specific dependencies, and I'm open to it changing.
If parsing happens as part of finalize options,
I think that right now the parsing is separated fromfinalize_options. If I am not wrong,distutils.core.setuprunsparse_config_filesas a separated statement, after the distribution object is initialized. On the other handDistribution.__init__runsfinalize_optionsat the end of the initialization process.
I started a related discussion in https://github.com/pypa/setuptools/issues/3415
hi! i'm trying to transition a setup.py-using cython project to using pyproject.toml, and i noticed that building wheels also includes the pyx/pxd sources files, which doesn't happen with setup.py based wheel building. i can't find a MANIFEST.in-like mechanism for excluding them. am i missing something?
Can you try include-package-data = false in your pyproject.toml tool.setuptools?
The pyx files are in your wheel or sdist?
in the wheel and sdist, but in the latter i'd expect them
@dreamy urchin putting that into setup.py at least doesn't change anything
adding it to the tool.setuptools section of pyproject.toml also changes nothing
@wild flicker, I tried again with a simple example (that contains a package directory), and include-package-data = false seems to work:
rm -rf /tmp/mypkg
mkdir -p /tmp/mypkg/mypkg
cd /tmp/mypkg
touch mypkg/hello.pyx
cat <<EOF > pyproject.toml
[build-system]
requires = ["setuptools", "Cython"]
build-backend = "setuptools.build_meta"
[project]
name = "mypkg"
version = "42"
[tool.setuptools]
include-package-data = false
EOF
cat <<EOF > setup.py
from setuptools import setup, Extension
setup(ext_modules=[Extension("mypkg.hello", ["mypkg/hello.pyx"])])
EOF
pipx run build
unzip -l dist/*.whl
Length Date Time Name
--------- ---------- ----- ----
74832 2022-07-04 22:36 mypkg/hello.cpython-38-x86_64-linux-gnu.so
47 2022-07-04 22:36 mypkg-42.dist-info/METADATA
103 2022-07-04 22:36 mypkg-42.dist-info/WHEEL
6 2022-07-04 22:36 mypkg-42.dist-info/top_level.txt
376 2022-07-04 22:36 mypkg-42.dist-info/RECORD
--------- -------
75364 5 files
Without include-package-data = false it shows .pyx inside the wheel. I suppose you can also use exclude-package-data to be more fine grained.
weird. neither including nor excluding nor putting them into the gitignore work for me. must be some weird interaction somewhere
disabling setuptools_scm also changes nothing
ha! actually it works, after i do a git clean -xdf to get a clean slate. thanks 🙂
How setuptools gets away with not following PEP-427 either, https://peps.python.org/pep-0427/#escaping-and-unicode, this says all components should be replaced with _, but still setuptools generates a.b-0.0.11.tar.gz for when the name is a.b
Python Enhancement Proposals (PEPs)
This again is reiterated at https://peps.python.org/pep-0503/#normalized-names
Python Enhancement Proposals (PEPs)
PEP 503 doesn't control filenames
just the simple repository URLs
PEP.. 427? controls wheel file names
and there's a 6xx PEP I think that controls sdist filenames
Python Enhancement Proposals (PEPs)
Both PEP-427 - Escaping and Unicode and PEP-503 - Normalized Names require the wheel/sdist files distribution name part to be normalised by replacing all non-alphanumeric characters wit the _ character. This means that a package name of a.b-c.d gets transformed to a_b_c_d. I’d like to propose to not make this escape for the . character. The . ...
Yeah, but even there do we really need to replace . with _ 🤔
It doesn't seem to be applied here https://pypi.org/simple/zope-sqlalchemy/ 🤔
and human beings are bad at determining the difference between . - and _
oh sorry, I thought you meant normalizing . at all
PEP 503 normalizes to - not _
that part 🙂
that's mostly historical
I meant normalizing the distribution name as the PEP implies, no/
filenames are normalized to _, because - otherwise has special meaning
(as does .)
What is the special meaning of .?
Historically AFAIK was used to separate namespaces in packages, but if we do this normalization that seems no longer possible
shouldn't the extension only apply for name.split('-')[-1] of the wheel/sdist name?
I guess you could have argued to normalize to . instead of _
that allows it to use it both for distribution name and version numbers
the royal you, not you specifically
but the choice of character isn't super important other than it's not -
I can accept all non-alpha numeric to be _, minus the .
to still allow package names to encode namespaces within the distribution name
the charachter we normalize to doesn't really matter to me, just want to be able to signal namespaces in the filename 🙂
and there's also an element of backwards compatibility and setuptools not really following the current recommendation
If I have a rule in my HTTP layer that user A can upload packages starting with https://pypi.org/simple/zope. this normalization breaks that because I can no longer use such rules because https://pypi.org/simple/zope_ could be both a namespace package and a root package named zope-magic 🤔
PyPI treats zope-sqlahcmeny and zope.sqlalchemy as the same name, and that's something that's unlikely to change, nor should I think it should change.
If people want to be allowed to say zope.sqlalchemy instead of zope_sqlalchemny in their filenames.. it's probably fine? But wheel files IIRC escape . to \_ .. or at least the spec says it does, nto sure if it does in practice
PyPI treats them the same because if a human says "install zope sqlalchemy", it's not clear if that means zope.sqla or zope-sqla
setuptools does not in practice 🙂 and pypi leaves it untouched
so technically yes you can upload both a.b and a-b package names under the same a.b project
pypi doesn't do much validation of the filename at all I think, which given the relevant PEPs we probably should
What I'm arguing here is that allowing . in the filenames (but in the PyPI backend still normalizing to -, e.g. to check if files is already uploaded) should be safe and what users would expect; that way people can use URL pattern permisioning to setup namespace upload rules 🤔
Do you mean in the PEP 503 URL (e.g. /simple/$THISPART/) or in the filename itself ($THISPART-1.0.tar.gz)
If you start enforcing PEP-427 with the current text at upload https://pypi.org/simple/zope-sqlalchemy/ will break unless you change setuptools to follow PEP-427
filename itself 🙂
in the URL is fine
that can/should be normalized
I'm happy with this https://pypi.org/simple/zope-sqlalchemy/ but I'd like zope.sqlalchemy-1.6-py2.py3-none-any.whl to still be valid once you load that page or upload a such filename to https://pypi.org/simple/zope-sqlalchemy/
I don't personally see a problem with that, but you'll probably need to get the PEPs ammended if you want that to be PEP valid
The way PEP-427 is formulated zope.sqlalchemy-1.6-py2.py3-none-any.whl should be zope_sqlalchemy-1.6-py2.py3-none-any.whl
the fact nobody is listening to PEP 427 on . is a strong signal that it's fine
and might be enough to convince folks to just ammend PEP 427 and 6whatever for leave . alone
I'm bad at spelling, pretend I spelled those words correctly
You're looking to amend 427 and 625 though, 503 only directly controls the /simple/$THISPART/ URLs (it starts to control sdists by 625 referencing it)
@robust yarrow seems you want to modify https://github.com/pypa/hatch/blob/master/backend/src/hatchling/metadata/utils.py#L11-L13 to refer to PEP-427 and PEP-625 not PEP-503
it's a little confusing because there's multiple things defining an escaped/normalized name, and one of them refers to another one
hmm 🤔
I'm actually not clear if PEP 427 intended for . to be escaped or not
the text says:
Each component of the filename is escaped by replacing runs of non-alphanumeric characters with an underscore _:
but
the code says
re.sub("[^\w\d.]+", "_", distribution, re.UNICODE)
that . in the character set is confusing, unless it was meant to be \.
I'm pretty sure Hatchling does it right with pep427(pep503(name))
it does it right for PEP 625, since they implemented escaping as "do PEP503, then do PEP427"
Yeah but does not do it right for PEP-427 and its regex specification as:
import re
re.sub("[^\w\d.]+", "_", "a.b", re.UNICODE)
'a.b'
https://docs.python.org/3/library/re.html
Special characters lose their special meaning inside sets.
Though the text seems to contradict the regex specified
so in PEP 427 the code and the text contradict each other
and in practice the code is what everyone is using, and what makes sense
since the text would also mean py2.py3 becomes py2-py3
seems setuptools decided to follow the regex and not the text, while hatchling followed the text, hence the difference
though PEP-625 is not yet accepted, so likely would suggest amending that to only do PEP-427 and not PEP-503
ok I see what I did. I also use regex, but only on name part b/c that made the most sense https://github.com/pypa/hatch/blob/325fec2d545fe78fd88c3870f0b068a00f631b83/backend/src/hatchling/builders/plugin/interface.py#L361
if we change 427 it should be to match 625 imo
It's not nobody -- it's setuptools. :P
we actually figured out the text and the code in PEP 427 are at odds with each other
Ah, ok.
and the code is what (most?) everyone is doing
and also what makes the most sense
since the text would require escaping version "1.0" as "1_0"
So... do we want wheels that are zope.interface-1.0.0-py3-none-any.whl to be valid? Or push them to be zope_interface-1.0.0-py3-none-any.whl? Or something else?
zope_interface-1.0.0-py3-none-any.whl
imo
I'm pretty sure that PEP 427 intended for zope.interface-1.0.0-py3-none-any.whl to be valid
because it doesn't call out name as a special case
it just says that every segment of the filename needs t obe scaped like X
and if you apply . -> \_ on anything but names, then the later segments break
but pep 621 says tools should internally store name using pep503
IIRC, the idea is that METADATA should have the display name, but all operations should use the canonical name.
And because - doesn't work in wheel names, changing that to _ is... consistent?
My only worry is zope_interface and zope.interface wheels being uploaded, as an attack or whatever.
pypi can normalize the filename like we already do for project names
for uniqueness
And, you have access to the upload tokens for package at that point... so... you can do a bunch more?
PyPI has Project.name and Project.normalized_name, and unique-ness is checked against normalized_name
Name is just used for display
I would probably say that requiring any internal uses of - within a filename segment to be escaped to _, but otherwise not caring about what a tool puts in the segments as long as it's valid is probably the right way
and just require that tools interpret those sections normalized
I'm strongly against outsourcing resolution of ambiguity to PyPI. the name part should only have one valid representation
Honestly, I'd prefer if everything that's in a distribution or whatever is normalised, with the display name only being in METADATA. I think the argument is that . can safely be in distribution files -- and... yes... at the cost of forcing normalisation on everyone on every ingestion? It's not costly, but it's cognitively annoying.
I don't think anyone is expecting projects to normalize names inside of the metadata itself
I guess I should soften that
I think that that it's unlikely we gain consensus on requiring names to 100% always be normalized in every context
so there's always going to be places where the unnormalized name exists, ideally as a display name only
& 503 is now used for https://peps.python.org/pep-0685/
Python Enhancement Proposals (PEPs)
every context -- of course not. I want zope.interface in the UI, not zope-interface.
But we definitely want to only have zope-interface in simple API, because tooling and consistency. The same argument applies for zope_interface in the distribution filenames IMO.
I don't personally care what the filename name is, as long as - is escaped
so I don't really have a horse in this race
so 503 for 621, 625, and now 685. we should use 503 everywhere
I don't think 621 actually uses 503 FWIW, I know it calls out that they should store it internally that way, but that PEP cannot actually dictate how tools operate internally, and later on in PEP 621 it explciitally calls out that requiring PEP 503 normalization was rejected
685 doesn't require storing extra names normalized, just defines how they're compared.
Requiring PEP 503 in the name key was rejected, precisely to allow display names like zope.interface to be presented as such.
AFAIK nobody is against using PEP 503 for comparison of these things
I think PEP-503 is fine for comparing stuff, but the package names for wheel/sdist should keep PEP-427 so the package namespace can be infered from the package name
and AFAIK nobody is against PEP 503 normalization for the simple API
it's just the question of whether PEP 503 normalization should be mandated in places where it's otherwise not required (like the filename)
rejected for "must" https://peps.python.org/pep-0621/#name
Tools SHOULD normalize this name, as specified by PEP 503, as soon as it is read for internal consistency.
that statement should be removed from the PEP tbh, or moved to a non-normative recommendation
it has ntohing to do with the spec in the PEP itself
Well, please look at https://packaging.python.org/en/latest/specifications/declaring-project-metadata/ instead. :P
that will lead to subtle bugs over time
well it should be removed there too most likely 😛
It's a trade off
it's a lot ahrder to get subtle bugs if you enforce that names are normalized, and only ever exist in normalized fashion
but like I said, there's no way we actually get consensus on that
I mean, I want PEPs to be left untouched -- making minor updates in the specifications pages.
Now, assuming we move everything over. Which... is a few weekends.
FWIW, pip's internals and packaging.metadata have display_name and canonical_name. So, no mixing of the two.
let's back up 🙂 ... what is gained by allowing inconsistency?
inconcistency is going to be allowed
you'll never get consensus on removing it
what is gained is that people are attached to their names
and get really upset if you say, change foo.bar to foo-bar in the PyPI UI
There's namespacing. Having foo.bar.baz be different from foo.bar_baz in the distribution names makes things work better with Artifactory.
to be clear I get the display name bit. I'm asking why in every other spot to not go with 503
The comment I just made -- tooling like Artifactory, which basically does namespacing permission handling based on names.
I think this is a bad decision, but I'll make Hatchling not follow the regex over the weekend
Yea, I think I agree too FWIW. But setuptools does this today, so it's reasonable to do this for now.
We could change to normalize . to _ but that's probably a longer transition period ask and we'd need to communicate that change with stakeholders like Artifactory
Would also require enforcing that namespace packages can be only alphanumerical to allow deducing from a_b_c the namespace the user is uploading too.
I mean... we could enforce normalisation rules coupled with a Python version (3.12, or more likely, 3.13) and expect that the platforms will add support in time for that. Then, 5 years after that, everything being built will need to be normalised and we've successfully transitioned to normalised names.
Care to elaborate?
I don't think it makes sense, what version of Python is "foo-1.0.targz" associated with to know how it should be normalized?
Oh, I meant on the build tooling side.
is it the python version of whoever happened to create it? they can control python version as easily as they can control build tool version
and if we're going to require it, ideally pypi should enforce it
seems weird for non-CPython stuff. like defaulting to utf-8 on Windows change
I understand the desire to have some project agnostic sigil for migrating some change in
I just think it isn't really going to work well in practice
and we'll end up with a bunch of things not respecting it
or not capable of respecting it
Like, 3.12 enforces that build-backends generate sdists/wheels with that format. Then, starting 3.17, installers start using only the enforced names to consume and reject other variants.
Anything that doesn't work, has been unmaintained for 5+ years and... it's bitrotten?
you'd be surprised how many projects haven't had a release in 5+ years and still work just fine
a number of the projects today were people ging
"I haven't released this since 2013, and it's still getting 5 million downloads?!"
Sure, how many of them have a . in their distribution names? :P
dunno, probably > 0
seems trivial to just say that installers should always accept the un-normalized name if they're able to parse it
why break things that don't need to be broken
I mean, in this case, I'm pretty sure it's not worthwhile FWIW.
Ah, I never posted one of the things I wrote. XD
I think I'm firmly in the "don't care" category for this at this point. This inconsitency already exists in the ecosystem and pip's gonna have to deal with it for basically forever.
Whether individual backends support having the . is upto them. 🤷🏻♂️
Yea, that's more or less where I'm at. If people feel strongly and really want to force normalized names in filenames.. I also don't really care
I don't think it affects much either way
I do think there's value to aligning PEP 427 and PEP 625
And whether we should update the specs to reflect the current reality -- yea, we should?
since right now they require different things
whether the alignment is "the name must be fully normalized" or "the name must have - escaped to _, but otherwise any valid name, normalzied or not is fine", Idon't really care
Pratically speaking, the latter is what is used in practice for wheels, what the code snippet in PEP 427 implements (but not the text, but I'm pretty sure the text is a bug in the PEP), and PEP 625 is not accepted or implemented, it's easier to align on the latter
So... PyPI should probably enforce that normalised_name-1.0.0-py-none-any.whl and normalised.name-1.0.0-py-none-any.whl are not considered distinct?
(but as @nimble bridge mentioned, build backends can emit normalized if they want, we're unlikely to require unnormalized names)
yea
it should
might even make sense to break the filename parts up for distinctness
or normalize the entire thing
normalized version, etc
pls no .whl2
pls yes .sdist
even though I think people didnt' like that suggestion when I made it ages ago
Which reminds me, do we still care about putting the actual contents of the wheel into an inner-archive within the .whl?
I think it would be a good thing to do
we got tons of extra compression that way IIRC
That's what I remember too.
and if we leave the dist-info, WHEEL can be rev'd to 2.0 which conformant tools should error on
I had to step away from packaging stuff mostly during the pandemic
my brain got real bad
ADHD and all that
on meds now though! so hopefully able to sustain participating again, and inner archive wheel is one of the things I want to tackle
(but don't let that discourage someone else from doing it if they want to)
@dreamy urchin 👋 any idea how/why https://github.com/maxbachmann/RapidFuzz/pull/236/files#diff-60f61ab7a8d1910d86d9fda2261620314edcae5894d5aaa236b821c7256badd7L37 is working even though package_dir points to the package directory itself? I thought it had to be the parent folder
(or if anybody else knows)
You can have an arbitrary mapping in package_dir... In theory a person can have a frankenstein project layout where each package is stored in a folder with a complete different name...
The empty string works as a special value. With the empty string you are mapping only the parent directory, but not the package folders themselves.
The configuration in this repo for package_dir is not wrong... but it is unnecessary (and if I had to guess, breaks setup.py develop?)
okay, I thought you were always meant to map the parent dir
it looks like it does break develop, easy-install.pth points to the project root
If the maintainer is interested, he can just remove it and use auto discovery (although I think the PEP 660 support should fix editable installs...)
Sorry, autodiscovery will not work because the project does specify ext_modules, right?
Yeah
I just changed it to '': 'src' - the maintainer was ok with that 😛
Thank you for spotting that. It is really better this way