Skip to content

Commit d626658

Browse files
author
andrew.kuchling
committed
#1858: re-apply patch for this, adding the missing files
git-svn-id: http://svn.python.org/projects/python/trunk@63060 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent c3942c3 commit d626658

11 files changed

Lines changed: 296 additions & 84 deletions

File tree

Doc/distutils/packageindex.rst

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,40 @@ The .pypirc file
5555

5656
The format of the :file:`.pypirc` file is as follows::
5757

58-
[server-login]
58+
[distutils]
59+
index-servers =
60+
pypi
61+
62+
[pypi]
5963
repository: <repository-url>
6064
username: <username>
6165
password: <password>
6266

6367
*repository* can be omitted and defaults to ``http://www.python.org/pypi``.
6468

69+
If you want to define another server a new section can be created::
70+
71+
[distutils]
72+
index-servers =
73+
pypi
74+
other
75+
76+
[pypi]
77+
repository: <repository-url>
78+
username: <username>
79+
password: <password>
80+
81+
[other]
82+
repository: http://example.com/pypi
83+
username: <username>
84+
password: <password>
85+
86+
The command can then be called with the -r option::
87+
88+
python setup.py register -r http://example.com/pypi
89+
90+
Or even with the section name::
91+
92+
python setup.py register -r other
6593

94+

Doc/distutils/uploading.rst

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,20 @@ The :command:`upload` command uses the username, password, and repository URL
2424
from the :file:`$HOME/.pypirc` file (see section :ref:`pypirc` for more on this
2525
file).
2626

27+
You can specify another PyPI server with the :option:`--repository=*url*` option::
28+
29+
python setup.py sdist bdist_wininst upload -r http://example.com/pypi
30+
31+
See section :ref:`pypirc` for more on defining several servers.
32+
2733
You can use the :option:`--sign` option to tell :command:`upload` to sign each
2834
uploaded file using GPG (GNU Privacy Guard). The :program:`gpg` program must
2935
be available for execution on the system :envvar:`PATH`. You can also specify
3036
which key to use for signing using the :option:`--identity=*name*` option.
3137

32-
Other :command:`upload` options include :option:`--repository=*url*` (which
33-
lets you override the repository setting from :file:`$HOME/.pypirc`), and
38+
Other :command:`upload` options include :option:`--repository=*url*`
39+
or :option:`--repository=*section*` where `url` is the url of the server
40+
and `section` the name of the section in :file:`$HOME/.pypirc`, and
3441
:option:`--show-response` (which displays the full response text from the PyPI
3542
server for help in debugging upload problems).
3643

37-

Lib/distutils/command/register.py

Lines changed: 49 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -8,37 +8,29 @@
88
__revision__ = "$Id$"
99

1010
import os, string, urllib2, getpass, urlparse
11-
import StringIO, ConfigParser
11+
import StringIO
1212

13-
from distutils.core import Command
13+
from distutils.core import PyPIRCCommand
1414
from distutils.errors import *
15+
from distutils import log
1516

16-
class register(Command):
17+
class register(PyPIRCCommand):
1718

1819
description = ("register the distribution with the Python package index")
19-
20-
DEFAULT_REPOSITORY = 'http://pypi.python.org/pypi'
21-
22-
user_options = [
23-
('repository=', 'r',
24-
"url of repository [default: %s]"%DEFAULT_REPOSITORY),
20+
user_options = PyPIRCCommand.user_options + [
2521
('list-classifiers', None,
2622
'list the valid Trove classifiers'),
27-
('show-response', None,
28-
'display full response text from server'),
2923
]
30-
boolean_options = ['verify', 'show-response', 'list-classifiers']
24+
boolean_options = PyPIRCCommand.boolean_options + [
25+
'verify', 'list-classifiers']
3126

3227
def initialize_options(self):
33-
self.repository = None
34-
self.show_response = 0
28+
PyPIRCCommand.initialize_options(self)
3529
self.list_classifiers = 0
3630

37-
def finalize_options(self):
38-
if self.repository is None:
39-
self.repository = self.DEFAULT_REPOSITORY
40-
4131
def run(self):
32+
self.finalize_options()
33+
self._set_config()
4234
self.check_metadata()
4335
if self.dry_run:
4436
self.verify_metadata()
@@ -77,6 +69,23 @@ def check_metadata(self):
7769
"or (maintainer and maintainer_email) " +
7870
"must be supplied")
7971

