summaryrefslogtreecommitdiff
path: root/setuptools/command
diff options
context:
space:
mode:
Diffstat (limited to 'setuptools/command')
-rw-r--r--setuptools/command/bdist_egg.py16
-rwxr-xr-xsetuptools/command/bdist_wininst.py67
-rw-r--r--setuptools/command/build_ext.py44
-rwxr-xr-xsetuptools/command/easy_install.py58
-rwxr-xr-xsetuptools/command/egg_info.py25
-rwxr-xr-xsetuptools/command/sdist.py75
-rw-r--r--setuptools/command/test.py2
-rwxr-xr-xsetuptools/command/upload.py2
-rw-r--r--setuptools/command/upload_docs.py16
9 files changed, 181 insertions, 124 deletions
diff --git a/setuptools/command/bdist_egg.py b/setuptools/command/bdist_egg.py
index 875971f0..c5776158 100644
--- a/setuptools/command/bdist_egg.py
+++ b/setuptools/command/bdist_egg.py
@@ -7,10 +7,14 @@ import sys, os, marshal
from setuptools import Command
from distutils.dir_util import remove_tree, mkpath
try:
- from distutils.sysconfig import get_python_version, get_python_lib
+ # Python 2.7 or >=3.2
+ from sysconfig import get_path, get_python_version
+ def _get_purelib():
+ return get_path("purelib")
except ImportError:
- from sysconfig import get_python_version
- from distutils.sysconfig import get_python_lib
+ 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
@@ -131,7 +135,7 @@ class bdist_egg(Command):
# 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_python_lib()))
+ site_packages = os.path.normcase(os.path.realpath(_get_purelib()))
old, self.distribution.data_files = self.distribution.data_files,[]
for item in old:
@@ -171,12 +175,13 @@ class bdist_egg(Command):
def run(self):
# Generate metadata first
self.run_command("egg_info")
-
# We run install_lib before install_data, because some data hacks
# pull their data path from the install_lib command.
log.info("installing library code to %s" % self.bdist_dir)
instcmd = self.get_finalized_command('install')
old_root = instcmd.root; instcmd.root = None
+ if self.distribution.has_c_libraries() and not self.skip_build:
+ self.run_command('build_clib')
cmd = self.call_command('install_lib', warn_dir=0)
instcmd.root = old_root
@@ -196,7 +201,6 @@ class bdist_egg(Command):
to_compile.extend(self.make_init_files())
if to_compile:
cmd.byte_compile(to_compile)
-
if self.distribution.data_files:
self.do_install_data()
diff --git a/setuptools/command/bdist_wininst.py b/setuptools/command/bdist_wininst.py
index 93e6846d..e8521f83 100755
--- a/setuptools/command/bdist_wininst.py
+++ b/setuptools/command/bdist_wininst.py
@@ -2,26 +2,24 @@ from distutils.command.bdist_wininst import bdist_wininst as _bdist_wininst
import os, sys
class bdist_wininst(_bdist_wininst):
+ _good_upload = _bad_upload = None
def create_exe(self, arcname, fullname, bitmap=None):
_bdist_wininst.create_exe(self, arcname, fullname, bitmap)
- dist_files = getattr(self.distribution, 'dist_files', [])
-
+ installer_name = self.get_installer_filename(fullname)
if self.target_version:
- installer_name = os.path.join(self.dist_dir,
- "%s.win32-py%s.exe" %
- (fullname, self.target_version))
pyversion = self.target_version
-
- # fix 2.5 bdist_wininst ignoring --target-version spec
- bad = ('bdist_wininst','any',installer_name)
- if bad in dist_files:
- dist_files.remove(bad)
+ # fix 2.5+ bdist_wininst ignoring --target-version spec
+ self._bad_upload = ('bdist_wininst', 'any', installer_name)
else:
- installer_name = os.path.join(self.dist_dir,
- "%s.win32.exe" % fullname)
pyversion = 'any'
- good = ('bdist_wininst', pyversion, installer_name)
+ self._good_upload = ('bdist_wininst', pyversion, installer_name)
+
+ def _fix_upload_names(self):
+ good, bad = self._good_upload, self._bad_upload
+ dist_files = getattr(self.distribution, 'dist_files', [])
+ if bad in dist_files:
+ dist_files.remove(bad)
if good not in dist_files:
dist_files.append(good)
@@ -36,6 +34,49 @@ class bdist_wininst(_bdist_wininst):
self._is_running = True
try:
_bdist_wininst.run(self)
+ self._fix_upload_names()
finally:
self._is_running = False
+
+ if not hasattr(_bdist_wininst, 'get_installer_filename'):
+ def get_installer_filename(self, fullname):
+ # Factored out to allow overriding in subclasses
+ if self.target_version:
+ # if we create an installer for a specific python version,
+ # it's better to include this in the name
+ installer_name = os.path.join(self.dist_dir,
+ "%s.win32-py%s.exe" %
+ (fullname, self.target_version))
+ else:
+ installer_name = os.path.join(self.dist_dir,
+ "%s.win32.exe" % fullname)
+ return installer_name
+ # get_installer_filename()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/setuptools/command/build_ext.py b/setuptools/command/build_ext.py
index 4a94572c..50a039ce 100644
--- a/setuptools/command/build_ext.py
+++ b/setuptools/command/build_ext.py
@@ -9,9 +9,15 @@ import os, 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, get_config_var
-get_config_var("LDSHARED") # make sure _config_vars is initialized
-from distutils.sysconfig import _config_vars
+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 *
@@ -82,17 +88,15 @@ class build_ext(_build_ext):
def get_ext_filename(self, fullname):
filename = _build_ext.get_ext_filename(self,fullname)
- if fullname not in self.ext_map:
- return filename
- ext = self.ext_map[fullname]
- if isinstance(ext,Library):
- fn, ext = os.path.splitext(filename)
- 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)
- else:
- return filename
+ if fullname in self.ext_map:
+ ext = self.ext_map[fullname]
+ if isinstance(ext,Library):
+ fn, ext = os.path.splitext(filename)
+ 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)
+ return filename
def initialize_options(self):
_build_ext.initialize_options(self)
@@ -133,16 +137,16 @@ class build_ext(_build_ext):
compiler=self.compiler, dry_run=self.dry_run, force=self.force
)
if sys.platform == "darwin":
- tmp = _config_vars.copy()
+ 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['CCSHARED'] = " -dynamiclib"
- _config_vars['SO'] = ".dylib"
+ _CONFIG_VARS['LDSHARED'] = "gcc -Wl,-x -dynamiclib -undefined dynamic_lookup"
+ _CONFIG_VARS['CCSHARED'] = " -dynamiclib"
+ _CONFIG_VARS['SO'] = ".dylib"
customize_compiler(compiler)
finally:
- _config_vars.clear()
- _config_vars.update(tmp)
+ _CONFIG_VARS.clear()
+ _CONFIG_VARS.update(tmp)
else:
customize_compiler(compiler)
diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py
index 50339e8f..3194644e 100755
--- a/setuptools/command/easy_install.py
+++ b/setuptools/command/easy_install.py
@@ -7,7 +7,7 @@ A tool for doing automatic download/extract/build of distutils-based Python
packages. For detailed documentation, see the accompanying EasyInstall.txt
file, or visit the `EasyInstall home page`__.
-__ http://packages.python.org/distribute/easy_install.html
+__ https://pythonhosted.org/setuptools/easy_install.html
"""
import sys
@@ -25,9 +25,22 @@ import pkg_resources
from setuptools import Command, _dont_write_bytecode
from setuptools.sandbox import run_setup
from distutils import log, dir_util
+try:
+ # Python 2.7 or >=3.2
+ from sysconfig import get_config_vars, get_path
+ def _get_platlib():
+ return get_path("platlib")
+ def _get_purelib():
+ return get_path("purelib")
+except ImportError:
+ from distutils.sysconfig import get_config_vars, get_python_lib
+ def _get_platlib():
+ return get_python_lib(True)
+ def _get_purelib():
+ return get_python_lib(False)
+
from distutils.util import get_platform
from distutils.util import convert_path, subst_vars
-from distutils.sysconfig import get_python_lib, get_config_vars
from distutils.errors import DistutilsArgError, DistutilsOptionError, \
DistutilsError, DistutilsPlatformError
from distutils.command.install import INSTALL_SCHEMES, SCHEME_KEYS
@@ -45,7 +58,10 @@ from pkg_resources import yield_lines, normalize_path, resource_string, \
DistributionNotFound, VersionConflict, \
DEVELOP_DIST
-sys_executable = os.path.normpath(sys.executable)
+if '__VENV_LAUNCHER__' in os.environ:
+ sys_executable = os.environ['__VENV_LAUNCHER__']
+else:
+ sys_executable = os.path.normpath(sys.executable)
__all__ = [
'samefile', 'easy_install', 'PthDistributions', 'extract_wininst_cfg',
@@ -204,7 +220,7 @@ class easy_install(Command):
def finalize_options(self):
if self.version:
- print('distribute %s' % get_distribution('distribute').version)
+ print('setuptools %s' % get_distribution('setuptools').version)
sys.exit()
py_version = sys.version.split()[0]
@@ -269,6 +285,8 @@ class easy_install(Command):
self.script_dir = self.install_scripts
# default --record from the install command
self.set_undefined_options('install', ('record', 'record'))
+ # Should this be moved to the if statement below? It's not used
+ # elsewhere
normpath = map(normalize_path, sys.path)
self.all_site_dirs = get_site_dirs()
if self.site_dirs is not None:
@@ -285,7 +303,7 @@ class easy_install(Command):
else:
self.all_site_dirs.append(normalize_path(d))
if not self.editable: self.check_site_dir()
- self.index_url = self.index_url or "http://pypi.python.org/simple"
+ 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):
if path_item not in self.shadow_path:
@@ -404,7 +422,7 @@ class easy_install(Command):
# Is it a configured, PYTHONPATH, implicit, or explicit site dir?
is_site_dir = instdir in self.all_site_dirs
- if not is_site_dir:
+ if not is_site_dir and not self.multi_version:
# No? Then directly test whether it does .pth file processing
is_site_dir = self.check_pth_processing()
else:
@@ -469,7 +487,7 @@ variable.
For information on other options, you may wish to consult the
documentation at:
- http://packages.python.org/distribute/easy_install.html
+ https://pythonhosted.org/setuptools/easy_install.html
Please make the appropriate changes for your system and try again.
"""
@@ -592,7 +610,6 @@ Please make the appropriate changes for your system and try again.
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:
@@ -663,8 +680,7 @@ Please make the appropriate changes for your system and try again.
self.update_pth(dist)
self.package_index.add(dist)
self.local_index.add(dist)
- if not self.editable:
- self.install_egg_scripts(dist)
+ self.install_egg_scripts(dist)
self.installed_projects[dist.key] = dist
log.info(self.installation_report(requirement, dist, *info))
if (dist.has_metadata('dependency_links.txt') and
@@ -714,7 +730,7 @@ Please make the appropriate changes for your system and try again.
return True
if not dist.has_metadata('zip-safe'):
return True
- return True
+ return False
def maybe_move(self, spec, dist_filename, setup_base):
dst = os.path.join(self.build_directory, spec.key)
@@ -1175,7 +1191,8 @@ See the setuptools documentation for the "develop" command for more info.
if not self.dry_run:
self.pth_file.save()
- if dist.key=='distribute':
+
+ 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')
@@ -1195,7 +1212,6 @@ See the setuptools documentation for the "develop" command for more info.
def pf(src,dst):
if dst.endswith('.py') and not src.startswith('EGG-INFO/'):
to_compile.append(dst)
- to_chmod.append(dst)
elif dst.endswith('.dll') or dst.endswith('.so'):
to_chmod.append(dst)
self.unpack_progress(src,dst)
@@ -1234,6 +1250,7 @@ See the setuptools documentation for the "develop" command for more info.
+
def no_default_version_msg(self):
return """bad install directory or PYTHONPATH
@@ -1260,7 +1277,7 @@ Here are some of your options for correcting the problem:
* You can set up the installation directory to support ".pth" files by
using one of the approaches described here:
- http://packages.python.org/distribute/easy_install.html#custom-installation-locations
+ https://pythonhosted.org/setuptools/easy_install.html#custom-installation-locations
Please make the appropriate changes for your system and try again.""" % (
self.install_dir, os.environ.get('PYTHONPATH','')
@@ -1405,8 +1422,7 @@ def get_site_dirs():
'Python',
sys.version[:3],
'site-packages'))
- for plat_specific in (0,1):
- site_lib = get_python_lib(plat_specific)
+ for site_lib in (_get_purelib(), _get_platlib()):
if site_lib not in sitedirs: sitedirs.append(site_lib)
if HAS_USER_SITE:
@@ -1519,7 +1535,7 @@ def get_exe_prefixes(exe_filename):
('PURELIB/', ''), ('PLATLIB/pywin32_system32', ''),
('PLATLIB/', ''),
('SCRIPTS/', 'EGG-INFO/scripts/'),
- ('DATA/LIB/site-packages', ''),
+ ('DATA/lib/site-packages', ''),
]
z = zipfile.ZipFile(exe_filename)
try:
@@ -1851,7 +1867,7 @@ def get_script_args(dist, executable=sys_executable, wininst=False):
ext = '-script.py'
old = ['.py','.pyc','.pyo']
new_header = re.sub('(?i)pythonw.exe','python.exe',header)
- if os.path.exists(new_header[2:-1]) or sys.platform!='win32':
+ if os.path.exists(new_header[2:-1].strip('"')) or sys.platform!='win32':
hdr = new_header
else:
hdr = header
@@ -1970,12 +1986,6 @@ usage: %(script)s [options] requirement_or_url ...
def _show_help(self,*args,**kw):
with_ei_usage(lambda: Distribution._show_help(self,*args,**kw))
- def find_config_files(self):
- files = Distribution.find_config_files(self)
- if 'setup.cfg' in files:
- files.remove('setup.cfg')
- return files
-
if argv is None:
argv = sys.argv[1:]
diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py
index 12acc422..642687b2 100755
--- a/setuptools/command/egg_info.py
+++ b/setuptools/command/egg_info.py
@@ -211,7 +211,8 @@ class egg_info(Command):
- def get_svn_revision(self):
+ @staticmethod
+ def get_svn_revision():
revision = 0
urlre = re.compile('url="([^"]+)"')
revre = re.compile('committed-rev="(\d+)"')
@@ -225,18 +226,21 @@ class egg_info(Command):
data = f.read()
f.close()
- if data.startswith('10') or data.startswith('9') or data.startswith('8'):
+ if data.startswith('<?xml'):
+ dirurl = urlre.search(data).group(1) # get repository URL
+ localrev = max([int(m.group(1)) for m in revre.finditer(data)]+[0])
+ else:
+ try: svnver = int(data.splitlines()[0])
+ except: svnver=-1
+ if svnver<8:
+ log.warn("unrecognized .svn/entries format; skipping %s", base)
+ dirs[:] = []
+ continue
+
data = list(map(str.splitlines,data.split('\n\x0c\n')))
del data[0][0] # get rid of the '8' or '9' or '10'
dirurl = data[0][3]
localrev = max([int(d[9]) for d in data if len(d)>9 and d[9]]+[0])
- elif data.startswith('<?xml'):
- dirurl = urlre.search(data).group(1) # get repository URL
- localrev = max([int(m.group(1)) for m in revre.finditer(data)]+[0])
- else:
- log.warn("unrecognized .svn/entries format; skipping %s", base)
- dirs[:] = []
- continue
if base==os.curdir:
base_url = dirurl+'/' # save the root url
elif not dirurl.startswith(base_url):
@@ -249,9 +253,6 @@ class egg_info(Command):
-
-
-
def find_sources(self):
"""Generate SOURCES.txt manifest file"""
manifest_filename = os.path.join(self.egg_info,"SOURCES.txt")
diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py
index 6f3f48c8..39cd6043 100755
--- a/setuptools/command/sdist.py
+++ b/setuptools/command/sdist.py
@@ -1,6 +1,7 @@
from distutils.command.sdist import sdist as _sdist
from distutils.util import convert_path
from distutils import log
+from glob import glob
import os, re, sys, pkg_resources
from glob import glob
@@ -41,7 +42,6 @@ def joinpath(prefix,suffix):
-
def walk_revctrl(dirname=''):
"""Find all files under revision control"""
for ep in pkg_resources.iter_entry_points('setuptools.file_finders'):
@@ -89,18 +89,22 @@ def entries_finder(dirname, filename):
f = open(filename,'rU')
data = f.read()
f.close()
- if data.startswith('10') or data.startswith('9') or data.startswith('8'):
+ if data.startswith('<?xml'):
+ for match in entries_pattern.finditer(data):
+ yield joinpath(dirname,unescape(match.group(1)))
+ else:
+ svnver=-1
+ try: svnver = int(data.splitlines()[0])
+ except: pass
+ if svnver<8:
+ log.warn("unrecognized .svn/entries format in %s", os.path.abspath(dirname))
+ return
for record in map(str.splitlines, data.split('\n\x0c\n')[1:]):
# subversion 1.6/1.5/1.4
if not record or len(record)>=6 and record[5]=="delete":
continue # skip deleted
yield joinpath(dirname, record[0])
- elif data.startswith('<?xml'):
- for match in entries_pattern.finditer(data):
- yield joinpath(dirname,unescape(match.group(1)))
- else:
- log.warn("unrecognized .svn/entries format in %s", os.path.abspath(dirname))
-
+
finders = [
(convert_path('CVS/Entries'),
@@ -121,10 +125,6 @@ finders = [
-
-
-
-
class sdist(_sdist):
"""Smart sdist that finds anything supported by revision control"""
@@ -157,7 +157,7 @@ class sdist(_sdist):
import distutils.command
if 'check' not in distutils.command.__all__:
self.check_metadata()
-
+
self.make_distribution()
dist_files = getattr(self.distribution,'dist_files',[])
@@ -166,6 +166,26 @@ class sdist(_sdist):
if data not in dist_files:
dist_files.append(data)
+ def __read_template_hack(self):
+ # This grody hack closes the template file (MANIFEST.in) if an
+ # exception occurs during read_template.
+ # Doing so prevents an error when easy_install attempts to delete the
+ # file.
+ try:
+ _sdist.read_template(self)
+ 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.
+ if (
+ sys.version_info < (2,7,2)
+ or (3,0) <= sys.version_info < (3,1,4)
+ or (3,2) <= sys.version_info < (3,2,1)
+ ):
+ read_template = __read_template_hack
+
def add_defaults(self):
standards = [READMES,
self.distribution.script_name]
@@ -219,26 +239,6 @@ class sdist(_sdist):
build_scripts = self.get_finalized_command('build_scripts')
self.filelist.extend(build_scripts.get_source_files())
- def __read_template_hack(self):
- # This grody hack closes the template file (MANIFEST.in) if an
- # exception occurs during read_template.
- # Doing so prevents an error when easy_install attempts to delete the
- # file.
- try:
- _sdist.read_template(self)
- 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.
- if (
- sys.version_info < (2,7,2)
- or (3,0) <= sys.version_info < (3,1,4)
- or (3,2) <= sys.version_info < (3,2,1)
- ):
- read_template = __read_template_hack
-
def check_readme(self):
for f in READMES:
if os.path.exists(f):
@@ -301,13 +301,4 @@ class sdist(_sdist):
-
-
-
-
-
-
-
-
-
#
diff --git a/setuptools/command/test.py b/setuptools/command/test.py
index a02ac142..db2fc7b1 100644
--- a/setuptools/command/test.py
+++ b/setuptools/command/test.py
@@ -154,7 +154,7 @@ class test(Command):
for name in sys.modules:
if name.startswith(module):
del_modules.append(name)
- map(sys.modules.__delitem__, del_modules)
+ list(map(sys.modules.__delitem__, del_modules))
loader_ep = EntryPoint.parse("x="+self.test_loader)
loader_class = loader_ep.load(require=False)
diff --git a/setuptools/command/upload.py b/setuptools/command/upload.py
index 7edbf56a..02d955ed 100755
--- a/setuptools/command/upload.py
+++ b/setuptools/command/upload.py
@@ -22,7 +22,7 @@ class upload(Command):
description = "upload binary package to PyPI"
- DEFAULT_REPOSITORY = 'http://pypi.python.org/pypi'
+ DEFAULT_REPOSITORY = 'https://pypi.python.org/pypi'
user_options = [
('repository=', 'r',
diff --git a/setuptools/command/upload_docs.py b/setuptools/command/upload_docs.py
index 178a8793..12bc916b 100644
--- a/setuptools/command/upload_docs.py
+++ b/setuptools/command/upload_docs.py
@@ -2,7 +2,7 @@
"""upload_docs
Implements a Distutils 'upload_docs' subcommand (upload documentation to
-PyPI's packages.python.org).
+PyPI's pythonhosted.org).
"""
import os
@@ -23,15 +23,21 @@ try:
except ImportError:
from setuptools.command.upload import upload
-from setuptools.compat import httplib, urlparse
+from setuptools.compat import httplib, urlparse, unicode, iteritems
_IS_PYTHON3 = sys.version > '3'
+if _IS_PYTHON3:
+ errors = 'surrogateescape'
+else:
+ errors = 'strict'
+
+
# This is not just a replacement for byte literals
# but works as a general purpose encoder
def b(s, encoding='utf-8'):
if isinstance(s, unicode):
- return s.encode(encoding)
+ return s.encode(encoding, errors)
return s
@@ -127,7 +133,7 @@ class upload_docs(upload):
sep_boundary = b('\n--') + b(boundary)
end_boundary = sep_boundary + b('--')
body = []
- for key, values in data.iteritems():
+ for key, values in iteritems(data):
title = '\nContent-Disposition: form-data; name="%s"' % key
# handle multiple entries for the same name
if type(values) != type([]):
@@ -187,7 +193,7 @@ class upload_docs(upload):
elif r.status == 301:
location = r.getheader('Location')
if location is None:
- location = 'http://packages.python.org/%s/' % meta.get_name()
+ location = 'https://pythonhosted.org/%s/' % meta.get_name()
self.announce('Upload successful. Visit %s' % location,
log.INFO)
else: