Merged revisions 85728,85731,85735,85766-85771,85773,85777 via svnmerge from

svn+ssh://svn.python.org/python/branches/py3k

........
  r85728 | georg.brandl | 2010-10-19 20:54:25 +0200 (Di, 19 Okt 2010) | 1 line

  #10092: Properly reset locale in Locale*Calendar classes.  The context manager was buggy because setlocale() returns the *new* locale, not the old.  Also add a test for this.
........
  r85731 | georg.brandl | 2010-10-19 23:07:16 +0200 (Di, 19 Okt 2010) | 1 line

  Be consistent in the spelling of thread-safe(ty).
........
  r85735 | georg.brandl | 2010-10-20 08:50:19 +0200 (Mi, 20 Okt 2010) | 1 line

  Fix r85728: use "" to mean the system default locale, which should work on more systems.
........
  r85766 | georg.brandl | 2010-10-21 09:40:03 +0200 (Do, 21 Okt 2010) | 1 line

  #10159: sort completion matches before comparing to dir() result.
........
  r85767 | georg.brandl | 2010-10-21 14:49:28 +0200 (Do, 21 Okt 2010) | 1 line

  #9095, #8912, #8999: add support in patchcheck for Mercurial checkouts, C file reindenting, and docs whitespace fixing.
........
  r85768 | georg.brandl | 2010-10-21 14:59:14 +0200 (Do, 21 Okt 2010) | 1 line

  #9919: fix off-by-one error in lineno command in Misc/gdbinit; also add newline to its output.
........
  r85769 | georg.brandl | 2010-10-21 15:01:23 +0200 (Do, 21 Okt 2010) | 1 line

  Fix missing import.
........
  r85770 | georg.brandl | 2010-10-21 15:29:10 +0200 (Do, 21 Okt 2010) | 1 line

  #3077: fix h2py substitution of character literals.
........
  r85771 | georg.brandl | 2010-10-21 15:34:51 +0200 (Do, 21 Okt 2010) | 1 line

  #1203650: allow larger list of files in windows makefile for freeze.
........
  r85773 | georg.brandl | 2010-10-21 15:45:52 +0200 (Do, 21 Okt 2010) | 1 line

  #4829: better error message for invalid file mode
........
  r85777 | georg.brandl | 2010-10-21 17:44:51 +0200 (Do, 21 Okt 2010) | 1 line

  Add .hgeol file for the Mercurial EOL extension.
........
This commit is contained in:
Georg Brandl 2010-11-26 08:52:36 +00:00
parent ab32fec83c
commit d62ecbf0ba
18 changed files with 196 additions and 81 deletions

36
.hgeol Normal file
View file

@ -0,0 +1,36 @@
[patterns]
** = native
**.bat = CRLF
**.def = CRLF
**.dsp = CRLF
**.dsw = CRLF
**.mak = CRLF
**.mk = CRLF
**.rc = CRLF
**.sln = CRLF
**.vcproj = CRLF
**.vsprops = CRLF
**.aif = BIN
**.au = BIN
**.bmp = BIN
**.db = BIN
**.exe = BIN
**.icns = BIN
**.gif = BIN
**.ico = BIN
**.info = BIN
**.jpg = BIN
**.pck = BIN
**.png = BIN
**.psd = BIN
**.tar = BIN
**.xar = BIN
**.zip = BIN
Lib/email/test/data/msg_26.txt = BIN
Lib/test/sndhdrdata/sndhdr.* = BIN
[repository]
native = LF

View file

