From 255f53bdb54a64b93035374ca4484ba0cc1b41e1 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Sat, 8 Dec 2007 15:33:56 +0000 Subject: Merged revisions 59376-59406 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r59377 | georg.brandl | 2007-12-06 01:24:23 +0100 (Thu, 06 Dec 2007) | 2 lines Add another GHOP student to ACKS. ........ r59378 | raymond.hettinger | 2007-12-06 01:56:53 +0100 (Thu, 06 Dec 2007) | 5 lines Fix Issue 1045. Factor-out common calling code by simplifying the length_hint API. Speed-up the function by caching the PyObject_String for the attribute lookup. ........ r59380 | georg.brandl | 2007-12-06 02:52:24 +0100 (Thu, 06 Dec 2007) | 2 lines Diverse markup fixes. ........ r59383 | georg.brandl | 2007-12-06 10:45:39 +0100 (Thu, 06 Dec 2007) | 2 lines Better re.split examples. ........ r59386 | christian.heimes | 2007-12-06 14:15:13 +0100 (Thu, 06 Dec 2007) | 2 lines Fixed get_config_h_filename for Windows. Without the patch it can't find the pyconfig.h file inside a build tree. Added several small unit tests for sysconfig. ........ r59387 | christian.heimes | 2007-12-06 14:30:11 +0100 (Thu, 06 Dec 2007) | 1 line Silence more warnings, _CRT_NONSTDC_NO_DEPRECATE is already defined in pyconfig.h but several projects don't include it. ........ r59389 | christian.heimes | 2007-12-06 14:55:01 +0100 (Thu, 06 Dec 2007) | 1 line Disabled one test that is failing on Unix ........ r59399 | christian.heimes | 2007-12-06 22:13:06 +0100 (Thu, 06 Dec 2007) | 8 lines Several Windows related cleanups: * Removed a #define from pyconfig.h. The macro was already defined a few lines higher. * Fixed path to tix in the build_tkinter.py script * Changed make_buildinfo.c to use versions of unlink and strcat which are considered safe by Windows (as suggested by MvL). * Removed two defines from pyproject.vsprops that are no longer required. Both are defined in pyconfig.h and make_buildinfo.c doesn't use the unsafe versions any more (as suggested by MvL). * Added some more information about PGO and the property files to PCbuild9/readme.txt. Are you fine with the changes, Martin? ........ r59400 | raymond.hettinger | 2007-12-07 02:53:01 +0100 (Fri, 07 Dec 2007) | 4 lines Don't have the docs berate themselves. Keep a professional tone. If a todo is needed, put it in the tracker. ........ r59402 | georg.brandl | 2007-12-07 10:07:10 +0100 (Fri, 07 Dec 2007) | 3 lines Increase unit test coverage of SimpleXMLRPCServer. Written for GHOP by Turkay Eren. ........ r59406 | georg.brandl | 2007-12-07 16:16:57 +0100 (Fri, 07 Dec 2007) | 2 lines Update to windows doc from Robert. ........ --- Doc/ACKS.txt | 1 + Doc/c-api/newtypes.rst | 4 +- Doc/library/bdb.rst | 2 +- Doc/library/logging.rst | 2 +- Doc/library/objects.rst | 5 -- Doc/library/othergui.rst | 2 +- Doc/library/re.rst | 28 +++++---- Doc/library/ssl.rst | 3 +- Doc/library/tarfile.rst | 2 +- Doc/using/windows.rst | 17 ++++-- Include/abstract.h | 21 ++----- Lib/distutils/sysconfig.py | 19 +++++-- Lib/test/list_tests.py | 2 - Lib/test/test_xmlrpc.py | 137 +++++++++++++++++++++++++++++++++++++++++++-- Misc/ACKS | 1 + Objects/abstract.c | 68 ++++++++++++---------- Objects/bytesobject.c | 15 +---- Objects/listobject.c | 12 +--- PC/pyconfig.h | 6 -- PCbuild9/build_tkinter.py | 3 +- PCbuild9/make_buildinfo.c | 26 +++++---- PCbuild9/pyproject.vsprops | 2 +- PCbuild9/readme.txt | 15 ++++- 23 files changed, 260 insertions(+), 133 deletions(-) diff --git a/Doc/ACKS.txt b/Doc/ACKS.txt index 350b1fa..09ac0ab 100644 --- a/Doc/ACKS.txt +++ b/Doc/ACKS.txt @@ -122,6 +122,7 @@ docs@python.org), and we'll be glad to correct the problem. * Vincent Marchetti * Laura Matson * Daniel May +* Rebecca McCreary * Doug Mennella * Paolo Milani * Skip Montanaro diff --git a/Doc/c-api/newtypes.rst b/Doc/c-api/newtypes.rst index 2cf2099..b557957 100644 --- a/Doc/c-api/newtypes.rst +++ b/Doc/c-api/newtypes.rst @@ -1541,13 +1541,13 @@ Sequence Object Structures .. cmember:: binaryfunc PySequenceMethods.sq_concat This function is used by :cfunc:`PySequence_Concat` and has the same - signature. It is also used by the `+` operator, after trying the numeric + signature. It is also used by the ``+`` operator, after trying the numeric addition via the :attr:`tp_as_number.nb_add` slot. .. cmember:: ssizeargfunc PySequenceMethods.sq_repeat This function is used by :cfunc:`PySequence_Repeat` and has the same - signature. It is also used by the `*` operator, after trying numeric + signature. It is also used by the ``*`` operator, after trying numeric multiplication via the :attr:`tp_as_number.nb_mul` slot. .. cmember:: ssizeargfunc PySequenceMethods.sq_item diff --git a/Doc/library/bdb.rst b/Doc/library/bdb.rst index a8a61f1..36f8300 100644 --- a/Doc/library/bdb.rst +++ b/Doc/library/bdb.rst @@ -239,7 +239,7 @@ something went wrong, or ``None`` if all is well. .. method:: Bdb.clear_bpbynumber(arg) Delete the breakpoint which has the index *arg* in the - :attr:`Breakpoint.bpbynumber`. If `arg` is not numeric or out of range, + :attr:`Breakpoint.bpbynumber`. If *arg* is not numeric or out of range, return an error message. .. method:: Bdb.clear_all_file_breaks(filename) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 7805154..537ac3a 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -741,7 +741,7 @@ functions. The proposal which described this feature for inclusion in the Python standard library. - `Original Python :mod:`logging` package `_ + `Original Python logging package `_ This is the original source for the :mod:`logging` package. The version of the package available from this site is suitable for use with Python 1.5.2, 2.1.x and 2.2.x, which do not include the :mod:`logging` package in the standard diff --git a/Doc/library/objects.rst b/Doc/library/objects.rst index c6cc9e4..a0e66d1 100644 --- a/Doc/library/objects.rst +++ b/Doc/library/objects.rst @@ -25,8 +25,3 @@ from left to right. (Unary operators group from right to left, but there you have no real choice.) See :ref:`operator-summary` for the complete picture on operator priorities. -.. rubric:: Footnotes - -.. [#] Most descriptions sorely lack explanations of the exceptions that may be raised - --- this will be fixed in a future version of this manual. - diff --git a/Doc/library/othergui.rst b/Doc/library/othergui.rst index aadb74d..91b59e0 100644 --- a/Doc/library/othergui.rst +++ b/Doc/library/othergui.rst @@ -48,7 +48,7 @@ also available for Python: online `tutorial `_ is available. - `PyQt `_ + `PyQt `_ PyQt is a :program:`sip`\ -wrapped binding to the Qt toolkit. Qt is an extensive C++ GUI application development framework that is available for Unix, Windows and Mac OS X. :program:`sip` is a tool diff --git a/Doc/library/re.rst b/Doc/library/re.rst index 17da18e..88912eb 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -1078,16 +1078,21 @@ method is invaluable for converting textual data into data structures that can b easily read and modified by Python as demonstrated in the following example that creates a phonebook. -First, get the input using triple-quoted string syntax:: +First, here is the input. Normally it may come from a file, here we are using +triple-quoted string syntax:: - >>> input = """Ross McFluff 834.345.1254 155 Elm Street - Ronald Heathmore 892.345.3428 436 Finley Avenue - Frank Burger 925.541.7625 662 South Dogwood Way - Heather Albrecht 548.326.4584 919 Park Place""" + >>> input = """Ross McFluff: 834.345.1254 155 Elm Street -Then, convert the string into a list with each line having its own entry:: + Ronald Heathmore: 892.345.3428 436 Finley Avenue + Frank Burger: 925.541.7625 662 South Dogwood Way - >>> entries = re.split("\n", input) + + Heather Albrecht: 548.326.4584 919 Park Place""" + +The entries are separated by one or more newlines. Now we convert the string +into a list with each nonempty line having its own entry:: + + >>> entries = re.split("\n+", input) >>> entries ['Ross McFluff 834.345.1254 155 Elm Street', 'Ronald Heathmore 892.345.3428 436 Finley Avenue', @@ -1098,16 +1103,17 @@ Finally, split each entry into a list with first name, last name, telephone number, and address. We use the ``maxsplit`` paramater of :func:`split` because the address has spaces, our splitting pattern, in it:: - >>> [re.split(" ", entry, 3) for entry in entries] + >>> [re.split(":? ", entry, 3) for entry in entries] [['Ross', 'McFluff', '834.345.1254', '155 Elm Street'], ['Ronald', 'Heathmore', '892.345.3428', '436 Finley Avenue'], ['Frank', 'Burger', '925.541.7625', '662 South Dogwood Way'], ['Heather', 'Albrecht', '548.326.4584', '919 Park Place']] -With a ``maxsplit`` of ``4``, we could seperate the house number from the street -name:: +The ``:?`` pattern matches the colon after the last name, so that it does not +occur in the result list. With a ``maxsplit`` of ``4``, we could seperate the +house number from the street name:: - >>> [re.split(" ", entry, 4) for entry in entries] + >>> [re.split(":? ", entry, 4) for entry in entries] [['Ross', 'McFluff', '834.345.1254', '155', 'Elm Street'], ['Ronald', 'Heathmore', '892.345.3428', '436', 'Finley Avenue'], ['Frank', 'Burger', '925.541.7625', '662', 'South Dogwood Way'], diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 5675baa..2fd651e 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -109,13 +109,14 @@ Functions, Constants, and Exceptions ======================== ========= ========= ========== ========= *client* / **server** **SSLv2** **SSLv3** **SSLv23** **TLSv1** + ------------------------ --------- --------- ---------- --------- *SSLv2* yes no yes* no *SSLv3* yes yes yes no *SSLv23* yes no yes no *TLSv1* no no yes yes ======================== ========= ========= ========== ========= - `*` In some older versions of OpenSSL (for instance, 0.9.7l on OS X 10.4), + In some older versions of OpenSSL (for instance, 0.9.7l on OS X 10.4), an SSLv2 client could not connect to an SSLv23 server. The parameter ``do_handshake_on_connect`` specifies whether to do the SSL diff --git a/Doc/library/tarfile.rst b/Doc/library/tarfile.rst index 7893ccd..5f18155 100644 --- a/Doc/library/tarfile.rst +++ b/Doc/library/tarfile.rst @@ -13,7 +13,7 @@ The :mod:`tarfile` module makes it possible to read and write tar archives, including those using gzip or bz2 compression. -(`.zip` files can be read and written using the :mod:`zipfile` module.) +(:file:`.zip` files can be read and written using the :mod:`zipfile` module.) Some facts and figures: diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index 9f549fa..9a16938 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -73,6 +73,8 @@ key features: Popular modules (such as PyWin32) with their respective documentation, tool suite for building extensible python applications +Notice that these packages are likely to install *older* versions of Python. + Configuring Python @@ -85,10 +87,11 @@ settings in Windows. Excursus: Setting environment variables --------------------------------------- -Windows has a built-in dialog for changing environment variables: Right-click -the icon for your machine (usually located on your Desktop and called "My -Computer") and choose :menuselection:`Properties` there. Then, open the -:guilabel:`Advanced` tab and click the :guilabel:`Environment Variables` button. +Windows has a built-in dialog for changing environment variables (following +guide applies to XP classical view): Right-click the icon for your machine +(usually located on your Desktop and called "My Computer") and choose +:menuselection:`Properties` there. Then, open the :guilabel:`Advanced` tab +and click the :guilabel:`Environment Variables` button. In short, your path is: @@ -107,7 +110,8 @@ command:: set PYTHONPATH=%PYTHONPATH%;C:\My_python_lib To make this setting permanent, you could add the corresponding command line to -your :file:`autoexec.bat`. +your :file:`autoexec.bat`. :program:`msconfig` is a graphical interface to this +file. Viewing environment variables can also be done more straight-forward: The command prompt will expand strings wrapped into percent signs automatically:: @@ -124,6 +128,9 @@ Consult :command:`set /?` for details on this behaviour. http://support.microsoft.com/kb/310519 How To Manage Environment Variables in Windows XP + http://www.chem.gla.ac.uk/~louis/software/faq/q1.html + Setting Environment variables, Louis J. Farrugia + Finding the Python executable ----------------------------- diff --git a/Include/abstract.h b/Include/abstract.h index dfef938..e344fba 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -410,25 +410,12 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/ PyAPI_FUNC(Py_ssize_t) PyObject_Length(PyObject *o); #define PyObject_Length PyObject_Size - PyAPI_FUNC(Py_ssize_t) _PyObject_LengthHint(PyObject *o); + PyAPI_FUNC(Py_ssize_t) _PyObject_LengthHint(PyObject *o, Py_ssize_t); /* - Return the size of object o. If the object, o, provides - both sequence and mapping protocols, the sequence size is - returned. On error, -1 is returned. If the object provides - a __length_hint__() method, its value is returned. This is an - internal undocumented API provided for performance reasons; - for compatibility, don't use it outside the core. This is the - equivalent to the Python expression: - try: - return len(o) - except (AttributeError, TypeError): - exc_type, exc_value, exc_tb = sys.exc_info() - try: - return o.__length_hint__() - except: - pass - raise exc_type, exc_value, exc_tb + Guess the size of object o using len(o) or o.__length_hint__(). + If neither of those return a non-negative value, then return the + default value. This function never fails. All exceptions are cleared. */ PyAPI_FUNC(PyObject *) PyObject_GetItem(PyObject *o, PyObject *key); diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py index 70a2799..191f3d1 100644 --- a/Lib/distutils/sysconfig.py +++ b/Lib/distutils/sysconfig.py @@ -22,13 +22,17 @@ from .errors import DistutilsPlatformError PREFIX = os.path.normpath(sys.prefix) EXEC_PREFIX = os.path.normpath(sys.exec_prefix) +# Path to the base directory of the project. On Windows the binary may +# live in project/PCBuild9 +project_base = os.path.dirname(os.path.abspath(sys.executable)) +if os.name == "nt" and "pcbuild" in project_base[-8:].lower(): + project_base = os.path.abspath(os.path.join(project_base, os.path.pardir)) + # python_build: (Boolean) if true, we're either building Python or # building an extension with an un-installed Python, so we use # different (hard-wired) directories. - -argv0_path = os.path.dirname(os.path.abspath(sys.executable)) -python_build = os.path.isfile(os.path.join(argv0_path, "Modules", "Setup")) - +python_build = os.path.isfile(os.path.join(project_base, "Modules", + "Setup.dist")) def get_python_version(): """Return a string containing the major and minor Python version, @@ -177,7 +181,10 @@ def customize_compiler(compiler): def get_config_h_filename(): """Return full pathname of installed pyconfig.h file.""" if python_build: - inc_dir = argv0_path + if os.name == "nt": + inc_dir = os.path.join(project_base, "PC") + else: + inc_dir = project_base else: inc_dir = get_python_inc(plat_specific=1) if get_python_version() < '2.2': @@ -402,6 +409,8 @@ def _init_nt(): g['SO'] = '.pyd' g['EXE'] = ".exe" + g['VERSION'] = get_python_version().replace(".", "") + g['BINDIR'] = os.path.dirname(os.path.abspath(sys.executable)) global _config_vars _config_vars = g diff --git a/Lib/test/list_tests.py b/Lib/test/list_tests.py index 4317316..f03cdfe 100644 --- a/Lib/test/list_tests.py +++ b/Lib/test/list_tests.py @@ -521,7 +521,5 @@ class CommonTest(seq_tests.CommonTest): # Bug #1242657 class F(object): def __iter__(self): - yield 23 - def __len__(self): raise KeyboardInterrupt self.assertRaises(KeyboardInterrupt, list, F()) diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py index 2674716..75a69e8 100644 --- a/Lib/test/test_xmlrpc.py +++ b/Lib/test/test_xmlrpc.py @@ -7,6 +7,9 @@ import xmlrpclib import SimpleXMLRPCServer import threading import mimetools +import httplib +import socket +import os from test import test_support alist = [{'astring': 'foo@bar.baz.spam', @@ -254,9 +257,16 @@ PORT = None def http_server(evt, numrequests): class TestInstanceClass: def div(self, x, y): - '''This is the div function''' return x // y + def _methodHelp(self, name): + if name == 'div': + return 'This is the div function' + + def my_function(): + '''This is my function''' + return True + try: serv = SimpleXMLRPCServer.SimpleXMLRPCServer(("localhost", 0), logRequests=False, bind_and_activate=False) @@ -268,6 +278,7 @@ def http_server(evt, numrequests): serv.register_multicall_functions() serv.register_function(pow) serv.register_function(lambda x,y: x+y, 'add') + serv.register_function(my_function) serv.register_instance(TestInstanceClass()) # handle up to 'numrequests' requests @@ -284,7 +295,6 @@ def http_server(evt, numrequests): - class SimpleServerTestCase(unittest.TestCase): def setUp(self): # enable traceback reporting @@ -318,12 +328,25 @@ class SimpleServerTestCase(unittest.TestCase): # protocol error; provide additional information in test output self.fail("%s\n%s" % (e, e.headers)) + def test_404(self): + # send POST with httplib, it should return 404 header and + # 'Not Found' message. + import pdb; pdb.set_trace() + conn = httplib.HTTPConnection('localhost', PORT) + conn.request(b'POST', b'/this-is-not-valid') + response = conn.getresponse() + conn.close() + + self.assertEqual(response.status, 404) + self.assertEqual(response.reason, 'Not Found') + def test_introspection1(self): try: p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT) meth = p.system.listMethods() - expected_methods = set(['pow', 'div', 'add', 'system.listMethods', - 'system.methodHelp', 'system.methodSignature', 'system.multicall']) + expected_methods = set(['pow', 'div', 'my_function', 'add', + 'system.listMethods', 'system.methodHelp', + 'system.methodSignature', 'system.multicall']) self.assertEqual(set(meth), expected_methods) except xmlrpclib.ProtocolError as e: # protocol error; provide additional information in test output @@ -331,6 +354,7 @@ class SimpleServerTestCase(unittest.TestCase): def test_introspection2(self): try: + # test _methodHelp() p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT) divhelp = p.system.methodHelp('div') self.assertEqual(divhelp, 'This is the div function') @@ -339,6 +363,18 @@ class SimpleServerTestCase(unittest.TestCase): self.fail("%s\n%s" % (e, e.headers)) def test_introspection3(self): + try: + # test native doc + p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT) + myfunction = p.system.methodHelp('my_function') + self.assertEqual(myfunction, 'This is my function') + except xmlrpclib.ProtocolError as e: + # ignore failures due to non-blocking socket 'unavailable' errors + if not is_unavailable_exception(e): + # protocol error; provide additional information in test output + self.fail("%s\n%s" % (e, e.headers)) + + def test_introspection4(self): # the SimpleXMLRPCServer doesn't support signatures, but # at least check that we can try making the call try: @@ -364,6 +400,34 @@ class SimpleServerTestCase(unittest.TestCase): # protocol error; provide additional information in test output self.fail("%s\n%s" % (e, e.headers)) + def test_non_existing_multicall(self): + try: + p = xmlrpclib.ServerProxy('http://localhost:%d' % PORT) + multicall = xmlrpclib.MultiCall(p) + multicall.this_is_not_exists() + result = multicall() + + # result.results contains; + # [{'faultCode': 1, 'faultString': ':' + # 'method "this_is_not_exists" is not supported'>}] + + self.assertEqual(result.results[0]['faultCode'], 1) + self.assertEqual(result.results[0]['faultString'], + ':method "this_is_not_exists" ' + 'is not supported') + except xmlrpclib.ProtocolError as e: + # ignore failures due to non-blocking socket 'unavailable' errors + if not is_unavailable_exception(e): + # protocol error; provide additional information in test output + self.fail("%s\n%s" % (e, e.headers)) + + def test_dotted_attribute(self): + # this will raise AttirebuteError because code don't want us to use + # private methods + self.assertRaises(AttributeError, + SimpleXMLRPCServer.resolve_dotted_attribute, str, '__add') + + self.assert_(SimpleXMLRPCServer.resolve_dotted_attribute(str, 'title')) # This is a contrived way to make a failure occur on the server side # in order to test the _send_traceback_header flag on the server @@ -447,6 +511,70 @@ class FailingServerTestCase(unittest.TestCase): else: self.fail('ProtocolError not raised') +class CGIHandlerTestCase(unittest.TestCase): + def setUp(self): + self.cgi = SimpleXMLRPCServer.CGIXMLRPCRequestHandler() + + def tearDown(self): + self.cgi = None + + def test_cgi_get(self): + os.environ['REQUEST_METHOD'] = 'GET' + # if the method is GET and no request_text is given, it runs handle_get + # get sysout output + tmp = sys.stdout + sys.stdout = open(test_support.TESTFN, "w") + self.cgi.handle_request() + sys.stdout.close() + sys.stdout = tmp + + # parse Status header + handle = open(test_support.TESTFN, "r").read() + status = handle.split()[1] + message = ' '.join(handle.split()[2:4]) + + self.assertEqual(status, '400') + self.assertEqual(message, 'Bad Request') + + os.remove(test_support.TESTFN) + os.environ['REQUEST_METHOD'] = '' + + def test_cgi_xmlrpc_response(self): + data = """ + + test_method + + + foo + + + bar + + + +""" + open("xmldata.txt", "w").write(data) + tmp1 = sys.stdin + tmp2 = sys.stdout + + sys.stdin = open("xmldata.txt", "r") + sys.stdout = open(test_support.TESTFN, "w") + + self.cgi.handle_request() + + sys.stdin.close() + sys.stdout.close() + sys.stdin = tmp1 + sys.stdout = tmp2 + + # will respond exception, if so, our goal is achieved ;) + handle = open(test_support.TESTFN, "r").read() + + # start with 44th char so as not to get http header, we just need only xml + self.assertRaises(xmlrpclib.Fault, xmlrpclib.loads, handle[44:]) + + os.remove("xmldata.txt") + os.remove(test_support.TESTFN) def test_main(): xmlrpc_tests = [XMLRPCTestCase, HelperTestCase, DateTimeTestCase, @@ -459,6 +587,7 @@ def test_main(): if sys.platform != 'win32': xmlrpc_tests.append(SimpleServerTestCase) xmlrpc_tests.append(FailingServerTestCase) + xmlrpc_tests.append(CGIHandlerTestCase) test_support.run_unittest(*xmlrpc_tests) diff --git a/Misc/ACKS b/Misc/ACKS index 7266ef7..05256ab 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -190,6 +190,7 @@ David Ely Jeff Epler Tom Epperly Stoffel Erasmus +Turkay Eren Jürgen A. Erhard Michael Ernst Ben Escoto diff --git a/Objects/abstract.c b/Objects/abstract.c index df5da5f..8b3006a 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -80,29 +80,47 @@ PyObject_Length(PyObject *o) } #define PyObject_Length PyObject_Size + +/* The length hint function returns a non-negative value from o.__len__() + or o.__length_hint__(). If those methods aren't found or return a negative + value, then the defaultvalue is returned. This function never fails. + Accordingly, it will mask exceptions raised in either method. +*/ + Py_ssize_t -_PyObject_LengthHint(PyObject *o) +_PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue) { - Py_ssize_t rv = PyObject_Size(o); - if (rv != -1) + static PyObject *hintstrobj = NULL; + PyObject *ro; + Py_ssize_t rv; + + /* try o.__len__() */ + rv = PyObject_Size(o); + if (rv >= 0) return rv; - if (PyErr_ExceptionMatches(PyExc_TypeError) || - PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyObject *err_type, *err_value, *err_tb, *ro; - - PyErr_Fetch(&err_type, &err_value, &err_tb); - ro = PyObject_CallMethod(o, "__length_hint__", NULL); - if (ro != NULL) { - rv = PyLong_AsLong(ro); - Py_DECREF(ro); - Py_XDECREF(err_type); - Py_XDECREF(err_value); - Py_XDECREF(err_tb); - return rv; - } - PyErr_Restore(err_type, err_value, err_tb); + if (PyErr_Occurred()) + PyErr_Clear(); + + /* cache a hashed version of the attribute string */ + if (hintstrobj == NULL) { + hintstrobj = PyUnicode_InternFromString("__length_hint__"); + if (hintstrobj == NULL) + goto defaultcase; } - return -1; + + /* try o.__length_hint__() */ + ro = PyObject_CallMethodObjArgs(o, hintstrobj, NULL); + if (ro == NULL) + goto defaultcase; + rv = PyLong_AsSsize_t(ro); + Py_DECREF(ro); + if (rv >= 0) + return rv; + +defaultcase: + if (PyErr_Occurred()) + PyErr_Clear(); + return defaultvalue; } PyObject * @@ -1655,17 +1673,7 @@ PySequence_Tuple(PyObject *v) return NULL; /* Guess result size and allocate space. */ - n = _PyObject_LengthHint(v); - if (n < 0) { - if (PyErr_Occurred() - && !PyErr_ExceptionMatches(PyExc_TypeError) - && !PyErr_ExceptionMatches(PyExc_AttributeError)) { - Py_DECREF(it); - return NULL; - } - PyErr_Clear(); - n = 10; /* arbitrary */ - } + n = _PyObject_LengthHint(v, 10); result = PyTuple_New(n); if (result == NULL) goto Fail; diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index c0f4e81..9e16b3b 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2598,19 +2598,8 @@ bytes_extend(PyBytesObject *self, PyObject *arg) if (it == NULL) return NULL; - /* Try to determine the length of the argument. */ - buf_size = _PyObject_LengthHint(arg); - /* The length of the argument is unknown or invalid. */ - if (buf_size < 0) { - if (PyErr_Occurred() - && !PyErr_ExceptionMatches(PyExc_TypeError) - && !PyErr_ExceptionMatches(PyExc_AttributeError)) { - Py_DECREF(it); - return NULL; - } - PyErr_Clear(); - buf_size = 32; /* arbitrary */ - } + /* Try to determine the length of the argument. 32 is abitrary. */ + buf_size = _PyObject_LengthHint(arg, 32); buf = (char *)PyMem_Malloc(buf_size * sizeof(char)); if (buf == NULL) diff --git a/Objects/listobject.c b/Objects/listobject.c index 18d3b90..efcedc7 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -758,17 +758,7 @@ listextend(PyListObject *self, PyObject *b) iternext = *it->ob_type->tp_iternext; /* Guess a result list size. */ - n = _PyObject_LengthHint(b); - if (n < 0) { - if (PyErr_Occurred() - && !PyErr_ExceptionMatches(PyExc_TypeError) - && !PyErr_ExceptionMatches(PyExc_AttributeError)) { - Py_DECREF(it); - return NULL; - } - PyErr_Clear(); - n = 8; /* arbitrary */ - } + n = _PyObject_LengthHint(b, 8); m = Py_Size(self); mn = m + n; if (mn >= m) { diff --git a/PC/pyconfig.h b/PC/pyconfig.h index 58beaa8..36cc0c9 100644 --- a/PC/pyconfig.h +++ b/PC/pyconfig.h @@ -209,12 +209,6 @@ typedef int pid_t; #define Py_IS_INFINITY(X) (!_finite(X) && !_isnan(X)) #define Py_IS_FINITE(X) _finite(X) -/* Turn off warnings about deprecated C runtime functions in - VisualStudio .NET 2005 */ -#if _MSC_VER >= 1400 && !defined _CRT_SECURE_NO_DEPRECATE -#define _CRT_SECURE_NO_DEPRECATE -#endif - #endif /* _MSC_VER */ /* define some ANSI types that are not defined in earlier Win headers */ diff --git a/PCbuild9/build_tkinter.py b/PCbuild9/build_tkinter.py index d76ea26..3e24d00 100644 --- a/PCbuild9/build_tkinter.py +++ b/PCbuild9/build_tkinter.py @@ -14,7 +14,7 @@ par = os.path.pardir TCL = "tcl8.4.16" TK = "tk8.4.16" -TIX = "Tix8.4.0" +TIX = "tix-8.4.0" #TIX = "Tix8.4.2" ROOT = os.path.abspath(os.path.join(here, par, par)) NMAKE = "nmake /nologo " @@ -53,6 +53,7 @@ def build(platform, clean): # TIX if True: + # python9.mak is available at http://svn.python.org os.chdir(os.path.join(ROOT, TIX, "win")) if clean: system(NMAKE + "/f python9.mak clean") diff --git a/PCbuild9/make_buildinfo.c b/PCbuild9/make_buildinfo.c index 4cebf45..22b9882 100644 --- a/PCbuild9/make_buildinfo.c +++ b/PCbuild9/make_buildinfo.c @@ -3,6 +3,8 @@ #include #include +#define CMD_SIZE 500 + /* This file creates the getbuildinfo.o object, by first invoking subwcrev.exe (if found), and then invoking cl.exe. As a side effect, it might generate PCBuild\getbuildinfo2.c @@ -23,7 +25,7 @@ int make_buildinfo2() { struct _stat st; HKEY hTortoise; - char command[500]; + char command[CMD_SIZE+1]; DWORD type, size; if (_stat(".svn", &st) < 0) return 0; @@ -40,11 +42,11 @@ int make_buildinfo2() type != REG_SZ) /* Registry corrupted */ return 0; - strcat(command, "bin\\subwcrev.exe"); + strcat_s(command, CMD_SIZE, "bin\\subwcrev.exe"); if (_stat(command+1, &st) < 0) /* subwcrev.exe not part of the release */ return 0; - strcat(command, "\" .. ..\\Modules\\getbuildinfo.c getbuildinfo2.c"); + strcat_s(command, CMD_SIZE, "\" .. ..\\Modules\\getbuildinfo.c getbuildinfo2.c"); puts(command); fflush(stdout); if (system(command) < 0) return 0; @@ -60,17 +62,17 @@ int main(int argc, char*argv[]) return EXIT_FAILURE; } if (strcmp(argv[1], "Release") == 0) { - strcat(command, "-MD "); + strcat_s(command, CMD_SIZE, "-MD "); } else if (strcmp(argv[1], "Debug") == 0) { - strcat(command, "-D_DEBUG -MDd "); + strcat_s(command, CMD_SIZE, "-D_DEBUG -MDd "); } else if (strcmp(argv[1], "ReleaseItanium") == 0) { - strcat(command, "-MD /USECL:MS_ITANIUM "); + strcat_s(command, CMD_SIZE, "-MD /USECL:MS_ITANIUM "); } else if (strcmp(argv[1], "ReleaseAMD64") == 0) { - strcat(command, "-MD "); - strcat(command, "-MD /USECL:MS_OPTERON "); + strcat_s(command, CMD_SIZE, "-MD "); + strcat_s(command, CMD_SIZE, "-MD /USECL:MS_OPTERON "); } else { fprintf(stderr, "unsupported configuration %s\n", argv[1]); @@ -78,14 +80,14 @@ int main(int argc, char*argv[]) } if ((do_unlink = make_buildinfo2())) - strcat(command, "getbuildinfo2.c -DSUBWCREV "); + strcat_s(command, CMD_SIZE, "getbuildinfo2.c -DSUBWCREV "); else - strcat(command, "..\\Modules\\getbuildinfo.c"); - strcat(command, " -Fogetbuildinfo.o -I..\\Include -I..\\PC"); + strcat_s(command, CMD_SIZE, "..\\Modules\\getbuildinfo.c"); + strcat_s(command, CMD_SIZE, " -Fogetbuildinfo.o -I..\\Include -I..\\PC"); puts(command); fflush(stdout); result = system(command); if (do_unlink) - unlink("getbuildinfo2.c"); + _unlink("getbuildinfo2.c"); if (result < 0) return EXIT_FAILURE; return 0; diff --git a/PCbuild9/pyproject.vsprops b/PCbuild9/pyproject.vsprops index ba3a675..e8252c0 100644 --- a/PCbuild9/pyproject.vsprops +++ b/PCbuild9/pyproject.vsprops @@ -12,7 +12,7 @@ InlineFunctionExpansion="1" EnableIntrinsicFunctions="true" AdditionalIncludeDirectories="..\Include; ..\PC" - PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WIN32" + PreprocessorDefinitions="_WIN32" StringPooling="true" ExceptionHandling="0" RuntimeLibrary="0" diff --git a/PCbuild9/readme.txt b/PCbuild9/readme.txt index fd3967a..ef3b97d 100644 --- a/PCbuild9/readme.txt +++ b/PCbuild9/readme.txt @@ -281,6 +281,14 @@ Edition. Profile Guided Optimization --------------------------- +The solution has two configurations for PGO. The PGInstrument configuration +must be build first. The PGInstrument binaries are lniked against a profiling +library and contain extra debug information. The PGUpdate configuration takes the profiling data and generates optimized binaries. + +The build_pgo.bat script automates the creation of optimized binaries. It +creates the PGI files, runs the unit test suite or PyBench with the PGI +python and finally creates the optimized files. + http://msdn2.microsoft.com/en-us/library/e7k32f4k(VS.90).aspx Static library @@ -300,7 +308,7 @@ The PCbuild9 solution makes heavy use of Visual Studio property files (*.vsprops). The properties can be viewed and altered in the Property Manager (View -> Other Windows -> Property Manager). - * debug (debug macros) + * debug (debug macro: _DEBUG) * pginstrument (PGO) * pgupdate (PGO) +-- pginstrument @@ -310,8 +318,8 @@ Manager (View -> Other Windows -> Property Manager). * pyd_d (python extension, debug build) +-- debug +-- pyproject - * pyproject (base settings for all projects) - * release (release macros) + * pyproject (base settings for all projects, user macros like PyDllName) + * release (release macro: NDEBUG) * x64 (AMD64 / x64 platform specific settings) The pyproject propertyfile defines _WIN32 and x64 defines _WIN64 and _M_X64 @@ -320,6 +328,7 @@ about the macros and confuse the user with false information. YOUR OWN EXTENSION DLLs ----------------------- + If you want to create your own extension module DLL, there's an example with easy-to-follow instructions in ../PC/example/; read the file readme.txt there first. -- cgit v0.12