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
8e3f9d32
Commit
8e3f9d32
authored
Jun 18, 2014
by
Alex Grönholm
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed PEP 8 compliancy of the setuptools.command package
parent
afea314a
Changes
22
Show whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
734 additions
and
602 deletions
+734
-602
setuptools/command/__init__.py
setuptools/command/__init__.py
+3
-2
setuptools/command/alias.py
setuptools/command/alias.py
+8
-6
setuptools/command/bdist_egg.py
setuptools/command/bdist_egg.py
+87
-70
setuptools/command/bdist_rpm.py
setuptools/command/bdist_rpm.py
+2
-1
setuptools/command/bdist_wininst.py
setuptools/command/bdist_wininst.py
+1
-0
setuptools/command/build_ext.py
setuptools/command/build_ext.py
+69
-53
setuptools/command/build_py.py
setuptools/command/build_py.py
+37
-28
setuptools/command/develop.py
setuptools/command/develop.py
+21
-16
setuptools/command/easy_install.py
setuptools/command/easy_install.py
+298
-231
setuptools/command/egg_info.py
setuptools/command/egg_info.py
+57
-43
setuptools/command/install.py
setuptools/command/install.py
+11
-7
setuptools/command/install_egg_info.py
setuptools/command/install_egg_info.py
+26
-44
setuptools/command/install_lib.py
setuptools/command/install_lib.py
+7
-5
setuptools/command/install_scripts.py
setuptools/command/install_scripts.py
+8
-5
setuptools/command/launcher manifest.xml
setuptools/command/launcher manifest.xml
+9
-9
setuptools/command/register.py
setuptools/command/register.py
+1
-0
setuptools/command/rotate.py
setuptools/command/rotate.py
+13
-10
setuptools/command/saveopts.py
setuptools/command/saveopts.py
+6
-8
setuptools/command/sdist.py
setuptools/command/sdist.py
+22
-17
setuptools/command/setopt.py
setuptools/command/setopt.py
+25
-20
setuptools/command/test.py
setuptools/command/test.py
+15
-17
setuptools/command/upload_docs.py
setuptools/command/upload_docs.py
+8
-10
No files found.
setuptools/command/__init__.py
View file @
8e3f9d32
...
...
@@ -5,10 +5,11 @@ __all__ = [
'register'
,
'bdist_wininst'
,
'upload_docs'
,
]
from
setuptools.command
import
install_scripts
from
distutils.command.bdist
import
bdist
import
sys
from
distutils.command.bdist
import
bdist
from
setuptools.command
import
install_scripts
if
'egg'
not
in
bdist
.
format_commands
:
bdist
.
format_command
[
'egg'
]
=
(
'bdist_egg'
,
"Python .egg file"
)
...
...
setuptools/command/alias.py
View file @
8e3f9d32
...
...
@@ -2,10 +2,12 @@ from distutils.errors import DistutilsOptionError
from
setuptools.command.setopt
import
edit_config
,
option_base
,
config_file
def
shquote
(
arg
):
"""Quote an argument for later parsing by shlex.split()"""
for
c
in
'"'
,
"'"
,
"
\
\
"
,
"#"
:
if
c
in
arg
:
return
repr
(
arg
)
if
c
in
arg
:
return
repr
(
arg
)
if
arg
.
split
()
!=
[
arg
]:
return
repr
(
arg
)
return
arg
...
...
@@ -46,7 +48,7 @@ class alias(option_base):
print
(
"setup.py alias"
,
format_alias
(
alias
,
aliases
))
return
elif
len
(
self
.
args
)
==
1
:
elif
len
(
self
.
args
)
==
1
:
alias
,
=
self
.
args
if
self
.
remove
:
command
=
None
...
...
@@ -58,9 +60,9 @@ class alias(option_base):
return
else
:
alias
=
self
.
args
[
0
]
command
=
' '
.
join
(
map
(
shquote
,
self
.
args
[
1
:]))
command
=
' '
.
join
(
map
(
shquote
,
self
.
args
[
1
:]))
edit_config
(
self
.
filename
,
{
'aliases'
:
{
alias
:
command
}},
self
.
dry_run
)
edit_config
(
self
.
filename
,
{
'aliases'
:
{
alias
:
command
}},
self
.
dry_run
)
def
format_alias
(
name
,
aliases
):
...
...
@@ -73,4 +75,4 @@ def format_alias(name, aliases):
source
=
''
else
:
source
=
'--filename=%r'
%
source
return
source
+
name
+
' '
+
command
return
source
+
name
+
' '
+
command
setuptools/command/bdist_egg.py
View file @
8e3f9d32
...
...
@@ -3,29 +3,33 @@
Build .egg distributions"""
# This module should be kept compatible with Python 2.3
from
distutils.errors
import
DistutilsSetupError
from
distutils.dir_util
import
remove_tree
,
mkpath
from
distutils
import
log
from
types
import
CodeType
import
sys
import
os
import
marshal
import
textwrap
from
pkg_resources
import
get_build_platform
,
Distribution
,
ensure_directory
from
pkg_resources
import
EntryPoint
from
setuptools.compat
import
basestring
,
next
from
setuptools.extension
import
Library
from
setuptools
import
Command
from
distutils.dir_util
import
remove_tree
,
mkpath
try
:
# Python 2.7 or >=3.2
from
sysconfig
import
get_path
,
get_python_version
def
_get_purelib
():
return
get_path
(
"purelib"
)
except
ImportError
:
from
distutils.sysconfig
import
get_python_lib
,
get_python_version
def
_get_purelib
():
return
get_python_lib
(
False
)
from
distutils
import
log
from
distutils.errors
import
DistutilsSetupError
from
pkg_resources
import
get_build_platform
,
Distribution
,
ensure_directory
from
pkg_resources
import
EntryPoint
from
types
import
CodeType
from
setuptools.compat
import
basestring
,
next
from
setuptools.extension
import
Library
def
strip_module
(
filename
):
if
'.'
in
filename
:
...
...
@@ -34,6 +38,7 @@ def strip_module(filename):
filename
=
filename
[:
-
6
]
return
filename
def
write_stub
(
resource
,
pyfile
):
_stub_template
=
textwrap
.
dedent
(
"""
def __bootstrap__():
...
...
@@ -49,7 +54,6 @@ def write_stub(resource, pyfile):
class
bdist_egg
(
Command
):
description
=
"create an
\
"
egg
\
"
distribution"
user_options
=
[
...
...
@@ -92,7 +96,7 @@ class bdist_egg(Command):
if
self
.
plat_name
is
None
:
self
.
plat_name
=
get_build_platform
()
self
.
set_undefined_options
(
'bdist'
,(
'dist_dir'
,
'dist_dir'
))
self
.
set_undefined_options
(
'bdist'
,
(
'dist_dir'
,
'dist_dir'
))
if
self
.
egg_output
is
None
:
...
...
@@ -103,24 +107,24 @@ class bdist_egg(Command):
self
.
distribution
.
has_ext_modules
()
and
self
.
plat_name
).
egg_name
()
self
.
egg_output
=
os
.
path
.
join
(
self
.
dist_dir
,
basename
+
'.egg'
)
self
.
egg_output
=
os
.
path
.
join
(
self
.
dist_dir
,
basename
+
'.egg'
)
def
do_install_data
(
self
):
# Hack for packages that install data to install's --install-lib
self
.
get_finalized_command
(
'install'
).
install_lib
=
self
.
bdist_dir
site_packages
=
os
.
path
.
normcase
(
os
.
path
.
realpath
(
_get_purelib
()))
old
,
self
.
distribution
.
data_files
=
self
.
distribution
.
data_files
,[]
old
,
self
.
distribution
.
data_files
=
self
.
distribution
.
data_files
,
[]
for
item
in
old
:
if
isinstance
(
item
,
tuple
)
and
len
(
item
)
==
2
:
if
isinstance
(
item
,
tuple
)
and
len
(
item
)
==
2
:
if
os
.
path
.
isabs
(
item
[
0
]):
realpath
=
os
.
path
.
realpath
(
item
[
0
])
normalized
=
os
.
path
.
normcase
(
realpath
)
if
normalized
==
site_packages
or
normalized
.
startswith
(
site_packages
+
os
.
sep
if
normalized
==
site_packages
or
normalized
.
startswith
(
site_packages
+
os
.
sep
):
item
=
realpath
[
len
(
site_packages
)
+
1
:],
item
[
1
]
item
=
realpath
[
len
(
site_packages
)
+
1
:],
item
[
1
]
# XXX else: raise ???
self
.
distribution
.
data_files
.
append
(
item
)
...
...
@@ -133,11 +137,11 @@ class bdist_egg(Command):
def
get_outputs
(
self
):
return
[
self
.
egg_output
]
def
call_command
(
self
,
cmdname
,
**
kw
):
def
call_command
(
self
,
cmdname
,
**
kw
):
"""Invoke reinitialized command `cmdname` with keyword args"""
for
dirname
in
INSTALL_DIRECTORY_ATTRS
:
kw
.
setdefault
(
dirname
,
self
.
bdist_dir
)
kw
.
setdefault
(
'skip_build'
,
self
.
skip_build
)
kw
.
setdefault
(
dirname
,
self
.
bdist_dir
)
kw
.
setdefault
(
'skip_build'
,
self
.
skip_build
)
kw
.
setdefault
(
'dry_run'
,
self
.
dry_run
)
cmd
=
self
.
reinitialize_command
(
cmdname
,
**
kw
)
self
.
run_command
(
cmdname
)
...
...
@@ -160,15 +164,16 @@ class bdist_egg(Command):
all_outputs
,
ext_outputs
=
self
.
get_ext_outputs
()
self
.
stubs
=
[]
to_compile
=
[]
for
(
p
,
ext_name
)
in
enumerate
(
ext_outputs
):
filename
,
ext
=
os
.
path
.
splitext
(
ext_name
)
pyfile
=
os
.
path
.
join
(
self
.
bdist_dir
,
strip_module
(
filename
)
+
'.py'
)
for
(
p
,
ext_name
)
in
enumerate
(
ext_outputs
):
filename
,
ext
=
os
.
path
.
splitext
(
ext_name
)
pyfile
=
os
.
path
.
join
(
self
.
bdist_dir
,
strip_module
(
filename
)
+
'.py'
)
self
.
stubs
.
append
(
pyfile
)
log
.
info
(
"creating stub loader for %s"
%
ext_name
)
if
not
self
.
dry_run
:
write_stub
(
os
.
path
.
basename
(
ext_name
),
pyfile
)
to_compile
.
append
(
pyfile
)
ext_outputs
[
p
]
=
ext_name
.
replace
(
os
.
sep
,
'/'
)
ext_outputs
[
p
]
=
ext_name
.
replace
(
os
.
sep
,
'/'
)
if
to_compile
:
cmd
.
byte_compile
(
to_compile
)
...
...
@@ -177,12 +182,13 @@ class bdist_egg(Command):
# Make the EGG-INFO directory
archive_root
=
self
.
bdist_dir
egg_info
=
os
.
path
.
join
(
archive_root
,
'EGG-INFO'
)
egg_info
=
os
.
path
.
join
(
archive_root
,
'EGG-INFO'
)
self
.
mkpath
(
egg_info
)
if
self
.
distribution
.
scripts
:
script_dir
=
os
.
path
.
join
(
egg_info
,
'scripts'
)
log
.
info
(
"installing scripts to %s"
%
script_dir
)
self
.
call_command
(
'install_scripts'
,
install_dir
=
script_dir
,
no_ep
=
1
)
self
.
call_command
(
'install_scripts'
,
install_dir
=
script_dir
,
no_ep
=
1
)
self
.
copy_metadata_to
(
egg_info
)
native_libs
=
os
.
path
.
join
(
egg_info
,
"native_libs.txt"
)
...
...
@@ -200,10 +206,10 @@ class bdist_egg(Command):
os
.
unlink
(
native_libs
)
write_safety_flag
(
os
.
path
.
join
(
archive_root
,
'EGG-INFO'
),
self
.
zip_safe
()
os
.
path
.
join
(
archive_root
,
'EGG-INFO'
),
self
.
zip_safe
()
)
if
os
.
path
.
exists
(
os
.
path
.
join
(
self
.
egg_info
,
'depends.txt'
)):
if
os
.
path
.
exists
(
os
.
path
.
join
(
self
.
egg_info
,
'depends.txt'
)):
log
.
warn
(
"WARNING: 'depends.txt' will not be used by setuptools 0.6!
\
n
"
"Use the install_requires/extras_require setup() args instead."
...
...
@@ -219,20 +225,20 @@ class bdist_egg(Command):
remove_tree
(
self
.
bdist_dir
,
dry_run
=
self
.
dry_run
)
# Add to 'Distribution.dist_files' so that the "upload" command works
getattr
(
self
.
distribution
,
'dist_files'
,
[]).
append
(
(
'bdist_egg'
,
get_python_version
(),
self
.
egg_output
))
getattr
(
self
.
distribution
,
'dist_files'
,
[]).
append
(
(
'bdist_egg'
,
get_python_version
(),
self
.
egg_output
))
def
zap_pyfiles
(
self
):
log
.
info
(
"Removing .py files from temporary directory"
)
for
base
,
dirs
,
files
in
walk_egg
(
self
.
bdist_dir
):
for
base
,
dirs
,
files
in
walk_egg
(
self
.
bdist_dir
):
for
name
in
files
:
if
name
.
endswith
(
'.py'
):
path
=
os
.
path
.
join
(
base
,
name
)
path
=
os
.
path
.
join
(
base
,
name
)
log
.
debug
(
"Deleting %s"
,
path
)
os
.
unlink
(
path
)
def
zip_safe
(
self
):
safe
=
getattr
(
self
.
distribution
,
'zip_safe'
,
None
)
safe
=
getattr
(
self
.
distribution
,
'zip_safe'
,
None
)
if
safe
is
not
None
:
return
safe
log
.
warn
(
"zip_safe flag not set; analyzing archive contents..."
)
...
...
@@ -240,7 +246,7 @@ class bdist_egg(Command):
def
gen_header
(
self
):
epm
=
EntryPoint
.
parse_map
(
self
.
distribution
.
entry_points
or
''
)
ep
=
epm
.
get
(
'setuptools.installation'
,{}).
get
(
'eggsecutable'
)
ep
=
epm
.
get
(
'setuptools.installation'
,
{}).
get
(
'eggsecutable'
)
if
ep
is
None
:
return
'w'
# not an eggsecutable, do it the usual way.
...
...
@@ -268,7 +274,6 @@ class bdist_egg(Command):
' echo Please rename it back to %(basename)s and try again.
\
n
'
' exec false
\
n
'
'fi
\
n
'
)
%
locals
()
if
not
self
.
dry_run
:
...
...
@@ -283,7 +288,7 @@ class bdist_egg(Command):
# normalize the path (so that a forward-slash in egg_info will
# match using startswith below)
norm_egg_info
=
os
.
path
.
normpath
(
self
.
egg_info
)
prefix
=
os
.
path
.
join
(
norm_egg_info
,
''
)
prefix
=
os
.
path
.
join
(
norm_egg_info
,
''
)
for
path
in
self
.
ei_cmd
.
filelist
.
files
:
if
path
.
startswith
(
prefix
):
target
=
os
.
path
.
join
(
target_dir
,
path
[
len
(
prefix
):])
...
...
@@ -296,23 +301,24 @@ class bdist_egg(Command):
all_outputs
=
[]
ext_outputs
=
[]
paths
=
{
self
.
bdist_dir
:
''
}
paths
=
{
self
.
bdist_dir
:
''
}
for
base
,
dirs
,
files
in
os
.
walk
(
self
.
bdist_dir
):
for
filename
in
files
:
if
os
.
path
.
splitext
(
filename
)[
1
].
lower
()
in
NATIVE_EXTENSIONS
:
all_outputs
.
append
(
paths
[
base
]
+
filename
)
all_outputs
.
append
(
paths
[
base
]
+
filename
)
for
filename
in
dirs
:
paths
[
os
.
path
.
join
(
base
,
filename
)]
=
paths
[
base
]
+
filename
+
'/'
paths
[
os
.
path
.
join
(
base
,
filename
)]
=
(
paths
[
base
]
+
filename
+
'/'
)
if
self
.
distribution
.
has_ext_modules
():
build_cmd
=
self
.
get_finalized_command
(
'build_ext'
)
for
ext
in
build_cmd
.
extensions
:
if
isinstance
(
ext
,
Library
):
if
isinstance
(
ext
,
Library
):
continue
fullname
=
build_cmd
.
get_ext_fullname
(
ext
.
name
)
filename
=
build_cmd
.
get_ext_filename
(
fullname
)
if
not
os
.
path
.
basename
(
filename
).
startswith
(
'dl-'
):
if
os
.
path
.
exists
(
os
.
path
.
join
(
self
.
bdist_dir
,
filename
)):
if
os
.
path
.
exists
(
os
.
path
.
join
(
self
.
bdist_dir
,
filename
)):
ext_outputs
.
append
(
filename
)
return
all_outputs
,
ext_outputs
...
...
@@ -324,19 +330,21 @@ NATIVE_EXTENSIONS = dict.fromkeys('.dll .so .dylib .pyd'.split())
def
walk_egg
(
egg_dir
):
"""Walk an unpacked egg's contents, skipping the metadata directory"""
walker
=
os
.
walk
(
egg_dir
)
base
,
dirs
,
files
=
next
(
walker
)
base
,
dirs
,
files
=
next
(
walker
)
if
'EGG-INFO'
in
dirs
:
dirs
.
remove
(
'EGG-INFO'
)
yield
base
,
dirs
,
files
yield
base
,
dirs
,
files
for
bdf
in
walker
:
yield
bdf
def
analyze_egg
(
egg_dir
,
stubs
):
# check for existing flag in EGG-INFO
for
flag
,
fn
in
safety_flags
.
items
():
if
os
.
path
.
exists
(
os
.
path
.
join
(
egg_dir
,
'EGG-INFO'
,
fn
)):
for
flag
,
fn
in
safety_flags
.
items
():
if
os
.
path
.
exists
(
os
.
path
.
join
(
egg_dir
,
'EGG-INFO'
,
fn
)):
return
flag
if
not
can_scan
():
return
False
if
not
can_scan
():
return
False
safe
=
True
for
base
,
dirs
,
files
in
walk_egg
(
egg_dir
):
for
name
in
files
:
...
...
@@ -347,36 +355,39 @@ def analyze_egg(egg_dir, stubs):
safe
=
scan_module
(
egg_dir
,
base
,
name
,
stubs
)
and
safe
return
safe
def
write_safety_flag
(
egg_dir
,
safe
):
# Write or remove zip safety flag file(s)
for
flag
,
fn
in
safety_flags
.
items
():
for
flag
,
fn
in
safety_flags
.
items
():
fn
=
os
.
path
.
join
(
egg_dir
,
fn
)
if
os
.
path
.
exists
(
fn
):
if
safe
is
None
or
bool
(
safe
)
!=
flag
:
os
.
unlink
(
fn
)
elif
safe
is
not
None
and
bool
(
safe
)
==
flag
:
f
=
open
(
fn
,
'wt'
)
elif
safe
is
not
None
and
bool
(
safe
)
==
flag
:
f
=
open
(
fn
,
'wt'
)
f
.
write
(
'
\
n
'
)
f
.
close
()
safety_flags
=
{
True
:
'zip-safe'
,
False
:
'not-zip-safe'
,
}
def
scan_module
(
egg_dir
,
base
,
name
,
stubs
):
"""Check whether module possibly uses unsafe-for-zipfile stuff"""
filename
=
os
.
path
.
join
(
base
,
name
)
filename
=
os
.
path
.
join
(
base
,
name
)
if
filename
[:
-
1
]
in
stubs
:
return
True
# Extension module
pkg
=
base
[
len
(
egg_dir
)
+
1
:].
replace
(
os
.
sep
,
'.'
)
module
=
pkg
+
(
pkg
and
'.'
or
''
)
+
os
.
path
.
splitext
(
name
)[
0
]
pkg
=
base
[
len
(
egg_dir
)
+
1
:].
replace
(
os
.
sep
,
'.'
)
module
=
pkg
+
(
pkg
and
'.'
or
''
)
+
os
.
path
.
splitext
(
name
)[
0
]
if
sys
.
version_info
<
(
3
,
3
):
skip
=
8
# skip magic & date
else
:
skip
=
12
# skip magic & date & file size
f
=
open
(
filename
,
'rb'
)
f
=
open
(
filename
,
'rb'
)
f
.
read
(
skip
)
code
=
marshal
.
load
(
f
)
f
.
close
()
...
...
@@ -396,21 +407,24 @@ def scan_module(egg_dir, base, name, stubs):
log
.
warn
(
"%s: module MAY be using inspect.%s"
,
module
,
bad
)
safe
=
False
if
'__name__'
in
symbols
and
'__main__'
in
symbols
and
'.'
not
in
module
:
if
sys
.
version
[:
3
]
==
"2.4"
:
# -m works w/zipfiles in 2.5
if
sys
.
version
[:
3
]
==
"2.4"
:
# -m works w/zipfiles in 2.5
log
.
warn
(
"%s: top-level module may be 'python -m' script"
,
module
)
safe
=
False
return
safe
def
iter_symbols
(
code
):
"""Yield names and strings used by `code` and its nested code objects"""
for
name
in
code
.
co_names
:
yield
name
for
name
in
code
.
co_names
:
yield
name
for
const
in
code
.
co_consts
:
if
isinstance
(
const
,
basestring
):
if
isinstance
(
const
,
basestring
):
yield
const
elif
isinstance
(
const
,
CodeType
):
elif
isinstance
(
const
,
CodeType
):
for
name
in
iter_symbols
(
const
):
yield
name
def
can_scan
():
if
not
sys
.
platform
.
startswith
(
'java'
)
and
sys
.
platform
!=
'cli'
:
# CPython, PyPy, etc.
...
...
@@ -426,6 +440,7 @@ INSTALL_DIRECTORY_ATTRS = [
'install_lib'
,
'install_dir'
,
'install_data'
,
'install_base'
]
def
make_zipfile
(
zip_filename
,
base_dir
,
verbose
=
0
,
dry_run
=
0
,
compress
=
None
,
mode
=
'w'
):
"""Create a zip file from all the files under 'base_dir'. The output
...
...
@@ -435,6 +450,7 @@ def make_zipfile(zip_filename, base_dir, verbose=0, dry_run=0, compress=None,
raises DistutilsExecError. Returns the name of the output zip file.
"""
import
zipfile
mkpath
(
os
.
path
.
dirname
(
zip_filename
),
dry_run
=
dry_run
)
log
.
info
(
"creating '%s' and adding '%s' to it"
,
zip_filename
,
base_dir
)
...
...
@@ -442,13 +458,14 @@ def make_zipfile(zip_filename, base_dir, verbose=0, dry_run=0, compress=None,
for
name
in
names
:
path
=
os
.
path
.
normpath
(
os
.
path
.
join
(
dirname
,
name
))
if
os
.
path
.
isfile
(
path
):
p
=
path
[
len
(
base_dir
)
+
1
:]
p
=
path
[
len
(
base_dir
)
+
1
:]
if
not
dry_run
:
z
.
write
(
path
,
p
)
log
.
debug
(
"adding '%s'"
%
p
)
if
compress
is
None
:
compress
=
(
sys
.
version
>=
"2.4"
)
# avoid 2.3 zipimport bug when 64 bits
# avoid 2.3 zipimport bug when 64 bits
compress
=
(
sys
.
version
>=
"2.4"
)
compression
=
[
zipfile
.
ZIP_STORED
,
zipfile
.
ZIP_DEFLATED
][
bool
(
compress
)]
if
not
dry_run
:
...
...
setuptools/command/bdist_rpm.py
View file @
8e3f9d32
import
distutils.command.bdist_rpm
as
orig
class
bdist_rpm
(
orig
.
bdist_rpm
):
"""
Override the default bdist_rpm behavior to do the following:
...
...
@@ -19,7 +20,7 @@ class bdist_rpm(orig.bdist_rpm):
def
_make_spec_file
(
self
):
version
=
self
.
distribution
.
get_version
()
rpmversion
=
version
.
replace
(
'-'
,
'_'
)
rpmversion
=
version
.
replace
(
'-'
,
'_'
)
spec
=
orig
.
bdist_rpm
.
_make_spec_file
(
self
)
line23
=
'%define version '
+
version
line24
=
'%define version '
+
rpmversion
...
...
setuptools/command/bdist_wininst.py
View file @
8e3f9d32
import
distutils.command.bdist_wininst
as
orig
class
bdist_wininst
(
orig
.
bdist_wininst
):
def
reinitialize_command
(
self
,
command
,
reinit_subcommands
=
0
):
"""
...
...
setuptools/command/build_ext.py
View file @
8e3f9d32
from
distutils.command.build_ext
import
build_ext
as
_du_build_ext
from
distutils.file_util
import
copy_file
from
distutils.ccompiler
import
new_compiler
from
distutils.sysconfig
import
customize_compiler
from
distutils.errors
import
DistutilsError
from
distutils
import
log
import
os
import
sys
from
setuptools.extension
import
Library
try
:
# Attempt to use Pyrex for building extensions, if available
from
Pyrex.Distutils.build_ext
import
build_ext
as
_build_ext
except
ImportError
:
_build_ext
=
_du_build_ext
import
os
import
sys
from
distutils.file_util
import
copy_file
from
setuptools.extension
import
Library
from
distutils.ccompiler
import
new_compiler
from
distutils.sysconfig
import
customize_compiler
try
:
# Python 2.7 or >=3.2
from
sysconfig
import
_CONFIG_VARS
except
ImportError
:
from
distutils.sysconfig
import
get_config_var
get_config_var
(
"LDSHARED"
)
# make sure _config_vars is initialized
del
get_config_var
from
distutils.sysconfig
import
_config_vars
as
_CONFIG_VARS
from
distutils
import
log
from
distutils.errors
import
DistutilsError
have_rtld
=
False
use_stubs
=
False
...
...
@@ -31,11 +34,13 @@ if sys.platform == "darwin":
elif
os
.
name
!=
'nt'
:
try
:
from
dl
import
RTLD_NOW
have_rtld
=
True
use_stubs
=
True
except
ImportError
:
pass
def
if_dl
(
s
):
if
have_rtld
:
return
s
...
...
@@ -59,8 +64,9 @@ class build_ext(_build_ext):
modpath
=
fullname
.
split
(
'.'
)
package
=
'.'
.
join
(
modpath
[:
-
1
])
package_dir
=
build_py
.
get_package_dir
(
package
)
dest_filename
=
os
.
path
.
join
(
package_dir
,
os
.
path
.
basename
(
filename
))
src_filename
=
os
.
path
.
join
(
self
.
build_lib
,
filename
)
dest_filename
=
os
.
path
.
join
(
package_dir
,
os
.
path
.
basename
(
filename
))
src_filename
=
os
.
path
.
join
(
self
.
build_lib
,
filename
)
# Always copy, even if source is older than destination, to ensure
# that the right extensions for the current Python/platform are
...
...
@@ -72,7 +78,8 @@ class build_ext(_build_ext):
if
ext
.
_needs_stub
:
self
.
write_stub
(
package_dir
or
os
.
curdir
,
ext
,
True
)
if
_build_ext
is
not
_du_build_ext
and
not
hasattr
(
_build_ext
,
'pyrex_sources'
):
if
_build_ext
is
not
_du_build_ext
and
not
hasattr
(
_build_ext
,
'pyrex_sources'
):
# Workaround for problems using some Pyrex versions w/SWIG and/or 2.4
def
swig_sources
(
self
,
sources
,
*
otherargs
):
# first do any Pyrex processing
...
...
@@ -81,15 +88,15 @@ class build_ext(_build_ext):
return
_du_build_ext
.
swig_sources
(
self
,
sources
,
*
otherargs
)
def
get_ext_filename
(
self
,
fullname
):
filename
=
_build_ext
.
get_ext_filename
(
self
,
fullname
)
filename
=
_build_ext
.
get_ext_filename
(
self
,
fullname
)
if
fullname
in
self
.
ext_map
:
ext
=
self
.
ext_map
[
fullname
]
if
isinstance
(
ext
,
Library
):
if
isinstance
(
ext
,
Library
):
fn
,
ext
=
os
.
path
.
splitext
(
filename
)
return
self
.
shlib_compiler
.
library_filename
(
fn
,
libtype
)
return
self
.
shlib_compiler
.
library_filename
(
fn
,
libtype
)
elif
use_stubs
and
ext
.
_links_to_dynamic
:
d
,
fn
=
os
.
path
.
split
(
filename
)
return
os
.
path
.
join
(
d
,
'dl-'
+
fn
)
d
,
fn
=
os
.
path
.
split
(
filename
)
return
os
.
path
.
join
(
d
,
'dl-'
+
fn
)
return
filename
def
initialize_options
(
self
):
...
...
@@ -118,9 +125,10 @@ class build_ext(_build_ext):
ltd
=
ext
.
_links_to_dynamic
=
\
self
.
shlibs
and
self
.
links_to_dynamic
(
ext
)
or
False
ext
.
_needs_stub
=
ltd
and
use_stubs
and
not
isinstance
(
ext
,
Library
)
ext
.
_needs_stub
=
ltd
and
use_stubs
and
not
isinstance
(
ext
,
Library
)
filename
=
ext
.
_file_name
=
self
.
get_ext_filename
(
fullname
)
libdir
=
os
.
path
.
dirname
(
os
.
path
.
join
(
self
.
build_lib
,
filename
))
libdir
=
os
.
path
.
dirname
(
os
.
path
.
join
(
self
.
build_lib
,
filename
))
if
ltd
and
libdir
not
in
ext
.
library_dirs
:
ext
.
library_dirs
.
append
(
libdir
)
if
ltd
and
use_stubs
and
os
.
curdir
not
in
ext
.
runtime_library_dirs
:
...
...
@@ -134,7 +142,8 @@ class build_ext(_build_ext):
tmp
=
_CONFIG_VARS
.
copy
()
try
:
# XXX Help! I don't have any idea whether these are right...
_CONFIG_VARS
[
'LDSHARED'
]
=
"gcc -Wl,-x -dynamiclib -undefined dynamic_lookup"
_CONFIG_VARS
[
'LDSHARED'
]
=
(
"gcc -Wl,-x -dynamiclib -undefined dynamic_lookup"
)
_CONFIG_VARS
[
'CCSHARED'
]
=
" -dynamiclib"
_CONFIG_VARS
[
'SO'
]
=
".dylib"
customize_compiler
(
compiler
)
...
...
@@ -148,7 +157,7 @@ class build_ext(_build_ext):
compiler
.
set_include_dirs
(
self
.
include_dirs
)
if
self
.
define
is
not
None
:
# 'define' option is a list of (name,value) tuples
for
(
name
,
value
)
in
self
.
define
:
for
(
name
,
value
)
in
self
.
define
:
compiler
.
define_macro
(
name
,
value
)
if
self
.
undef
is
not
None
:
for
macro
in
self
.
undef
:
...
...
@@ -166,16 +175,16 @@ class build_ext(_build_ext):
compiler
.
link_shared_object
=
link_shared_object
.
__get__
(
compiler
)
def
get_export_symbols
(
self
,
ext
):
if
isinstance
(
ext
,
Library
):
if
isinstance
(
ext
,
Library
):
return
ext
.
export_symbols
return
_build_ext
.
get_export_symbols
(
self
,
ext
)
return
_build_ext
.
get_export_symbols
(
self
,
ext
)
def
build_extension
(
self
,
ext
):
_compiler
=
self
.
compiler
try
:
if
isinstance
(
ext
,
Library
):
if
isinstance
(
ext
,
Library
):
self
.
compiler
=
self
.
shlib_compiler
_build_ext
.
build_extension
(
self
,
ext
)
_build_ext
.
build_extension
(
self
,
ext
)
if
ext
.
_needs_stub
:
self
.
write_stub
(
self
.
get_finalized_command
(
'build_py'
).
build_lib
,
ext
...
...
@@ -189,9 +198,10 @@ class build_ext(_build_ext):
# XXX as dynamic, and not just using a locally-found version or a
# XXX static-compiled version
libnames
=
dict
.
fromkeys
([
lib
.
_full_name
for
lib
in
self
.
shlibs
])
pkg
=
'.'
.
join
(
ext
.
_full_name
.
split
(
'.'
)[:
-
1
]
+
[
''
])
pkg
=
'.'
.
join
(
ext
.
_full_name
.
split
(
'.'
)[:
-
1
]
+
[
''
])
for
libname
in
ext
.
libraries
:
if
pkg
+
libname
in
libnames
:
return
True
if
pkg
+
libname
in
libnames
:
return
True
return
False
def
get_outputs
(
self
):
...
...
@@ -200,25 +210,28 @@ class build_ext(_build_ext):
for
ext
in
self
.
extensions
:
if
ext
.
_needs_stub
:
base
=
os
.
path
.
join
(
self
.
build_lib
,
*
ext
.
_full_name
.
split
(
'.'
))
outputs
.
append
(
base
+
'.py'
)
outputs
.
append
(
base
+
'.pyc'
)
outputs
.
append
(
base
+
'.py'
)
outputs
.
append
(
base
+
'.pyc'
)
if
optimize
:
outputs
.
append
(
base
+
'.pyo'
)
outputs
.
append
(
base
+
'.pyo'
)
return
outputs
def
write_stub
(
self
,
output_dir
,
ext
,
compile
=
False
):
log
.
info
(
"writing stub loader for %s to %s"
,
ext
.
_full_name
,
output_dir
)
stub_file
=
os
.
path
.
join
(
output_dir
,
*
ext
.
_full_name
.
split
(
'.'
))
+
'.py'
log
.
info
(
"writing stub loader for %s to %s"
,
ext
.
_full_name
,
output_dir
)
stub_file
=
(
os
.
path
.
join
(
output_dir
,
*
ext
.
_full_name
.
split
(
'.'
))
+
'.py'
)
if
compile
and
os
.
path
.
exists
(
stub_file
):
raise
DistutilsError
(
stub_file
+
" already exists! Please delete."
)
raise
DistutilsError
(
stub_file
+
" already exists! Please delete."
)
if
not
self
.
dry_run
:
f
=
open
(
stub_file
,
'w'
)
f
=
open
(
stub_file
,
'w'
)
f
.
write
(
'
\
n
'
.
join
([
"def __bootstrap__():"
,
" global __bootstrap__, __file__, __loader__"
,
" import sys, os, pkg_resources, imp"
+
if_dl
(
", dl"
),
" __file__ = pkg_resources.resource_filename(__name__,%r)"
" import sys, os, pkg_resources, imp"
+
if_dl
(
", dl"
),
" __file__ = pkg_resources.resource_filename"
"(__name__,%r)"
%
os
.
path
.
basename
(
ext
.
_file_name
),
" del __bootstrap__"
,
" if '__loader__' in globals():"
,
...
...
@@ -239,6 +252,7 @@ class build_ext(_build_ext):
f
.
close
()
if
compile
:
from
distutils.util
import
byte_compile
byte_compile
([
stub_file
],
optimize
=
0
,
force
=
True
,
dry_run
=
self
.
dry_run
)
optimize
=
self
.
get_finalized_command
(
'install_lib'
).
optimize
...
...
@@ -249,13 +263,14 @@ class build_ext(_build_ext):
os
.
unlink
(
stub_file
)
if
use_stubs
or
os
.
name
==
'nt'
:
if
use_stubs
or
os
.
name
==
'nt'
:
# Build shared libraries
#
def
link_shared_object
(
self
,
objects
,
output_libname
,
output_dir
=
None
,
libraries
=
None
,
library_dirs
=
None
,
runtime_library_dirs
=
None
,
export_symbols
=
None
,
debug
=
0
,
extra_preargs
=
None
,
extra_postargs
=
None
,
build_temp
=
None
,
target_lang
=
None
):
def
link_shared_object
(
self
,
objects
,
output_libname
,
output_dir
=
None
,
libraries
=
None
,
library_dirs
=
None
,
runtime_library_dirs
=
None
,
export_symbols
=
None
,
debug
=
0
,
extra_preargs
=
None
,
extra_postargs
=
None
,
build_temp
=
None
,
target_lang
=
None
):
self
.
link
(
self
.
SHARED_LIBRARY
,
objects
,
output_libname
,
output_dir
,
libraries
,
library_dirs
,
runtime_library_dirs
,
...
...
@@ -266,18 +281,19 @@ else:
# Build static libraries everywhere else
libtype
=
'static'
def
link_shared_object
(
self
,
objects
,
output_libname
,
output_dir
=
None
,
libraries
=
None
,
library_dirs
=
None
,
runtime_library_dirs
=
None
,
export_symbols
=
None
,
debug
=
0
,
extra_preargs
=
None
,
extra_postargs
=
None
,
build_temp
=
None
,
target_lang
=
None
):
def
link_shared_object
(
self
,
objects
,
output_libname
,
output_dir
=
None
,
libraries
=
None
,
library_dirs
=
None
,
runtime_library_dirs
=
None
,
export_symbols
=
None
,
debug
=
0
,
extra_preargs
=
None
,
extra_postargs
=
None
,
build_temp
=
None
,
target_lang
=
None
):
# XXX we need to either disallow these attrs on Library instances,
# or warn/abort here if set, or something...
#libraries=None, library_dirs=None, runtime_library_dirs=None,
#export_symbols=None, extra_preargs=None, extra_postargs=None,
#build_temp=None
#
libraries=None, library_dirs=None, runtime_library_dirs=None,
#
export_symbols=None, extra_preargs=None, extra_postargs=None,
#
build_temp=None
assert
output_dir
is
None
# distutils build_ext doesn't pass this
output_dir
,
filename
=
os
.
path
.
split
(
output_libname
)
output_dir
,
filename
=
os
.
path
.
split
(
output_libname
)
basename
,
ext
=
os
.
path
.
splitext
(
filename
)
if
self
.
library_filename
(
"x"
).
startswith
(
'lib'
):
# strip 'lib' prefix; this is kludgy if some platform uses
...
...
setuptools/command/build_py.py
View file @
8e3f9d32
from
glob
import
glob
from
distutils.util
import
convert_path
import
distutils.command.build_py
as
orig
import
os
import
sys
import
fnmatch
import
textwrap
import
distutils.command.build_py
as
orig
from
distutils.util
import
convert_path
from
glob
import
glob
try
:
from
setuptools.lib2to3_ex
import
Mixin2to3
...
...
@@ -13,6 +13,7 @@ except ImportError:
def
run_2to3
(
self
,
files
,
doctests
=
True
):
"do nothing"
class
build_py
(
orig
.
build_py
,
Mixin2to3
):
"""Enhanced 'build_py' command that includes data files with packages
...
...
@@ -22,11 +23,14 @@ class build_py(orig.build_py, Mixin2to3):
Also, this version of the 'build_py' command allows you to specify both
'py_modules' and 'packages' in the same setup operation.
"""
def
finalize_options
(
self
):
orig
.
build_py
.
finalize_options
(
self
)
self
.
package_data
=
self
.
distribution
.
package_data
self
.
exclude_package_data
=
self
.
distribution
.
exclude_package_data
or
{}
if
'data_files'
in
self
.
__dict__
:
del
self
.
__dict__
[
'data_files'
]
self
.
exclude_package_data
=
(
self
.
distribution
.
exclude_package_data
or
{})
if
'data_files'
in
self
.
__dict__
:
del
self
.
__dict__
[
'data_files'
]
self
.
__updated_files
=
[]
self
.
__doctests_2to3
=
[]
...
...
@@ -51,13 +55,14 @@ class build_py(orig.build_py, Mixin2to3):
self
.
byte_compile
(
orig
.
build_py
.
get_outputs
(
self
,
include_bytecode
=
0
))
def
__getattr__
(
self
,
attr
):
if
attr
==
'data_files'
:
# lazily compute data files
if
attr
==
'data_files'
:
# lazily compute data files
self
.
data_files
=
files
=
self
.
_get_data_files
()
return
files
return
orig
.
build_py
.
__getattr__
(
self
,
attr
)
return
orig
.
build_py
.
__getattr__
(
self
,
attr
)
def
build_module
(
self
,
module
,
module_file
,
package
):
outfile
,
copied
=
orig
.
build_py
.
build_module
(
self
,
module
,
module_file
,
package
)
outfile
,
copied
=
orig
.
build_py
.
build_module
(
self
,
module
,
module_file
,
package
)
if
copied
:
self
.
__updated_files
.
append
(
outfile
)
return
outfile
,
copied
...
...
@@ -74,7 +79,7 @@ class build_py(orig.build_py, Mixin2to3):
build_dir
=
os
.
path
.
join
(
*
([
self
.
build_lib
]
+
package
.
split
(
'.'
)))
# Length of path to strip from found files
plen
=
len
(
src_dir
)
+
1
plen
=
len
(
src_dir
)
+
1
# Strip directory from globbed filenames
filenames
=
[
...
...
@@ -102,7 +107,8 @@ class build_py(orig.build_py, Mixin2to3):
srcfile
=
os
.
path
.
join
(
src_dir
,
filename
)
outf
,
copied
=
self
.
copy_file
(
srcfile
,
target
)
srcfile
=
os
.
path
.
abspath
(
srcfile
)
if
copied
and
srcfile
in
self
.
distribution
.
convert_2to3_doctests
:
if
(
copied
and
srcfile
in
self
.
distribution
.
convert_2to3_doctests
):
self
.
__doctests_2to3
.
append
(
outf
)
def
analyze_manifest
(
self
):
...
...
@@ -117,21 +123,22 @@ class build_py(orig.build_py, Mixin2to3):
self
.
run_command
(
'egg_info'
)
ei_cmd
=
self
.
get_finalized_command
(
'egg_info'
)
for
path
in
ei_cmd
.
filelist
.
files
:
d
,
f
=
os
.
path
.
split
(
assert_relative
(
path
))
d
,
f
=
os
.
path
.
split
(
assert_relative
(
path
))
prev
=
None
oldf
=
f
while
d
and
d
!=
prev
and
d
not
in
src_dirs
:
while
d
and
d
!=
prev
and
d
not
in
src_dirs
:
prev
=
d
d
,
df
=
os
.
path
.
split
(
d
)
f
=
os
.
path
.
join
(
df
,
f
)
if
d
in
src_dirs
:
if
path
.
endswith
(
'.py'
)
and
f
==
oldf
:
if
path
.
endswith
(
'.py'
)
and
f
==
oldf
:
continue
# it's a module, not data
mf
.
setdefault
(
src_dirs
[
d
],[]).
append
(
path
)
mf
.
setdefault
(
src_dirs
[
d
],
[]).
append
(
path
)
def
get_data_files
(
self
):
pass
# kludge 2.4 for lazy computation
def
get_data_files
(
self
):
pass
# kludge 2.4 for lazy computation
if
sys
.
version
<
"2.4"
:
# Python 2.4 already has this code
if
sys
.
version
<
"2.4"
:
# Python 2.4 already has this code
def
get_outputs
(
self
,
include_bytecode
=
1
):
"""Return complete list of files copied to the build directory
...
...
@@ -142,7 +149,7 @@ class build_py(orig.build_py, Mixin2to3):
"""
return
orig
.
build_py
.
get_outputs
(
self
,
include_bytecode
)
+
[
os
.
path
.
join
(
build_dir
,
filename
)
for
package
,
src_dir
,
build_dir
,
filenames
in
self
.
data_files
for
package
,
src_dir
,
build_dir
,
filenames
in
self
.
data_files
for
filename
in
filenames
]
...
...
@@ -160,25 +167,26 @@ class build_py(orig.build_py, Mixin2to3):
return
init_py
for
pkg
in
self
.
distribution
.
namespace_packages
:
if
pkg
==
package
or
pkg
.
startswith
(
package
+
'.'
):
if
pkg
==
package
or
pkg
.
startswith
(
package
+
'.'
):
break
else
:
return
init_py
f
=
open
(
init_py
,
'rbU'
)
f
=
open
(
init_py
,
'rbU'
)
if
'declare_namespace'
.
encode
()
not
in
f
.
read
():
from
distutils.errors
import
DistutilsError
raise
DistutilsError
(
"Namespace package problem: %s is a namespace package, but
its
\
n
"
"
__init__.py does not call declare_namespace()! Please fix it.
\
n
"
'
(See the setuptools manual under "Namespace Packages" fo
r '
"details.)
\
n
"
%
(
package
,)
"Namespace package problem: %s is a namespace package, but "
"
its
\
n
__init__.py does not call declare_namespace()! Please
"
'
fix it.
\
n
(See the setuptools manual unde
r '
'"Namespace Packages" for details.)
\
n
"'
%
(
package
,)
)
f
.
close
()
return
init_py
def
initialize_options
(
self
):
self
.
packages_checked
=
{}
self
.
packages_checked
=
{}
orig
.
build_py
.
initialize_options
(
self
)
def
get_package_dir
(
self
,
package
):
...
...
@@ -202,7 +210,7 @@ class build_py(orig.build_py, Mixin2to3):
seen
=
{}
return
[
f
for
f
in
files
if
f
not
in
bad
and
f
not
in
seen
and
seen
.
setdefault
(
f
,
1
)
# ditch dupes
and
f
not
in
seen
and
seen
.
setdefault
(
f
,
1
)
# ditch dupes
]
...
...
@@ -210,6 +218,7 @@ def assert_relative(path):
if
not
os
.
path
.
isabs
(
path
):
return
path
from
distutils.errors
import
DistutilsSetupError
msg
=
textwrap
.
dedent
(
"""
Error: setup script specifies an absolute path:
...
...
setuptools/command/develop.py
View file @
8e3f9d32
import
os
import
glob
from
distutils.util
import
convert_path
from
distutils
import
log
from
distutils.errors
import
DistutilsError
,
DistutilsOptionError
import
os
import
glob
import
setuptools
from
pkg_resources
import
Distribution
,
PathMetadata
,
normalize_path
from
setuptools.command.easy_install
import
easy_install
from
setuptools.compat
import
PY3
import
setuptools
class
develop
(
easy_install
):
"""Set up package for development"""
...
...
@@ -52,29 +53,31 @@ class develop(easy_install):
# pick up setup-dir .egg files only: no .egg-info
self
.
package_index
.
scan
(
glob
.
glob
(
'*.egg'
))
self
.
egg_link
=
os
.
path
.
join
(
self
.
install_dir
,
ei
.
egg_name
+
'.egg-link'
)
self
.
egg_link
=
os
.
path
.
join
(
self
.
install_dir
,
ei
.
egg_name
+
'.egg-link'
)
self
.
egg_base
=
ei
.
egg_base
if
self
.
egg_path
is
None
:
self
.
egg_path
=
os
.
path
.
abspath
(
ei
.
egg_base
)
target
=
normalize_path
(
self
.
egg_base
)
egg_path
=
normalize_path
(
os
.
path
.
join
(
self
.
install_dir
,
self
.
egg_path
))
egg_path
=
normalize_path
(
os
.
path
.
join
(
self
.
install_dir
,
self
.
egg_path
))
if
egg_path
!=
target
:
raise
DistutilsOptionError
(
"--egg-path must be a relative path from the install"
" directory to "
+
target
" directory to "
+
target
)
# Make a distribution for the package's source
self
.
dist
=
Distribution
(
target
,
PathMetadata
(
target
,
os
.
path
.
abspath
(
ei
.
egg_info
)),
project_name
=
ei
.
egg_name
project_name
=
ei
.
egg_name
)
p
=
self
.
egg_base
.
replace
(
os
.
sep
,
'/'
)
if
p
!=
os
.
curdir
:
p
=
'../'
*
(
p
.
count
(
'/'
)
+
1
)
p
=
self
.
egg_base
.
replace
(
os
.
sep
,
'/'
)
if
p
!=
os
.
curdir
:
p
=
'../'
*
(
p
.
count
(
'/'
)
+
1
)
self
.
setup_path
=
p
p
=
normalize_path
(
os
.
path
.
join
(
self
.
install_dir
,
self
.
egg_path
,
p
))
if
p
!=
normalize_path
(
os
.
curdir
):
...
...
@@ -103,7 +106,8 @@ class develop(easy_install):
ei_cmd
=
self
.
get_finalized_command
(
"egg_info"
)
self
.
egg_path
=
build_path
self
.
dist
.
location
=
build_path
self
.
dist
.
_provider
=
PathMetadata
(
build_path
,
ei_cmd
.
egg_info
)
# XXX
# XXX
self
.
dist
.
_provider
=
PathMetadata
(
build_path
,
ei_cmd
.
egg_info
)
else
:
# Without 2to3 inplace works fine:
self
.
run_command
(
'egg_info'
)
...
...
@@ -120,7 +124,7 @@ class develop(easy_install):
# create an .egg-link in the installation dir, pointing to our egg
log
.
info
(
"Creating %s (link to %s)"
,
self
.
egg_link
,
self
.
egg_base
)
if
not
self
.
dry_run
:
f
=
open
(
self
.
egg_link
,
"w"
)
f
=
open
(
self
.
egg_link
,
"w"
)
f
.
write
(
self
.
egg_path
+
"
\
n
"
+
self
.
setup_path
)
f
.
close
()
# postprocess the installed distro, fixing up .pth, installing scripts,
...
...
@@ -133,7 +137,8 @@ class develop(easy_install):
egg_link_file
=
open
(
self
.
egg_link
)
contents
=
[
line
.
rstrip
()
for
line
in
egg_link_file
]
egg_link_file
.
close
()
if
contents
not
in
([
self
.
egg_path
],
[
self
.
egg_path
,
self
.
setup_path
]):
if
contents
not
in
([
self
.
egg_path
],
[
self
.
egg_path
,
self
.
setup_path
]):
log
.
warn
(
"Link points to %s: uninstall aborted"
,
contents
)
return
if
not
self
.
dry_run
:
...
...
@@ -147,7 +152,7 @@ class develop(easy_install):
def
install_egg_scripts
(
self
,
dist
):
if
dist
is
not
self
.
dist
:
# Installing a dependency, so fall back to normal behavior
return
easy_install
.
install_egg_scripts
(
self
,
dist
)
return
easy_install
.
install_egg_scripts
(
self
,
dist
)
# create wrapper scripts in the script dir, pointing to dist.scripts
...
...
@@ -158,7 +163,7 @@ class develop(easy_install):
for
script_name
in
self
.
distribution
.
scripts
or
[]:
script_path
=
os
.
path
.
abspath
(
convert_path
(
script_name
))
script_name
=
os
.
path
.
basename
(
script_path
)
f
=
open
(
script_path
,
'rU'
)
f
=
open
(
script_path
,
'rU'
)
script_text
=
f
.
read
()
f
.
close
()
self
.
install_script
(
dist
,
script_name
,
script_text
,
script_path
)
setuptools/command/easy_install.py
View file @
8e3f9d32
...
...
@@ -12,6 +12,14 @@ __ https://pythonhosted.org/setuptools/easy_install.html
"""
from
glob
import
glob
from
distutils.util
import
get_platform
from
distutils.util
import
convert_path
,
subst_vars
from
distutils.errors
import
DistutilsArgError
,
DistutilsOptionError
,
\
DistutilsError
,
DistutilsPlatformError
from
distutils.command.install
import
INSTALL_SCHEMES
,
SCHEME_KEYS
from
distutils
import
log
,
dir_util
from
distutils.command.build_scripts
import
first_line_re
import
sys
import
os
import
zipimport
...
...
@@ -26,21 +34,10 @@ import textwrap
import
warnings
import
site
import
struct
from
glob
import
glob
from
distutils
import
log
,
dir_util
from
distutils.command.build_scripts
import
first_line_re
import
pkg_resources
from
setuptools
import
Command
,
_dont_write_bytecode
from
setuptools.sandbox
import
run_setup
from
setuptools.py31compat
import
get_path
,
get_config_vars
from
distutils.util
import
get_platform
from
distutils.util
import
convert_path
,
subst_vars
from
distutils.errors
import
DistutilsArgError
,
DistutilsOptionError
,
\
DistutilsError
,
DistutilsPlatformError
from
distutils.command.install
import
INSTALL_SCHEMES
,
SCHEME_KEYS
from
setuptools.command
import
setopt
from
setuptools.archive_util
import
unpack_archive
from
setuptools.package_index
import
PackageIndex
...
...
@@ -54,6 +51,8 @@ from pkg_resources import (
Distribution
,
PathMetadata
,
EggMetadata
,
WorkingSet
,
DistributionNotFound
,
VersionConflict
,
DEVELOP_DIST
,
)
import
pkg_resources
sys_executable
=
os
.
environ
.
get
(
'__PYVENV_LAUNCHER__'
,
os
.
path
.
normpath
(
sys
.
executable
))
...
...
@@ -63,9 +62,11 @@ __all__ = [
'main'
,
'get_exe_prefixes'
,
]
def
is_64bit
():
return
struct
.
calcsize
(
"P"
)
==
8
def
samefile
(
p1
,
p2
):
both_exist
=
os
.
path
.
exists
(
p1
)
and
os
.
path
.
exists
(
p2
)
use_samefile
=
hasattr
(
os
.
path
,
'samefile'
)
and
both_exist
...
...
@@ -75,9 +76,11 @@ def samefile(p1, p2):
norm_p2
=
os
.
path
.
normpath
(
os
.
path
.
normcase
(
p2
))
return
norm_p1
==
norm_p2
if
PY2
:
def
_to_ascii
(
s
):
return
s
def
isascii
(
s
):
try
:
unicode
(
s
,
'ascii'
)
...
...
@@ -87,6 +90,7 @@ if PY2:
else
:
def
_to_ascii
(
s
):
return
s
.
encode
(
'ascii'
)
def
isascii
(
s
):
try
:
s
.
encode
(
'ascii'
)
...
...
@@ -94,6 +98,7 @@ else:
except
UnicodeError
:
return
False
class
easy_install
(
Command
):
"""Manage a download/build/install process"""
description
=
"Find/get/install Python packages"
...
...
@@ -118,7 +123,7 @@ class easy_install(Command):
(
'record='
,
None
,
"filename in which to record list of installed files"
),
(
'always-unzip'
,
'Z'
,
"don't install as a zipfile, no matter what"
),
(
'site-dirs='
,
'S'
,
"list of directories where .pth files work"
),
(
'site-dirs='
,
'S'
,
"list of directories where .pth files work"
),
(
'editable'
,
'e'
,
"Install specified packages in editable form"
),
(
'no-deps'
,
'N'
,
"don't install dependencies"
),
(
'allow-hosts='
,
'H'
,
"pattern(s) that hostnames must match"
),
...
...
@@ -198,7 +203,8 @@ class easy_install(Command):
if
os
.
path
.
exists
(
filename
)
or
os
.
path
.
islink
(
filename
):
log
.
info
(
"Deleting %s"
,
filename
)
if
not
self
.
dry_run
:
if
os
.
path
.
isdir
(
filename
)
and
not
os
.
path
.
islink
(
filename
):
if
(
os
.
path
.
isdir
(
filename
)
and
not
os
.
path
.
islink
(
filename
)):
rmtree
(
filename
)
else
:
os
.
unlink
(
filename
)
...
...
@@ -231,7 +237,7 @@ class easy_install(Command):
self
.
config_vars
[
'usersite'
]
=
self
.
install_usersite
# fix the install_dir if "--user" was used
#XXX: duplicate of the code in the setup command
#
XXX: duplicate of the code in the setup command
if
self
.
user
and
site
.
ENABLE_USER_SITE
:
self
.
create_home_path
()
if
self
.
install_userbase
is
None
:
...
...
@@ -246,7 +252,8 @@ class easy_install(Command):
self
.
expand_basedirs
()
self
.
expand_dirs
()
self
.
_expand
(
'install_dir'
,
'script_dir'
,
'build_directory'
,
'site_dirs'
)
self
.
_expand
(
'install_dir'
,
'script_dir'
,
'build_directory'
,
'site_dirs'
)
# If a non-default installation directory was specified, default the
# script directory to match it.
if
self
.
script_dir
is
None
:
...
...
@@ -258,12 +265,12 @@ class easy_install(Command):
# Let install_dir get set by install_lib command, which in turn
# gets its info from the install command, and takes into account
# --prefix and --home and all that other crud.
self
.
set_undefined_options
(
'install_lib'
,
(
'install_dir'
,
'install_dir'
)
self
.
set_undefined_options
(
'install_lib'
,
(
'install_dir'
,
'install_dir'
)
)
# Likewise, set default script_dir from 'install_scripts.install_dir'
self
.
set_undefined_options
(
'install_scripts'
,
(
'install_dir'
,
'script_dir'
)
self
.
set_undefined_options
(
'install_scripts'
,
(
'install_dir'
,
'script_dir'
)
)
if
self
.
user
and
self
.
install_purelib
:
...
...
@@ -277,18 +284,20 @@ class easy_install(Command):
self
.
all_site_dirs
=
get_site_dirs
()
if
self
.
site_dirs
is
not
None
:
site_dirs
=
[
os
.
path
.
expanduser
(
s
.
strip
())
for
s
in
self
.
site_dirs
.
split
(
','
)
os
.
path
.
expanduser
(
s
.
strip
())
for
s
in
self
.
site_dirs
.
split
(
','
)
]
for
d
in
site_dirs
:
if
not
os
.
path
.
isdir
(
d
):
log
.
warn
(
"%s (in --site-dirs) does not exist"
,
d
)
elif
normalize_path
(
d
)
not
in
normpath
:
raise
DistutilsOptionError
(
d
+
" (in --site-dirs) is not on sys.path"
d
+
" (in --site-dirs) is not on sys.path"
)
else
:
self
.
all_site_dirs
.
append
(
normalize_path
(
d
))
if
not
self
.
editable
:
self
.
check_site_dir
()
if
not
self
.
editable
:
self
.
check_site_dir
()
self
.
index_url
=
self
.
index_url
or
"https://pypi.python.org/simple"
self
.
shadow_path
=
self
.
all_site_dirs
[:]
for
path_item
in
self
.
install_dir
,
normalize_path
(
self
.
script_dir
):
...
...
@@ -301,9 +310,9 @@ class easy_install(Command):
hosts
=
[
'*'
]
if
self
.
package_index
is
None
:
self
.
package_index
=
self
.
create_index
(
self
.
index_url
,
search_path
=
self
.
shadow_path
,
hosts
=
hosts
,
self
.
index_url
,
search_path
=
self
.
shadow_path
,
hosts
=
hosts
,
)
self
.
local_index
=
Environment
(
self
.
shadow_path
+
sys
.
path
)
self
.
local_index
=
Environment
(
self
.
shadow_path
+
sys
.
path
)
if
self
.
find_links
is
not
None
:
if
isinstance
(
self
.
find_links
,
basestring
):
...
...
@@ -311,14 +320,15 @@ class easy_install(Command):
else
:
self
.
find_links
=
[]
if
self
.
local_snapshots_ok
:
self
.
package_index
.
scan_egg_links
(
self
.
shadow_path
+
sys
.
path
)
self
.
package_index
.
scan_egg_links
(
self
.
shadow_path
+
sys
.
path
)
if
not
self
.
no_find_links
:
self
.
package_index
.
add_find_links
(
self
.
find_links
)
self
.
set_undefined_options
(
'install_lib'
,
(
'optimize'
,
'optimize'
))
if
not
isinstance
(
self
.
optimize
,
int
):
self
.
set_undefined_options
(
'install_lib'
,
(
'optimize'
,
'optimize'
))
if
not
isinstance
(
self
.
optimize
,
int
):
try
:
self
.
optimize
=
int
(
self
.
optimize
)
if
not
(
0
<=
self
.
optimize
<=
2
):
raise
ValueError
if
not
(
0
<=
self
.
optimize
<=
2
):
raise
ValueError
except
ValueError
:
raise
DistutilsOptionError
(
"--optimize must be 0, 1, or 2"
)
...
...
@@ -350,7 +360,7 @@ class easy_install(Command):
"""Calls `os.path.expanduser` on install dirs."""
self
.
_expand_attrs
([
'install_purelib'
,
'install_platlib'
,
'install_lib'
,
'install_headers'
,
'install_scripts'
,
'install_data'
,])
'install_scripts'
,
'install_data'
,
])
def
run
(
self
):
if
self
.
verbose
!=
self
.
distribution
.
verbose
:
...
...
@@ -365,6 +375,7 @@ class easy_install(Command):
for
counter
in
range
(
len
(
outputs
)):
outputs
[
counter
]
=
outputs
[
counter
][
root_len
:]
from
distutils
import
file_util
self
.
execute
(
file_util
.
write_file
,
(
self
.
record
,
outputs
),
"writing list of installed files to '%s'"
%
...
...
@@ -392,7 +403,7 @@ class easy_install(Command):
"""Verify that self.install_dir is .pth-capable dir, if needed"""
instdir
=
normalize_path
(
self
.
install_dir
)
pth_file
=
os
.
path
.
join
(
instdir
,
'easy-install.pth'
)
pth_file
=
os
.
path
.
join
(
instdir
,
'easy-install.pth'
)
# Is it a configured, PYTHONPATH, implicit, or explicit site dir?
is_site_dir
=
instdir
in
self
.
all_site_dirs
...
...
@@ -402,13 +413,14 @@ class easy_install(Command):
is_site_dir
=
self
.
check_pth_processing
()
else
:
# make sure we can write to target dir
testfile
=
self
.
pseudo_tempname
()
+
'.write-test'
testfile
=
self
.
pseudo_tempname
()
+
'.write-test'
test_exists
=
os
.
path
.
exists
(
testfile
)
try
:
if
test_exists
:
os
.
unlink
(
testfile
)
open
(
testfile
,
'w'
).
close
()
if
test_exists
:
os
.
unlink
(
testfile
)
open
(
testfile
,
'w'
).
close
()
os
.
unlink
(
testfile
)
except
(
OSError
,
IOError
):
except
(
OSError
,
IOError
):
self
.
cant_write_to_target
()
if
not
is_site_dir
and
not
self
.
multi_version
:
...
...
@@ -421,7 +433,7 @@ class easy_install(Command):
else
:
self
.
pth_file
=
None
PYTHONPATH
=
os
.
environ
.
get
(
'PYTHONPATH'
,
''
).
split
(
os
.
pathsep
)
PYTHONPATH
=
os
.
environ
.
get
(
'PYTHONPATH'
,
''
).
split
(
os
.
pathsep
)
if
instdir
not
in
map
(
normalize_path
,
[
_f
for
_f
in
PYTHONPATH
if
_f
]):
# only PYTHONPATH dirs need a site.py, so pretend it's there
self
.
sitepy_installed
=
True
...
...
@@ -473,32 +485,36 @@ Please make the appropriate changes for your system and try again.
"""Empirically verify whether .pth files are supported in inst. dir"""
instdir
=
self
.
install_dir
log
.
info
(
"Checking .pth file support in %s"
,
instdir
)
pth_file
=
self
.
pseudo_tempname
()
+
".pth"
ok_file
=
pth_file
+
'.ok'
pth_file
=
self
.
pseudo_tempname
()
+
".pth"
ok_file
=
pth_file
+
'.ok'
ok_exists
=
os
.
path
.
exists
(
ok_file
)
try
:
if
ok_exists
:
os
.
unlink
(
ok_file
)
if
ok_exists
:
os
.
unlink
(
ok_file
)
dirname
=
os
.
path
.
dirname
(
ok_file
)
if
not
os
.
path
.
exists
(
dirname
):
os
.
makedirs
(
dirname
)
f
=
open
(
pth_file
,
'w'
)
except
(
OSError
,
IOError
):
f
=
open
(
pth_file
,
'w'
)
except
(
OSError
,
IOError
):
self
.
cant_write_to_target
()
else
:
try
:
f
.
write
(
"import os; f = open(%r, 'w'); f.write('OK'); f.close()
\
n
"
%
(
ok_file
,))
f
.
write
(
"import os; f = open(%r, 'w'); f.write('OK'); "
"f.close()
\
n
"
%
(
ok_file
,))
f
.
close
()
f
=
None
f
=
None
executable
=
sys
.
executable
if
os
.
name
==
'nt'
:
dirname
,
basename
=
os
.
path
.
split
(
executable
)
alt
=
os
.
path
.
join
(
dirname
,
'pythonw.exe'
)
if
basename
.
lower
()
==
'python.exe'
and
os
.
path
.
exists
(
alt
):
if
os
.
name
==
'nt'
:
dirname
,
basename
=
os
.
path
.
split
(
executable
)
alt
=
os
.
path
.
join
(
dirname
,
'pythonw.exe'
)
if
(
basename
.
lower
()
==
'python.exe'
and
os
.
path
.
exists
(
alt
)):
# use pythonw.exe to avoid opening a console window
executable
=
alt
from
distutils.spawn
import
spawn
spawn
([
executable
,
'-E'
,
'-c'
,
'pass'
],
0
)
spawn
([
executable
,
'-E'
,
'-c'
,
'pass'
],
0
)
if
os
.
path
.
exists
(
ok_file
):
log
.
info
(
...
...
@@ -527,7 +543,7 @@ Please make the appropriate changes for your system and try again.
continue
self
.
install_script
(
dist
,
script_name
,
dist
.
get_metadata
(
'scripts/'
+
script_name
)
dist
.
get_metadata
(
'scripts/'
+
script_name
)
)
self
.
install_wrapper_scripts
(
dist
)
...
...
@@ -535,7 +551,7 @@ Please make the appropriate changes for your system and try again.
if
os
.
path
.
isdir
(
path
):
for
base
,
dirs
,
files
in
os
.
walk
(
path
):
for
filename
in
files
:
self
.
outputs
.
append
(
os
.
path
.
join
(
base
,
filename
))
self
.
outputs
.
append
(
os
.
path
.
join
(
base
,
filename
))
else
:
self
.
outputs
.
append
(
path
)
...
...
@@ -547,7 +563,7 @@ Please make the appropriate changes for your system and try again.
%
(
spec
,)
)
def
check_editable
(
self
,
spec
):
def
check_editable
(
self
,
spec
):
if
not
self
.
editable
:
return
...
...
@@ -560,15 +576,17 @@ Please make the appropriate changes for your system and try again.
def
easy_install
(
self
,
spec
,
deps
=
False
):
tmpdir
=
tempfile
.
mkdtemp
(
prefix
=
"easy_install-"
)
download
=
None
if
not
self
.
editable
:
self
.
install_site_py
()
if
not
self
.
editable
:
self
.
install_site_py
()
try
:
if
not
isinstance
(
spec
,
Requirement
):
if
not
isinstance
(
spec
,
Requirement
):
if
URL_SCHEME
(
spec
):
# It's a url, download it to tmpdir and process
self
.
not_editable
(
spec
)
download
=
self
.
package_index
.
download
(
spec
,
tmpdir
)
return
self
.
install_item
(
None
,
download
,
tmpdir
,
deps
,
True
)
return
self
.
install_item
(
None
,
download
,
tmpdir
,
deps
,
True
)
elif
os
.
path
.
exists
(
spec
):
# Existing file or directory, just process it directly
...
...
@@ -579,15 +597,15 @@ Please make the appropriate changes for your system and try again.
self
.
check_editable
(
spec
)
dist
=
self
.
package_index
.
fetch_distribution
(
spec
,
tmpdir
,
self
.
upgrade
,
self
.
editable
,
not
self
.
always_copy
,
self
.
local_index
spec
,
tmpdir
,
self
.
upgrade
,
self
.
editable
,
not
self
.
always_copy
,
self
.
local_index
)
if
dist
is
None
:
msg
=
"Could not find suitable distribution for %r"
%
spec
if
self
.
always_copy
:
msg
+=
" (--always-copy skips system and development eggs)"
msg
+=
" (--always-copy skips system and development eggs)"
raise
DistutilsError
(
msg
)
elif
dist
.
precedence
==
DEVELOP_DIST
:
elif
dist
.
precedence
==
DEVELOP_DIST
:
# .egg-info dists don't need installing, just process deps
self
.
process_distribution
(
spec
,
dist
,
deps
,
"Using"
)
return
dist
...
...
@@ -614,7 +632,7 @@ Please make the appropriate changes for your system and try again.
# at this point, we know it's a local .egg, we just don't know if
# it's already installed.
for
dist
in
self
.
local_index
[
spec
.
project_name
]:
if
dist
.
location
==
download
:
if
dist
.
location
==
download
:
break
else
:
install_needed
=
True
# it's not in the local index
...
...
@@ -704,17 +722,18 @@ Please make the appropriate changes for your system and try again.
def
maybe_move
(
self
,
spec
,
dist_filename
,
setup_base
):
dst
=
os
.
path
.
join
(
self
.
build_directory
,
spec
.
key
)
if
os
.
path
.
exists
(
dst
):
msg
=
"%r already exists in %s; build directory %s will not be kept"
msg
=
(
"%r already exists in %s; build directory %s will not be "
"kept"
)
log
.
warn
(
msg
,
spec
.
key
,
self
.
build_directory
,
setup_base
)
return
setup_base
if
os
.
path
.
isdir
(
dist_filename
):
setup_base
=
dist_filename
else
:
if
os
.
path
.
dirname
(
dist_filename
)
==
setup_base
:
if
os
.
path
.
dirname
(
dist_filename
)
==
setup_base
:
os
.
unlink
(
dist_filename
)
# get it out of the tmp dir
contents
=
os
.
listdir
(
setup_base
)
if
len
(
contents
)
==
1
:
dist_filename
=
os
.
path
.
join
(
setup_base
,
contents
[
0
])
if
len
(
contents
)
==
1
:
dist_filename
=
os
.
path
.
join
(
setup_base
,
contents
[
0
])
if
os
.
path
.
isdir
(
dist_filename
):
# if the only thing there is a directory, move it instead
setup_base
=
dist_filename
...
...
@@ -755,7 +774,8 @@ Please make the appropriate changes for your system and try again.
def
write_script
(
self
,
script_name
,
contents
,
mode
=
"t"
,
blockers
=
()):
"""Write an executable file to the scripts directory"""
self
.
delete_blockers
(
# clean up old .py/.pyw w/o a script
[
os
.
path
.
join
(
self
.
script_dir
,
x
)
for
x
in
blockers
])
[
os
.
path
.
join
(
self
.
script_dir
,
x
)
for
x
in
blockers
]
)
log
.
info
(
"Installing %s script to %s"
,
script_name
,
self
.
script_dir
)
target
=
os
.
path
.
join
(
self
.
script_dir
,
script_name
)
self
.
add_output
(
target
)
...
...
@@ -765,10 +785,10 @@ Please make the appropriate changes for your system and try again.
ensure_directory
(
target
)
if
os
.
path
.
exists
(
target
):
os
.
unlink
(
target
)
f
=
open
(
target
,
"w"
+
mode
)
f
=
open
(
target
,
"w"
+
mode
)
f
.
write
(
contents
)
f
.
close
()
chmod
(
target
,
0o777
-
mask
)
chmod
(
target
,
0o777
-
mask
)
def
install_eggs
(
self
,
spec
,
dist_filename
,
tmpdir
):
# .egg dirs or files are already built, so just return them
...
...
@@ -795,11 +815,13 @@ Please make the appropriate changes for your system and try again.
setups
=
glob
(
os
.
path
.
join
(
setup_base
,
'*'
,
'setup.py'
))
if
not
setups
:
raise
DistutilsError
(
"Couldn't find a setup script in %s"
%
os
.
path
.
abspath
(
dist_filename
)
"Couldn't find a setup script in %s"
%
os
.
path
.
abspath
(
dist_filename
)
)
if
len
(
setups
)
>
1
:
if
len
(
setups
)
>
1
:
raise
DistutilsError
(
"Multiple setup scripts in %s"
%
os
.
path
.
abspath
(
dist_filename
)
"Multiple setup scripts in %s"
%
os
.
path
.
abspath
(
dist_filename
)
)
setup_script
=
setups
[
0
]
...
...
@@ -812,13 +834,15 @@ Please make the appropriate changes for your system and try again.
def
egg_distribution
(
self
,
egg_path
):
if
os
.
path
.
isdir
(
egg_path
):
metadata
=
PathMetadata
(
egg_path
,
os
.
path
.
join
(
egg_path
,
'EGG-INFO'
))
metadata
=
PathMetadata
(
egg_path
,
os
.
path
.
join
(
egg_path
,
'EGG-INFO'
))
else
:
metadata
=
EggMetadata
(
zipimport
.
zipimporter
(
egg_path
))
return
Distribution
.
from_filename
(
egg_path
,
metadata
=
metadata
)
return
Distribution
.
from_filename
(
egg_path
,
metadata
=
metadata
)
def
install_egg
(
self
,
egg_path
,
tmpdir
):
destination
=
os
.
path
.
join
(
self
.
install_dir
,
os
.
path
.
basename
(
egg_path
))
destination
=
os
.
path
.
join
(
self
.
install_dir
,
os
.
path
.
basename
(
egg_path
))
destination
=
os
.
path
.
abspath
(
destination
)
if
not
self
.
dry_run
:
ensure_directory
(
destination
)
...
...
@@ -828,26 +852,28 @@ Please make the appropriate changes for your system and try again.
if
os
.
path
.
isdir
(
destination
)
and
not
os
.
path
.
islink
(
destination
):
dir_util
.
remove_tree
(
destination
,
dry_run
=
self
.
dry_run
)
elif
os
.
path
.
exists
(
destination
):
self
.
execute
(
os
.
unlink
,(
destination
,),
"Removing "
+
destination
)
self
.
execute
(
os
.
unlink
,
(
destination
,),
"Removing "
+
destination
)
try
:
new_dist_is_zipped
=
False
if
os
.
path
.
isdir
(
egg_path
):
if
egg_path
.
startswith
(
tmpdir
):
f
,
m
=
shutil
.
move
,
"Moving"
f
,
m
=
shutil
.
move
,
"Moving"
else
:
f
,
m
=
shutil
.
copytree
,
"Copying"
f
,
m
=
shutil
.
copytree
,
"Copying"
elif
self
.
should_unzip
(
dist
):
self
.
mkpath
(
destination
)
f
,
m
=
self
.
unpack_and_compile
,
"Extracting"
f
,
m
=
self
.
unpack_and_compile
,
"Extracting"
else
:
new_dist_is_zipped
=
True
if
egg_path
.
startswith
(
tmpdir
):
f
,
m
=
shutil
.
move
,
"Moving"
f
,
m
=
shutil
.
move
,
"Moving"
else
:
f
,
m
=
shutil
.
copy2
,
"Copying"
f
,
m
=
shutil
.
copy2
,
"Copying"
self
.
execute
(
f
,
(
egg_path
,
destination
),
(
m
+
" %s to %s"
)
%
(
os
.
path
.
basename
(
egg_path
),
os
.
path
.
dirname
(
destination
)))
(
m
+
" %s to %s"
)
%
(
os
.
path
.
basename
(
egg_path
),
os
.
path
.
dirname
(
destination
)))
update_dist_caches
(
destination
,
fix_zipimporter_caches
=
new_dist_is_zipped
)
except
:
...
...
@@ -867,12 +893,13 @@ Please make the appropriate changes for your system and try again.
# Create a dummy distribution object until we build the real distro
dist
=
Distribution
(
None
,
project_name
=
cfg
.
get
(
'metadata'
,
'name'
),
version
=
cfg
.
get
(
'metadata'
,
'version'
),
platform
=
get_platform
(),
project_name
=
cfg
.
get
(
'metadata'
,
'name'
),
version
=
cfg
.
get
(
'metadata'
,
'version'
),
platform
=
get_platform
(),
)
# Convert the .exe to an unpacked egg
egg_path
=
dist
.
location
=
os
.
path
.
join
(
tmpdir
,
dist
.
egg_name
()
+
'.egg'
)
egg_path
=
dist
.
location
=
os
.
path
.
join
(
tmpdir
,
dist
.
egg_name
()
+
'.egg'
)
egg_tmp
=
egg_path
+
'.tmp'
_egg_info
=
os
.
path
.
join
(
egg_tmp
,
'EGG-INFO'
)
pkg_inf
=
os
.
path
.
join
(
_egg_info
,
'PKG-INFO'
)
...
...
@@ -882,15 +909,16 @@ Please make the appropriate changes for your system and try again.
# Write EGG-INFO/PKG-INFO
if
not
os
.
path
.
exists
(
pkg_inf
):
f
=
open
(
pkg_inf
,
'w'
)
f
=
open
(
pkg_inf
,
'w'
)
f
.
write
(
'Metadata-Version: 1.0
\
n
'
)
for
k
,
v
in
cfg
.
items
(
'metadata'
):
for
k
,
v
in
cfg
.
items
(
'metadata'
):
if
k
!=
'target_version'
:
f
.
write
(
'%s: %s
\
n
'
%
(
k
.
replace
(
'_'
,
'-'
).
title
(),
v
))
f
.
write
(
'%s: %s
\
n
'
%
(
k
.
replace
(
'_'
,
'-'
).
title
(),
v
))
f
.
close
()
script_dir
=
os
.
path
.
join
(
_egg_info
,
'scripts'
)
script_dir
=
os
.
path
.
join
(
_egg_info
,
'scripts'
)
self
.
delete_blockers
(
# delete entry-point scripts to avoid duping
[
os
.
path
.
join
(
script_dir
,
args
[
0
])
for
args
in
get_script_args
(
dist
)]
[
os
.
path
.
join
(
script_dir
,
args
[
0
])
for
args
in
get_script_args
(
dist
)]
)
# Build .egg file from tmpdir
bdist_egg
.
make_zipfile
(
...
...
@@ -906,11 +934,12 @@ Please make the appropriate changes for your system and try again.
to_compile
=
[]
native_libs
=
[]
top_level
=
{}
def
process
(
src
,
dst
):
def
process
(
src
,
dst
):
s
=
src
.
lower
()
for
old
,
new
in
prefixes
:
for
old
,
new
in
prefixes
:
if
s
.
startswith
(
old
):
src
=
new
+
src
[
len
(
old
):]
src
=
new
+
src
[
len
(
old
):]
parts
=
src
.
split
(
'/'
)
dst
=
os
.
path
.
join
(
egg_tmp
,
*
parts
)
dl
=
dst
.
lower
()
...
...
@@ -918,13 +947,14 @@ Please make the appropriate changes for your system and try again.
parts
[
-
1
]
=
bdist_egg
.
strip_module
(
parts
[
-
1
])
top_level
[
os
.
path
.
splitext
(
parts
[
0
])[
0
]]
=
1
native_libs
.
append
(
src
)
elif
dl
.
endswith
(
'.py'
)
and
old
!=
'SCRIPTS/'
:
elif
dl
.
endswith
(
'.py'
)
and
old
!=
'SCRIPTS/'
:
top_level
[
os
.
path
.
splitext
(
parts
[
0
])[
0
]]
=
1
to_compile
.
append
(
dst
)
return
dst
if
not
src
.
endswith
(
'.pth'
):
log
.
warn
(
"WARNING: can't process %s"
,
src
)
return
None
# extract, tracking .pyd/.dll->native_libs and .py -> to_compile
unpack_archive
(
dist_filename
,
egg_tmp
,
process
)
stubs
=
[]
...
...
@@ -932,21 +962,22 @@ Please make the appropriate changes for your system and try again.
if
res
.
lower
().
endswith
(
'.pyd'
):
# create stubs for .pyd's
parts
=
res
.
split
(
'/'
)
resource
=
parts
[
-
1
]
parts
[
-
1
]
=
bdist_egg
.
strip_module
(
parts
[
-
1
])
+
'.py'
parts
[
-
1
]
=
bdist_egg
.
strip_module
(
parts
[
-
1
])
+
'.py'
pyfile
=
os
.
path
.
join
(
egg_tmp
,
*
parts
)
to_compile
.
append
(
pyfile
)
stubs
.
append
(
pyfile
)
bdist_egg
.
write_stub
(
resource
,
pyfile
)
self
.
byte_compile
(
to_compile
)
# compile .py's
bdist_egg
.
write_safety_flag
(
os
.
path
.
join
(
egg_tmp
,
'EGG-INFO'
),
bdist_egg
.
write_safety_flag
(
os
.
path
.
join
(
egg_tmp
,
'EGG-INFO'
),
bdist_egg
.
analyze_egg
(
egg_tmp
,
stubs
))
# write zip-safety flag
for
name
in
'top_level'
,
'native_libs'
:
for
name
in
'top_level'
,
'native_libs'
:
if
locals
()[
name
]:
txt
=
os
.
path
.
join
(
egg_tmp
,
'EGG-INFO'
,
name
+
'.txt'
)
txt
=
os
.
path
.
join
(
egg_tmp
,
'EGG-INFO'
,
name
+
'.txt'
)
if
not
os
.
path
.
exists
(
txt
):
f
=
open
(
txt
,
'w'
)
f
.
write
(
'
\
n
'
.
join
(
locals
()[
name
])
+
'
\
n
'
)
f
=
open
(
txt
,
'w'
)
f
.
write
(
'
\
n
'
.
join
(
locals
()[
name
])
+
'
\
n
'
)
f
.
close
()
def
installation_report
(
self
,
req
,
dist
,
what
=
"Installed"
):
...
...
@@ -964,7 +995,7 @@ these examples, in order to select the desired version:
pkg_resources.require("%(name)s==%(version)s") # this exact version
pkg_resources.require("%(name)s>=%(version)s") # this version or higher
"""
if
self
.
install_dir
not
in
map
(
normalize_path
,
sys
.
path
):
if
self
.
install_dir
not
in
map
(
normalize_path
,
sys
.
path
):
msg
+=
"""
Note also that the installation directory must be on sys.path at runtime for
...
...
@@ -995,15 +1026,15 @@ See the setuptools documentation for the "develop" command for more info.
sys
.
modules
.
setdefault
(
'distutils.command.egg_info'
,
egg_info
)
args
=
list
(
args
)
if
self
.
verbose
>
2
:
if
self
.
verbose
>
2
:
v
=
'v'
*
(
self
.
verbose
-
1
)
args
.
insert
(
0
,
'-'
+
v
)
elif
self
.
verbose
<
2
:
args
.
insert
(
0
,
'-q'
)
args
.
insert
(
0
,
'-'
+
v
)
elif
self
.
verbose
<
2
:
args
.
insert
(
0
,
'-q'
)
if
self
.
dry_run
:
args
.
insert
(
0
,
'-n'
)
args
.
insert
(
0
,
'-n'
)
log
.
info
(
"Running %s %s"
,
setup_script
[
len
(
setup_base
)
+
1
:],
' '
.
join
(
args
)
"Running %s %s"
,
setup_script
[
len
(
setup_base
)
+
1
:],
' '
.
join
(
args
)
)
try
:
run_setup
(
setup_script
,
args
)
...
...
@@ -1051,7 +1082,8 @@ See the setuptools documentation for the "develop" command for more info.
)
fetch_options
=
{}
for
key
,
val
in
ei_opts
.
items
():
if
key
not
in
fetch_directives
:
continue
if
key
not
in
fetch_directives
:
continue
fetch_options
[
key
.
replace
(
'_'
,
'-'
)]
=
val
[
1
]
# create a settings dictionary suitable for `edit_config`
settings
=
dict
(
easy_install
=
fetch_options
)
...
...
@@ -1085,13 +1117,14 @@ See the setuptools documentation for the "develop" command for more info.
self
.
pth_file
.
save
()
if
dist
.
key
==
'setuptools'
:
if
dist
.
key
==
'setuptools'
:
# Ensure that setuptools itself never becomes unavailable!
# XXX should this check for latest version?
filename
=
os
.
path
.
join
(
self
.
install_dir
,
'setuptools.pth'
)
if
os
.
path
.
islink
(
filename
):
os
.
unlink
(
filename
)
filename
=
os
.
path
.
join
(
self
.
install_dir
,
'setuptools.pth'
)
if
os
.
path
.
islink
(
filename
):
os
.
unlink
(
filename
)
f
=
open
(
filename
,
'wt'
)
f
.
write
(
self
.
pth_file
.
make_relative
(
dist
.
location
)
+
'
\
n
'
)
f
.
write
(
self
.
pth_file
.
make_relative
(
dist
.
location
)
+
'
\
n
'
)
f
.
close
()
def
unpack_progress
(
self
,
src
,
dst
):
...
...
@@ -1108,7 +1141,7 @@ See the setuptools documentation for the "develop" command for more info.
to_compile
.
append
(
dst
)
elif
dst
.
endswith
(
'.dll'
)
or
dst
.
endswith
(
'.so'
):
to_chmod
.
append
(
dst
)
self
.
unpack_progress
(
src
,
dst
)
self
.
unpack_progress
(
src
,
dst
)
return
not
self
.
dry_run
and
dst
or
None
unpack_archive
(
egg_path
,
destination
,
pf
)
...
...
@@ -1124,6 +1157,7 @@ See the setuptools documentation for the "develop" command for more info.
return
from
distutils.util
import
byte_compile
try
:
# try to make the byte compile messages quieter
log
.
set_verbosity
(
self
.
verbose
-
1
)
...
...
@@ -1166,7 +1200,7 @@ Here are some of your options for correcting the problem:
https://pythonhosted.org/setuptools/easy_install.html#custom-installation-locations
Please make the appropriate changes for your system and try again."""
return
template
%
(
self
.
install_dir
,
os
.
environ
.
get
(
'PYTHONPATH'
,
''
))
return
template
%
(
self
.
install_dir
,
os
.
environ
.
get
(
'PYTHONPATH'
,
''
))
def
install_site_py
(
self
):
"""Make sure there's a site.py in the target dir, if needed"""
...
...
@@ -1180,7 +1214,7 @@ Please make the appropriate changes for your system and try again."""
if
os
.
path
.
exists
(
sitepy
):
log
.
debug
(
"Checking existing site.py in %s"
,
self
.
install_dir
)
f
=
open
(
sitepy
,
'rb'
)
f
=
open
(
sitepy
,
'rb'
)
current
=
f
.
read
()
# we want str, not bytes
if
PY3
:
...
...
@@ -1197,7 +1231,7 @@ Please make the appropriate changes for your system and try again."""
log
.
info
(
"Creating %s"
,
sitepy
)
if
not
self
.
dry_run
:
ensure_directory
(
sitepy
)
f
=
open
(
sitepy
,
'wb'
)
f
=
open
(
sitepy
,
'wb'
)
f
.
write
(
source
)
f
.
close
()
self
.
byte_compile
([
sitepy
])
...
...
@@ -1215,15 +1249,15 @@ Please make the appropriate changes for your system and try again."""
os
.
makedirs
(
path
,
0o700
)
INSTALL_SCHEMES
=
dict
(
posix
=
dict
(
install_dir
=
'$base/lib/python$py_version_short/site-packages'
,
script_dir
=
'$base/bin'
,
posix
=
dict
(
install_dir
=
'$base/lib/python$py_version_short/site-packages'
,
script_dir
=
'$base/bin'
,
),
)
DEFAULT_SCHEME
=
dict
(
install_dir
=
'$base/Lib/site-packages'
,
script_dir
=
'$base/Scripts'
,
install_dir
=
'$base/Lib/site-packages'
,
script_dir
=
'$base/Scripts'
,
)
def
_expand
(
self
,
*
attrs
):
...
...
@@ -1233,12 +1267,13 @@ Please make the appropriate changes for your system and try again."""
# Set default install_dir/scripts from --prefix
config_vars
=
config_vars
.
copy
()
config_vars
[
'base'
]
=
self
.
prefix
scheme
=
self
.
INSTALL_SCHEMES
.
get
(
os
.
name
,
self
.
DEFAULT_SCHEME
)
for
attr
,
val
in
scheme
.
items
():
if
getattr
(
self
,
attr
,
None
)
is
None
:
setattr
(
self
,
attr
,
val
)
scheme
=
self
.
INSTALL_SCHEMES
.
get
(
os
.
name
,
self
.
DEFAULT_SCHEME
)
for
attr
,
val
in
scheme
.
items
():
if
getattr
(
self
,
attr
,
None
)
is
None
:
setattr
(
self
,
attr
,
val
)
from
distutils.util
import
subst_vars
for
attr
in
attrs
:
val
=
getattr
(
self
,
attr
)
if
val
is
not
None
:
...
...
@@ -1247,6 +1282,7 @@ Please make the appropriate changes for your system and try again."""
val
=
os
.
path
.
expanduser
(
val
)
setattr
(
self
,
attr
,
val
)
def
get_site_dirs
():
# return a list of 'site' dirs
sitedirs
=
[
_f
for
_f
in
os
.
environ
.
get
(
'PYTHONPATH'
,
...
...
@@ -1283,7 +1319,8 @@ def get_site_dirs():
'site-packages'
))
lib_paths
=
get_path
(
'purelib'
),
get_path
(
'platlib'
)
for
site_lib
in
lib_paths
:
if
site_lib
not
in
sitedirs
:
sitedirs
.
append
(
site_lib
)
if
site_lib
not
in
sitedirs
:
sitedirs
.
append
(
site_lib
)
if
site
.
ENABLE_USER_SITE
:
sitedirs
.
append
(
site
.
USER_SITE
)
...
...
@@ -1314,12 +1351,12 @@ def expand_paths(inputs):
if
not
name
.
endswith
(
'.pth'
):
# We only care about the .pth files
continue
if
name
in
(
'easy-install.pth'
,
'setuptools.pth'
):
if
name
in
(
'easy-install.pth'
,
'setuptools.pth'
):
# Ignore .pth files that we control
continue
# Read the .pth file
f
=
open
(
os
.
path
.
join
(
dirname
,
name
))
f
=
open
(
os
.
path
.
join
(
dirname
,
name
))
lines
=
list
(
yield_lines
(
f
))
f
.
close
()
...
...
@@ -1339,7 +1376,7 @@ def extract_wininst_cfg(dist_filename):
Returns a ConfigParser.RawConfigParser, or None
"""
f
=
open
(
dist_filename
,
'rb'
)
f
=
open
(
dist_filename
,
'rb'
)
try
:
endrec
=
zipfile
.
_EndRecData
(
f
)
if
endrec
is
None
:
...
...
@@ -1348,21 +1385,23 @@ def extract_wininst_cfg(dist_filename):
prepended
=
(
endrec
[
9
]
-
endrec
[
5
])
-
endrec
[
6
]
if
prepended
<
12
:
# no wininst data here
return
None
f
.
seek
(
prepended
-
12
)
f
.
seek
(
prepended
-
12
)
from
setuptools.compat
import
StringIO
,
ConfigParser
import
struct
tag
,
cfglen
,
bmlen
=
struct
.
unpack
(
"<iii"
,
f
.
read
(
12
))
tag
,
cfglen
,
bmlen
=
struct
.
unpack
(
"<iii"
,
f
.
read
(
12
))
if
tag
not
in
(
0x1234567A
,
0x1234567B
):
return
None
# not a valid tag
f
.
seek
(
prepended
-
(
12
+
cfglen
))
cfg
=
ConfigParser
.
RawConfigParser
({
'version'
:
''
,
'target_version'
:
''
})
f
.
seek
(
prepended
-
(
12
+
cfglen
))
cfg
=
ConfigParser
.
RawConfigParser
(
{
'version'
:
''
,
'target_version'
:
''
})
try
:
part
=
f
.
read
(
cfglen
)
# part is in bytes, but we need to read up to the first null
# byte.
if
sys
.
version_info
>=
(
2
,
6
):
if
sys
.
version_info
>=
(
2
,
6
):
null_byte
=
bytes
([
0
])
else
:
null_byte
=
chr
(
0
)
...
...
@@ -1395,25 +1434,25 @@ def get_exe_prefixes(exe_filename):
for
info
in
z
.
infolist
():
name
=
info
.
filename
parts
=
name
.
split
(
'/'
)
if
len
(
parts
)
==
3
and
parts
[
2
]
==
'PKG-INFO'
:
if
len
(
parts
)
==
3
and
parts
[
2
]
==
'PKG-INFO'
:
if
parts
[
1
].
endswith
(
'.egg-info'
):
prefixes
.
insert
(
0
,(
'/'
.
join
(
parts
[:
2
]),
'EGG-INFO/'
))
prefixes
.
insert
(
0
,
(
'/'
.
join
(
parts
[:
2
]),
'EGG-INFO/'
))
break
if
len
(
parts
)
!=
2
or
not
name
.
endswith
(
'.pth'
):
continue
if
name
.
endswith
(
'-nspkg.pth'
):
continue
if
parts
[
0
].
upper
()
in
(
'PURELIB'
,
'PLATLIB'
):
if
parts
[
0
].
upper
()
in
(
'PURELIB'
,
'PLATLIB'
):
contents
=
z
.
read
(
name
)
if
PY3
:
contents
=
contents
.
decode
()
for
pth
in
yield_lines
(
contents
):
pth
=
pth
.
strip
().
replace
(
'
\
\
'
,
'/'
)
pth
=
pth
.
strip
().
replace
(
'
\
\
'
,
'/'
)
if
not
pth
.
startswith
(
'import'
):
prefixes
.
append
(((
'%s/%s/'
%
(
parts
[
0
],
pth
)),
''
))
prefixes
.
append
(((
'%s/%s/'
%
(
parts
[
0
],
pth
)),
''
))
finally
:
z
.
close
()
prefixes
=
[(
x
.
lower
(),
y
)
for
x
,
y
in
prefixes
]
prefixes
=
[(
x
.
lower
(),
y
)
for
x
,
y
in
prefixes
]
prefixes
.
sort
()
prefixes
.
reverse
()
return
prefixes
...
...
@@ -1427,6 +1466,7 @@ def parse_requirement_arg(spec):
"Not a URL, existing file, or requirement spec: %r"
%
(
spec
,)
)
class
PthDistributions
(
Environment
):
"""A .pth file with Distribution paths in it"""
...
...
@@ -1446,7 +1486,7 @@ class PthDistributions(Environment):
saw_import
=
False
seen
=
dict
.
fromkeys
(
self
.
sitedirs
)
if
os
.
path
.
isfile
(
self
.
filename
):
f
=
open
(
self
.
filename
,
'rt'
)
f
=
open
(
self
.
filename
,
'rt'
)
for
line
in
f
:
if
line
.
startswith
(
'import'
):
saw_import
=
True
...
...
@@ -1458,7 +1498,7 @@ class PthDistributions(Environment):
# skip non-existent paths, in case somebody deleted a package
# manually, and duplicate paths as well
path
=
self
.
paths
[
-
1
]
=
normalize_path
(
os
.
path
.
join
(
self
.
basedir
,
path
)
os
.
path
.
join
(
self
.
basedir
,
path
)
)
if
not
os
.
path
.
exists
(
path
)
or
path
in
seen
:
self
.
paths
.
pop
()
# skip it
...
...
@@ -1477,7 +1517,7 @@ class PthDistributions(Environment):
if
not
self
.
dirty
:
return
data
=
'
\
n
'
.
join
(
map
(
self
.
make_relative
,
self
.
paths
))
data
=
'
\
n
'
.
join
(
map
(
self
.
make_relative
,
self
.
paths
))
if
data
:
log
.
debug
(
"Saving %s"
,
self
.
filename
)
data
=
(
...
...
@@ -1491,7 +1531,7 @@ class PthDistributions(Environment):
if
os
.
path
.
islink
(
self
.
filename
):
os
.
unlink
(
self
.
filename
)
f
=
open
(
self
.
filename
,
'wt'
)
f
=
open
(
self
.
filename
,
'wt'
)
f
.
write
(
data
)
f
.
close
()
...
...
@@ -1518,13 +1558,13 @@ class PthDistributions(Environment):
self
.
dirty
=
True
Environment
.
remove
(
self
,
dist
)
def
make_relative
(
self
,
path
):
def
make_relative
(
self
,
path
):
npath
,
last
=
os
.
path
.
split
(
normalize_path
(
path
))
baselen
=
len
(
self
.
basedir
)
parts
=
[
last
]
sep
=
os
.
altsep
==
'/'
and
'/'
or
os
.
sep
while
len
(
npath
)
>=
baselen
:
if
npath
==
self
.
basedir
:
sep
=
os
.
altsep
==
'/'
and
'/'
or
os
.
sep
while
len
(
npath
)
>=
baselen
:
if
npath
==
self
.
basedir
:
parts
.
append
(
os
.
curdir
)
parts
.
reverse
()
return
sep
.
join
(
parts
)
...
...
@@ -1548,12 +1588,13 @@ def _first_line_re():
def
get_script_header
(
script_text
,
executable
=
sys_executable
,
wininst
=
False
):
"""Create a #! line, getting options (if any) from script_text"""
first
=
(
script_text
+
'
\
n
'
).
splitlines
()[
0
]
first
=
(
script_text
+
'
\
n
'
).
splitlines
()[
0
]
match
=
_first_line_re
().
match
(
first
)
options
=
''
if
match
:
options
=
match
.
group
(
1
)
or
''
if
options
:
options
=
' '
+
options
if
options
:
options
=
' '
+
options
if
wininst
:
executable
=
"python.exe"
else
:
...
...
@@ -1563,7 +1604,7 @@ def get_script_header(script_text, executable=sys_executable, wininst=False):
# Non-ascii path to sys.executable, use -x to prevent warnings
if
options
:
if
options
.
strip
().
startswith
(
'-'
):
options
=
' -x'
+
options
.
strip
()[
1
:]
options
=
' -x'
+
options
.
strip
()[
1
:]
# else: punt, we can't do it, let the warning happen anyway
else
:
options
=
' -x'
...
...
@@ -1571,12 +1612,14 @@ def get_script_header(script_text, executable=sys_executable, wininst=False):
hdr
=
"#!%(executable)s%(options)s
\
n
"
%
locals
()
return
hdr
def
auto_chmod
(
func
,
arg
,
exc
):
if
func
is
os
.
remove
and
os
.
name
==
'nt'
:
if
func
is
os
.
remove
and
os
.
name
==
'nt'
:
chmod
(
arg
,
stat
.
S_IWRITE
)
return
func
(
arg
)
et
,
ev
,
_
=
sys
.
exc_info
()
reraise
(
et
,
(
ev
[
0
],
ev
[
1
]
+
(
" %s %s"
%
(
func
,
arg
))))
reraise
(
et
,
(
ev
[
0
],
ev
[
1
]
+
(
" %s %s"
%
(
func
,
arg
))))
def
update_dist_caches
(
dist_path
,
fix_zipimporter_caches
):
"""
...
...
@@ -1659,6 +1702,7 @@ def update_dist_caches(dist_path, fix_zipimporter_caches):
# this is really needed.
_remove_and_clear_zip_directory_cache_data
(
normalized_path
)
def
_collect_zipimporter_cache_entries
(
normalized_path
,
cache
):
"""
Return zipimporter cache entry keys related to a given normalized path.
...
...
@@ -1678,6 +1722,7 @@ def _collect_zipimporter_cache_entries(normalized_path, cache):
result
.
append
(
p
)
return
result
def
_update_zipimporter_cache
(
normalized_path
,
cache
,
updater
=
None
):
"""
Update zipimporter cache data for a given normalized path.
...
...
@@ -1709,14 +1754,17 @@ def _update_zipimporter_cache(normalized_path, cache, updater=None):
if
new_entry
is
not
None
:
cache
[
p
]
=
new_entry
def
_uncache
(
normalized_path
,
cache
):
_update_zipimporter_cache
(
normalized_path
,
cache
)
def
_remove_and_clear_zip_directory_cache_data
(
normalized_path
):
def
clear_and_remove_cached_zip_archive_directory_data
(
path
,
old_entry
):
old_entry
.
clear
()
_update_zipimporter_cache
(
normalized_path
,
zipimport
.
_zip_directory_cache
,
_update_zipimporter_cache
(
normalized_path
,
zipimport
.
_zip_directory_cache
,
updater
=
clear_and_remove_cached_zip_archive_directory_data
)
# PyPy Python implementation does not allow directly writing to the
...
...
@@ -1744,10 +1792,12 @@ else:
zipimport
.
zipimporter
(
path
)
old_entry
.
update
(
zipimport
.
_zip_directory_cache
[
path
])
return
old_entry
_update_zipimporter_cache
(
normalized_path
,
zipimport
.
_zip_directory_cache
,
_update_zipimporter_cache
(
normalized_path
,
zipimport
.
_zip_directory_cache
,
updater
=
replace_cached_zip_archive_directory_data
)
def
is_python
(
text
,
filename
=
'<string>'
):
"Is this string a valid Python script?"
try
:
...
...
@@ -1757,15 +1807,18 @@ def is_python(text, filename='<string>'):
else
:
return
True
def
is_sh
(
executable
):
"""Determine if the specified executable is a .sh (contains a #! line)"""
try
:
fp
=
open
(
executable
)
magic
=
fp
.
read
(
2
)
fp
.
close
()
except
(
OSError
,
IOError
):
return
executable
except
(
OSError
,
IOError
):
return
executable
return
magic
==
'#!'
def
nt_quote_arg
(
arg
):
"""Quote a command line argument according to Windows parsing rules"""
...
...
@@ -1782,7 +1835,7 @@ def nt_quote_arg(arg):
nb
+=
1
elif
c
==
'"'
:
# double preceding backslashes, then add a \"
result
.
append
(
'
\
\
'
*
(
nb
*
2
)
+
'
\
\
"'
)
result
.
append
(
'
\
\
'
*
(
nb
*
2
)
+
'
\
\
"'
)
nb
=
0
else
:
if
nb
:
...
...
@@ -1799,6 +1852,7 @@ def nt_quote_arg(arg):
return
''
.
join
(
result
)
def
is_python_script
(
script_text
,
filename
):
"""Is this text, as a whole, a Python script? (as opposed to shell/bat/etc.
"""
...
...
@@ -1812,11 +1866,14 @@ def is_python_script(script_text, filename):
return
False
# Not any Python I can recognize
try
:
from
os
import
chmod
as
_chmod
except
ImportError
:
# Jython compatibility
def
_chmod
(
*
args
):
pass
def
_chmod
(
*
args
):
pass
def
chmod
(
path
,
mode
):
log
.
debug
(
"changing mode of %s to %o"
,
path
,
mode
)
...
...
@@ -1826,10 +1883,12 @@ def chmod(path, mode):
e
=
sys
.
exc_info
()[
1
]
log
.
debug
(
"chmod failed: %s"
,
e
)
def
fix_jython_executable
(
executable
,
options
):
if
sys
.
platform
.
startswith
(
'java'
)
and
is_sh
(
executable
):
# Workaround for Jython is not needed on Linux systems.
import
java
if
java
.
lang
.
System
.
getProperty
(
"os.name"
)
==
"Linux"
:
return
executable
...
...
@@ -1883,14 +1942,14 @@ class ScriptWriter(object):
@
classmethod
def
get_writer
(
cls
,
force_windows
):
if
force_windows
or
sys
.
platform
==
'win32'
:
if
force_windows
or
sys
.
platform
==
'win32'
:
return
WindowsScriptWriter
.
get_writer
()
return
cls
@
classmethod
def
_get_script_args
(
cls
,
type_
,
name
,
header
,
script_text
):
# Simply write the stub with no extension.
yield
(
name
,
header
+
script_text
)
yield
(
name
,
header
+
script_text
)
class
WindowsScriptWriter
(
ScriptWriter
):
...
...
@@ -1917,8 +1976,8 @@ class WindowsScriptWriter(ScriptWriter):
old
=
[
'.pya'
,
'.py'
,
'-script.py'
,
'.pyc'
,
'.pyo'
,
'.pyw'
,
'.exe'
]
old
.
remove
(
ext
)
header
=
cls
.
_adjust_header
(
type_
,
header
)
blockers
=
[
name
+
x
for
x
in
old
]
yield
name
+
ext
,
header
+
script_text
,
't'
,
blockers
blockers
=
[
name
+
x
for
x
in
old
]
yield
name
+
ext
,
header
+
script_text
,
't'
,
blockers
@
staticmethod
def
_adjust_header
(
type_
,
orig_header
):
...
...
@@ -1945,19 +2004,19 @@ class WindowsExecutableLauncherWriter(WindowsScriptWriter):
"""
For Windows, add a .py extension and an .exe launcher
"""
if
type_
==
'gui'
:
if
type_
==
'gui'
:
launcher_type
=
'gui'
ext
=
'-script.pyw'
old
=
[
'.pyw'
]
else
:
launcher_type
=
'cli'
ext
=
'-script.py'
old
=
[
'.py'
,
'.pyc'
,
'.pyo'
]
old
=
[
'.py'
,
'.pyc'
,
'.pyo'
]
hdr
=
cls
.
_adjust_header
(
type_
,
header
)
blockers
=
[
name
+
x
for
x
in
old
]
yield
(
name
+
ext
,
hdr
+
script_text
,
't'
,
blockers
)
blockers
=
[
name
+
x
for
x
in
old
]
yield
(
name
+
ext
,
hdr
+
script_text
,
't'
,
blockers
)
yield
(
name
+
'.exe'
,
get_win_launcher
(
launcher_type
),
name
+
'.exe'
,
get_win_launcher
(
launcher_type
),
'b'
# write in binary mode
)
if
not
is_64bit
():
...
...
@@ -1969,9 +2028,11 @@ class WindowsExecutableLauncherWriter(WindowsScriptWriter):
m_name
=
name
+
'.exe.manifest'
yield
(
m_name
,
load_launcher_manifest
(
name
),
't'
)
# for backward-compatibility
get_script_args
=
ScriptWriter
.
get_script_args
def
get_win_launcher
(
type
):
"""
Load the Windows launcher (executable) suitable for launching a script.
...
...
@@ -1981,7 +2042,7 @@ def get_win_launcher(type):
Returns the executable as a byte string.
"""
launcher_fn
=
'%s.exe'
%
type
if
platform
.
machine
().
lower
()
==
'arm'
:
if
platform
.
machine
().
lower
()
==
'arm'
:
launcher_fn
=
launcher_fn
.
replace
(
"."
,
"-arm."
)
if
is_64bit
():
launcher_fn
=
launcher_fn
.
replace
(
"."
,
"-64."
)
...
...
@@ -1989,6 +2050,7 @@ def get_win_launcher(type):
launcher_fn
=
launcher_fn
.
replace
(
"."
,
"-32."
)
return
resource_string
(
'setuptools'
,
launcher_fn
)
def
load_launcher_manifest
(
name
):
manifest
=
pkg_resources
.
resource_string
(
__name__
,
'launcher manifest.xml'
)
if
PY2
:
...
...
@@ -1996,6 +2058,7 @@ def load_launcher_manifest(name):
else
:
return
manifest
.
decode
(
'utf-8'
)
%
vars
()
def
rmtree
(
path
,
ignore_errors
=
False
,
onerror
=
auto_chmod
):
"""Recursively delete a directory tree.
...
...
@@ -2031,19 +2094,23 @@ def rmtree(path, ignore_errors=False, onerror=auto_chmod):
except
os
.
error
:
onerror
(
os
.
rmdir
,
path
,
sys
.
exc_info
())
def
current_umask
():
tmp
=
os
.
umask
(
0o022
)
os
.
umask
(
tmp
)
return
tmp
def
bootstrap
():
# This function is called when setuptools*.egg is run using /bin/sh
import
setuptools
argv0
=
os
.
path
.
dirname
(
setuptools
.
__path__
[
0
])
sys
.
argv
[
0
]
=
argv0
sys
.
argv
.
append
(
argv0
)
main
()
def
main
(
argv
=
None
,
**
kw
):
from
setuptools
import
setup
from
setuptools.dist
import
Distribution
...
...
@@ -2070,16 +2137,16 @@ usage: %(script)s [options] requirement_or_url ...
class
DistributionWithoutHelpCommands
(
Distribution
):
common_usage
=
""
def
_show_help
(
self
,
*
args
,
**
kw
):
with_ei_usage
(
lambda
:
Distribution
.
_show_help
(
self
,
*
args
,
**
kw
))
def
_show_help
(
self
,
*
args
,
**
kw
):
with_ei_usage
(
lambda
:
Distribution
.
_show_help
(
self
,
*
args
,
**
kw
))
if
argv
is
None
:
argv
=
sys
.
argv
[
1
:]
with_ei_usage
(
lambda
:
setup
(
script_args
=
[
'-q'
,
'easy_install'
,
'-v'
]
+
argv
,
script_name
=
sys
.
argv
[
0
]
or
'easy_install'
,
with_ei_usage
(
lambda
:
setup
(
script_args
=
[
'-q'
,
'easy_install'
,
'-v'
]
+
argv
,
script_name
=
sys
.
argv
[
0
]
or
'easy_install'
,
distclass
=
DistributionWithoutHelpCommands
,
**
kw
)
)
setuptools/command/egg_info.py
View file @
8e3f9d32
...
...
@@ -2,21 +2,22 @@
Create a distribution's .egg-info directory and contents"""
from
distutils.filelist
import
FileList
as
_FileList
from
distutils.util
import
convert_path
from
distutils
import
log
import
distutils.errors
import
os
import
re
import
sys
from
setuptools
import
Command
import
distutils.errors
from
distutils
import
log
from
setuptools.command.sdist
import
sdist
from
setuptools.compat
import
basestring
,
PY3
,
StringIO
from
setuptools
import
svn_utils
from
distutils.util
import
convert_path
from
distutils.filelist
import
FileList
as
_FileList
from
pkg_resources
import
(
parse_requirements
,
safe_name
,
parse_version
,
safe_version
,
yield_lines
,
EntryPoint
,
iter_entry_points
,
to_filename
)
from
setuptools.command.sdist
import
walk_revctrl
from
pkg_resources
import
(
parse_requirements
,
safe_name
,
parse_version
,
safe_version
,
yield_lines
,
EntryPoint
,
iter_entry_points
,
to_filename
)
import
setuptools.unicode_utils
as
unicode_utils
...
...
@@ -52,6 +53,7 @@ class egg_info(Command):
def
save_version_info
(
self
,
filename
):
from
setuptools.command.setopt
import
edit_config
values
=
dict
(
egg_info
=
dict
(
tag_svn_revision
=
0
,
...
...
@@ -68,23 +70,25 @@ class egg_info(Command):
try
:
list
(
parse_requirements
(
'%s==%s'
%
(
self
.
egg_name
,
self
.
egg_version
))
parse_requirements
(
'%s==%s'
%
(
self
.
egg_name
,
self
.
egg_version
))
)
except
ValueError
:
raise
distutils
.
errors
.
DistutilsOptionError
(
"Invalid distribution name or version syntax: %s-%s"
%
(
self
.
egg_name
,
self
.
egg_version
)
(
self
.
egg_name
,
self
.
egg_version
)
)
if
self
.
egg_base
is
None
:
dirs
=
self
.
distribution
.
package_dir
self
.
egg_base
=
(
dirs
or
{}).
get
(
''
,
os
.
curdir
)
self
.
egg_base
=
(
dirs
or
{}).
get
(
''
,
os
.
curdir
)
self
.
ensure_dirname
(
'egg_base'
)
self
.
egg_info
=
to_filename
(
self
.
egg_name
)
+
'.egg-info'
self
.
egg_info
=
to_filename
(
self
.
egg_name
)
+
'.egg-info'
if
self
.
egg_base
!=
os
.
curdir
:
self
.
egg_info
=
os
.
path
.
join
(
self
.
egg_base
,
self
.
egg_info
)
if
'-'
in
self
.
egg_name
:
self
.
check_broken_egg_info
()
if
'-'
in
self
.
egg_name
:
self
.
check_broken_egg_info
()
# Set package version for the benefit of dumber commands
# (e.g. sdist, bdist_wininst, etc.)
...
...
@@ -96,7 +100,7 @@ class egg_info(Command):
# to the version info
#
pd
=
self
.
distribution
.
_patched_dist
if
pd
is
not
None
and
pd
.
key
==
self
.
egg_name
.
lower
():
if
pd
is
not
None
and
pd
.
key
==
self
.
egg_name
.
lower
():
pd
.
_version
=
self
.
egg_version
pd
.
_parsed_version
=
parse_version
(
self
.
egg_version
)
self
.
distribution
.
_patched_dist
=
None
...
...
@@ -154,7 +158,7 @@ class egg_info(Command):
installer
=
self
.
distribution
.
fetch_build_egg
for
ep
in
iter_entry_points
(
'egg_info.writers'
):
writer
=
ep
.
load
(
installer
=
installer
)
writer
(
self
,
ep
.
name
,
os
.
path
.
join
(
self
.
egg_info
,
ep
.
name
))
writer
(
self
,
ep
.
name
,
os
.
path
.
join
(
self
.
egg_info
,
ep
.
name
))
# Get rid of native_libs.txt if it was put there by older bdist_egg
nl
=
os
.
path
.
join
(
self
.
egg_info
,
"native_libs.txt"
)
...
...
@@ -166,12 +170,14 @@ class egg_info(Command):
def
tags
(
self
):
version
=
''
if
self
.
tag_build
:
version
+=
self
.
tag_build
version
+=
self
.
tag_build
if
self
.
tag_svn_revision
and
(
os
.
path
.
exists
(
'.svn'
)
or
os
.
path
.
exists
(
'PKG-INFO'
)
):
version
+=
'-r%s'
%
self
.
get_svn_revision
()
):
version
+=
'-r%s'
%
self
.
get_svn_revision
()
if
self
.
tag_date
:
import
time
version
+=
time
.
strftime
(
"-%Y%m%d"
)
return
version
...
...
@@ -181,27 +187,28 @@ class egg_info(Command):
def
find_sources
(
self
):
"""Generate SOURCES.txt manifest file"""
manifest_filename
=
os
.
path
.
join
(
self
.
egg_info
,
"SOURCES.txt"
)
manifest_filename
=
os
.
path
.
join
(
self
.
egg_info
,
"SOURCES.txt"
)
mm
=
manifest_maker
(
self
.
distribution
)
mm
.
manifest
=
manifest_filename
mm
.
run
()
self
.
filelist
=
mm
.
filelist
def
check_broken_egg_info
(
self
):
bei
=
self
.
egg_name
+
'.egg-info'
bei
=
self
.
egg_name
+
'.egg-info'
if
self
.
egg_base
!=
os
.
curdir
:
bei
=
os
.
path
.
join
(
self
.
egg_base
,
bei
)
if
os
.
path
.
exists
(
bei
):
log
.
warn
(
"-"
*
78
+
'
\
n
'
"-"
*
78
+
'
\
n
'
"Note: Your current .egg-info directory has a '-' in its name;"
'
\
n
this will not work correctly with "setup.py develop".
\
n
\
n
'
'Please rename %s to %s to correct this problem.
\
n
'
+
'-'
*
78
,
'Please rename %s to %s to correct this problem.
\
n
'
+
'-'
*
78
,
bei
,
self
.
egg_info
)
self
.
broken_egg_info
=
self
.
egg_info
self
.
egg_info
=
bei
# make it work for now
class
FileList
(
_FileList
):
"""File list that accepts only existing, platform-independent paths"""
...
...
@@ -229,29 +236,28 @@ class FileList(_FileList):
def
_safe_path
(
self
,
path
):
enc_warn
=
"'%s' not %s encodable -- skipping"
#To avoid accidental trans-codings errors, first to unicode
#
To avoid accidental trans-codings errors, first to unicode
u_path
=
unicode_utils
.
filesys_decode
(
path
)
if
u_path
is
None
:
log
.
warn
(
"'%s' in unexpected encoding -- skipping"
%
path
)
return
False
#Must ensure utf-8 encodability
#
Must ensure utf-8 encodability
utf8_path
=
unicode_utils
.
try_encode
(
u_path
,
"utf-8"
)
if
utf8_path
is
None
:
log
.
warn
(
enc_warn
,
path
,
'utf-8'
)
return
False
try
:
#accept is either way checks out
#
accept is either way checks out
if
os
.
path
.
exists
(
u_path
)
or
os
.
path
.
exists
(
utf8_path
):
return
True
#this will catch any encode errors decoding u_path
#
this will catch any encode errors decoding u_path
except
UnicodeEncodeError
:
log
.
warn
(
enc_warn
,
path
,
sys
.
getfilesystemencoding
())
class
manifest_maker
(
sdist
):
template
=
"MANIFEST.in"
def
initialize_options
(
self
):
...
...
@@ -287,7 +293,7 @@ class manifest_maker(sdist):
"""
self
.
filelist
.
_repair
()
#Now _repairs should encodability, but not unicode
#
Now _repairs should encodability, but not unicode
files
=
[
self
.
_manifest_normalize
(
f
)
for
f
in
self
.
filelist
.
files
]
msg
=
"writing manifest file '%s'"
%
self
.
manifest
self
.
execute
(
write_file
,
(
self
.
manifest
,
files
),
msg
)
...
...
@@ -314,7 +320,8 @@ class manifest_maker(sdist):
self
.
filelist
.
exclude_pattern
(
None
,
prefix
=
build
.
build_base
)
self
.
filelist
.
exclude_pattern
(
None
,
prefix
=
base_dir
)
sep
=
re
.
escape
(
os
.
sep
)
self
.
filelist
.
exclude_pattern
(
sep
+
r'(RCS|CVS|\
.s
vn)'
+
sep
,
is_regex
=
1
)
self
.
filelist
.
exclude_pattern
(
sep
+
r'(RCS|CVS|\
.s
vn)'
+
sep
,
is_regex
=
1
)
def
write_file
(
filename
,
contents
):
...
...
@@ -323,7 +330,7 @@ def write_file(filename, contents):
"""
contents
=
"
\
n
"
.
join
(
contents
)
#assuming the contents has been vetted for utf-8 encoding
#
assuming the contents has been vetted for utf-8 encoding
contents
=
contents
.
encode
(
"utf-8"
)
with
open
(
filename
,
"wb"
)
as
f
:
# always write POSIX-style manifest
...
...
@@ -343,10 +350,12 @@ def write_pkg_info(cmd, basename, filename):
finally
:
metadata
.
name
,
metadata
.
version
=
oldname
,
oldver
safe
=
getattr
(
cmd
.
distribution
,
'zip_safe'
,
None
)
safe
=
getattr
(
cmd
.
distribution
,
'zip_safe'
,
None
)
from
setuptools.command
import
bdist_egg
bdist_egg
.
write_safety_flag
(
cmd
.
egg_info
,
safe
)
def
warn_depends_obsolete
(
cmd
,
basename
,
filename
):
if
os
.
path
.
exists
(
filename
):
log
.
warn
(
...
...
@@ -361,6 +370,7 @@ def _write_requirements(stream, reqs):
lines
=
map
(
append_cr
,
lines
)
stream
.
writelines
(
lines
)
def
write_requirements
(
cmd
,
basename
,
filename
):
dist
=
cmd
.
distribution
data
=
StringIO
()
...
...
@@ -371,48 +381,52 @@ def write_requirements(cmd, basename, filename):
_write_requirements
(
data
,
extras_require
[
extra
])
cmd
.
write_or_delete_file
(
"requirements"
,
filename
,
data
.
getvalue
())
def
write_toplevel_names
(
cmd
,
basename
,
filename
):
pkgs
=
dict
.
fromkeys
(
[
k
.
split
(
'.'
,
1
)[
0
]
k
.
split
(
'.'
,
1
)[
0
]
for
k
in
cmd
.
distribution
.
iter_distribution_names
()
]
)
cmd
.
write_file
(
"top-level names"
,
filename
,
'
\
n
'
.
join
(
pkgs
)
+
'
\
n
'
)
cmd
.
write_file
(
"top-level names"
,
filename
,
'
\
n
'
.
join
(
pkgs
)
+
'
\
n
'
)
def
overwrite_arg
(
cmd
,
basename
,
filename
):
write_arg
(
cmd
,
basename
,
filename
,
True
)
def
write_arg
(
cmd
,
basename
,
filename
,
force
=
False
):
argname
=
os
.
path
.
splitext
(
basename
)[
0
]
value
=
getattr
(
cmd
.
distribution
,
argname
,
None
)
if
value
is
not
None
:
value
=
'
\
n
'
.
join
(
value
)
+
'
\
n
'
value
=
'
\
n
'
.
join
(
value
)
+
'
\
n
'
cmd
.
write_or_delete_file
(
argname
,
filename
,
value
,
force
)
def
write_entries
(
cmd
,
basename
,
filename
):
ep
=
cmd
.
distribution
.
entry_points
if
isinstance
(
ep
,
basestring
)
or
ep
is
None
:
if
isinstance
(
ep
,
basestring
)
or
ep
is
None
:
data
=
ep
elif
ep
is
not
None
:
data
=
[]
for
section
,
contents
in
sorted
(
ep
.
items
()):
if
not
isinstance
(
contents
,
basestring
):
if
not
isinstance
(
contents
,
basestring
):
contents
=
EntryPoint
.
parse_group
(
section
,
contents
)
contents
=
'
\
n
'
.
join
(
sorted
(
map
(
str
,
contents
.
values
())))
data
.
append
(
'[%s]
\
n
%s
\
n
\
n
'
%
(
section
,
contents
))
contents
=
'
\
n
'
.
join
(
sorted
(
map
(
str
,
contents
.
values
())))
data
.
append
(
'[%s]
\
n
%s
\
n
\
n
'
%
(
section
,
contents
))
data
=
''
.
join
(
data
)
cmd
.
write_or_delete_file
(
'entry points'
,
filename
,
data
,
True
)
def
get_pkg_info_revision
():
# See if we can get a -r### off of PKG-INFO, in case this is an sdist of
# a subversion revision
#
if
os
.
path
.
exists
(
'PKG-INFO'
):
f
=
open
(
'PKG-INFO'
,
'rU'
)
f
=
open
(
'PKG-INFO'
,
'rU'
)
for
line
in
f
:
match
=
re
.
match
(
r"Version:.*-r(\
d+)
\s*$"
,
line
)
if
match
:
...
...
setuptools/command/install.py
View file @
8e3f9d32
import
setuptools
from
distutils.errors
import
DistutilsArgError
import
inspect
import
glob
import
warnings
import
platform
import
distutils.command.install
as
orig
from
distutils.errors
import
DistutilsArgError
import
setuptools
# Prior to numpy 1.9, NumPy relies on the '_install' name, so provide it for
# now. See https://bitbucket.org/pypa/setuptools/issue/199/
_install
=
orig
.
install
class
install
(
orig
.
install
):
"""Use easy_install to install the package, w/dependencies"""
...
...
@@ -115,7 +117,9 @@ class install(orig.install):
cmd
.
run
()
setuptools
.
bootstrap_install_from
=
None
# XXX Python 3.1 doesn't see _nc if this is inside the class
install
.
sub_commands
=
[
cmd
for
cmd
in
orig
.
install
.
sub_commands
if
cmd
[
0
]
not
in
install
.
_nc
]
+
install
.
new_commands
install
.
sub_commands
=
(
[
cmd
for
cmd
in
orig
.
install
.
sub_commands
if
cmd
[
0
]
not
in
install
.
_nc
]
+
install
.
new_commands
)
setuptools/command/install_egg_info.py
View file @
8e3f9d32
from
distutils
import
log
,
dir_util
import
os
from
setuptools
import
Command
from
setuptools.archive_util
import
unpack_archive
from
distutils
import
log
,
dir_util
import
os
,
pkg_resources
import
pkg_resources
class
install_egg_info
(
Command
):
"""Install an .egg-info directory for the package"""
...
...
@@ -16,11 +19,12 @@ class install_egg_info(Command):
self
.
install_dir
=
None
def
finalize_options
(
self
):
self
.
set_undefined_options
(
'install_lib'
,(
'install_dir'
,
'install_dir'
))
self
.
set_undefined_options
(
'install_lib'
,
(
'install_dir'
,
'install_dir'
))
ei_cmd
=
self
.
get_finalized_command
(
"egg_info"
)
basename
=
pkg_resources
.
Distribution
(
None
,
None
,
ei_cmd
.
egg_name
,
ei_cmd
.
egg_version
).
egg_name
()
+
'.egg-info'
).
egg_name
()
+
'.egg-info'
self
.
source
=
ei_cmd
.
egg_info
self
.
target
=
os
.
path
.
join
(
self
.
install_dir
,
basename
)
self
.
outputs
=
[
self
.
target
]
...
...
@@ -31,11 +35,11 @@ class install_egg_info(Command):
if
os
.
path
.
isdir
(
self
.
target
)
and
not
os
.
path
.
islink
(
self
.
target
):
dir_util
.
remove_tree
(
self
.
target
,
dry_run
=
self
.
dry_run
)
elif
os
.
path
.
exists
(
self
.
target
):
self
.
execute
(
os
.
unlink
,
(
self
.
target
,),
"Removing "
+
self
.
target
)
self
.
execute
(
os
.
unlink
,
(
self
.
target
,),
"Removing "
+
self
.
target
)
if
not
self
.
dry_run
:
pkg_resources
.
ensure_directory
(
self
.
target
)
self
.
execute
(
self
.
copytree
,
(),
"Copying %s to %s"
%
(
self
.
source
,
self
.
target
)
self
.
execute
(
self
.
copytree
,
(),
"Copying %s to %s"
%
(
self
.
source
,
self
.
target
)
)
self
.
install_namespaces
()
...
...
@@ -44,50 +48,29 @@ class install_egg_info(Command):
def
copytree
(
self
):
# Copy the .egg-info tree to site-packages
def
skimmer
(
src
,
dst
):
def
skimmer
(
src
,
dst
):
# filter out source-control directories; note that 'src' is always
# a '/'-separated path, regardless of platform. 'dst' is a
# platform-specific path.
for
skip
in
'.svn/'
,
'CVS/'
:
if
src
.
startswith
(
skip
)
or
'/'
+
skip
in
src
:
for
skip
in
'.svn/'
,
'CVS/'
:
if
src
.
startswith
(
skip
)
or
'/'
+
skip
in
src
:
return
None
self
.
outputs
.
append
(
dst
)
log
.
debug
(
"Copying %s to %s"
,
src
,
dst
)
return
dst
unpack_archive
(
self
.
source
,
self
.
target
,
skimmer
)
unpack_archive
(
self
.
source
,
self
.
target
,
skimmer
)
def
install_namespaces
(
self
):
nsp
=
self
.
_get_all_ns_packages
()
if
not
nsp
:
return
filename
,
ext
=
os
.
path
.
splitext
(
self
.
target
)
filename
+=
'-nspkg.pth'
;
self
.
outputs
.
append
(
filename
)
log
.
info
(
"Installing %s"
,
filename
)
if
not
nsp
:
return
filename
,
ext
=
os
.
path
.
splitext
(
self
.
target
)
filename
+=
'-nspkg.pth'
self
.
outputs
.
append
(
filename
)
log
.
info
(
"Installing %s"
,
filename
)
if
not
self
.
dry_run
:
f
=
open
(
filename
,
'wt'
)
f
=
open
(
filename
,
'wt'
)
for
pkg
in
nsp
:
# ensure pkg is not a unicode string under Python 2.7
pkg
=
str
(
pkg
)
...
...
@@ -104,7 +87,8 @@ class install_egg_info(Command):
"*%(pth)r); "
"ie = os.path.exists(os.path.join(p,'__init__.py')); "
"m = not ie and "
"sys.modules.setdefault(%(pkg)r,types.ModuleType(%(pkg)r)); "
"sys.modules.setdefault(%(pkg)r,types.ModuleType"
"(%(pkg)r)); "
"mp = (m or []) and m.__dict__.setdefault('__path__',[]); "
"(p not in mp) and mp.append(p)%(trailer)s"
%
locals
()
...
...
@@ -118,8 +102,6 @@ class install_egg_info(Command):
while
pkg
:
nsp
[
'.'
.
join
(
pkg
)]
=
1
pkg
.
pop
()
nsp
=
list
(
nsp
)
nsp
=
list
(
nsp
)
nsp
.
sort
()
# set up shorter names first
return
nsp
setuptools/command/install_lib.py
View file @
8e3f9d32
import
distutils.command.install_lib
as
orig
import
os
class
install_lib
(
orig
.
install_lib
):
"""Don't add compiled flags to filenames of non-Python files"""
...
...
@@ -22,7 +23,7 @@ class install_lib(orig.install_lib):
while
parts
:
pkgdir
=
os
.
path
.
join
(
self
.
install_dir
,
*
parts
)
for
f
in
'__init__.py'
,
'__init__.pyc'
,
'__init__.pyo'
:
exclude
[
os
.
path
.
join
(
pkgdir
,
f
)]
=
1
exclude
[
os
.
path
.
join
(
pkgdir
,
f
)]
=
1
parts
.
pop
()
return
exclude
...
...
@@ -45,7 +46,8 @@ class install_lib(orig.install_lib):
def
pf
(
src
,
dst
):
if
dst
in
exclude
:
log
.
warn
(
"Skipping installation of %s (namespace package)"
,
dst
)
log
.
warn
(
"Skipping installation of %s (namespace package)"
,
dst
)
return
False
log
.
info
(
"copying %s -> %s"
,
src
,
os
.
path
.
dirname
(
dst
))
...
...
setuptools/command/install_scripts.py
View file @
8e3f9d32
from
distutils
import
log
import
distutils.command.install_scripts
as
orig
from
pkg_resources
import
Distribution
,
PathMetadata
,
ensure_directory
import
os
from
distutils
import
log
from
pkg_resources
import
Distribution
,
PathMetadata
,
ensure_directory
class
install_scripts
(
orig
.
install_scripts
):
"""Do normal script install, plus any egg_info wrapper scripts"""
...
...
@@ -29,7 +31,7 @@ class install_scripts(orig.install_scripts):
ei_cmd
.
egg_name
,
ei_cmd
.
egg_version
,
)
bs_cmd
=
self
.
get_finalized_command
(
'build_scripts'
)
executable
=
getattr
(
bs_cmd
,
'executable'
,
sys_executable
)
executable
=
getattr
(
bs_cmd
,
'executable'
,
sys_executable
)
is_wininst
=
getattr
(
self
.
get_finalized_command
(
"bdist_wininst"
),
'_is_running'
,
False
)
...
...
@@ -39,6 +41,7 @@ class install_scripts(orig.install_scripts):
def
write_script
(
self
,
script_name
,
contents
,
mode
=
"t"
,
*
ignored
):
"""Write an executable file to the scripts directory"""
from
setuptools.command.easy_install
import
chmod
,
current_umask
log
.
info
(
"Installing %s script to %s"
,
script_name
,
self
.
install_dir
)
target
=
os
.
path
.
join
(
self
.
install_dir
,
script_name
)
self
.
outfiles
.
append
(
target
)
...
...
@@ -46,7 +49,7 @@ class install_scripts(orig.install_scripts):
mask
=
current_umask
()
if
not
self
.
dry_run
:
ensure_directory
(
target
)
f
=
open
(
target
,
"w"
+
mode
)
f
=
open
(
target
,
"w"
+
mode
)
f
.
write
(
contents
)
f
.
close
()
chmod
(
target
,
0o777
-
mask
)
chmod
(
target
,
0o777
-
mask
)
setuptools/command/launcher manifest.xml
View file @
8e3f9d32
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly
xmlns=
"urn:schemas-microsoft-com:asm.v1"
manifestVersion=
"1.0"
>
<assemblyIdentity
version=
"1.0.0.0"
<assemblyIdentity
version=
"1.0.0.0"
processorArchitecture=
"X86"
name=
"%(name)s"
type=
"win32"
/>
...
...
setuptools/command/register.py
View file @
8e3f9d32
import
distutils.command.register
as
orig
class
register
(
orig
.
register
):
__doc__
=
orig
.
register
.
__doc__
...
...
setuptools/command/rotate.py
View file @
8e3f9d32
import
os
from
setuptools
import
Command
from
setuptools.compat
import
basestring
from
distutils.util
import
convert_path
from
distutils
import
log
from
distutils.errors
import
DistutilsOptionError
import
os
from
setuptools
import
Command
from
setuptools.compat
import
basestring
class
rotate
(
Command
):
"""Delete older distributions"""
...
...
@@ -38,21 +40,22 @@ class rotate(Command):
self
.
match
=
[
convert_path
(
p
.
strip
())
for
p
in
self
.
match
.
split
(
','
)
]
self
.
set_undefined_options
(
'bdist'
,(
'dist_dir'
,
'dist_dir'
))
self
.
set_undefined_options
(
'bdist'
,
(
'dist_dir'
,
'dist_dir'
))
def
run
(
self
):
self
.
run_command
(
"egg_info"
)
from
glob
import
glob
for
pattern
in
self
.
match
:
pattern
=
self
.
distribution
.
get_name
()
+
'*'
+
pattern
files
=
glob
(
os
.
path
.
join
(
self
.
dist_dir
,
pattern
))
files
=
[(
os
.
path
.
getmtime
(
f
),
f
)
for
f
in
files
]
pattern
=
self
.
distribution
.
get_name
()
+
'*'
+
pattern
files
=
glob
(
os
.
path
.
join
(
self
.
dist_dir
,
pattern
))
files
=
[(
os
.
path
.
getmtime
(
f
),
f
)
for
f
in
files
]
files
.
sort
()
files
.
reverse
()
log
.
info
(
"%d file(s) matching %s"
,
len
(
files
),
pattern
)
files
=
files
[
self
.
keep
:]
for
(
t
,
f
)
in
files
:
for
(
t
,
f
)
in
files
:
log
.
info
(
"Deleting %s"
,
f
)
if
not
self
.
dry_run
:
os
.
unlink
(
f
)
setuptools/command/saveopts.py
View file @
8e3f9d32
import
distutils
,
os
from
setuptools
import
Command
from
setuptools.command.setopt
import
edit_config
,
option_base
class
saveopts
(
option_base
):
"""Save command-line options to a file"""
...
...
@@ -13,12 +12,11 @@ class saveopts(option_base):
for
cmd
in
dist
.
command_options
:
if
cmd
==
'saveopts'
:
if
cmd
==
'saveopts'
:
continue
# don't save our own options!
for
opt
,
(
src
,
val
)
in
dist
.
get_option_dict
(
cmd
).
items
():
if
src
==
"command line"
:
settings
.
setdefault
(
cmd
,{})[
opt
]
=
val
for
opt
,
(
src
,
val
)
in
dist
.
get_option_dict
(
cmd
).
items
():
if
src
==
"command line"
:
settings
.
setdefault
(
cmd
,
{})[
opt
]
=
val
edit_config
(
self
.
filename
,
settings
,
self
.
dry_run
)
setuptools/command/sdist.py
View file @
8e3f9d32
from
glob
import
glob
from
distutils.util
import
convert_path
from
distutils
import
log
import
distutils.command.sdist
as
orig
import
os
import
re
import
sys
from
glob
import
glob
import
pkg_resources
import
distutils.command.sdist
as
orig
from
distutils.util
import
convert_path
from
distutils
import
log
from
setuptools
import
svn_utils
from
setuptools.compat
import
PY3
import
pkg_resources
READMES
=
(
'README'
,
'README.rst'
,
'README.txt'
)
...
...
@@ -20,7 +20,7 @@ def walk_revctrl(dirname=''):
yield
item
#TODO will need test case
#
TODO will need test case
class
re_finder
(
object
):
"""
Finder that locates files based on entries in a file matched by a
...
...
@@ -33,7 +33,7 @@ class re_finder(object):
self
.
entries_path
=
convert_path
(
path
)
def
_finder
(
self
,
dirname
,
filename
):
f
=
open
(
filename
,
'rU'
)
f
=
open
(
filename
,
'rU'
)
try
:
data
=
f
.
read
()
finally
:
...
...
@@ -51,12 +51,13 @@ class re_finder(object):
if
not
os
.
path
.
isfile
(
path
):
# entries file doesn't exist
return
for
path
in
self
.
_finder
(
dirname
,
path
):
for
path
in
self
.
_finder
(
dirname
,
path
):
if
os
.
path
.
isfile
(
path
):
yield
path
elif
os
.
path
.
isdir
(
path
):
for
item
in
self
.
find
(
path
):
yield
item
__call__
=
find
...
...
@@ -93,7 +94,7 @@ class sdist(orig.sdist):
self.run_command('egg_info')
ei_cmd = self.get_finalized_command('egg_info')
self.filelist = ei_cmd.filelist
self.filelist.append(os.path.join(ei_cmd.egg_info,'SOURCES.txt'))
self.filelist.append(os.path.join(ei_cmd.egg_info,
'SOURCES.txt'))
self.check_readme()
# Run sub commands
...
...
@@ -103,12 +104,13 @@ class sdist(orig.sdist):
# Call check_metadata only if no 'check' command
# (distutils <= 2.6)
import distutils.command
if 'check' not in distutils.command.__all__:
self.check_metadata()
self.make_distribution()
dist_files = getattr(self.distribution,
'dist_files',
[])
dist_files = getattr(self.distribution,
'dist_files',
[])
for file in self.archive_files:
data = ('sdist', '', file)
if data not in dist_files:
...
...
@@ -124,13 +126,14 @@ class sdist(orig.sdist):
except:
sys.exc_info()[2].tb_next.tb_frame.f_locals['template'].close()
raise
# Beginning with Python 2.7.2, 3.1.4, and 3.2.1, this leaky file handle
# has been fixed, so only override the method if we're using an earlier
# Python.
has_leaky_handle = (
sys.version_info < (2,
7,
2)
or (3,
0) <= sys.version_info < (3,1,
4)
or (3,
2) <= sys.version_info < (3,2,
1)
sys.version_info < (2,
7,
2)
or (3,
0) <= sys.version_info < (3, 1,
4)
or (3,
2) <= sys.version_info < (3, 2,
1)
)
if has_leaky_handle:
read_template = __read_template_hack
...
...
@@ -194,7 +197,8 @@ class sdist(orig.sdist):
return
else:
self.warn(
"
standard
file
not
found
:
should
have
one
of
" +', '.join(READMES)
"
standard
file
not
found
:
should
have
one
of
" +
', '.join(READMES)
)
def make_release_tree(self, base_dir, files):
...
...
@@ -202,7 +206,7 @@ class sdist(orig.sdist):
# Save any egg_info command line options used to create this sdist
dest = os.path.join(base_dir, 'setup.cfg')
if hasattr(os,'link') and os.path.exists(dest):
if hasattr(os,
'link') and os.path.exists(dest):
# unlink and re-copy, since it might be hard-linked, and
# we don't want to change the source version
os.unlink(dest)
...
...
@@ -220,7 +224,8 @@ class sdist(orig.sdist):
first_line = fp.readline()
finally:
fp.close()
return first_line != '# file GENERATED by distutils, do NOT edit
\
n
'.encode()
return (first_line !=
'# file GENERATED by distutils, do NOT edit
\
n
'.encode())
def read_manifest(self):
"""Read the manifest file (named by 'self.manifest') and use it to
...
...
setuptools/command/setopt.py
View file @
8e3f9d32
import
os
import
distutils
from
setuptools
import
Command
from
distutils.util
import
convert_path
from
distutils
import
log
from
distutils.errors
import
DistutilsOptionError
import
distutils
import
os
from
setuptools
import
Command
__all__
=
[
'config_file'
,
'edit_config'
,
'option_base'
,
'setopt'
]
...
...
@@ -13,19 +15,20 @@ def config_file(kind="local"):
`kind` must be one of "local", "global", or "user"
"""
if
kind
==
'local'
:
if
kind
==
'local'
:
return
'setup.cfg'
if
kind
==
'global'
:
if
kind
==
'global'
:
return
os
.
path
.
join
(
os
.
path
.
dirname
(
distutils
.
__file__
),
'distutils.cfg'
os
.
path
.
dirname
(
distutils
.
__file__
),
'distutils.cfg'
)
if
kind
==
'user'
:
dot
=
os
.
name
==
'posix'
and
'.'
or
''
if
kind
==
'user'
:
dot
=
os
.
name
==
'posix'
and
'.'
or
''
return
os
.
path
.
expanduser
(
convert_path
(
"~/%spydistutils.cfg"
%
dot
))
raise
ValueError
(
"config_file() type must be 'local', 'global', or 'user'"
,
kind
)
def
edit_config
(
filename
,
settings
,
dry_run
=
False
):
"""Edit a configuration file to include `settings`
...
...
@@ -35,6 +38,7 @@ def edit_config(filename, settings, dry_run=False):
A setting of ``None`` means to delete that setting.
"""
from
setuptools.compat
import
ConfigParser
log
.
debug
(
"Reading configuration from %s"
,
filename
)
opts
=
ConfigParser
.
RawConfigParser
()
opts
.
read
([
filename
])
...
...
@@ -46,13 +50,13 @@ def edit_config(filename, settings, dry_run=False):
if
not
opts
.
has_section
(
section
):
log
.
debug
(
"Adding new section [%s] to %s"
,
section
,
filename
)
opts
.
add_section
(
section
)
for
option
,
value
in
options
.
items
():
for
option
,
value
in
options
.
items
():
if
value
is
None
:
log
.
debug
(
"Deleting %s.%s from %s"
,
section
,
option
,
filename
)
opts
.
remove_option
(
section
,
option
)
opts
.
remove_option
(
section
,
option
)
if
not
opts
.
options
(
section
):
log
.
info
(
"Deleting empty [%s] section from %s"
,
section
,
filename
)
...
...
@@ -62,13 +66,14 @@ def edit_config(filename, settings, dry_run=False):
"Setting %s.%s to %r in %s"
,
section
,
option
,
value
,
filename
)
opts
.
set
(
section
,
option
,
value
)
opts
.
set
(
section
,
option
,
value
)
log
.
info
(
"Writing %s"
,
filename
)
if
not
dry_run
:
with
open
(
filename
,
'w'
)
as
f
:
opts
.
write
(
f
)
class
option_base
(
Command
):
"""Abstract base class for commands that mess with config files"""
...
...
@@ -100,7 +105,7 @@ class option_base(Command):
filenames
.
append
(
self
.
filename
)
if
not
filenames
:
filenames
.
append
(
config_file
(
'local'
))
if
len
(
filenames
)
>
1
:
if
len
(
filenames
)
>
1
:
raise
DistutilsOptionError
(
"Must specify only one configuration file option"
,
filenames
...
...
@@ -139,7 +144,7 @@ class setopt(option_base):
def
run
(
self
):
edit_config
(
self
.
filename
,
{
self
.
command
:
{
self
.
option
.
replace
(
'-'
,
'_'
):
self
.
set_value
}
self
.
command
:
{
self
.
option
.
replace
(
'-'
,
'_'
):
self
.
set_value
}
},
self
.
dry_run
)
setuptools/command/test.py
View file @
8e3f9d32
import
unittest
from
unittest
import
TestLoader
from
setuptools
import
Command
from
distutils.errors
import
DistutilsOptionError
from
unittest
import
TestLoader
import
unittest
import
sys
from
pkg_resources
import
(
resource_listdir
,
resource_exists
,
normalize_path
,
working_set
,
_namespace_packages
,
add_activation_listener
,
require
,
EntryPoint
)
from
pkg_resources
import
(
resource_listdir
,
resource_exists
,
normalize_path
,
working_set
,
_namespace_packages
,
add_activation_listener
,
require
,
EntryPoint
)
from
setuptools
import
Command
from
setuptools.compat
import
PY3
from
setuptools.py31compat
import
unittest_main
class
ScanningLoader
(
TestLoader
):
def
loadTestsFromModule
(
self
,
module
):
"""Return a suite of all tests cases contained in the given module
...
...
@@ -34,7 +32,7 @@ class ScanningLoader(TestLoader):
submodule
=
module
.
__name__
+
'.'
+
file
[:
-
3
]
else
:
if
resource_exists
(
module
.
__name__
,
file
+
'/__init__.py'
):
submodule
=
module
.
__name__
+
'.'
+
file
submodule
=
module
.
__name__
+
'.'
+
file
else
:
continue
tests
.
append
(
self
.
loadTestsFromName
(
submodule
))
...
...
@@ -46,14 +44,13 @@ class ScanningLoader(TestLoader):
class
test
(
Command
):
"""Command to run unit tests after in-place build"""
description
=
"run unit tests after in-place build"
user_options
=
[
(
'test-module='
,
'm'
,
"Run 'test_suite' in specified module"
),
(
'test-suite='
,
's'
,
(
'test-module='
,
'm'
,
"Run 'test_suite' in specified module"
),
(
'test-suite='
,
's'
,
"Test suite to run (e.g. 'some_module.test_suite')"
),
(
'test-runner='
,
'r'
,
"Test runner to use"
),
]
...
...
@@ -79,7 +76,7 @@ class test(Command):
self
.
test_args
=
[
self
.
test_suite
]
if
self
.
verbose
:
self
.
test_args
.
insert
(
0
,
'--verbose'
)
self
.
test_args
.
insert
(
0
,
'--verbose'
)
if
self
.
test_loader
is
None
:
self
.
test_loader
=
getattr
(
self
.
distribution
,
'test_loader'
,
None
)
if
self
.
test_loader
is
None
:
...
...
@@ -132,7 +129,8 @@ class test(Command):
def
run
(
self
):
if
self
.
distribution
.
install_requires
:
self
.
distribution
.
fetch_build_eggs
(
self
.
distribution
.
install_requires
)
self
.
distribution
.
fetch_build_eggs
(
self
.
distribution
.
install_requires
)
if
self
.
distribution
.
tests_require
:
self
.
distribution
.
fetch_build_eggs
(
self
.
distribution
.
tests_require
)
...
...
@@ -161,7 +159,7 @@ class test(Command):
list
(
map
(
sys
.
modules
.
__delitem__
,
del_modules
))
unittest_main
(
None
,
None
,
[
unittest
.
__file__
]
+
self
.
test_args
,
None
,
None
,
[
unittest
.
__file__
]
+
self
.
test_args
,
testLoader
=
self
.
_resolve_as_ep
(
self
.
test_loader
),
testRunner
=
self
.
_resolve_as_ep
(
self
.
test_runner
),
)
...
...
setuptools/command/upload_docs.py
View file @
8e3f9d32
...
...
@@ -5,6 +5,10 @@ Implements a Distutils 'upload_docs' subcommand (upload documentation to
PyPI's pythonhosted.org).
"""
from
base64
import
standard_b64encode
from
distutils
import
log
from
distutils.errors
import
DistutilsOptionError
from
distutils.command.upload
import
upload
import
os
import
socket
import
zipfile
...
...
@@ -12,14 +16,9 @@ import tempfile
import
sys
import
shutil
from
base64
import
standard_b64encode
from
setuptools.compat
import
httplib
,
urlparse
,
unicode
,
iteritems
,
PY3
from
pkg_resources
import
iter_entry_points
from
distutils
import
log
from
distutils.errors
import
DistutilsOptionError
from
distutils.command.upload
import
upload
from
setuptools.compat
import
httplib
,
urlparse
,
unicode
,
iteritems
,
PY3
errors
=
'surrogateescape'
if
PY3
else
'strict'
...
...
@@ -33,7 +32,6 @@ def b(s, encoding='utf-8'):
class
upload_docs
(
upload
):
description
=
'Upload documentation to PyPI'
user_options
=
[
...
...
@@ -159,7 +157,7 @@ class upload_docs(upload):
elif
schema
==
'https'
:
conn
=
httplib
.
HTTPSConnection
(
netloc
)
else
:
raise
AssertionError
(
"unsupported schema "
+
schema
)
raise
AssertionError
(
"unsupported schema "
+
schema
)
data
=
''
try
:
...
...
@@ -190,4 +188,4 @@ class upload_docs(upload):
self
.
announce
(
'Upload failed (%s): %s'
%
(
r
.
status
,
r
.
reason
),
log
.
ERROR
)
if
self
.
show_response
:
print
(
'-'
*
75
,
r
.
read
(),
'-'
*
75
)
print
(
'-'
*
75
,
r
.
read
(),
'-'
*
75
)
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