72+
def _set_config(self):
73+
''' Reads the configuration file and set attributes.
74+
'''
75+
config = self._read_pypirc()
76+
if config != {}:
77+
self.username = config['username']
78+
self.password = config['password']
79+
self.repository = config['repository']
80+
self.realm = config['realm']
81+
self.has_config = True
82+
else:
83+
if self.repository not in ('pypi', self.DEFAULT_REPOSITORY):
84+
raise ValueError('%s not found in .pypirc' % self.repository)
85+
if self.repository == 'pypi':
86+
self.repository = self.DEFAULT_REPOSITORY
87+
self.has_config = False
88+
8089
def classifiers(self):
8190
''' Fetch the list of classifiers from the server.
8291
'''
@@ -90,6 +99,7 @@ def verify_metadata(self):
9099
(code, result) = self.post_to_server(self.build_post_data('verify'))
91100
print 'Server response (%s): %s'%(code, result)
92101

102+
93103
def send_metadata(self):
94104
''' Send the metadata to the package index server.
95105
@@ -99,10 +109,14 @@ def send_metadata(self):
99109
100110
First we try to read the username/password from $HOME/.pypirc,
101111
which is a ConfigParser-formatted file with a section
102-
[server-login] containing username and password entries (both
112+
[distutils] containing username and password entries (both
103113
in clear text). Eg:
104114
105-
[server-login]
115+
[distutils]
116+
index-servers =
117+
pypi
118+
119+
[pypi]
106120
username: fred
107121
password: sekrit
108122
@@ -114,21 +128,15 @@ def send_metadata(self):
114128
3. set the password to a random string and email the user.
115129
116130
'''
117-
choice = 'x'
118-
username = password = ''
119-
120131
# see if we can short-cut and get the username/password from the
121132
# config
122-
config = None
123-
if 'HOME' in os.environ:
124-
rc = os.path.join(os.environ['HOME'], '.pypirc')
125-
if os.path.exists(rc):
126-
print 'Using PyPI login from %s'%rc
127-
config = ConfigParser.ConfigParser()
128-
config.read(rc)
129-
username = config.get('server-login', 'username')
130-
password = config.get('server-login', 'password')
131-
choice = '1'
133+
if self.has_config:
134+
choice = '1'
135+
username = self.username
136+
password = self.password
137+
else:
138+
choice = 'x'
139+
username = password = ''
132140

133141
# get the user's login info
134142
choices = '1 2 3 4'.split()
@@ -155,32 +163,24 @@ def send_metadata(self):
155163
# set up the authentication
156164
auth = urllib2.HTTPPasswordMgr()
157165
host = urlparse.urlparse(self.repository)[1]
158-
auth.add_password('pypi', host, username, password)
159-
166+
auth.add_password(self.realm, host, username, password)
160167
# send the info to the server and report the result
161168
code, result = self.post_to_server(self.build_post_data('submit'),
162169
auth)
163-
print 'Server response (%s): %s'%(code, result)
170+
print 'Server response (%s): %s' % (code, result)
164171

165172
# possibly save the login
166-
if 'HOME' in os.environ and config is None and code == 200:
167-
rc = os.path.join(os.environ['HOME'], '.pypirc')
173+
if not self.has_config and code == 200:
168174
print 'I can store your PyPI login so future submissions will be faster.'
169-
print '(the login will be stored in %s)'%rc
175+
print '(the login will be stored in %s)' % self._get_rc_file()
170176
choice = 'X'
171177
while choice.lower() not in 'yn':
172178
choice = raw_input('Save your login (y/N)?')
173179
if not choice:
174180
choice = 'n'
175181
if choice.lower() == 'y':
176-
f = open(rc, 'w')
177-
f.write('[server-login]\nusername:%s\npassword:%s\n'%(
178-
username, password))
179-
f.close()
180-
try:
181-
os.chmod(rc, 0600)
182-
except:
183-
pass
182+
self._store_pypirc(username, password)
183+
184184
elif choice == '2':
185185
data = {':action': 'user'}
186186
data['name'] = data['password'] = data['email'] = ''
@@ -243,7 +243,8 @@ def build_post_data(self, action):
243243
def post_to_server(self, data, auth=None):
244244
''' Post a query to the server, and return a string response.
245245
'''
246-
246+
self.announce('Registering %s to %s' % (data['name'],
247+
self.repository), log.INFO)
247248
# Build up the MIME payload for the urllib2 POST data
248249
boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
249250
sep_boundary = '\n--' + boundary

Lib/distutils/command/upload.py

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Implements the Distutils 'upload' subcommand (upload package to PyPI)."""
44

55
from distutils.errors import *
6-
from distutils.core import Command
6+
from distutils.core import PyPIRCCommand
77
from distutils.spawn import spawn
88
from distutils import log
99
from hashlib import md5
@@ -16,53 +16,38 @@
1616
import urlparse
1717
import cStringIO as StringIO
1818

19-
class upload(Command):
19+
class upload(PyPIRCCommand):
2020

2121
description = "upload binary package to PyPI"
2222

23-
DEFAULT_REPOSITORY = 'http://pypi.python.org/pypi'
24-
25-
user_options = [
26-
('repository=', 'r',
27-
"url of repository [default: %s]" % DEFAULT_REPOSITORY),
28-
('show-response', None,
29-
'display full response text from server'),
23+
user_options = PyPIRCCommand.user_options + [
3024
('sign', 's',
3125
'sign files to upload using gpg'),
3226
('identity=', 'i', 'GPG identity used to sign files'),
3327
]
34-
boolean_options = ['show-response', 'sign']
28+
29+
boolean_options = PyPIRCCommand.boolean_options + ['sign']
3530

3631
def initialize_options(self):
32+
PyPIRCCommand.initialize_options(self)
3733
self.username = ''
3834
self.password = ''
39-
self.repository = ''
4035
self.show_response = 0
4136
self.sign = False
4237
self.identity = None
4338

4439
def finalize_options(self):
40+
PyPIRCCommand.finalize_options(self)
4541
if self.identity and not self.sign:
4642
raise DistutilsOptionError(
4743
"Must use --sign for --identity to have meaning"
4844
)
49-
if 'HOME' in os.environ:
50-
rc = os.path.join(os.environ['HOME'], '.pypirc')
51-
if os.path.exists(rc):
52-
self.announce('Using PyPI login from %s' % rc)
53-
config = ConfigParser.ConfigParser({
54-
'username':'',
55-
'password':'',
56-
'repository':''})
57-
config.read(rc)
58-
if not self.repository:
59-
self.repository = config.get('server-login', 'repository')
60-
if not self.username:
61-
self.username = config.get('server-login', 'username')
62-
if not self.password:
63-
self.password = config.get('server-login', 'password')
64-
if not self.repository:
65-
self.repository = self.DEFAULT_REPOSITORY
45+
config = self._read_pypirc()
46+
if config != {}:
47+
self.username = config['username']
48+
self.password = config['password']
49+
self.repository = config['repository']
50+
self.realm = config['realm']
6651

6752
def run(self):
6853
if not self.distribution.dist_files:

Lib/distutils/core.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
# Mainly import these so setup scripts can "from distutils.core import" them.
2121
from distutils.dist import Distribution
2222
from distutils.cmd import Command
23+
from distutils.config import PyPIRCCommand
2324
from distutils.extension import Extension
2425

2526
# This is a barebones help message generated displayed when the user

Lib/distutils/dist.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -343,10 +343,9 @@ def find_config_files (self):
343343
user_filename = "pydistutils.cfg"
344344

345345
# And look for the user config file
346-
if 'HOME' in os.environ:
347-
user_file = os.path.join(os.environ.get('HOME'), user_filename)
348-
if os.path.isfile(user_file):
349-
files.append(user_file)
346+
user_file = os.path.join(os.path.expanduser('~'), user_filename)
347+
if os.path.isfile(user_file):
348+
files.append(user_file)
350349

351350
# All platforms support local setup.cfg
352351
local_file = "setup.cfg"

0 commit comments

Comments
 (0)