Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0eb32a6

Browse files
committed
Add support for package data.
This is basically the support for package data from Phillip Eby's setuptools package. I've changed it only to fit it into the core implementation rather than to live in subclasses, and added documentation.
1 parent 5c26e86 commit 0eb32a6

3 files changed

Lines changed: 101 additions & 0 deletions

File tree

Doc/dist/dist.tex

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,55 @@ \subsection{Installing Scripts}
652652
\end{verbatim}
653653

654654

655+
\subsection{Installing Package Data}
656+
657+
Often, additional files need to be installed into a package. These
658+
files are often data that's closely related to the package's
659+
implementation, or text files containing documentation that might be
660+
of interest to programmers using the package. These files are called
661+
\dfn{package data}.
662+
663+
Package data can be added to packages using the \code{package_data}
664+
keyword argument to the \function{setup()} function. The value must
665+
be a mapping from package name to a list of relative path names that
666+
should be copied into the package. The paths are interpreted as
667+
relative to the directory containing the package (information from the
668+
\code{package_dir} mapping is used if appropriate); that is, the files
669+
are expected to be part of the package in the source directories.
670+
They may contain glob patterns as well.
671+
672+
The path names may contain directory portions; any necessary
673+
directories will be created in the installation.
674+
675+
For example, if a package should contain a subdirectory with several
676+
data files, the files can be arranged like this in the source tree:
677+
678+
\begin{verbatim}
679+
setup.py
680+
src/
681+
mypkg/
682+
__init__.py
683+
module.py
684+
data/
685+
tables.dat
686+
spoons.dat
687+
forks.dat
688+
\end{verbatim}
689+
690+
The corresponding call to \function{setup()} might be:
691+
692+
\begin{verbatim}
693+
setup(...,
694+
packages=['mypkg'],
695+
package_dir={'mypkg': 'src/mypkg'},
696+
package_data={'pypkg': ['data/*.dat']},
697+
)
698+
\end{verbatim}
699+
700+
701+
\versionadded{2.4}
702+
703+
655704
\subsection{Installing Additional Files}
656705

657706
The \option{data\_files} option can be used to specify additional

Lib/distutils/command/build_py.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ def initialize_options (self):
3737
self.build_lib = None
3838
self.py_modules = None
3939
self.package = None
40+
self.package_data = None
4041
self.package_dir = None
4142
self.compile = 0
4243
self.optimize = 0
@@ -51,6 +52,8 @@ def finalize_options (self):
5152
# options -- list of packages and list of modules.
5253
self.packages = self.distribution.packages
5354
self.py_modules = self.distribution.py_modules
55+
self.package_data = self.distribution.package_data
56+
self.data_files = self.get_data_files()
5457
self.package_dir = {}
5558
if self.distribution.package_dir:
5659
for name, path in self.distribution.package_dir.items():
@@ -92,11 +95,53 @@ def run (self):
9295
self.build_modules()
9396
if self.packages:
9497
self.build_packages()
98+
self.build_package_data()
9599

96100
self.byte_compile(self.get_outputs(include_bytecode=0))
97101

98102
# run ()
99103

104+
def get_data_files (self):
105+
"""Generate list of '(package,src_dir,build_dir,filenames)' tuples"""
106+
data = []
107+
for package in self.packages:
108+
# Locate package source directory
109+
src_dir = self.get_package_dir(package)
110+
111+
# Compute package build directory
112+
build_dir = os.path.join(*([self.build_lib] + package.split('.')))
113+
114+
# Length of path to strip from found files
115+
plen = len(src_dir)+1
116+
117+
# Strip directory from globbed filenames
118+
filenames = [
119+
file[plen:] for file in self.find_data_files(package, src_dir)
120+
]
121+
data.append((package, src_dir, build_dir, filenames))
122+
return data
123+
124+
def find_data_files (self, package, src_dir):
125+
"""Return filenames for package's data files in 'src_dir'"""
126+
globs = (self.package_data.get('', [])
127+
+ self.package_data.get(package, []))
128+
files = []
129+
for pattern in globs:
130+
# Each pattern has to be converted to a platform-specific path
131+
filelist = glob(os.path.join(src_dir, convert_path(pattern)))
132+
# Files that match more than one pattern are only added once
133+
files.extend([fn for fn in filelist if fn not in files])
134+
return files
135+
136+
def build_package_data (self):
137+
"""Copy data files into build directory"""
138+
lastdir = None
139+
for package, src_dir, build_dir, filenames in self.data_files:
140+
for filename in filenames:
141+
target = os.path.join(build_dir, filename)
142+
self.mkpath(os.path.dirname(target))
143+
self.copy_file(os.path.join(src_dir, filename), target,
144+
preserve_mode=False)
100145

101146
def get_package_dir (self, package):
102147
"""Return the directory, relative to the top of the source
@@ -304,6 +349,12 @@ def get_outputs (self, include_bytecode=1):
304349
if self.optimize > 0:
305350
outputs.append(filename + "o")
306351

352+
outputs += [
353+
os.path.join(build_dir, filename)
354+
for package, src_dir, build_dir, filenames in self.data_files
355+
for filename in filenames
356+
]
357+
307358
return outputs
308359

309360

Lib/distutils/dist.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ def __init__ (self, attrs=None):
158158
# than of the Distribution itself. We provide aliases for them in
159159
# Distribution as a convenience to the developer.
160160
self.packages = None
161+
self.package_data = {}
161162
self.package_dir = None
162163
self.py_modules = None
163164
self.libraries = None

0 commit comments

Comments
 (0)