@ -416,7 +416,7 @@ Thread State and the Global Interpreter Lock
single: interpreter lock single: interpreter lock
single: lock, interpreter single: lock, interpreter
The Python interpreter is not fully thread safe. In order to support The Python interpreter is not fully thread-safe. In order to support
multi-threaded Python programs, there's a global lock, called the :dfn:`global multi-threaded Python programs, there's a global lock, called the :dfn:`global
interpreter lock` or :dfn:`GIL`, that must be held by the current thread before interpreter lock` or :dfn:`GIL`, that must be held by the current thread before
it can safely access Python objects. Without the lock, even the simplest it can safely access Python objects. Without the lock, even the simplest

View file

@ -170,9 +170,9 @@ it's the base calendar for all computations.
.. class:: LocaleTextCalendar(firstweekday=0, locale=None) .. class:: LocaleTextCalendar(firstweekday=0, locale=None)
This subclass of :class:`TextCalendar` can be passed a locale name in the This subclass of :class:`TextCalendar` can be passed a locale name in the
constructor and will return month and weekday names in the specified constructor and will return month and weekday names in the specified locale.
locale. If this locale includes an encoding all strings containing month and If this locale includes an encoding all strings containing month and weekday
weekday names will be returned as unicode. names will be returned as unicode.
.. class:: LocaleHTMLCalendar(firstweekday=0, locale=None) .. class:: LocaleHTMLCalendar(firstweekday=0, locale=None)
@ -182,6 +182,12 @@ it's the base calendar for all computations.
locale. If this locale includes an encoding all strings containing month and locale. If this locale includes an encoding all strings containing month and
weekday names will be returned as unicode. weekday names will be returned as unicode.
.. note::
The :meth:`formatweekday` and :meth:`formatmonthname` methods of these two
classes temporarily change the current locale to the given *locale*. Because
the current locale is a process-wide setting, they are not thread-safe.
For simple text calendars this module provides the following functions. For simple text calendars this module provides the following functions.

View file

@ -39,7 +39,7 @@ The :mod:`locale` module defines the following exception and functions:
If *locale* is omitted or ``None``, the current setting for *category* is If *locale* is omitted or ``None``, the current setting for *category* is
returned. returned.
:func:`setlocale` is not thread safe on most systems. Applications typically :func:`setlocale` is not thread-safe on most systems. Applications typically
start with a call of :: start with a call of ::
import locale import locale

View file

@ -214,7 +214,7 @@ However, if you really do need to use some shared data then
The ``'d'`` and ``'i'`` arguments used when creating ``num`` and ``arr`` are The ``'d'`` and ``'i'`` arguments used when creating ``num`` and ``arr`` are
typecodes of the kind used by the :mod:`array` module: ``'d'`` indicates a typecodes of the kind used by the :mod:`array` module: ``'d'`` indicates a
double precision float and ``'i'`` indicates a signed integer. These shared double precision float and ``'i'`` indicates a signed integer. These shared
objects will be process and thread safe. objects will be process and thread-safe.
For more flexibility in using shared memory one can use the For more flexibility in using shared memory one can use the
:mod:`multiprocessing.sharedctypes` module which supports the creation of :mod:`multiprocessing.sharedctypes` module which supports the creation of

View file

@ -753,9 +753,9 @@ Currently, :class:`Lock`, :class:`RLock`, :class:`Condition`,
Importing in threaded code Importing in threaded code
-------------------------- --------------------------
While the import machinery is thread safe, there are two key While the import machinery is thread-safe, there are two key restrictions on
restrictions on threaded imports due to inherent limitations in the way threaded imports due to inherent limitations in the way that thread-safety is
that thread safety is provided: provided:
* Firstly, other than in the main module, an import should not have the * Firstly, other than in the main module, an import should not have the
side effect of spawning a new thread and then waiting for that thread in side effect of spawning a new thread and then waiting for that thread in

View file

@ -486,8 +486,8 @@ class different_locale:
self.locale = locale self.locale = locale
def __enter__(self): def __enter__(self):
self.oldlocale = _locale.setlocale(_locale.LC_TIME, self.locale) self.oldlocale = _locale.getlocale(_locale.LC_TIME)
#return _locale.getlocale(_locale.LC_TIME)[1] _locale.setlocale(_locale.LC_TIME, self.locale)
def __exit__(self, *args): def __exit__(self, *args):
_locale.setlocale(_locale.LC_TIME, self.oldlocale) _locale.setlocale(_locale.LC_TIME, self.oldlocale)

View file

@ -2,6 +2,7 @@ import calendar
import unittest import unittest
from test import support from test import support
import locale
result_2004_text = """ result_2004_text = """
@ -250,6 +251,19 @@ class CalendarTestCase(unittest.TestCase):
# verify it "acts like a sequence" in two forms of iteration # verify it "acts like a sequence" in two forms of iteration
self.assertEqual(value[::-1], list(reversed(value))) self.assertEqual(value[::-1], list(reversed(value)))
def test_localecalendars(self):
# ensure that Locale{Text,HTML}Calendar resets the locale properly
# (it is still not thread-safe though)
old_october = calendar.TextCalendar().formatmonthname(2010, 10, 10)
try:
calendar.LocaleTextCalendar(locale='').formatmonthname(2010, 10, 10)
except locale.Error:
# cannot set the system default locale -- skip rest of test
return
calendar.LocaleHTMLCalendar(locale='').formatmonthname(2010, 10)
new_october = calendar.TextCalendar().formatmonthname(2010, 10, 10)
self.assertEquals(old_october, new_october)
class MonthCalendarTestCase(unittest.TestCase): class MonthCalendarTestCase(unittest.TestCase):
def setUp(self): def setUp(self):

View file

@ -31,9 +31,9 @@ class TestRlcompleter(unittest.TestCase):
def test_global_matches(self): def test_global_matches(self):
# test with builtins namespace # test with builtins namespace
self.assertEqual(self.stdcompleter.global_matches('di'), self.assertEqual(sorted(self.stdcompleter.global_matches('di')),
[x+'(' for x in dir(builtins) if x.startswith('di')]) [x+'(' for x in dir(builtins) if x.startswith('di')])
self.assertEqual(self.stdcompleter.global_matches('st'), self.assertEqual(sorted(self.stdcompleter.global_matches('st')),
[x+'(' for x in dir(builtins) if x.startswith('st')]) [x+'(' for x in dir(builtins) if x.startswith('st')])
self.assertEqual(self.stdcompleter.global_matches('akaksajadhak'), []) self.assertEqual(self.stdcompleter.global_matches('akaksajadhak'), [])

View file

@ -18,6 +18,8 @@ Library
- Issue #10459: Update CJK character names to Unicode 5.1. - Issue #10459: Update CJK character names to Unicode 5.1.
- Issue #10092: Properly reset locale in calendar.Locale*Calendar classes.
- Issue #6098: Don't claim DOM level 3 conformance in minidom. - Issue #6098: Don't claim DOM level 3 conformance in minidom.
- Issue #5762: Fix AttributeError raised by ``xml.dom.minidom`` when an empty - Issue #5762: Fix AttributeError raised by ``xml.dom.minidom`` when an empty

View file

@ -62,11 +62,12 @@ define lineno
set $__p = $__p + 1 set $__p = $__p + 1
if ($__ad > $__lasti) if ($__ad > $__lasti)
set $__continue = 0 set $__continue = 0
else
set $__li = $__li + *$__p
set $__p = $__p + 1
end end
set $__li = $__li + *$__p
set $__p = $__p + 1
end end
printf "%d", $__li printf "%d\n", $__li
end end
# print the current frame - verbose # print the current frame - verbose

View file

@ -265,7 +265,8 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
if (rwa) { if (rwa) {
bad_mode: bad_mode:
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"Must have exactly one of read/write/append mode"); "Must have exactly one of read/write/append "
"mode and at most one plus");
goto error; goto error;
} }
rwa = 1; rwa = 1;

View file

@ -1,5 +1,5 @@
import re import re
import sys
# Write the config.c file # Write the config.c file
@ -38,7 +38,6 @@ def makeconfig(infp, outfp, modules, with_ifdef=0):
# Test program. # Test program.
def test(): def test():
import sys
if not sys.argv[3:]: if not sys.argv[3:]:
print('usage: python makeconfig.py config.c.in outputfile', end=' ') print('usage: python makeconfig.py config.c.in outputfile', end=' ')
print('modulename ...') print('modulename ...')

View file

@ -134,12 +134,14 @@ def realwork(vars, moddefns, target):
print() ; print() print() ; print()
print("$(target)$(debug_suffix)%s: $(temp_dir) $(OBJS)" % (target_ext)) print("$(target)$(debug_suffix)%s: $(temp_dir) $(OBJS)" % (target_ext))
print("\tlink -out:$(target)$(debug_suffix)%s %s" % (target_ext, target_link_flags), end=' ') print("\tlink -out:$(target)$(debug_suffix)%s %s" %
print("\t$(OBJS) \\") (target_ext, target_link_flags), "@<<")
print("\t$(LIBS) \\") print("\t$(OBJS)")
print("\t$(ADDN_LINK_FILES) \\") print("\t$(LIBS)")
print("\t$(pythonlib) $(lcustom) $(l_debug)\\") print("\t$(ADDN_LINK_FILES)")
print("\t$(pythonlib) $(lcustom) $(l_debug)")
print("\t$(resources)") print("\t$(resources)")
print("<<")
print() print()
print("clean:") print("clean:")
print("\t-rm -f *.obj") print("\t-rm -f *.obj")

View file

@ -93,7 +93,7 @@ def pytify(body):
for p in ignores: for p in ignores:
body = p.sub(' ', body) body = p.sub(' ', body)
# replace char literals by ord(...) # replace char literals by ord(...)
body = p_char.sub('ord(\\0)', body) body = p_char.sub("ord('\\1')", body)
# Compute negative hexadecimal constants # Compute negative hexadecimal constants
start = 0 start = 0
UMAX = 2*(sys.maxsize+1) UMAX = 2*(sys.maxsize+1)

View file

@ -1,8 +1,16 @@
import re
import sys
import shutil
import os.path import os.path
import subprocess import subprocess
import sys
import reindent import reindent
import untabify
def n_files_str(count):
"""Return 'N file(s)' with the proper plurality on 'file'."""
return "{} file{}".format(count, "s" if count != 1 else "")
def status(message, modal=False, info=None): def status(message, modal=False, info=None):
@ -17,53 +25,105 @@ def status(message, modal=False, info=None):
elif info: elif info:
print(info(result)) print(info(result))
else: else:
if result: print("yes" if result else "NO")
print("yes")
else:
print("NO")
return result return result
return call_fxn return call_fxn
return decorated_fxn return decorated_fxn
@status("Getting the list of files that have been added/changed",
info=lambda x: "%s files" % len(x))
def changed_files():
"""Run ``svn status`` and return a set of files that have been
changed/added."""
cmd = 'svn status --quiet --non-interactive --ignore-externals'
svn_st = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
svn_st.wait()
output = [x.decode().rstrip() for x in svn_st.stdout.readlines()]
files = set()
for line in output:
if not line[0] in ('A', 'M'):
continue
line_parts = line.split()
path = line_parts[-1]
if os.path.isfile(path):
files.add(path)
return files
@status("Fixing whitespace", info=lambda x: "%s files" % x) @status("Getting the list of files that have been added/changed",
info=lambda x: n_files_str(len(x)))
def changed_files():
"""Get the list of changed or added files from the VCS."""
if os.path.isdir('.hg'):
vcs = 'hg'
cmd = 'hg status --added --modified --no-status'
elif os.path.isdir('.svn'):
vcs = 'svn'
cmd = 'svn status --quiet --non-interactive --ignore-externals'
else:
sys.exit('need a checkout to get modified files')
st = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
try:
st.wait()
if vcs == 'hg':
return [x.decode().rstrip() for x in st.stdout]
else:
output = (x.decode().rstrip().rsplit(None, 1)[-1]
for x in st.stdout if x[0] in b'AM')
return set(path for path in output if os.path.isfile(path))
finally:
st.stdout.close()
def report_modified_files(file_paths):
count = len(file_paths)
if count == 0:
return n_files_str(count)
else:
lines = ["{}:".format(n_files_str(count))]
for path in file_paths:
lines.append(" {}".format(path))
return "\n".join(lines)
@status("Fixing whitespace", info=report_modified_files)
def normalize_whitespace(file_paths): def normalize_whitespace(file_paths):
"""Make sure that the whitespace for .py files have been normalized.""" """Make sure that the whitespace for .py files have been normalized."""
reindent.makebackup = False # No need to create backups. reindent.makebackup = False # No need to create backups.
result = list(map(reindent.check, (x for x in file_paths if x.endswith('.py')))) fixed = []
return sum(result) for path in (x for x in file_paths if x.endswith('.py')):
if reindent.check(path):
fixed.append(path)
return fixed
@status("Fixing C file whitespace", info=report_modified_files)
def normalize_c_whitespace(file_paths):
"""Report if any C files """
fixed = []
for path in file_paths:
with open(path, 'r') as f:
if '\t' not in f.read():
continue
untabify.process(path, 8, verbose=False)
fixed.append(path)
return fixed
ws_re = re.compile(br'\s+(\r?\n)$')
@status("Fixing docs whitespace", info=report_modified_files)
def normalize_docs_whitespace(file_paths):
fixed = []
for path in file_paths:
try:
with open(path, 'rb') as f:
lines = f.readlines()
new_lines = [ws_re.sub(br'\1', line) for line in lines]
if new_lines != lines:
shutil.copyfile(path, path + '.bak')
with open(path, 'wb') as f:
f.writelines(new_lines)
fixed.append(path)
except Exception as err:
print('Cannot fix %s: %s' % (path, err))
return fixed
@status("Docs modified", modal=True) @status("Docs modified", modal=True)
def docs_modified(file_paths): def docs_modified(file_paths):
"""Report if any files in the Docs directory.""" """Report if any file in the Doc directory has been changed."""
for path in file_paths: return bool(file_paths)
if path.startswith("Doc"):
return True
return False
@status("Misc/ACKS updated", modal=True) @status("Misc/ACKS updated", modal=True)
def credit_given(file_paths): def credit_given(file_paths):
"""Check if Misc/ACKS has been changed.""" """Check if Misc/ACKS has been changed."""
return 'Misc/ACKS' in file_paths return 'Misc/ACKS' in file_paths
@status("Misc/NEWS updated", modal=True) @status("Misc/NEWS updated", modal=True)
def reported_news(file_paths): def reported_news(file_paths):
"""Check if Misc/NEWS has been changed.""" """Check if Misc/NEWS has been changed."""
@ -72,14 +132,22 @@ def reported_news(file_paths):
def main(): def main():
file_paths = changed_files() file_paths = changed_files()
# PEP 7/8 verification. python_files = [fn for fn in file_paths if fn.endswith('.py')]
normalize_whitespace(file_paths) c_files = [fn for fn in file_paths if fn.endswith(('.c', '.h'))]
doc_files = [fn for fn in file_paths if fn.startswith('Doc')]
special_files = {'Misc/ACKS', 'Misc/NEWS'} & set(file_paths)
# PEP 8 whitespace rules enforcement.
normalize_whitespace(python_files)
# C rules enforcement.
normalize_c_whitespace(c_files)
# Doc whitespace enforcement.
normalize_docs_whitespace(doc_files)
# Docs updated. # Docs updated.
docs_modified(file_paths) docs_modified(doc_files)
# Misc/ACKS changed. # Misc/ACKS changed.
credit_given(file_paths) credit_given(special_files)
# Misc/NEWS changed. # Misc/NEWS changed.
reported_news(file_paths) reported_news(special_files)
# Test suite run and passed. # Test suite run and passed.
print() print()

View file

@ -3,27 +3,12 @@
# Make a reST file compliant to our pre-commit hook. # Make a reST file compliant to our pre-commit hook.
# Currently just remove trailing whitespace. # Currently just remove trailing whitespace.
import sys
import sys, re, shutil import patchcheck
ws_re = re.compile(r'\s+(\r?\n)$')
def main(argv=sys.argv): def main(argv=sys.argv):
rv = 0 patchcheck.normalize_docs_whitespace(argv[1:])
for filename in argv[1:]:
try:
with open(filename, 'rb') as f:
lines = f.readlines()
new_lines = [ws_re.sub(r'\1', line) for line in lines]
if new_lines != lines:
print('Fixing %s...' % filename)
shutil.copyfile(filename, filename + '.bak')
with open(filename, 'wb') as f:
f.writelines(new_lines)
except Exception as err:
print('Cannot fix %s: %s' % (filename, err))
rv = 1
return rv
if __name__ == '__main__': if __name__ == '__main__':
sys.exit(main()) sys.exit(main())

View file

@ -23,7 +23,7 @@ def main():
for filename in args: for filename in args:
process(filename, tabsize) process(filename, tabsize)
def process(filename, tabsize): def process(filename, tabsize, verbose=True):
try: try:
f = open(filename) f = open(filename)
text = f.read() text = f.read()
@ -46,7 +46,8 @@ def process(filename, tabsize):
f = open(filename, "w") f = open(filename, "w")
f.write(newtext) f.write(newtext)
f.close() f.close()
print(filename) if verbose:
print(filename)
if __name__ == '__main__': if __name__ == '__main__':
main() main()