-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix #97 PEP420: find_packages() #1312
Conversation
I think there were objections to making the Namespace packages finder the default. I don't see those objections addressed here or in #97. This change, if I understand it correctly, will break the expectation of many packages, where they have 'tests' and 'docs' without a |
I'm also -1 on changing the default, especially changing the default only on Python 3. People find it hard enough to reason about writing a 2/3 compatible I think having a way to use |
One consideration, these implicit namespace packages only work for Python 3-only packages, right? I guess it happens at different times, but it would probably be a good idea to check the |
Yes, I was thinking about this in my waking hours this morning. Ultimately, Python 3.4 (and earlier) will get old and all namespace packages will look like PEP420 namespace packages. When that happens, we'd like for setuptools and libraries like setuptools to have an interface that's clean and free of legacy cruft. To get there without breaking existing packages, I believe we need a mechanism for the Here's an idea. What if: phase 1
phase 2About 6 months later, as a backward-incompatible release, I could imagine a 3-phase release that retains the legacy behavior, but the more I think about it, the less important that seems to retain. |
@jaraco I mostly don't like that the default behavior changes based on what interpreter you use to run That said, the "legacy behavior" is probably the overwhelmingly common case here. I think most packages use a single folder with an |
@pganssle the current solution supports both, the legacy and the future, yet one might need to exclude additional paths. @jaraco perhaps we need to add additional checks, preventing non python packages from being included in the legacy (default) case while still making sure that PEP420 packages are being found. Maybe searching for |
What I meant was that if the PEP 420 The default should be the thing that works correctly in the common case, with an easy upgrade path for the uncommon case. If 1% of packages use implicit namespaces (I think this number is probably a dramatic over-estimate), and 20% have a
Just so that 1% of people don't have to write:
We're also at a pretty significant risk of having a bunch of packages not realize that this has happened and accidentally installing |
>>> from setuptools import PEP420PackageFinder as pf
>>> from setuptools import find_packages
>>> print(find_packages())
['dateutil', 'dateutil.tz', 'dateutil.test', 'dateutil.zoneinfo', 'dateutil.parser']
>>> print(pf.find())'
['dateutil', 'build', 'ci_tools', 'docs', 'dist', 'dateutil.tz', 'dateutil.test',
'dateutil.zoneinfo', 'dateutil.parser', 'build.lib', 'build.lib.dateutil',
'build.lib.dateutil.tz', 'build.lib.dateutil.zoneinfo', 'build.lib.dateutil.parser',
'docs.samples'] This would be a very dangerous change to the default, for very little gain. Some of those directories are generated directories (meaning that running |
@pganssle you need to define the excludes when running personally, i think that omitting the |
@pganssle considering for example the maven over at java world, it defines some common grounds, e.g. test-sources, test-resources, sources, and resources. all of these are based on specific conventions, especially the location on where to find these resources. yet, one can still configure the otherwise heavily biased build system to their likings. and given the current PR, one can always choose to import just the old version of find packages, namely and considering also that all of this happens during the packaging phase, it will not affect users of the package. so it is solely up to the users of setuptools to make it happen. i.e. adapt, adopt and improve, to cite monty python. for my part i strongly believe that the migration to the new approach is rather easy to do, unless of course most of the users are unwilling to touch their existing code bases. in that case i'd say: wait for contributions to happen, i.e. people wanting to install your package from source and failing to do so because you fucked up and did no manage to maintain your package accordingly. and if you still fail to maintain your package, be prepared for people to fork and do their own thing, even more quickly than you. |
@silkentrance I know how to write the excludes, what I'm saying is that currently What that means is that by changing the default thing that Changing the default for PACKAGES = find_packages(include=['src'], implicit_namespace=True) And it will work just fine. If it's so easy for people to manually include and exclude their package directories, why is it so difficult to ask people with implicit namespace packages to opt-in to this behavior? After all, you want the default option to be the common case and the opt-in to be the uncommon case. Implicit namespace packages are decidedly the uncommon case. I don't think that the "new approach" is inherently more virtuous, so changing the default in direct contradiction to how the majority of packages are laid out in a backwards incompatible way is hardly justified. |
Just please don't have a boolean flag in the parameters to the function. Use a different function name for selecting different behavior (e.g. |
I'm fine with it being a separate function. Normally I'm not a big fan of a bunch of proliferating boolean parameters, but I think this is a borderline case. It's fundamentally the same function used in one of two modes. All the rest of the input parameters are the same and have the same effects and the result is the same (conceptually). This sort of "mode" flag is just providing information about whether this is a package with implicit namespaces or not in the same way that In any case, if you're fundamentally against a boolean parameter I don't see a problem with keeping it separate. I've been promoting using alternate constructor-style variants lately because I prefer |
setuptools/__init__.py
Outdated
@@ -17,7 +18,7 @@ | |||
|
|||
__all__ = [ | |||
'setup', 'Distribution', 'Feature', 'Command', 'Extension', 'Require', | |||
'find_packages', | |||
'find_packages' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add find_packages_ns
here?
@silkentrance I think you maybe forgot to push or commit your changes or something, because I'm still seeing the version where |
@pganssle I have changed the exports and tests accordingly. find_packages_ns is exported only for Python 3.3+. Similarly, the tests will now be executed for Python 3.3+. |
Codecov Report
@@ Coverage Diff @@
## master #1312 +/- ##
==========================================
+ Coverage 80.9% 81.45% +0.54%
==========================================
Files 105 103 -2
Lines 12346 12162 -184
==========================================
- Hits 9988 9906 -82
+ Misses 2358 2256 -102
Continue to review full report at Codecov.
|
# just catch | ||
pass | ||
|
||
py33_upwards = pytest.mark.xfail(sys.version_info < (3,3), reason="Test runs on Python >= 3.3 only") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be skipif
not xfail
.
xfail
indicates that it is currently a failing test that needs to be fixed. skipif
indicates that the tested behavior isn't intended to occur under the skipif
conditions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pganssle i found that all other conditional tests use xfail, as in expected failure. but i can make this a skipif.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, I was planning on going through and checking on those other xfail
tests because I did notice a few of them passing inappropriately.
I think it's a bit strange to use xfail
instead of skipif
, because xfail
is more useful if you would like it to start passing at some point in the future and it's unnecessary to run tests where you don't actually care whether or not they pass.
One possible objection in favor of letting this That said, it would be pretty unusual to create Python 3-only packages using Python 2, so I think I'm in favor of leaving it the way it is. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like the discussion on this has mostly settled on the current form; is there anything further beyond documentation updates and a changelog.d entry that needs to be done before merging?
setuptools/__init__.py
Outdated
@@ -107,7 +115,11 @@ def _looks_like_package(path): | |||
return True | |||
|
|||
|
|||
find_packages = PackageFinder.find | |||
find_packages = find_packages_std = PackageFinder.find |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is find_packages_std
actually used anywhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I think the idea is that it would be a more explicit public interface, but I think let's just drop it.
@jmbowman Yes, I think there are no substantive objections to adding this, it just needs documentation and a changelog entry as you mention. Ideally once we have the documentation built on PRs, we can rebase this PR and look at the docs. I'd really like to reconsider how this looks in the API documentation before merging. |
@pganssle I have rebased to master and dropped find_packages_std. |
@pganssle rebased and resolved conflicts. what is the status about this? |
find_420_packages = setuptools.PEP420PackageFinder.find | ||
try: | ||
from setuptools import find_packages_ns | ||
except: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this needs to be except ImportError
457446d
to
382ec75
Compare
Python 2.7 is still supported. |
@pganssle argh. okay, will include the checks again. |
4fef13b
to
bb87cd4
Compare
CHANGES.rst
Outdated
@@ -1,6 +1,7 @@ | |||
v39.2.0 | |||
------- | |||
|
|||
* #97: PEP 420: introduce find_packages_ns() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the future, changes go in their own separate files in the changelog.d
folder (for various reasons, including avoiding merge conflicts with everyone editing the same CHANGELOG file). In this case you should create a stub called changelog.d/1312.change.rst
.
See the contributing guide for more details. (Though I think when you first made this PR we hadn't set up town crier, so there's no way you could have known).
This fixes GH pypa#97 by introducing an alternate version of find_packages that works with PEP 420 namespace packages.
@silkentrance FYI I moved the changelog entry into changelog.d and rewrote the history of the branch to separate the commits into the logical changes (that's not necessary it's just something I like to do). I'd like to take a quick look at the documentation before merging but I think it's essentially ready. |
docs/setuptools.txt
Outdated
@@ -107,6 +110,21 @@ As you can see, it doesn't take much to use setuptools in a project. | |||
Run that script in your project folder, alongside the Python packages | |||
you have developed. | |||
|
|||
For Python 3.3+, and whenever you are using PEP 420 compliant implicit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this should be under "Basic Use". The majority of people will not be using namespace packages, and we should probably go into more detail about the exact caveats of using this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, where should we put it then? As for exact caveats, what do you have in mind? Present the user with a possible project structure and folders underneath some source root that look like packages but should be excluded?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will put it into its own section directly below Using find_packages().
@pganssle how did you separate the forced commits? or did you do new commits, assuming my user name when committing? |
I made some changes to the documentation and pushed them to this branch. I was going to make it a PR against your fork, but there was some sort of problem with that, not sure what was going on there.
Are you sure you want to know this? I have been afflicted by this knowledge in the sense that now that I know it is possible to rewrite commit histories to align with my aesthetic preferences, I feel compelled to do so, which really makes the "Merge pull request" button a less useful :P. In any case, I did |
This moves the documentation out of "Basic Usage" and expands on some of the caveats of this approach.
@pganssle Okay, so you've been using the rebase trickery then 👍 |
Here is the relevant section of the documentation: https://deploy-preview-1312--ecstatic-morse-dada75.netlify.com/setuptools.html#find-packages-ns @jmbowman Any interest in giving it a once over? |
@pganssle ok, this is looking good. I was about to do something similar:
But I think that your version is far more elaborate. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like everything's been addressed, 👍
Thanks for your contribution @silkentrance! |
You are welcome. |
make find_packages() find also PEP420 namespace packages when supported