Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
setuptools
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jérome Perrin
setuptools
Commits
89155abb
Commit
89155abb
authored
Jul 11, 2018
by
Paul Ganssle
Committed by
GitHub
Jul 11, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1312 from coldrye-collaboration/gh-97
fix #97 PEP420: find_packages()
parents
e50d77ef
a5797d2c
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
91 additions
and
11 deletions
+91
-11
changelog.d/1312.change.rst
changelog.d/1312.change.rst
+1
-0
docs/setuptools.txt
docs/setuptools.txt
+64
-0
setuptools/__init__.py
setuptools/__init__.py
+10
-1
setuptools/tests/test_find_packages.py
setuptools/tests/test_find_packages.py
+16
-10
No files found.
changelog.d/1312.change.rst
0 → 100644
View file @
89155abb
Introduce find_packages_ns() to find PEP 420 namespace packages.
docs/setuptools.txt
View file @
89155abb
...
...
@@ -57,6 +57,9 @@ Feature Highlights:
* Create extensible applications and frameworks that automatically discover
extensions, using simple "entry points" declared in a project's setup script.
* Full support for PEP 420 via ``find_packages_ns()``, which is also backwards
compatible to the existing ``find_packages()`` for Python >= 3.3.
.. contents:: **Table of Contents**
.. _ez_setup.py: `bootstrap module`_
...
...
@@ -459,6 +462,67 @@ argument in your setup script. Especially since it frees you from having to
remember to modify your setup script whenever your project grows additional
top-level packages or subpackages.
``find_packages_ns()``
----------------------
In Python 3.3+, ``setuptools`` also provides the ``find_packages_ns`` variant
of ``find_packages``, which has the same function signature as
``find_packages``, but works with `PEP 420`_ compliant implicit namespace
packages. Here is a minimal setup script using ``find_packages_ns``::
from setuptools import setup, find_packages_ns
setup(
name="HelloWorld",
version="0.1",
packages=find_packages_ns(),
)
Keep in mind that according to PEP 420, you may have to either re-organize your
codebase a bit or define a few exclusions, as the definition of an implicit
namespace package is quite lenient, so for a project organized like so::
├── namespace
│ └── mypackage
│ ├── __init__.py
│ └── mod1.py
├── setup.py
└── tests
└── test_mod1.py
A naive ``find_packages_ns()`` would install both ``namespace.mypackage`` and a
top-level package called ``tests``! One way to avoid this problem is to use the
``include`` keyword to whitelist the packages to include, like so::
from setuptools import setup, find_packages_ns
setup(
name="namespace.mypackage",
version="0.1",
packages=find_packages_ns(include=['namespace.*'])
)
Another option is to use the "src" layout, where all package code is placed in
the ``src`` directory, like so::
├── setup.py
├── src
│ └── namespace
│ └── mypackage
│ ├── __init__.py
│ └── mod1.py
└── tests
└── test_mod1.py
With this layout, the package directory is specified as ``src``, as such::
setup(name="namespace.mypackage",
version="0.1",
package_dir={'': 'src'},
packages=find_packages_ns(where='src'))
.. _PEP 420: https://www.python.org/dev/peps/pep-0420/
Automatic Script Creation
=========================
...
...
setuptools/__init__.py
View file @
89155abb
"""Extensions to the 'distutils' for large or complex distributions"""
import
os
import
sys
import
functools
import
distutils.core
import
distutils.filelist
from
distutils.util
import
convert_path
from
fnmatch
import
fnmatchcase
from
setuptools.extern.six
import
PY3
from
setuptools.extern.six.moves
import
filter
,
map
import
setuptools.version
...
...
@@ -17,11 +19,15 @@ from . import monkey
__metaclass__
=
type
__all__
=
[
'setup'
,
'Distribution'
,
'Feature'
,
'Command'
,
'Extension'
,
'Require'
,
'find_packages'
,
'find_packages'
]
if
PY3
:
__all__
.
append
(
'find_packages_ns'
)
__version__
=
setuptools
.
version
.
__version__
bootstrap_install_from
=
None
...
...
@@ -111,6 +117,9 @@ class PEP420PackageFinder(PackageFinder):
find_packages
=
PackageFinder
.
find
if
PY3
:
find_packages_ns
=
PEP420PackageFinder
.
find
def
_install_setup_requires
(
attrs
):
# Note: do not use `setuptools.Distribution` directly, as
...
...
setuptools/tests/test_find_packages.py
View file @
89155abb
...
...
@@ -7,14 +7,15 @@ import platform
import
pytest
import
setuptools
from
setuptools.extern.six
import
PY3
from
setuptools
import
find_packages
find_420_packages
=
setuptools
.
PEP420PackageFinder
.
find
py3_only
=
pytest
.
mark
.
xfail
(
not
PY3
,
reason
=
"Test runs on Python 3 only"
)
if
PY3
:
from
setuptools
import
find_packages_ns
# modeled after CPython's test.support.can_symlink
def
can_symlink
():
TESTFN
=
tempfile
.
mktemp
()
symlink_path
=
TESTFN
+
"can_symlink"
...
...
@@ -153,30 +154,35 @@ class TestFindPackages:
def
_assert_packages
(
self
,
actual
,
expected
):
assert
set
(
actual
)
==
set
(
expected
)
@
py3_only
def
test_pep420_ns_package
(
self
):
packages
=
find_
420_package
s
(
packages
=
find_
packages_n
s
(
self
.
dist_dir
,
include
=
[
'pkg*'
],
exclude
=
[
'pkg.subpkg.assets'
])
self
.
_assert_packages
(
packages
,
[
'pkg'
,
'pkg.nspkg'
,
'pkg.subpkg'
])
@
py3_only
def
test_pep420_ns_package_no_includes
(
self
):
packages
=
find_
420_package
s
(
packages
=
find_
packages_n
s
(
self
.
dist_dir
,
exclude
=
[
'pkg.subpkg.assets'
])
self
.
_assert_packages
(
packages
,
[
'docs'
,
'pkg'
,
'pkg.nspkg'
,
'pkg.subpkg'
])
@
py3_only
def
test_pep420_ns_package_no_includes_or_excludes
(
self
):
packages
=
find_420_packages
(
self
.
dist_dir
)
expected
=
[
'docs'
,
'pkg'
,
'pkg.nspkg'
,
'pkg.subpkg'
,
'pkg.subpkg.assets'
]
packages
=
find_packages_ns
(
self
.
dist_dir
)
expected
=
[
'docs'
,
'pkg'
,
'pkg.nspkg'
,
'pkg.subpkg'
,
'pkg.subpkg.assets'
]
self
.
_assert_packages
(
packages
,
expected
)
@
py3_only
def
test_regular_package_with_nested_pep420_ns_packages
(
self
):
self
.
_touch
(
'__init__.py'
,
self
.
pkg_dir
)
packages
=
find_
420_package
s
(
packages
=
find_
packages_n
s
(
self
.
dist_dir
,
exclude
=
[
'docs'
,
'pkg.subpkg.assets'
])
self
.
_assert_packages
(
packages
,
[
'pkg'
,
'pkg.nspkg'
,
'pkg.subpkg'
])
@
py3_only
def
test_pep420_ns_package_no_non_package_dirs
(
self
):
shutil
.
rmtree
(
self
.
docs_dir
)
shutil
.
rmtree
(
os
.
path
.
join
(
self
.
dist_dir
,
'pkg/subpkg/assets'
))
packages
=
find_
420_package
s
(
self
.
dist_dir
)
packages
=
find_
packages_n
s
(
self
.
dist_dir
)
self
.
_assert_packages
(
packages
,
[
'pkg'
,
'pkg.nspkg'
,
'pkg.subpkg'
])
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment