Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
This repository was archived by the owner on Feb 13, 2025. It is now read-only.

Commit 608d34a

Browse filesBrowse files
author
Anselm Kruis
committed
Merge with branch 3.3 just before the conversion to git.
2 parents 9fbbf8b + c276ffa commit 608d34a
Copy full SHA for 608d34a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Dismiss banner
Expand file treeCollapse file tree

60 files changed

+756
-718
lines changed

‎Doc/README.txt

Copy file name to clipboardExpand all lines: Doc/README.txt
-24Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -108,27 +108,3 @@ and we will process your request as soon as possible.
108108

109109
If you want to help the Documentation Team, you are always welcome. Just send
110110
a mail to docs@python.org.
111-
112-
113-
Copyright notice
114-
================
115-
116-
The Python source is copyrighted, but you can freely use and copy it
117-
as long as you don't change or remove the copyright notice:
118-
119-
----------------------------------------------------------------------
120-
Copyright (c) 2000-2014 Python Software Foundation.
121-
All rights reserved.
122-
123-
Copyright (c) 2000 BeOpen.com.
124-
All rights reserved.
125-
126-
Copyright (c) 1995-2000 Corporation for National Research Initiatives.
127-
All rights reserved.
128-
129-
Copyright (c) 1991-1995 Stichting Mathematisch Centrum.
130-
All rights reserved.
131-
132-
See the file "license.rst" for information on usage and redistribution
133-
of this file, and for a DISCLAIMER OF ALL WARRANTIES.
134-
----------------------------------------------------------------------

‎Doc/copyright.rst

Copy file name to clipboardExpand all lines: Doc/copyright.rst
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Copyright
44

55
Python and this documentation is:
66

7-
Copyright © 2001-2015 Python Software Foundation. All rights reserved.
7+
Copyright © 2001-2016 Python Software Foundation. All rights reserved.
88

99
Copyright © 2000 BeOpen.com. All rights reserved.
1010

‎Doc/howto/urllib2.rst

Copy file name to clipboardExpand all lines: Doc/howto/urllib2.rst
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,11 @@ setting up a `Basic Authentication`_ handler: ::
538538
through a proxy. However, this can be enabled by extending urllib.request as
539539
shown in the recipe [#]_.
540540

541+
.. note::
542+
543+
`HTTP_PROXY`` will be ignored if a variable ``REQUEST_METHOD`` is set; see
544+
the documentation on :func:`~urllib.request.getproxies`.
545+
541546

542547
Sockets and Layers
543548
==================

‎Doc/library/urllib.request.rst

Copy file name to clipboardExpand all lines: Doc/library/urllib.request.rst
+13Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,14 @@ The :mod:`urllib.request` module defines the following functions:
161161
cannot find it, looks for proxy information from Mac OSX System
162162
Configuration for Mac OS X and Windows Systems Registry for Windows.
163163

164+
.. note::
165+
166+
If the environment variable ``REQUEST_METHOD`` is set, which usually
167+
indicates your script is running in a CGI environment, the environment
168+
variable ``HTTP_PROXY`` (uppercase ``_PROXY``) will be ignored. This is
169+
because that variable can be injected by a client using the "Proxy:" HTTP
170+
header. If you need to use an HTTP proxy in a CGI environment use
171+
``ProxyHandler`` explicitly.
164172

165173
The following classes are provided:
166174

@@ -265,6 +273,11 @@ The following classes are provided:
265273

266274
To disable autodetected proxy pass an empty dictionary.
267275

276+
.. note::
277+
278+
``HTTP_PROXY`` will be ignored if a variable ``REQUEST_METHOD`` is set;
279+
see the documentation on :func:`~urllib.request.getproxies`.
280+
268281

269282
.. class:: HTTPPasswordMgr()
270283

‎Doc/license.rst

Copy file name to clipboardExpand all lines: Doc/license.rst
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ Terms and conditions for accessing or otherwise using Python
8484
analyze, test, perform and/or display publicly, prepare derivative works,
8585
distribute, and otherwise use Python |release| alone or in any derivative
8686
version, provided, however, that PSF's License Agreement and PSF's notice of
87-
copyright, i.e., "Copyright © 2001-2015 Python Software Foundation; All Rights
87+
copyright, i.e., "Copyright © 2001-2017 Python Software Foundation; All Rights
8888
Reserved" are retained in Python |release| alone or in any derivative version
8989
prepared by Licensee.
9090

‎LICENSE

Copy file name to clipboardExpand all lines: LICENSE
+3-2Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,9 @@ analyze, test, perform and/or display publicly, prepare derivative works,
7474
distribute, and otherwise use Python alone or in any derivative version,
7575
provided, however, that PSF's License Agreement and PSF's notice of copyright,
7676
i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
77-
2011, 2012, 2013, 2014, 2015 Python Software Foundation; All Rights Reserved"
78-
are retained in Python alone or in any derivative version prepared by Licensee.
77+
2011, 2012, 2013, 2014, 2015, 2016, 2017 Python Software Foundation; All Rights
78+
Reserved" are retained in Python alone or in any derivative version prepared by
79+
Licensee.
7980

8081
3. In the event Licensee prepares a derivative work that is based on
8182
or incorporates Python or any part thereof, and wants to make

‎Lib/ctypes/test/test_callbacks.py

Copy file name to clipboardExpand all lines: Lib/ctypes/test/test_callbacks.py
+35Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import functools
12
import unittest
23
from ctypes import *
34
import _ctypes_test
@@ -243,6 +244,40 @@ def callback(a, b, c, d, e):
243244
self.assertEqual(result,
244245
callback(1.1*1.1, 2.2*2.2, 3.3*3.3, 4.4*4.4, 5.5*5.5))
245246

247+
def test_callback_large_struct(self):
248+
class Check: pass
249+
250+
class X(Structure):
251+
_fields_ = [
252+
('first', c_ulong),
253+
('second', c_ulong),
254+
('third', c_ulong),
255+
]
256+
257+
def callback(check, s):
258+
check.first = s.first
259+
check.second = s.second
260+
check.third = s.third
261+
262+
check = Check()
263+
s = X()
264+
s.first = 0xdeadbeef
265+
s.second = 0xcafebabe
266+
s.third = 0x0bad1dea
267+
268+
CALLBACK = CFUNCTYPE(None, X)
269+
dll = CDLL(_ctypes_test.__file__)
270+
func = dll._testfunc_cbk_large_struct
271+
func.argtypes = (X, CALLBACK)
272+
func.restype = None
273+
# the function just calls the callback with the passed structure
274+
func(s, CALLBACK(functools.partial(callback, check)))
275+
self.assertEqual(check.first, s.first)
276+
self.assertEqual(check.second, s.second)
277+
self.assertEqual(check.third, s.third)
278+
self.assertEqual(check.first, 0xdeadbeef)
279+
self.assertEqual(check.second, 0xcafebabe)
280+
self.assertEqual(check.third, 0x0bad1dea)
246281

247282
################################################################
248283

‎Lib/distutils/__init__.py

Copy file name to clipboardExpand all lines: Lib/distutils/__init__.py
+3-7Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@
88
setup (...)
99
"""
1010

11-
# Distutils version
12-
#
13-
# Updated automatically by the Python release process.
14-
#
15-
#--start constants--
16-
__version__ = "3.3.6"
17-
#--end constants--
11+
import sys
12+
13+
__version__ = sys.version[:sys.version.index(' ')]

‎Lib/distutils/config.py

Copy file name to clipboardExpand all lines: Lib/distutils/config.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
class PyPIRCCommand(Command):
2222
"""Base command that knows how to handle the .pypirc file
2323
"""
24-
DEFAULT_REPOSITORY = 'https://pypi.python.org/pypi'
24+
DEFAULT_REPOSITORY = 'https://upload.pypi.org/legacy/'
2525
DEFAULT_REALM = 'pypi'
2626
repository = None
2727
realm = None

‎Lib/distutils/tests/test_config.py

Copy file name to clipboardExpand all lines: Lib/distutils/tests/test_config.py
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def test_server_registration(self):
8787

8888
config = list(sorted(config.items()))
8989
waited = [('password', 'secret'), ('realm', 'pypi'),
90-
('repository', 'https://pypi.python.org/pypi'),
90+
('repository', 'https://upload.pypi.org/legacy/'),
9191
('server', 'server1'), ('username', 'me')]
9292
self.assertEqual(config, waited)
9393

@@ -96,7 +96,7 @@ def test_server_registration(self):
9696
config = cmd._read_pypirc()
9797
config = list(sorted(config.items()))
9898
waited = [('password', 'secret'), ('realm', 'pypi'),
99-
('repository', 'https://pypi.python.org/pypi'),
99+
('repository', 'https://upload.pypi.org/legacy/'),
100100
('server', 'server-login'), ('username', 'tarek')]
101101
self.assertEqual(config, waited)
102102

‎Lib/distutils/tests/test_upload.py

Copy file name to clipboardExpand all lines: Lib/distutils/tests/test_upload.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ def test_upload(self):
127127
self.assertTrue(headers['Content-type'].startswith('multipart/form-data'))
128128
self.assertEqual(self.last_open.req.get_method(), 'POST')
129129
self.assertEqual(self.last_open.req.get_full_url(),
130-
'https://pypi.python.org/pypi')
130+
'https://upload.pypi.org/legacy/')
131131
self.assertIn(b'xxx', self.last_open.req.data)
132132

133133
# The PyPI response body was echoed

‎Lib/gettext.py

Copy file name to clipboardExpand all lines: Lib/gettext.py
+136-44Lines changed: 136 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -57,55 +57,147 @@
5757

5858
_default_localedir = os.path.join(sys.base_prefix, 'share', 'locale')
5959

60+
# Expression parsing for plural form selection.
61+
#
62+
# The gettext library supports a small subset of C syntax. The only
63+
# incompatible difference is that integer literals starting with zero are
64+
# decimal.
65+
#
66+
# https://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms
67+
# http://git.savannah.gnu.org/cgit/gettext.git/tree/gettext-runtime/intl/plural.y
68+
69+
_token_pattern = re.compile(r"""
70+
(?P<WHITESPACES>[ \t]+) | # spaces and horizontal tabs
71+
(?P<NUMBER>[0-9]+\b) | # decimal integer
72+
(?P<NAME>n\b) | # only n is allowed
73+
(?P<PARENTHESIS>[()]) |
74+
(?P<OPERATOR>[-*/%+?:]|[><!]=?|==|&&|\|\|) | # !, *, /, %, +, -, <, >,
75+
# <=, >=, ==, !=, &&, ||,
76+
# ? :
77+
# unary and bitwise ops
78+
# not allowed
79+
(?P<INVALID>\w+|.) # invalid token
80+
""", re.VERBOSE|re.DOTALL)
81+
82+
def _tokenize(plural):
83+
for mo in re.finditer(_token_pattern, plural):
84+
kind = mo.lastgroup
85+
if kind == 'WHITESPACES':
86+
continue
87+
value = mo.group(kind)
88+
if kind == 'INVALID':
89+
raise ValueError('invalid token in plural form: %s' % value)
90+
yield value
91+
yield ''
92+
93+
def _error(value):
94+
if value:
95+
return ValueError('unexpected token in plural form: %s' % value)
96+
else:
97+
return ValueError('unexpected end of plural form')
98+
99+
_binary_ops = (
100+
('||',),
101+
('&&',),
102+
('==', '!='),
103+
('<', '>', '<=', '>='),
104+
('+', '-'),
105+
('*', '/', '%'),
106+
)
107+
_binary_ops = {op: i for i, ops in enumerate(_binary_ops, 1) for op in ops}
108+
_c2py_ops = {'||': 'or', '&&': 'and', '/': '//'}
109+
110+
def _parse(tokens, priority=-1):
111+
result = ''
112+
nexttok = next(tokens)
113+
while nexttok == '!':
114+
result += 'not '
115+
nexttok = next(tokens)
116+
117+
if nexttok == '(':
118+
sub, nexttok = _parse(tokens)
119+
result = '%s(%s)' % (result, sub)
120+
if nexttok != ')':
121+
raise ValueError('unbalanced parenthesis in plural form')
122+
elif nexttok == 'n':
123+
result = '%s%s' % (result, nexttok)
124+
else:
125+
try:
126+
value = int(nexttok, 10)
127+
except ValueError:
128+
raise _error(nexttok) from None
129+
result = '%s%d' % (result, value)
130+
nexttok = next(tokens)
131+
132+
j = 100
133+
while nexttok in _binary_ops:
134+
i = _binary_ops[nexttok]
135+
if i < priority:
136+
break
137+
# Break chained comparisons
138+
if i in (3, 4) and j in (3, 4): # '==', '!=', '<', '>', '<=', '>='
139+
result = '(%s)' % result
140+
# Replace some C operators by their Python equivalents
141+
op = _c2py_ops.get(nexttok, nexttok)
142+
right, nexttok = _parse(tokens, i + 1)
143+
result = '%s %s %s' % (result, op, right)
144+
j = i
145+
if j == priority == 4: # '<', '>', '<=', '>='
146+
result = '(%s)' % result
147+
148+
if nexttok == '?' and priority <= 0:
149+
if_true, nexttok = _parse(tokens, 0)
150+
if nexttok != ':':
151+
raise _error(nexttok)
152+
if_false, nexttok = _parse(tokens)
153+
result = '%s if %s else %s' % (if_true, result, if_false)
154+
if priority == 0:
155+
result = '(%s)' % result
156+
157+
return result, nexttok
158+
159+
def _as_int(n):
160+
try:
161+
i = round(n)
162+
except TypeError:
163+
raise TypeError('Plural value must be an integer, got %s' %
164+
(n.__class__.__name__,)) from None
165+
return n
60166

61167
def c2py(plural):
62168
"""Gets a C expression as used in PO files for plural forms and returns a
63-
Python lambda function that implements an equivalent expression.
169+
Python function that implements an equivalent expression.
64170
"""
65-
# Security check, allow only the "n" identifier
66-
import token, tokenize
67-
tokens = tokenize.generate_tokens(io.StringIO(plural).readline)
68-
try:
69-
danger = [x for x in tokens if x[0] == token.NAME and x[1] != 'n']
70-
except tokenize.TokenError:
71-
raise ValueError('plural forms expression error, maybe unbalanced parenthesis')
72-
else:
73-
if danger:
74-
raise ValueError('plural forms expression could be dangerous')
75-
76-
# Replace some C operators by their Python equivalents
77-
plural = plural.replace('&&', ' and ')
78-
plural = plural.replace('||', ' or ')
79-
80-
expr = re.compile(r'\!([^=])')
81-
plural = expr.sub(' not \\1', plural)
82-
83-
# Regular expression and replacement function used to transform
84-
# "a?b:c" to "b if a else c".
85-
expr = re.compile(r'(.*?)\?(.*?):(.*)')
86-
def repl(x):
87-
return "(%s if %s else %s)" % (x.group(2), x.group(1),
88-
expr.sub(repl, x.group(3)))
89-
90-
# Code to transform the plural expression, taking care of parentheses
91-
stack = ['']
92-
for c in plural:
93-
if c == '(':
94-
stack.append('')
95-
elif c == ')':
96-
if len(stack) == 1:
97-
# Actually, we never reach this code, because unbalanced
98-
# parentheses get caught in the security check at the
99-
# beginning.
100-
raise ValueError('unbalanced parenthesis in plural form')
101-
s = expr.sub(repl, stack.pop())
102-
stack[-1] += '(%s)' % s
103-
else:
104-
stack[-1] += c
105-
plural = expr.sub(repl, stack.pop())
106-
107-
return eval('lambda n: int(%s)' % plural)
108171

172+
if len(plural) > 1000:
173+
raise ValueError('plural form expression is too long')
174+
try:
175+
result, nexttok = _parse(_tokenize(plural))
176+
if nexttok:
177+
raise _error(nexttok)
178+
179+
depth = 0
180+
for c in result:
181+
if c == '(':
182+
depth += 1
183+
if depth > 20:
184+
# Python compiler limit is about 90.
185+
# The most complex example has 2.
186+
raise ValueError('plural form expression is too complex')
187+
elif c == ')':
188+
depth -= 1
189+
190+
ns = {'_as_int': _as_int}
191+
exec('''if True:
192+
def func(n):
193+
if not isinstance(n, int):
194+
n = _as_int(n)
195+
return int(%s)
196+
''' % result, ns)
197+
return ns['func']
198+
except RuntimeError:
199+
# Recursion error can be raised in _parse() or exec().
200+
raise ValueError('plural form expression is too complex')
109201

110202

111203
def _expand_lang(loc):

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.