From 0be894b2f6ca17204922399d6982f0b8a9dc59a1 Mon Sep 17 00:00:00 2001 From: Martin Panter Date: Wed, 7 Sep 2016 12:03:06 +0000 Subject: =?UTF-8?q?Issue=20#27895:=20=20Spelling=20fixes=20(Contributed=20?= =?UTF-8?q?by=20Ville=20Skytt=C3=A4).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Doc/library/email.contentmanager.rst | 2 +- Doc/library/smtpd.rst | 4 ++-- Doc/whatsnew/3.3.rst | 2 +- Include/abstract.h | 2 +- Include/pymath.h | 2 +- Lib/asyncio/streams.py | 2 +- Lib/concurrent/futures/process.py | 2 +- Lib/concurrent/futures/thread.py | 2 +- Lib/distutils/tests/test_msvc9compiler.py | 2 +- Lib/email/message.py | 2 +- Lib/http/client.py | 2 +- Lib/idlelib/idle_test/test_formatparagraph.py | 2 +- Lib/shutil.py | 2 +- Lib/test/_test_multiprocessing.py | 2 +- Lib/test/datetimetester.py | 2 +- Lib/test/test_asyncio/test_locks.py | 4 ++-- Lib/test/test_concurrent_futures.py | 2 +- Lib/test/test_descr.py | 2 +- Lib/test/test_email/test_email.py | 4 ++-- Lib/test/test_importlib/test_util.py | 2 +- Lib/test/test_ipaddress.py | 6 +++--- Lib/test/test_pep247.py | 2 +- Lib/test/test_subprocess.py | 2 +- Lib/test/test_urllib.py | 2 +- Lib/test/test_winreg.py | 2 +- Lib/unittest/test/test_discovery.py | 2 +- Lib/unittest/test/testmock/testcallable.py | 2 +- Lib/venv/scripts/posix/activate | 2 +- Lib/venv/scripts/posix/activate.csh | 2 +- Lib/venv/scripts/posix/activate.fish | 2 +- Mac/PythonLauncher/MyAppDelegate.m | 2 +- Misc/HISTORY | 20 ++++++++++---------- Misc/NEWS | 10 +++++----- Modules/_ctypes/ctypes.h | 2 +- Modules/_hashopenssl.c | 2 +- Modules/_io/iobase.c | 2 +- Modules/_testcapimodule.c | 2 +- Modules/_threadmodule.c | 2 +- Modules/_tracemalloc.c | 2 +- Modules/mathmodule.c | 2 +- Modules/socketmodule.c | 2 +- Modules/zipimport.c | 2 +- Objects/bytearrayobject.c | 2 +- Objects/codeobject.c | 2 +- Objects/listsort.txt | 2 +- Objects/longobject.c | 2 +- Objects/typeobject.c | 2 +- Python/condvar.h | 2 +- Python/formatter_unicode.c | 2 +- README | 2 +- configure | 2 +- configure.ac | 2 +- 52 files changed, 70 insertions(+), 70 deletions(-) diff --git a/Doc/library/email.contentmanager.rst b/Doc/library/email.contentmanager.rst index c25d073..a9c078b 100644 --- a/Doc/library/email.contentmanager.rst +++ b/Doc/library/email.contentmanager.rst @@ -433,5 +433,5 @@ Currently the email package provides only one concrete content manager, If *headers* is specified and is a list of strings of the form ``headername: headervalue`` or a list of ``header`` objects - (distinguised from strings by having a ``name`` attribute), add the + (distinguished from strings by having a ``name`` attribute), add the headers to *msg*. diff --git a/Doc/library/smtpd.rst b/Doc/library/smtpd.rst index 080411b..a096de0 100644 --- a/Doc/library/smtpd.rst +++ b/Doc/library/smtpd.rst @@ -45,7 +45,7 @@ SMTPServer Objects dictionary is a suitable value). If not specified the :mod:`asyncore` global socket map is used. - *enable_SMTPUTF8* determins whether the ``SMTPUTF8`` extension (as defined + *enable_SMTPUTF8* determines whether the ``SMTPUTF8`` extension (as defined in :RFC:`6531`) should be enabled. The default is ``False``. If set to ``True``, *decode_data* must be ``False`` (otherwise an error is raised). When ``True``, ``SMTPUTF8`` is accepted as a parameter to the ``MAIL`` @@ -162,7 +162,7 @@ SMTPChannel Objects accepted in a ``DATA`` command. A value of ``None`` or ``0`` means no limit. - *enable_SMTPUTF8* determins whether the ``SMTPUTF8`` extension (as defined + *enable_SMTPUTF8* determines whether the ``SMTPUTF8`` extension (as defined in :RFC:`6531`) should be enabled. The default is ``False``. A :exc:`ValueError` is raised if both *enable_SMTPUTF8* and *decode_data* are set to ``True`` at the same time. diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst index 3e48c82..1cfa926 100644 --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -1954,7 +1954,7 @@ ssl :attr:`~ssl.OP_NO_COMPRESSION` can be used to disable compression. (Contributed by Antoine Pitrou in :issue:`13634`.) -* Support has been added for the Next Procotol Negotiation extension using +* Support has been added for the Next Protocol Negotiation extension using the :meth:`ssl.SSLContext.set_npn_protocols` method. (Contributed by Colin Marc in :issue:`14204`.) diff --git a/Include/abstract.h b/Include/abstract.h index 4ff79f2..438610b 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -458,7 +458,7 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/ /* old buffer API FIXME: usage of these should all be replaced in Python itself but for backwards compatibility we will implement them. - Their usage without a corresponding "unlock" mechansim + Their usage without a corresponding "unlock" mechanism may create issues (but they would already be there). */ PyAPI_FUNC(int) PyObject_AsCharBuffer(PyObject *obj, diff --git a/Include/pymath.h b/Include/pymath.h index 1ea9ac1..1c8d718 100644 --- a/Include/pymath.h +++ b/Include/pymath.h @@ -37,7 +37,7 @@ extern double pow(double, double); #endif /* __STDC__ */ #endif /* _MSC_VER */ -/* High precision defintion of pi and e (Euler) +/* High precision definition of pi and e (Euler) * The values are taken from libc6's math.h. */ #ifndef Py_MATH_PIl diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py index c88a87c..b4adc7d 100644 --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -590,7 +590,7 @@ class StreamReader: bytes. If the EOF was received and the internal buffer is empty, return an empty bytes object. - If n is zero, return empty bytes object immediatelly. + If n is zero, return empty bytes object immediately. If n is positive, this function try to read `n` bytes, and may return less or equal bytes than requested, but at least one byte. If EOF was diff --git a/Lib/concurrent/futures/process.py b/Lib/concurrent/futures/process.py index 590edba..8f1d714 100644 --- a/Lib/concurrent/futures/process.py +++ b/Lib/concurrent/futures/process.py @@ -63,7 +63,7 @@ import traceback # interpreter to exit when there are still idle processes in a # ProcessPoolExecutor's process pool (i.e. shutdown() was not called). However, # allowing workers to die with the interpreter has two undesirable properties: -# - The workers would still be running during interpretor shutdown, +# - The workers would still be running during interpreter shutdown, # meaning that they would fail in unpredictable ways. # - The workers could be killed while evaluating a work item, which could # be bad if the callable being evaluated has external side-effects e.g. diff --git a/Lib/concurrent/futures/thread.py b/Lib/concurrent/futures/thread.py index 3ae442d..9c3aec9 100644 --- a/Lib/concurrent/futures/thread.py +++ b/Lib/concurrent/futures/thread.py @@ -16,7 +16,7 @@ import os # to exit when there are still idle threads in a ThreadPoolExecutor's thread # pool (i.e. shutdown() was not called). However, allowing workers to die with # the interpreter has two undesirable properties: -# - The workers would still be running during interpretor shutdown, +# - The workers would still be running during interpreter shutdown, # meaning that they would fail in unpredictable ways. # - The workers could be killed while evaluating a work item, which could # be bad if the callable being evaluated has external side-effects e.g. diff --git a/Lib/distutils/tests/test_msvc9compiler.py b/Lib/distutils/tests/test_msvc9compiler.py index 5e18c61..77a07ef 100644 --- a/Lib/distutils/tests/test_msvc9compiler.py +++ b/Lib/distutils/tests/test_msvc9compiler.py @@ -125,7 +125,7 @@ class msvc9compilerTestCase(support.TempdirManager, self.assertRaises(KeyError, Reg.get_value, 'xxx', 'xxx') # looking for values that should exist on all - # windows registeries versions. + # windows registry versions. path = r'Control Panel\Desktop' v = Reg.get_value(path, 'dragfullwindows') self.assertIn(v, ('0', '1', '2')) diff --git a/Lib/email/message.py b/Lib/email/message.py index 6cd6cb7..4b04283 100644 --- a/Lib/email/message.py +++ b/Lib/email/message.py @@ -1043,7 +1043,7 @@ class MIMEPart(Message): yield from parts return # Otherwise we more or less invert the remaining logic in get_body. - # This only really works in edge cases (ex: non-text relateds or + # This only really works in edge cases (ex: non-text related or # alternatives) if the sending agent sets content-disposition. seen = [] # Only skip the first example of each candidate type. for part in parts: diff --git a/Lib/http/client.py b/Lib/http/client.py index 350313e8..25ae588 100644 --- a/Lib/http/client.py +++ b/Lib/http/client.py @@ -136,7 +136,7 @@ _MAXHEADERS = 100 # # VCHAR defined in http://tools.ietf.org/html/rfc5234#appendix-B.1 -# the patterns for both name and value are more leniant than RFC +# the patterns for both name and value are more lenient than RFC # definitions to allow for backwards compatibility _is_legal_header_name = re.compile(rb'[^:\s][^:\r\n]*').fullmatch _is_illegal_header_value = re.compile(rb'\n(?![ \t])|\r(?![ \t\n])').search diff --git a/Lib/idlelib/idle_test/test_formatparagraph.py b/Lib/idlelib/idle_test/test_formatparagraph.py index e5561d8..b6eb2f3 100644 --- a/Lib/idlelib/idle_test/test_formatparagraph.py +++ b/Lib/idlelib/idle_test/test_formatparagraph.py @@ -159,7 +159,7 @@ class FindTest(unittest.TestCase): class ReformatFunctionTest(unittest.TestCase): """Test the reformat_paragraph function without the editor window.""" - def test_reformat_paragrah(self): + def test_reformat_paragraph(self): Equal = self.assertEqual reform = fp.reformat_paragraph hw = "O hello world" diff --git a/Lib/shutil.py b/Lib/shutil.py index 3174648..dc9f2eb 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -64,7 +64,7 @@ class ReadError(OSError): class RegistryError(Exception): """Raised when a registry operation with the archiving - and unpacking registeries fails""" + and unpacking registries fails""" def copyfileobj(fsrc, fdst, length=16*1024): diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 11a6310..2becfaa 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -26,7 +26,7 @@ import test.support.script_helper _multiprocessing = test.support.import_module('_multiprocessing') # Skip tests if sem_open implementation is broken. test.support.import_module('multiprocessing.synchronize') -# import threading after _multiprocessing to raise a more revelant error +# import threading after _multiprocessing to raise a more relevant error # message: "No module named _multiprocessing". _multiprocessing is not compiled # without thread support. import threading diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index f5222c7..0860db8 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -3884,7 +3884,7 @@ class Oddballs(unittest.TestCase): self.assertRaises(TypeError, lambda: as_date >= as_datetime) self.assertRaises(TypeError, lambda: as_datetime >= as_date) - # Neverthelss, comparison should work with the base-class (date) + # Nevertheless, comparison should work with the base-class (date) # projection if use of a date method is forced. self.assertEqual(as_date.__eq__(as_datetime), True) different_day = (as_date.day + 1) % 20 + 1 diff --git a/Lib/test/test_asyncio/test_locks.py b/Lib/test/test_asyncio/test_locks.py index d3bdc51..e557212 100644 --- a/Lib/test/test_asyncio/test_locks.py +++ b/Lib/test/test_asyncio/test_locks.py @@ -130,8 +130,8 @@ class LockTests(test_utils.TestCase): def test_cancel_race(self): # Several tasks: # - A acquires the lock - # - B is blocked in aqcuire() - # - C is blocked in aqcuire() + # - B is blocked in acquire() + # - C is blocked in acquire() # # Now, concurrently: # - B is cancelled diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index cdb9308..7513815 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -4,7 +4,7 @@ import test.support test.support.import_module('_multiprocessing') # Skip tests if sem_open implementation is broken. test.support.import_module('multiprocessing.synchronize') -# import threading after _multiprocessing to raise a more revelant error +# import threading after _multiprocessing to raise a more relevant error # message: "No module named _multiprocessing". _multiprocessing is not compiled # without thread support. test.support.import_module('threading') diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index a130cec..418f8d2 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -876,7 +876,7 @@ class ClassPropertiesAndMethods(unittest.TestCase): self.assertEqual(Frag().__int__(), 42) self.assertEqual(int(Frag()), 42) - def test_diamond_inheritence(self): + def test_diamond_inheritance(self): # Testing multiple inheritance special cases... class A(object): def spam(self): return "A" diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py index 8e407f7..1e5366c 100644 --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -723,12 +723,12 @@ class TestMessageAPI(TestEmailBase): # Issue 5871: reject an attempt to embed a header inside a header value # (header injection attack). - def test_embeded_header_via_Header_rejected(self): + def test_embedded_header_via_Header_rejected(self): msg = Message() msg['Dummy'] = Header('dummy\nX-Injected-Header: test') self.assertRaises(errors.HeaderParseError, msg.as_string) - def test_embeded_header_via_string_rejected(self): + def test_embedded_header_via_string_rejected(self): msg = Message() msg['Dummy'] = 'dummy\nX-Injected-Header: test' self.assertRaises(errors.HeaderParseError, msg.as_string) diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py index 69466b2..41ca333 100644 --- a/Lib/test/test_importlib/test_util.py +++ b/Lib/test/test_importlib/test_util.py @@ -372,7 +372,7 @@ class ResolveNameTests: # bacon self.assertEqual('bacon', self.util.resolve_name('bacon', None)) - def test_aboslute_within_package(self): + def test_absolute_within_package(self): # bacon in spam self.assertEqual('bacon', self.util.resolve_name('bacon', 'spam')) diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py index 94bf4cd..91ae8d8 100644 --- a/Lib/test/test_ipaddress.py +++ b/Lib/test/test_ipaddress.py @@ -1262,7 +1262,7 @@ class IpaddrUnitTest(unittest.TestCase): ip4 = ipaddress.IPv4Address('1.1.1.3') ip5 = ipaddress.IPv4Address('1.1.1.4') ip6 = ipaddress.IPv4Address('1.1.1.0') - # check that addreses are subsumed properly. + # check that addresses are subsumed properly. collapsed = ipaddress.collapse_addresses( [ip1, ip2, ip3, ip4, ip5, ip6]) self.assertEqual(list(collapsed), @@ -1276,7 +1276,7 @@ class IpaddrUnitTest(unittest.TestCase): ip4 = ipaddress.IPv4Address('1.1.1.3') #ip5 = ipaddress.IPv4Interface('1.1.1.4/30') #ip6 = ipaddress.IPv4Interface('1.1.1.4/30') - # check that addreses are subsumed properly. + # check that addresses are subsumed properly. collapsed = ipaddress.collapse_addresses([ip1, ip2, ip3, ip4]) self.assertEqual(list(collapsed), [ipaddress.IPv4Network('1.1.1.0/30')]) @@ -1290,7 +1290,7 @@ class IpaddrUnitTest(unittest.TestCase): # stored in no particular order b/c we want CollapseAddr to call # [].sort ip6 = ipaddress.IPv4Network('1.1.0.0/22') - # check that addreses are subsumed properly. + # check that addresses are subsumed properly. collapsed = ipaddress.collapse_addresses([ip1, ip2, ip3, ip4, ip5, ip6]) self.assertEqual(list(collapsed), diff --git a/Lib/test/test_pep247.py b/Lib/test/test_pep247.py index ab5f4189..c17ceed 100644 --- a/Lib/test/test_pep247.py +++ b/Lib/test/test_pep247.py @@ -1,5 +1,5 @@ """ -Test suite to check compilance with PEP 247, the standard API +Test suite to check compliance with PEP 247, the standard API for hashing algorithms """ diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index 4b409b7..758e094 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -686,7 +686,7 @@ class ProcessTestCase(BaseTestCase): self.assertEqual(stdout, "banana") self.assertStderrEqual(stderr.encode(), b"pineapple\npear\n") - def test_communicate_timeout_large_ouput(self): + def test_communicate_timeout_large_output(self): # Test an expiring timeout while the child is outputting lots of data. p = subprocess.Popen([sys.executable, "-c", 'import sys,os,time;' diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py index c26c52a..247598a 100644 --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -1,4 +1,4 @@ -"""Regresssion tests for what was in Python 2's "urllib" module""" +"""Regression tests for what was in Python 2's "urllib" module""" import urllib.parse import urllib.request diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py index 2c4ac08..60207fb 100644 --- a/Lib/test/test_winreg.py +++ b/Lib/test/test_winreg.py @@ -168,7 +168,7 @@ class BaseWinregTests(unittest.TestCase): DeleteKey(key, subkeystr) try: - # Shouldnt be able to delete it twice! + # Shouldn't be able to delete it twice! DeleteKey(key, subkeystr) self.fail("Deleting the key twice succeeded") except OSError: diff --git a/Lib/unittest/test/test_discovery.py b/Lib/unittest/test/test_discovery.py index 8f4017f..1996a8e 100644 --- a/Lib/unittest/test/test_discovery.py +++ b/Lib/unittest/test/test_discovery.py @@ -349,7 +349,7 @@ class TestDiscovery(unittest.TestCase): suite = list(loader._find_tests(abspath('/foo'), 'test*.py')) # We should have loaded tests from both my_package and - # my_pacakge.test_module, and also run the load_tests hook in both. + # my_package.test_module, and also run the load_tests hook in both. # (normally this would be nested TestSuites.) self.assertEqual(suite, [['my_package load_tests', [], diff --git a/Lib/unittest/test/testmock/testcallable.py b/Lib/unittest/test/testmock/testcallable.py index 5390a4e..af1ce7e 100644 --- a/Lib/unittest/test/testmock/testcallable.py +++ b/Lib/unittest/test/testmock/testcallable.py @@ -27,7 +27,7 @@ class TestCallable(unittest.TestCase): self.assertIn(mock.__class__.__name__, repr(mock)) - def test_heirarchy(self): + def test_hierarchy(self): self.assertTrue(issubclass(MagicMock, Mock)) self.assertTrue(issubclass(NonCallableMagicMock, NonCallableMock)) diff --git a/Lib/venv/scripts/posix/activate b/Lib/venv/scripts/posix/activate index 7bbffd9..c78a4ef 100644 --- a/Lib/venv/scripts/posix/activate +++ b/Lib/venv/scripts/posix/activate @@ -34,7 +34,7 @@ deactivate () { fi } -# unset irrelavent variables +# unset irrelevant variables deactivate nondestructive VIRTUAL_ENV="__VENV_DIR__" diff --git a/Lib/venv/scripts/posix/activate.csh b/Lib/venv/scripts/posix/activate.csh index 99d79e0..b0c7028 100644 --- a/Lib/venv/scripts/posix/activate.csh +++ b/Lib/venv/scripts/posix/activate.csh @@ -5,7 +5,7 @@ alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate' -# Unset irrelavent variables. +# Unset irrelevant variables. deactivate nondestructive setenv VIRTUAL_ENV "__VENV_DIR__" diff --git a/Lib/venv/scripts/posix/activate.fish b/Lib/venv/scripts/posix/activate.fish index 45391aa..ca98466 100644 --- a/Lib/venv/scripts/posix/activate.fish +++ b/Lib/venv/scripts/posix/activate.fish @@ -29,7 +29,7 @@ function deactivate -d "Exit virtualenv and return to normal shell environment" end end -# unset irrelavent variables +# unset irrelevant variables deactivate nondestructive set -gx VIRTUAL_ENV "__VENV_DIR__" diff --git a/Mac/PythonLauncher/MyAppDelegate.m b/Mac/PythonLauncher/MyAppDelegate.m index e75fb06..25779a2 100644 --- a/Mac/PythonLauncher/MyAppDelegate.m +++ b/Mac/PythonLauncher/MyAppDelegate.m @@ -34,7 +34,7 @@ - (BOOL)shouldShowUI { // if this call comes before applicationDidFinishLaunching: we - // should terminate immedeately after starting the script. + // should terminate immediately after starting the script. if (!initial_action_done) should_terminate = YES; initial_action_done = YES; diff --git a/Misc/HISTORY b/Misc/HISTORY index 98e9041..5995d3a 100644 --- a/Misc/HISTORY +++ b/Misc/HISTORY @@ -1131,7 +1131,7 @@ Library and http.client. Patch by EungJun Yi. - Issue #14777: tkinter may return undecoded UTF-8 bytes as a string when - accessing the Tk clipboard. Modify clipboad_get() to first request type + accessing the Tk clipboard. Modify clipboard_get() to first request type UTF8_STRING when no specific type is requested in an X11 windowing environment, falling back to the current default type STRING if that fails. Original patch by Thomas Kluyver. @@ -5693,7 +5693,7 @@ Library for reading). - hashlib has two new constant attributes: algorithms_guaranteed and - algorithms_avaiable that respectively list the names of hash algorithms + algorithms_available that respectively list the names of hash algorithms guaranteed to exist in all Python implementations and the names of hash algorithms available in the current process. @@ -7344,7 +7344,7 @@ Library - Issue #2846: Add support for gzip.GzipFile reading zero-padded files. Patch by Brian Curtin. -- Issue #7681: Use floor division in appropiate places in the wave module. +- Issue #7681: Use floor division in appropriate places in the wave module. - Issue #5372: Drop the reuse of .o files in Distutils' ccompiler (since Extension extra options may change the output without changing the .c @@ -10921,7 +10921,7 @@ Platforms - Support for BeOS and AtheOS was removed (according to PEP 11). -- Support for RiscOS, Irix, Tru64 was removed (alledgedly). +- Support for RiscOS, Irix, Tru64 was removed (allegedly). Tools/Demos ----------- @@ -12912,7 +12912,7 @@ Library - Bug #947906: An object oriented interface has been added to the calendar module. It's possible to generate HTML calendar now and the module can be called as a script (e.g. via ``python -mcalendar``). Localized month and - weekday names can be ouput (even if an exotic encoding is used) using + weekday names can be output (even if an exotic encoding is used) using special classes that use unicode. Build @@ -13295,7 +13295,7 @@ Library ``True`` for ``!=``, and raises ``TypeError`` for other comparison operators. Because datetime is a subclass of date, comparing only the base class (date) members can still be done, if that's desired, by - forcing using of the approprate date method; e.g., + forcing using of the appropriate date method; e.g., ``a_date.__eq__(a_datetime)`` is true if and only if the year, month and day members of ``a_date`` and ``a_datetime`` are equal. @@ -23770,7 +23770,7 @@ Netscape on Windows/Mac). - copy.py: Make sure the objects returned by __getinitargs__() are kept alive (in the memo) to avoid a certain kind of nasty crash. (Not -easily reproducable because it requires a later call to +easily reproducible because it requires a later call to __getinitargs__() to return a tuple that happens to be allocated at the same address.) @@ -27402,7 +27402,7 @@ bullet-proof, after reports of (minor) trouble on certain platforms. There is now a script to patch Makefile and config.c to add a new optional built-in module: Addmodule.sh. Read the script before using! -Useing Addmodule.sh, all optional modules can now be configured at +Using Addmodule.sh, all optional modules can now be configured at compile time using Configure.py, so there are no modules left that require dynamic loading. @@ -27833,9 +27833,9 @@ SOCKET: symbolic constant definitions for socket options SUNAUDIODEV: symbolic constant definitions for sunaudiodef (sun only) -SV: symbolic constat definitions for sv (sgi only) +SV: symbolic constant definitions for sv (sgi only) -CD: symbolic constat definitions for cd (sgi only) +CD: symbolic constant definitions for cd (sgi only) New demos diff --git a/Misc/NEWS b/Misc/NEWS index 83dc4f6..816f959 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -4577,7 +4577,7 @@ Tools/Demos - Issue #22120: For functions using an unsigned integer return converter, Argument Clinic now generates a cast to that type for the comparison - to -1 in the generated code. (This supresses a compilation warning.) + to -1 in the generated code. (This suppresses a compilation warning.) - Issue #18974: Tools/scripts/diff.py now uses argparse instead of optparse. @@ -5677,7 +5677,7 @@ Core and Builtins - Issue #19466: Clear the frames of daemon threads earlier during the Python shutdown to call objects destructors. So "unclosed file" resource - warnings are now corretly emitted for daemon threads. + warnings are now correctly emitted for daemon threads. - Issue #19514: Deduplicate some _Py_IDENTIFIER declarations. Patch by Andrei Dorian Duma. @@ -6607,7 +6607,7 @@ Library - Issue #18709: Fix CVE-2013-4238. The SSL module now handles NULL bytes inside subjectAltName correctly. Formerly the module has used OpenSSL's - GENERAL_NAME_print() function to get the string represention of ASN.1 + GENERAL_NAME_print() function to get the string representation of ASN.1 strings for ``rfc822Name`` (email), ``dNSName`` (DNS) and ``uniformResourceIdentifier`` (URI). @@ -6700,7 +6700,7 @@ IDLE Documentation ------------- -- Issue #18743: Fix references to non-existant "StringIO" module. +- Issue #18743: Fix references to non-existent "StringIO" module. - Issue #18783: Removed existing mentions of Python long type in docstrings, error messages and comments. @@ -7639,7 +7639,7 @@ Library specifically addresses a stack misalignment issue on x86 and issues on some more recent platforms. -- Issue #8862: Fixed curses cleanup when getkey is interrputed by a signal. +- Issue #8862: Fixed curses cleanup when getkey is interrupted by a signal. - Issue #17443: imaplib.IMAP4_stream was using the default unbuffered IO in subprocess, but the imap code assumes buffered IO. In Python2 this diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index 0d3f724..f2df5c0 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -238,7 +238,7 @@ typedef struct { StgDictObject function to a generic one. Currently, PyCFuncPtr types have 'converters' and 'checker' entries in their - type dict. They are only used to cache attributes from other entries, whihc + type dict. They are only used to cache attributes from other entries, which is wrong. One use case is the .value attribute that all simple types have. But some diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 986c10b..ff57614 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -771,7 +771,7 @@ generate_hash_name_list(void) /* * This macro generates constructor function definitions for specific * hash algorithms. These constructors are much faster than calling - * the generic one passing it a python string and are noticably + * the generic one passing it a python string and are noticeably * faster than calling a python new() wrapper. Thats important for * code that wants to make hashes of a bunch of small strings. */ diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 212b0dd..57541a8 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -90,7 +90,7 @@ iobase_unsupported(const char *message) return NULL; } -/* Positionning */ +/* Positioning */ PyDoc_STRVAR(iobase_seek_doc, "Change stream position.\n" diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 3810e94..81f5b1d 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -3781,7 +3781,7 @@ get_recursion_depth(PyObject *self, PyObject *args) { PyThreadState *tstate = PyThreadState_GET(); - /* substract one to ignore the frame of the get_recursion_depth() call */ + /* subtract one to ignore the frame of the get_recursion_depth() call */ return PyLong_FromLong(tstate->recursion_depth - 1); } diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index 968181c..0219559 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -45,7 +45,7 @@ lock_dealloc(lockobject *self) /* Helper to acquire an interruptible lock with a timeout. If the lock acquire * is interrupted, signal handlers are run, and if they raise an exception, * PY_LOCK_INTR is returned. Otherwise, PY_LOCK_ACQUIRED or PY_LOCK_FAILURE - * are returned, depending on whether the lock can be acquired withing the + * are returned, depending on whether the lock can be acquired within the * timeout. */ static PyLockStatus diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index 796ac0f..65bf7a3 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -516,7 +516,7 @@ tracemalloc_realloc(void *ctx, void *ptr, size_t new_size) if (tracemalloc_add_trace(ptr2, new_size) < 0) { /* Memory allocation failed. The error cannot be reported to - the caller, because realloc() may already have shrinked the + the caller, because realloc() may already have shrunk the memory block and so removed bytes. This case is very unlikely: a hash entry has just been diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 7ebf8e8..b945bd6 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -1274,7 +1274,7 @@ count_set_bits(unsigned long n) /* Divide-and-conquer factorial algorithm * - * Based on the formula and psuedo-code provided at: + * Based on the formula and pseudo-code provided at: * http://www.luschny.de/math/factorial/binarysplitfact.html * * Faster algorithms exist, but they're more complicated and depend on diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index b34981c..d059617 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -6538,7 +6538,7 @@ PyInit__socket(void) PyModule_AddIntConstant(m, "SOMAXCONN", 5); /* Common value */ #endif - /* Ancilliary message types */ + /* Ancillary message types */ #ifdef SCM_RIGHTS PyModule_AddIntMacro(m, SCM_RIGHTS); #endif diff --git a/Modules/zipimport.c b/Modules/zipimport.c index e840271..6d5c68a 100644 --- a/Modules/zipimport.c +++ b/Modules/zipimport.c @@ -1315,7 +1315,7 @@ unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime) return code; } -/* Replace any occurances of "\r\n?" in the input string with "\n". +/* Replace any occurrences of "\r\n?" in the input string with "\n". This converts DOS and Mac line endings to Unix line endings. Also append a trailing "\n" to be compatible with PyParser_SimpleParseFile(). Returns a new reference. */ diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 1458635..6d4c6a1 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -506,7 +506,7 @@ bytearray_setslice_linear(PyByteArrayObject *self, If growth < 0 and lo != 0, the operation is completed, but a MemoryError is still raised and the memory block is not - shrinked. Otherwise, the bytearray is restored in its previous + shrunk. Otherwise, the bytearray is restored in its previous state and a MemoryError is raised. */ if (lo == 0) { self->ob_start += growth; diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 964ae62..6c0e5bf 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -718,7 +718,7 @@ _PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds) /* possible optimization: if f->f_lasti == instr_ub (likely to be a common case) then we already know instr_lb -- if we stored the matching value of p - somwhere we could skip the first while loop. */ + somewhere we could skip the first while loop. */ /* See lnotab_notes.txt for the description of co_lnotab. A point to remember: increments to p diff --git a/Objects/listsort.txt b/Objects/listsort.txt index 832e4f2..152a270 100644 --- a/Objects/listsort.txt +++ b/Objects/listsort.txt @@ -694,7 +694,7 @@ search doesn't reduce the quadratic data movement costs. But in CPython's case, comparisons are extraordinarily expensive compared to moving data, and the details matter. Moving objects is just copying -pointers. Comparisons can be arbitrarily expensive (can invoke arbitary +pointers. Comparisons can be arbitrarily expensive (can invoke arbitrary user-supplied Python code), but even in simple cases (like 3 < 4) _all_ decisions are made at runtime: what's the type of the left comparand? the type of the right? do they need to be coerced to a common type? where's the diff --git a/Objects/longobject.c b/Objects/longobject.c index cd04e36..9b62d92 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -368,7 +368,7 @@ PyLong_FromDouble(double dval) /* Checking for overflow in PyLong_AsLong is a PITA since C doesn't define * anything about what happens when a signed integer operation overflows, * and some compilers think they're doing you a favor by being "clever" - * then. The bit pattern for the largest postive signed long is + * then. The bit pattern for the largest positive signed long is * (unsigned long)LONG_MAX, and for the smallest negative signed long * it is abs(LONG_MIN), which we could write -(unsigned long)LONG_MIN. * However, some other compilers warn about applying unary minus to an diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 1181d77..ccde3de 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3759,7 +3759,7 @@ import_copyreg(void) /* Try to fetch cached copy of copyreg from sys.modules first in an attempt to avoid the import overhead. Previously this was implemented by storing a reference to the cached module in a static variable, but - this broke when multiple embeded interpreters were in use (see issue + this broke when multiple embedded interpreters were in use (see issue #17408 and #19088). */ copyreg_module = PyDict_GetItemWithError(interp->modules, copyreg_str); if (copyreg_module != NULL) { diff --git a/Python/condvar.h b/Python/condvar.h index bb5b1b6..ced910f 100644 --- a/Python/condvar.h +++ b/Python/condvar.h @@ -238,7 +238,7 @@ _PyCOND_WAIT_MS(PyCOND_T *cv, PyMUTEX_T *cs, DWORD ms) cv->waiting++; PyMUTEX_UNLOCK(cs); /* "lost wakeup bug" would occur if the caller were interrupted here, - * but we are safe because we are using a semaphore wich has an internal + * but we are safe because we are using a semaphore which has an internal * count. */ wait = WaitForSingleObjectEx(cv->sem, ms, FALSE); diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c index 8e9c502..e7c6a4f 100644 --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -118,7 +118,7 @@ typedef struct { } InternalFormatSpec; #if 0 -/* Occassionally useful for debugging. Should normally be commented out. */ +/* Occasionally useful for debugging. Should normally be commented out. */ static void DEBUG_PRINT_FORMAT_SPEC(InternalFormatSpec *format) { diff --git a/README b/README index 483134d..7d8eecc 100644 --- a/README +++ b/README @@ -68,7 +68,7 @@ workloads, as it has profiling instructions embedded inside. After this instrumented version of the interpreter is built, the Makefile will automatically run a training workload. This is necessary in order to profile the interpreter execution. Note also that any output, both stdout -and stderr, that may appear at this step is supressed. +and stderr, that may appear at this step is suppressed. Finally, the last step is to rebuild the interpreter, using the information collected in the previous one. The end result will be a Python binary diff --git a/configure b/configure index 2541015..c73b829 100755 --- a/configure +++ b/configure @@ -7267,7 +7267,7 @@ $as_echo "$CC" >&6; } # Calculate an appropriate deployment target for this build: # The deployment target value is used explicitly to enable certain # features are enabled (such as builtin libedit support for readline) - # through the use of Apple's Availabiliy Macros and is used as a + # through the use of Apple's Availability Macros and is used as a # component of the string returned by distutils.get_platform(). # # Use the value from: diff --git a/configure.ac b/configure.ac index dff1242..c2aa8ae 100644 --- a/configure.ac +++ b/configure.ac @@ -1689,7 +1689,7 @@ yes) # Calculate an appropriate deployment target for this build: # The deployment target value is used explicitly to enable certain # features are enabled (such as builtin libedit support for readline) - # through the use of Apple's Availabiliy Macros and is used as a + # through the use of Apple's Availability Macros and is used as a # component of the string returned by distutils.get_platform(). # # Use the value from: -- cgit v0.12 From 0f0eac431f6abcc5f6853b26e848b15f848e8844 Mon Sep 17 00:00:00 2001 From: Martin Panter Date: Wed, 7 Sep 2016 11:04:41 +0000 Subject: Issue #27993: Fix problems with plural objects in docs and comments --- Doc/library/argparse.rst | 4 ++-- Doc/library/weakref.rst | 2 +- Doc/library/xml.dom.rst | 2 +- Lib/inspect.py | 5 ++--- Lib/test/test_json/test_decode.py | 2 +- Misc/HISTORY | 2 +- Misc/NEWS | 4 ++-- 7 files changed, 10 insertions(+), 11 deletions(-) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index 995c4ee..fab0727 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -188,7 +188,7 @@ The following sections describe how each of these are used. prog ^^^^ -By default, :class:`ArgumentParser` objects uses ``sys.argv[0]`` to determine +By default, :class:`ArgumentParser` objects use ``sys.argv[0]`` to determine how to display the name of the program in help messages. This default is almost always desirable because it will make the help messages match how the program was invoked on the command line. For example, consider a file named @@ -558,7 +558,7 @@ conflict_handler ^^^^^^^^^^^^^^^^ :class:`ArgumentParser` objects do not allow two actions with the same option -string. By default, :class:`ArgumentParser` objects raises an exception if an +string. By default, :class:`ArgumentParser` objects raise an exception if an attempt is made to create an argument with an option string that is already in use:: diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst index 0470bd1..e289b97 100644 --- a/Doc/library/weakref.rst +++ b/Doc/library/weakref.rst @@ -414,7 +414,7 @@ the referent is accessed:: Example ------- -This simple example shows how an application can use objects IDs to retrieve +This simple example shows how an application can use object IDs to retrieve objects that it has seen before. The IDs of the objects can then be used in other data structures without forcing the objects to remain alive, but the objects can still be retrieved by ID if they do. diff --git a/Doc/library/xml.dom.rst b/Doc/library/xml.dom.rst index b037ff6..de334af 100644 --- a/Doc/library/xml.dom.rst +++ b/Doc/library/xml.dom.rst @@ -404,7 +404,7 @@ NodeList Objects ^^^^^^^^^^^^^^^^ A :class:`NodeList` represents a sequence of nodes. These objects are used in -two ways in the DOM Core recommendation: the :class:`Element` objects provides +two ways in the DOM Core recommendation: an :class:`Element` object provides one as its list of child nodes, and the :meth:`getElementsByTagName` and :meth:`getElementsByTagNameNS` methods of :class:`Node` return objects with this interface to represent query results. diff --git a/Lib/inspect.py b/Lib/inspect.py index e830eb6..ca1d551 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -171,9 +171,8 @@ def isfunction(object): def isgeneratorfunction(object): """Return true if the object is a user-defined generator function. - Generator function objects provides same attributes as functions. - - See help(isfunction) for attributes listing.""" + Generator function objects provide the same attributes as functions. + See help(isfunction) for a list of attributes.""" return bool((isfunction(object) or ismethod(object)) and object.__code__.co_flags & CO_GENERATOR) diff --git a/Lib/test/test_json/test_decode.py b/Lib/test/test_json/test_decode.py index cc83b45..fdafeb6 100644 --- a/Lib/test/test_json/test_decode.py +++ b/Lib/test/test_json/test_decode.py @@ -35,7 +35,7 @@ class TestDecode: self.assertEqual(self.loads(s, object_pairs_hook=OrderedDict, object_hook=lambda x: None), OrderedDict(p)) - # check that empty objects literals work (see #17368) + # check that empty object literals work (see #17368) self.assertEqual(self.loads('{}', object_pairs_hook=OrderedDict), OrderedDict()) self.assertEqual(self.loads('{"empty": {}}', diff --git a/Misc/HISTORY b/Misc/HISTORY index 5995d3a..73fb1d3 100644 --- a/Misc/HISTORY +++ b/Misc/HISTORY @@ -26057,7 +26057,7 @@ machinery is moved to the new file importdl.c. module implementing deepcopy and normal (shallow) copy operations. See the library reference manual. -- Documentation strings for many objects types are accessible through +- Documentation strings for many object types are accessible through the __doc__ attribute. Modules, classes and functions support special syntax to initialize the __doc__ attribute: if the first statement consists of just a string literal, that string literal becomes the diff --git a/Misc/NEWS b/Misc/NEWS index 816f959..d142675 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -4771,7 +4771,7 @@ Core and Builtins - Issue #20588: Make Python-ast.c C89 compliant. -- Issue #20437: Fixed 22 potential bugs when deleting objects references. +- Issue #20437: Fixed 22 potential bugs when deleting object references. - Issue #20500: Displaying an exception at interpreter shutdown no longer risks triggering an assertion failure in PyObject_Str. @@ -5676,7 +5676,7 @@ Core and Builtins when the creation of the replacement exception won't lose any information. - Issue #19466: Clear the frames of daemon threads earlier during the - Python shutdown to call objects destructors. So "unclosed file" resource + Python shutdown to call object destructors. So "unclosed file" resource warnings are now correctly emitted for daemon threads. - Issue #19514: Deduplicate some _Py_IDENTIFIER declarations. -- cgit v0.12 f='#n1238'>1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651

/* Write Python objects to files and read them back.
   This is primarily intended for writing and reading compiled Python code,
   even though dicts, lists, sets and frozensets, not commonly seen in
   code objects, are supported.
   Version 3 of this protocol properly supports circular links
   and sharing. */

#define PY_SSIZE_T_CLEAN

#include "Python.h"
#include "longintrepr.h"
#include "code.h"
#include "marshal.h"

#define ABS(x) ((x) < 0 ? -(x) : (x))

/* High water mark to determine when the marshalled object is dangerously deep
 * and risks coring the interpreter.  When the object stack gets this deep,
 * raise an exception instead of continuing.
 * On Windows debug builds, reduce this value.
 */
#if defined(MS_WINDOWS) && defined(_DEBUG)
#define MAX_MARSHAL_STACK_DEPTH 1500
#else
#define MAX_MARSHAL_STACK_DEPTH 2000
#endif

#define TYPE_NULL               '0'
#define TYPE_NONE               'N'
#define TYPE_FALSE              'F'
#define TYPE_TRUE               'T'
#define TYPE_STOPITER           'S'
#define TYPE_ELLIPSIS           '.'
#define TYPE_INT                'i'
#define TYPE_FLOAT              'f'
#define TYPE_BINARY_FLOAT       'g'
#define TYPE_COMPLEX            'x'
#define TYPE_BINARY_COMPLEX     'y'
#define TYPE_LONG               'l'
#define TYPE_STRING             's'
#define TYPE_INTERNED           't'
#define TYPE_REF                'r'
#define TYPE_TUPLE              '('
#define TYPE_LIST               '['
#define TYPE_DICT               '{'
#define TYPE_CODE               'c'
#define TYPE_UNICODE            'u'
#define TYPE_UNKNOWN            '?'
#define TYPE_SET                '<'
#define TYPE_FROZENSET          '>'
#define FLAG_REF                '\x80' /* with a type, add obj to index */

#define WFERR_OK 0
#define WFERR_UNMARSHALLABLE 1
#define WFERR_NESTEDTOODEEP 2
#define WFERR_NOMEMORY 3

typedef struct {
    FILE *fp;
    int error;  /* see WFERR_* values */
    int depth;
    /* If fp == NULL, the following are valid: */
    PyObject *readable;    /* Stream-like object being read from */
    PyObject *str;
    PyObject *current_filename;
    char *ptr;
    char *end;
    PyObject *refs; /* dict on marshal, list on unmarshal */
    int version;
} WFILE;

#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
                      else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \
                           else w_more(c, p)

static void
w_more(int c, WFILE *p)
{
    Py_ssize_t size, newsize;
    if (p->str == NULL)
        return; /* An error already occurred */
    size = PyBytes_Size(p->str);
    newsize = size + size + 1024;
    if (newsize > 32*1024*1024) {
        newsize = size + (size >> 3);           /* 12.5% overallocation */
    }
    if (_PyBytes_Resize(&p->str, newsize) != 0) {
        p->ptr = p->end = NULL;
    }
    else {
        p->ptr = PyBytes_AS_STRING((PyBytesObject *)p->str) + size;
        p->end =
            PyBytes_AS_STRING((PyBytesObject *)p->str) + newsize;
        *p->ptr++ = Py_SAFE_DOWNCAST(c, int, char);
    }
}

static void
w_string(char *s, Py_ssize_t n, WFILE *p)
{
    if (p->fp != NULL) {
        fwrite(s, 1, n, p->fp);
    }
    else {
        while (--n >= 0) {
            w_byte(*s, p);
            s++;
        }
    }
}

static void
w_short(int x, WFILE *p)
{
    w_byte((char)( x      & 0xff), p);
    w_byte((char)((x>> 8) & 0xff), p);
}

static void
w_long(long x, WFILE *p)
{
    w_byte((char)( x      & 0xff), p);
    w_byte((char)((x>> 8) & 0xff), p);
    w_byte((char)((x>>16) & 0xff), p);
    w_byte((char)((x>>24) & 0xff), p);
}

#define SIZE32_MAX  0x7FFFFFFF

#if SIZEOF_SIZE_T > 4
# define W_SIZE(n, p)  do {                     \
        if ((n) > SIZE32_MAX) {                 \
            (p)->depth--;                       \
            (p)->error = WFERR_UNMARSHALLABLE;  \
            return;                             \
        }                                       \
        w_long((long)(n), p);                   \
    } while(0)
#else
# define W_SIZE  w_long
#endif

/* We assume that Python longs are stored internally in base some power of
   2**15; for the sake of portability we'll always read and write them in base
   exactly 2**15. */

#define PyLong_MARSHAL_SHIFT 15
#define PyLong_MARSHAL_BASE ((short)1 << PyLong_MARSHAL_SHIFT)
#define PyLong_MARSHAL_MASK (PyLong_MARSHAL_BASE - 1)
#if PyLong_SHIFT % PyLong_MARSHAL_SHIFT != 0
#error "PyLong_SHIFT must be a multiple of PyLong_MARSHAL_SHIFT"
#endif
#define PyLong_MARSHAL_RATIO (PyLong_SHIFT / PyLong_MARSHAL_SHIFT)

#define W_TYPE(t, p) do { \
    w_byte((t) | flag, (p)); \
} while(0)

static void
w_PyLong(const PyLongObject *ob, char flag, WFILE *p)
{
    Py_ssize_t i, j, n, l;
    digit d;

    W_TYPE(TYPE_LONG, p);
    if (Py_SIZE(ob) == 0) {
        w_long((long)0, p);
        return;
    }

    /* set l to number of base PyLong_MARSHAL_BASE digits */
    n = ABS(Py_SIZE(ob));
    l = (n-1) * PyLong_MARSHAL_RATIO;
    d = ob->ob_digit[n-1];
    assert(d != 0); /* a PyLong is always normalized */
    do {
        d >>= PyLong_MARSHAL_SHIFT;
        l++;
    } while (d != 0);
    if (l > SIZE32_MAX) {
        p->depth--;
        p->error = WFERR_UNMARSHALLABLE;
        return;
    }
    w_long((long)(Py_SIZE(ob) > 0 ? l : -l), p);

    for (i=0; i < n-1; i++) {
        d = ob->ob_digit[i];
        for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
            w_short(d & PyLong_MARSHAL_MASK, p);
            d >>= PyLong_MARSHAL_SHIFT;
        }
        assert (d == 0);
    }
    d = ob->ob_digit[n-1];
    do {
        w_short(d & PyLong_MARSHAL_MASK, p);
        d >>= PyLong_MARSHAL_SHIFT;
    } while (d != 0);
}

static int
w_ref(PyObject *v, char *flag, WFILE *p)
{
    PyObject *id;
    PyObject *idx;

    if (p->version < 3 || p->refs == NULL)
        return 0; /* not writing object references */

    /* if it has only one reference, it definitely isn't shared */
    if (Py_REFCNT(v) == 1)
        return 0;

    id = PyLong_FromVoidPtr((void*)v);
    if (id == NULL)
        goto err;
    idx = PyDict_GetItem(p->refs, id);
    if (idx != NULL) {
        /* write the reference index to the stream */
        long w = PyLong_AsLong(idx);
        Py_DECREF(id);
        if (w == -1 && PyErr_Occurred()) {
            goto err;
        }
        /* we don't store "long" indices in the dict */
        assert(0 <= w && w <= 0x7fffffff);
        w_byte(TYPE_REF, p);
        w_long(w, p);
        return 1;
    } else {
        int ok;
        Py_ssize_t s = PyDict_Size(p->refs);
        /* we don't support long indices */
        if (s >= 0x7fffffff) {
            PyErr_SetString(PyExc_ValueError, "too many objects");
            goto err;
        }
        idx = PyLong_FromSsize_t(s);
        ok = idx && PyDict_SetItem(p->refs, id, idx) == 0;
        Py_DECREF(id);
        Py_XDECREF(idx);
        if (!ok)
            goto err;
        *flag |= FLAG_REF;
        return 0;
    }
err:
    p->error = WFERR_UNMARSHALLABLE;
    return 1;
}

static void
w_complex_object(PyObject *v, char flag, WFILE *p);

static void
w_object(PyObject *v, WFILE *p)
{
    char flag = '\0';

    p->depth++;

    if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
        p->error = WFERR_NESTEDTOODEEP;
    }
    else if (v == NULL) {
        w_byte(TYPE_NULL, p);
    }
    else if (v == Py_None) {
        w_byte(TYPE_NONE, p);
    }
    else if (v == PyExc_StopIteration) {
        w_byte(TYPE_STOPITER, p);
    }
    else if (v == Py_Ellipsis) {
        w_byte(TYPE_ELLIPSIS, p);
    }
    else if (v == Py_False) {
        w_byte(TYPE_FALSE, p);
    }
    else if (v == Py_True) {
        w_byte(TYPE_TRUE, p);
    }
    else if (!w_ref(v, &flag, p))
        w_complex_object(v, flag, p);

    p->depth--;
}

static void
w_complex_object(PyObject *v, char flag, WFILE *p)
{
    Py_ssize_t i, n;

    if (PyLong_CheckExact(v)) {
        long x = PyLong_AsLong(v);
        if ((x == -1)  && PyErr_Occurred()) {
            PyLongObject *ob = (PyLongObject *)v;
            PyErr_Clear();
            w_PyLong(ob, flag, p);
        }
        else {
#if SIZEOF_LONG > 4
            long y = Py_ARITHMETIC_RIGHT_SHIFT(long, x, 31);
            if (y && y != -1) {
                /* Too large for TYPE_INT */
                w_PyLong((PyLongObject*)v, flag, p);
            }
            else
#endif
            {
                W_TYPE(TYPE_INT, p);
                w_long(x, p);
            }
        }
    }
    else if (PyFloat_CheckExact(v)) {
        if (p->version > 1) {
            unsigned char buf[8];
            if (_PyFloat_Pack8(PyFloat_AsDouble(v),
                               buf, 1) < 0) {
                p->error = WFERR_UNMARSHALLABLE;
                return;
            }
            W_TYPE(TYPE_BINARY_FLOAT, p);
            w_string((char*)buf, 8, p);
        }
        else {
            char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v),
                                              'g', 17, 0, NULL);
            if (!buf) {
                p->error = WFERR_NOMEMORY;
                return;
            }
            n = strlen(buf);
            W_TYPE(TYPE_FLOAT, p);
            w_byte((int)n, p);
            w_string(buf, n, p);
            PyMem_Free(buf);
        }
    }
    else if (PyComplex_CheckExact(v)) {
        if (p->version > 1) {
            unsigned char buf[8];
            if (_PyFloat_Pack8(PyComplex_RealAsDouble(v),
                               buf, 1) < 0) {
                p->error = WFERR_UNMARSHALLABLE;
                return;
            }
            W_TYPE(TYPE_BINARY_COMPLEX, p);
            w_string((char*)buf, 8, p);
            if (_PyFloat_Pack8(PyComplex_ImagAsDouble(v),
                               buf, 1) < 0) {
                p->error = WFERR_UNMARSHALLABLE;
                return;
            }
            w_string((char*)buf, 8, p);
        }
        else {
            char *buf;
            W_TYPE(TYPE_COMPLEX, p);
            buf = PyOS_double_to_string(PyComplex_RealAsDouble(v),
                                        'g', 17, 0, NULL);
            if (!buf) {
                p->error = WFERR_NOMEMORY;
                return;
            }
            n = strlen(buf);
            w_byte((int)n, p);
            w_string(buf, n, p);
            PyMem_Free(buf);
            buf = PyOS_double_to_string(PyComplex_ImagAsDouble(v),
                                        'g', 17, 0, NULL);
            if (!buf) {
                p->error = WFERR_NOMEMORY;
                return;
            }
            n = strlen(buf);
            w_byte((int)n, p);
            w_string(buf, n, p);
            PyMem_Free(buf);
        }
    }
    else if (PyBytes_CheckExact(v)) {
        W_TYPE(TYPE_STRING, p);
        n = PyBytes_GET_SIZE(v);
        W_SIZE(n, p);
        w_string(PyBytes_AS_STRING(v), n, p);
    }
    else if (PyUnicode_CheckExact(v)) {
        PyObject *utf8;
        utf8 = PyUnicode_AsEncodedString(v, "utf8", "surrogatepass");
        if (utf8 == NULL) {
            p->depth--;
            p->error = WFERR_UNMARSHALLABLE;
            return;
        }
        if (p->version >= 3 &&  PyUnicode_CHECK_INTERNED(v))
            W_TYPE(TYPE_INTERNED, p);
        else
            W_TYPE(TYPE_UNICODE, p);
        n = PyBytes_GET_SIZE(utf8);
        W_SIZE(n, p);
        w_string(PyBytes_AS_STRING(utf8), n, p);
        Py_DECREF(utf8);
    }
    else if (PyTuple_CheckExact(v)) {
        W_TYPE(TYPE_TUPLE, p);
        n = PyTuple_Size(v);
        W_SIZE(n, p);
        for (i = 0; i < n; i++) {
            w_object(PyTuple_GET_ITEM(v, i), p);
        }
    }
    else if (PyList_CheckExact(v)) {
        W_TYPE(TYPE_LIST, p);
        n = PyList_GET_SIZE(v);
        W_SIZE(n, p);
        for (i = 0; i < n; i++) {
            w_object(PyList_GET_ITEM(v, i), p);
        }
    }
    else if (PyDict_CheckExact(v)) {
        Py_ssize_t pos;
        PyObject *key, *value;
        W_TYPE(TYPE_DICT, p);
        /* This one is NULL object terminated! */
        pos = 0;
        while (PyDict_Next(v, &pos, &key, &value)) {
            w_object(key, p);
            w_object(value, p);
        }
        w_object((PyObject *)NULL, p);
    }
    else if (PyAnySet_CheckExact(v)) {
        PyObject *value, *it;

        if (PyObject_TypeCheck(v, &PySet_Type))
            W_TYPE(TYPE_SET, p);
        else
            W_TYPE(TYPE_FROZENSET, p);
        n = PyObject_Size(v);
        if (n == -1) {
            p->depth--;
            p->error = WFERR_UNMARSHALLABLE;
            return;
        }
        W_SIZE(n, p);
        it = PyObject_GetIter(v);
        if (it == NULL) {
            p->depth--;
            p->error = WFERR_UNMARSHALLABLE;
            return;
        }
        while ((value = PyIter_Next(it)) != NULL) {
            w_object(value, p);
            Py_DECREF(value);
        }
        Py_DECREF(it);
        if (PyErr_Occurred()) {
            p->depth--;
            p->error = WFERR_UNMARSHALLABLE;
            return;
        }
    }
    else if (PyCode_Check(v)) {
        PyCodeObject *co = (PyCodeObject *)v;
        W_TYPE(TYPE_CODE, p);
        w_long(co->co_argcount, p);
        w_long(co->co_kwonlyargcount, p);
        w_long(co->co_nlocals, p);
        w_long(co->co_stacksize, p);
        w_long(co->co_flags, p);
        w_object(co->co_code, p);
        w_object(co->co_consts, p);
        w_object(co->co_names, p);
        w_object(co->co_varnames, p);
        w_object(co->co_freevars, p);
        w_object(co->co_cellvars, p);
        w_object(co->co_filename, p);
        w_object(co->co_name, p);
        w_long(co->co_firstlineno, p);
        w_object(co->co_lnotab, p);
    }
    else if (PyObject_CheckBuffer(v)) {
        /* Write unknown buffer-style objects as a string */
        char *s;
        Py_buffer view;
        if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) != 0) {
            w_byte(TYPE_UNKNOWN, p);
            p->depth--;
            p->error = WFERR_UNMARSHALLABLE;
            return;
        }
        W_TYPE(TYPE_STRING, p);
        n = view.len;
        s = view.buf;
        W_SIZE(n, p);
        w_string(s, n, p);
        PyBuffer_Release(&view);
    }
    else {
        W_TYPE(TYPE_UNKNOWN, p);
        p->error = WFERR_UNMARSHALLABLE;
    }
}

/* version currently has no effect for writing longs. */
void
PyMarshal_WriteLongToFile(long x, FILE *fp, int version)
{
    WFILE wf;
    wf.fp = fp;
    wf.error = WFERR_OK;
    wf.depth = 0;
    wf.refs = NULL;
    wf.version = version;
    w_long(x, &wf);
}

void
PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
{
    WFILE wf;
    wf.fp = fp;
    wf.error = WFERR_OK;
    wf.depth = 0;
    if (version >= 3) {
        if ((wf.refs = PyDict_New()) == NULL)
            return; /* caller mush check PyErr_Occurred() */
    } else
        wf.refs = NULL;
    wf.version = version;
    w_object(x, &wf);
    Py_XDECREF(wf.refs);
}

typedef WFILE RFILE; /* Same struct with different invariants */

#define rs_byte(p) (((p)->ptr < (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)

static Py_ssize_t
r_string(char *s, Py_ssize_t n, RFILE *p)
{
    char *ptr;
    Py_ssize_t read, left;

    if (!p->readable) {
        if (p->fp != NULL)
            /* The result fits into int because it must be <=n. */
            read = fread(s, 1, n, p->fp);
        else {
            left = p->end - p->ptr;
            read = (left < n) ? left : n;
            memcpy(s, p->ptr, read);
            p->ptr += read;
        }
    }
    else {
        _Py_IDENTIFIER(read);

        PyObject *data = _PyObject_CallMethodId(p->readable, &PyId_read, "n", n);
        read = 0;
        if (data != NULL) {
            if (!PyBytes_Check(data)) {
                PyErr_Format(PyExc_TypeError,
                             "f.read() returned not bytes but %.100s",
                             data->ob_type->tp_name);
            }
            else {
                read = (int)PyBytes_GET_SIZE(data);
                if (read > 0) {
                    ptr = PyBytes_AS_STRING(data);
                    memcpy(s, ptr, read);
                }
            }
            Py_DECREF(data);
        }
    }
    if (!PyErr_Occurred() && (read < n)) {
        PyErr_SetString(PyExc_EOFError, "EOF read where not expected");
    }
    return read;
}


static int
r_byte(RFILE *p)
{
    int c = EOF;
    unsigned char ch;
    Py_ssize_t n;

    if (!p->readable)
        c = p->fp ? getc(p->fp) : rs_byte(p);
    else {
        n = r_string((char *) &ch, 1, p);
        if (n > 0)
            c = ch;
    }
    return c;
}

static int
r_short(RFILE *p)
{
    register short x;
    unsigned char buffer[2];

    r_string((char *) buffer, 2, p);
    x = buffer[0];
    x |= buffer[1] << 8;
    /* Sign-extension, in case short greater than 16 bits */
    x |= -(x & 0x8000);
    return x;
}

static long
r_long(RFILE *p)
{
    register long x;
    unsigned char buffer[4];

    r_string((char *) buffer, 4, p);
    x = buffer[0];
    x |= (long)buffer[1] << 8;
    x |= (long)buffer[2] << 16;
    x |= (long)buffer[3] << 24;
#if SIZEOF_LONG > 4
    /* Sign extension for 64-bit machines */
    x |= -(x & 0x80000000L);
#endif
    return x;
}

static PyObject *
r_PyLong(RFILE *p)
{
    PyLongObject *ob;
    long n, size, i;
    int j, md, shorts_in_top_digit;
    digit d;

    n = r_long(p);
    if (PyErr_Occurred())
        return NULL;
    if (n == 0)
        return (PyObject *)_PyLong_New(0);
    if (n < -SIZE32_MAX || n > SIZE32_MAX) {
        PyErr_SetString(PyExc_ValueError,
                       "bad marshal data (long size out of range)");
        return NULL;
    }

    size = 1 + (ABS(n) - 1) / PyLong_MARSHAL_RATIO;
    shorts_in_top_digit = 1 + (ABS(n) - 1) % PyLong_MARSHAL_RATIO;
    ob = _PyLong_New(size);
    if (ob == NULL)
        return NULL;
    Py_SIZE(ob) = n > 0 ? size : -size;

    for (i = 0; i < size-1; i++) {
        d = 0;
        for (j=0; j < PyLong_MARSHAL_RATIO; j++) {
            md = r_short(p);
            if (PyErr_Occurred())
                break;
            if (md < 0 || md > PyLong_MARSHAL_BASE)
                goto bad_digit;
            d += (digit)md << j*PyLong_MARSHAL_SHIFT;
        }
        ob->ob_digit[i] = d;
    }
    d = 0;
    for (j=0; j < shorts_in_top_digit; j++) {
        md = r_short(p);
        if (PyErr_Occurred())
            break;
        if (md < 0 || md > PyLong_MARSHAL_BASE)
            goto bad_digit;
        /* topmost marshal digit should be nonzero */
        if (md == 0 && j == shorts_in_top_digit - 1) {
            Py_DECREF(ob);
            PyErr_SetString(PyExc_ValueError,
                "bad marshal data (unnormalized long data)");
            return NULL;
        }
        d += (digit)md << j*PyLong_MARSHAL_SHIFT;
    }
    if (PyErr_Occurred()) {
        Py_DECREF(ob);
        return NULL;
    }
    /* top digit should be nonzero, else the resulting PyLong won't be
       normalized */
    ob->ob_digit[size-1] = d;
    return (PyObject *)ob;
  bad_digit:
    Py_DECREF(ob);
    PyErr_SetString(PyExc_ValueError,
                    "bad marshal data (digit out of range in long)");
    return NULL;
}

/* allocate the reflist index for a new object. Return -1 on failure */
static Py_ssize_t
r_ref_reserve(int flag, RFILE *p)
{
    if (flag) { /* currently only FLAG_REF is defined */
        Py_ssize_t idx = PyList_Size(p->refs);
        if (idx < 0)
            return -1;
        if (idx >= 0x7ffffffe) {
            PyErr_SetString(PyExc_ValueError, "bad marshal data (index list too large)");
            return -1;
        }
        if (PyList_Append(p->refs, Py_None) < 0)
            return -1;
        return idx;
    } else
        return 0;
}

/* insert the new object 'o' to the reflist at previously
 * allocated index 'idx'.
 * 'o' can be NULL, in which case nothing is done.
 * if 'o' was non-NULL, and the function succeeds, 'o' is returned.
 * if 'o' was non-NULL, and the function fails, 'o' is released and
 * NULL returned. This simplifies error checking at the call site since
 * a single test for NULL for the function result is enough.
 */
static PyObject *
r_ref_insert(PyObject *o, Py_ssize_t idx, int flag, RFILE *p)
{
    if (o != NULL && flag) { /* currently only FLAG_REF is defined */
        if (PyList_SetItem(p->refs, idx, o) < 0) {
            Py_DECREF(o); /* release the new object */
            return NULL;
        } else {
            Py_INCREF(o); /* a reference for the list */
        }
    }
    return o;
}

/* combination of both above, used when an object can be
 * created whenever it is seen in the file, as opposed to
 * after having loaded its sub-objects.
 */
static PyObject *
r_ref(PyObject *o, int flag, RFILE *p)
{
    if (o != NULL && flag) { /* currently only FLAG_REF is defined */
        if (PyList_Append(p->refs, o) < 0) {
            Py_DECREF(o); /* release the new object */
            return NULL;
        }
    }
    return o;
}

static PyObject *
r_object(RFILE *p)
{
    /* NULL is a valid return value, it does not necessarily means that
       an exception is set. */
    PyObject *v, *v2;
    Py_ssize_t idx = 0;
    long i, n;
    int type, code = r_byte(p);
    int flag;
    PyObject *retval;

    if (code == EOF) {
        PyErr_SetString(PyExc_EOFError,
                        "EOF read where object expected");
        return NULL;
    }

    p->depth++;

    if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
        p->depth--;
        PyErr_SetString(PyExc_ValueError, "recursion limit exceeded");
        return NULL;
    }

    flag = code & FLAG_REF;
    type = code & ~FLAG_REF;

#define R_REF(O) do{\
    if (flag) \
        O = r_ref(O, flag, p);\
} while (0)

    switch (type) {

    case TYPE_NULL:
        retval = NULL;
        break;

    case TYPE_NONE:
        Py_INCREF(Py_None);
        retval = Py_None;
        break;

    case TYPE_STOPITER:
        Py_INCREF(PyExc_StopIteration);
        retval = PyExc_StopIteration;
        break;

    case TYPE_ELLIPSIS:
        Py_INCREF(Py_Ellipsis);
        retval = Py_Ellipsis;
        break;

    case TYPE_FALSE:
        Py_INCREF(Py_False);
        retval = Py_False;
        break;

    case TYPE_TRUE:
        Py_INCREF(Py_True);
        retval = Py_True;
        break;

    case TYPE_INT:
        n = r_long(p);
        retval = PyErr_Occurred() ? NULL : PyLong_FromLong(n);
        R_REF(retval);
        break;

    case TYPE_LONG:
        retval = r_PyLong(p);
        R_REF(retval);
        break;

    case TYPE_FLOAT:
        {
            char buf[256];
            double dx;
            retval = NULL;
            n = r_byte(p);
            if (n == EOF || r_string(buf, n, p) != n) {
                PyErr_SetString(PyExc_EOFError,
                    "EOF read where object expected");
                break;
            }
            buf[n] = '\0';
            dx = PyOS_string_to_double(buf, NULL, NULL);
            if (dx == -1.0 && PyErr_Occurred())
                break;
            retval = PyFloat_FromDouble(dx);
            R_REF(retval);
            break;
        }

    case TYPE_BINARY_FLOAT:
        {
            unsigned char buf[8];
            double x;
            if (r_string((char*)buf, 8, p) != 8) {
                PyErr_SetString(PyExc_EOFError,
                    "EOF read where object expected");
                retval = NULL;
                break;
            }
            x = _PyFloat_Unpack8(buf, 1);
            if (x == -1.0 && PyErr_Occurred()) {
                retval = NULL;
                break;
            }
            retval = PyFloat_FromDouble(x);
            R_REF(retval);
            break;
        }

    case TYPE_COMPLEX:
        {
            char buf[256];
            Py_complex c;
            retval = NULL;
            n = r_byte(p);
            if (n == EOF || r_string(buf, n, p) != n) {
                PyErr_SetString(PyExc_EOFError,
                    "EOF read where object expected");
                break;
            }
            buf[n] = '\0';
            c.real = PyOS_string_to_double(buf, NULL, NULL);
            if (c.real == -1.0 && PyErr_Occurred())
                break;
            n = r_byte(p);
            if (n == EOF || r_string(buf, n, p) != n) {
                PyErr_SetString(PyExc_EOFError,
                    "EOF read where object expected");
                break;
            }
            buf[n] = '\0';
            c.imag = PyOS_string_to_double(buf, NULL, NULL);
            if (c.imag == -1.0 && PyErr_Occurred())
                break;
            retval = PyComplex_FromCComplex(c);
            R_REF(retval);
            break;
        }

    case TYPE_BINARY_COMPLEX:
        {
            unsigned char buf[8];
            Py_complex c;
            if (r_string((char*)buf, 8, p) != 8) {
                PyErr_SetString(PyExc_EOFError,
                    "EOF read where object expected");
                retval = NULL;
                break;
            }
            c.real = _PyFloat_Unpack8(buf, 1);
            if (c.real == -1.0 && PyErr_Occurred()) {
                retval = NULL;
                break;
            }
            if (r_string((char*)buf, 8, p) != 8) {
                PyErr_SetString(PyExc_EOFError,
                    "EOF read where object expected");
                retval = NULL;
                break;
            }
            c.imag = _PyFloat_Unpack8(buf, 1);
            if (c.imag == -1.0 && PyErr_Occurred()) {
                retval = NULL;
                break;
            }
            retval = PyComplex_FromCComplex(c);
            R_REF(retval);
            break;
        }

    case TYPE_STRING:
        n = r_long(p);
        if (PyErr_Occurred()) {
            retval = NULL;
            break;
        }
        if (n < 0 || n > SIZE32_MAX) {
            PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)");
            retval = NULL;
            break;
        }
        v = PyBytes_FromStringAndSize((char *)NULL, n);
        if (v == NULL) {
            retval = NULL;
            break;
        }
        if (r_string(PyBytes_AS_STRING(v), n, p) != n) {
            Py_DECREF(v);
            PyErr_SetString(PyExc_EOFError,
                            "EOF read where object expected");
            retval = NULL;
            break;
        }
        retval = v;
        R_REF(retval);
        break;

    case TYPE_UNICODE:
    case TYPE_INTERNED:
        {
        char *buffer;

        n = r_long(p);
        if (PyErr_Occurred()) {
            retval = NULL;
            break;
        }
        if (n < 0 || n > SIZE32_MAX) {
            PyErr_SetString(PyExc_ValueError, "bad marshal data (unicode size out of range)");
            retval = NULL;
            break;
        }
        if (n != 0) {
            buffer = PyMem_NEW(char, n);
            if (buffer == NULL) {
                retval = PyErr_NoMemory();
                break;
            }
            if (r_string(buffer, n, p) != n) {
                PyMem_DEL(buffer);
                PyErr_SetString(PyExc_EOFError,
                    "EOF read where object expected");
                retval = NULL;
                break;
            }
            v = PyUnicode_DecodeUTF8(buffer, n, "surrogatepass");
            PyMem_DEL(buffer);
        }
        else {
            v = PyUnicode_New(0, 0);
        }
        if (v == NULL) {
            retval = NULL;
            break;
        }
        if (type == TYPE_INTERNED)
            PyUnicode_InternInPlace(&v);
        retval = v;
        R_REF(retval);
        break;
        }

    case TYPE_TUPLE:
        n = r_long(p);
        if (PyErr_Occurred()) {
            retval = NULL;
            break;
        }
        if (n < 0 || n > SIZE32_MAX) {
            PyErr_SetString(PyExc_ValueError, "bad marshal data (tuple size out of range)");
            retval = NULL;
            break;
        }
        v = PyTuple_New(n);
        R_REF(v);
        if (v == NULL) {
            retval = NULL;
            break;
        }
        for (i = 0; i < n; i++) {
            v2 = r_object(p);
            if ( v2 == NULL ) {
                if (!PyErr_Occurred())
                    PyErr_SetString(PyExc_TypeError,
                        "NULL object in marshal data for tuple");
                Py_DECREF(v);
                v = NULL;
                break;
            }
            PyTuple_SET_ITEM(v, i, v2);
        }
        retval = v;
        break;

    case TYPE_LIST:
        n = r_long(p);
        if (PyErr_Occurred()) {
            retval = NULL;
            break;
        }
        if (n < 0 || n > SIZE32_MAX) {
            PyErr_SetString(PyExc_ValueError, "bad marshal data (list size out of range)");
            retval = NULL;
            break;
        }
        v = PyList_New(n);
        R_REF(v);
        if (v == NULL) {
            retval = NULL;
            break;
        }
        for (i = 0; i < n; i++) {
            v2 = r_object(p);
            if ( v2 == NULL ) {
                if (!PyErr_Occurred())
                    PyErr_SetString(PyExc_TypeError,
                        "NULL object in marshal data for list");
                Py_DECREF(v);
                v = NULL;
                break;
            }
            PyList_SET_ITEM(v, i, v2);
        }
        retval = v;
        break;

    case TYPE_DICT:
        v = PyDict_New();
        R_REF(v);
        if (v == NULL) {
            retval = NULL;
            break;
        }
        for (;;) {
            PyObject *key, *val;
            key = r_object(p);
            if (key == NULL)
                break;
            val = r_object(p);
            if (val != NULL)
                PyDict_SetItem(v, key, val);
            Py_DECREF(key);
            Py_XDECREF(val);
        }
        if (PyErr_Occurred()) {
            Py_DECREF(v);
            v = NULL;
        }
        retval = v;
        break;

    case TYPE_SET:
    case TYPE_FROZENSET:
        n = r_long(p);
        if (PyErr_Occurred()) {
            retval = NULL;
            break;
        }
        if (n < 0 || n > SIZE32_MAX) {
            PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)");
            retval = NULL;
            break;
        }
        v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL);
        if (type == TYPE_SET) {
            R_REF(v);
        } else {
            /* must use delayed registration of frozensets because they must
             * be init with a refcount of 1
             */
            idx = r_ref_reserve(flag, p);
            if (idx < 0)
                Py_CLEAR(v); /* signal error */
        }
        if (v == NULL) {
            retval = NULL;
            break;
        }
        for (i = 0; i < n; i++) {
            v2 = r_object(p);
            if ( v2 == NULL ) {
                if (!PyErr_Occurred())
                    PyErr_SetString(PyExc_TypeError,
                        "NULL object in marshal data for set");
                Py_DECREF(v);
                v = NULL;
                break;
            }
            if (PySet_Add(v, v2) == -1) {
                Py_DECREF(v);
                Py_DECREF(v2);
                v = NULL;
                break;
            }
            Py_DECREF(v2);
        }
        if (type != TYPE_SET)
            v = r_ref_insert(v, idx, flag, p);
        retval = v;
        break;

    case TYPE_CODE:
        {
            int argcount;
            int kwonlyargcount;
            int nlocals;
            int stacksize;
            int flags;
            PyObject *code = NULL;
            PyObject *consts = NULL;
            PyObject *names = NULL;
            PyObject *varnames = NULL;
            PyObject *freevars = NULL;
            PyObject *cellvars = NULL;
            PyObject *filename = NULL;
            PyObject *name = NULL;
            int firstlineno;
            PyObject *lnotab = NULL;

            idx = r_ref_reserve(flag, p);
            if (idx < 0) {
                retval = NULL;
                break;
            }

            v = NULL;

            /* XXX ignore long->int overflows for now */
            argcount = (int)r_long(p);
            if (PyErr_Occurred())
                goto code_error;
            kwonlyargcount = (int)r_long(p);
            if (PyErr_Occurred())
                goto code_error;
            nlocals = (int)r_long(p);
            if (PyErr_Occurred())
                goto code_error;
            stacksize = (int)r_long(p);
            if (PyErr_Occurred())
                goto code_error;
            flags = (int)r_long(p);
            if (PyErr_Occurred())
                goto code_error;
            code = r_object(p);
            if (code == NULL)
                goto code_error;
            consts = r_object(p);
            if (consts == NULL)
                goto code_error;
            names = r_object(p);
            if (names == NULL)
                goto code_error;
            varnames = r_object(p);
            if (varnames == NULL)
                goto code_error;
            freevars = r_object(p);
            if (freevars == NULL)
                goto code_error;
            cellvars = r_object(p);
            if (cellvars == NULL)
                goto code_error;
            filename = r_object(p);
            if (filename == NULL)
                goto code_error;
            if (PyUnicode_CheckExact(filename)) {
                if (p->current_filename != NULL) {
                    if (!PyUnicode_Compare(filename, p->current_filename)) {
                        Py_DECREF(filename);
                        Py_INCREF(p->current_filename);
                        filename = p->current_filename;
                    }
                }
                else {
                    p->current_filename = filename;
                }
            }
            name = r_object(p);
            if (name == NULL)
                goto code_error;
            firstlineno = (int)r_long(p);
            lnotab = r_object(p);
            if (lnotab == NULL)
                goto code_error;

            v = (PyObject *) PyCode_New(
                            argcount, kwonlyargcount,
                            nlocals, stacksize, flags,
                            code, consts, names, varnames,
                            freevars, cellvars, filename, name,
                            firstlineno, lnotab);
            v = r_ref_insert(v, idx, flag, p);

          code_error:
            Py_XDECREF(code);
            Py_XDECREF(consts);
            Py_XDECREF(names);
            Py_XDECREF(varnames);
            Py_XDECREF(freevars);
            Py_XDECREF(cellvars);
            Py_XDECREF(filename);
            Py_XDECREF(name);
            Py_XDECREF(lnotab);
        }
        retval = v;
        break;

    case TYPE_REF:
        n = r_long(p);
        if (n < 0 || n >= PyList_GET_SIZE(p->refs)) {
            PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)");
            retval = NULL;
            break;
        }
        v = PyList_GET_ITEM(p->refs, n);
        if (v == Py_None) {
            PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)");
            retval = NULL;
            break;
        }
        Py_INCREF(v);
        retval = v;
        break;

    default:
        /* Bogus data got written, which isn't ideal.
           This will let you keep working and recover. */
        PyErr_SetString(PyExc_ValueError, "bad marshal data (unknown type code)");
        retval = NULL;
        break;

    }
    p->depth--;
    return retval;
}

static PyObject *
read_object(RFILE *p)
{
    PyObject *v;
    if (PyErr_Occurred()) {
        fprintf(stderr, "XXX readobject called with exception set\n");
        return NULL;
    }
    v = r_object(p);
    if (v == NULL && !PyErr_Occurred())
        PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for object");
    return v;
}

int
PyMarshal_ReadShortFromFile(FILE *fp)
{
    RFILE rf;
    assert(fp);
    rf.readable = NULL;
    rf.fp = fp;
    rf.current_filename = NULL;
    rf.end = rf.ptr = NULL;
    return r_short(&rf);
}

long
PyMarshal_ReadLongFromFile(FILE *fp)
{
    RFILE rf;
    rf.fp = fp;
    rf.readable = NULL;
    rf.current_filename = NULL;
    rf.ptr = rf.end = NULL;
    return r_long(&rf);
}

#ifdef HAVE_FSTAT
/* Return size of file in bytes; < 0 if unknown. */
static off_t
getfilesize(FILE *fp)
{
    struct stat st;
    if (fstat(fileno(fp), &st) != 0)
        return -1;
    else
        return st.st_size;
}
#endif

/* If we can get the size of the file up-front, and it's reasonably small,
 * read it in one gulp and delegate to ...FromString() instead.  Much quicker
 * than reading a byte at a time from file; speeds .pyc imports.
 * CAUTION:  since this may read the entire remainder of the file, don't
 * call it unless you know you're done with the file.
 */
PyObject *
PyMarshal_ReadLastObjectFromFile(FILE *fp)
{
/* REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc. */
#define REASONABLE_FILE_LIMIT (1L << 18)
#ifdef HAVE_FSTAT
    off_t filesize;
    filesize = getfilesize(fp);
    if (filesize > 0 && filesize <= REASONABLE_FILE_LIMIT) {
        char* pBuf = (char *)PyMem_MALLOC(filesize);
        if (pBuf != NULL) {
            size_t n = fread(pBuf, 1, (size_t)filesize, fp);
            PyObject* v = PyMarshal_ReadObjectFromString(pBuf, n);
            PyMem_FREE(pBuf);
            return v;
        }

    }
#endif
    /* We don't have fstat, or we do but the file is larger than
     * REASONABLE_FILE_LIMIT or malloc failed -- read a byte at a time.
     */
    return PyMarshal_ReadObjectFromFile(fp);

#undef REASONABLE_FILE_LIMIT
}

PyObject *
PyMarshal_ReadObjectFromFile(FILE *fp)
{
    RFILE rf;
    PyObject *result;
    rf.fp = fp;
    rf.readable = NULL;
    rf.current_filename = NULL;
    rf.depth = 0;
    rf.ptr = rf.end = NULL;
    rf.refs = PyList_New(0);
    if (rf.refs == NULL)
        return NULL;
    result = r_object(&rf);
    Py_DECREF(rf.refs);
    return result;
}

PyObject *
PyMarshal_ReadObjectFromString(char *str, Py_ssize_t len)
{
    RFILE rf;
    PyObject *result;
    rf.fp = NULL;
    rf.readable = NULL;
    rf.current_filename = NULL;
    rf.ptr = str;
    rf.end = str + len;
    rf.depth = 0;
    rf.refs = PyList_New(0);
    if (rf.refs == NULL)
        return NULL;
    result = r_object(&rf);
    Py_DECREF(rf.refs);
    return result;
}

PyObject *
PyMarshal_WriteObjectToString(PyObject *x, int version)
{
    WFILE wf;

    wf.fp = NULL;
    wf.readable = NULL;
    wf.str = PyBytes_FromStringAndSize((char *)NULL, 50);
    if (wf.str == NULL)
        return NULL;
    wf.ptr = PyBytes_AS_STRING((PyBytesObject *)wf.str);
    wf.end = wf.ptr + PyBytes_Size(wf.str);
    wf.error = WFERR_OK;
    wf.depth = 0;
    wf.version = version;
    if (version >= 3) {
        if ((wf.refs = PyDict_New()) == NULL)
            return NULL;
    } else
        wf.refs = NULL;
    w_object(x, &wf);
    Py_XDECREF(wf.refs);
    if (wf.str != NULL) {
        char *base = PyBytes_AS_STRING((PyBytesObject *)wf.str);
        if (wf.ptr - base > PY_SSIZE_T_MAX) {
            Py_DECREF(wf.str);
            PyErr_SetString(PyExc_OverflowError,
                            "too much marshal data for a string");
            return NULL;
        }
        if (_PyBytes_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)) < 0)
            return NULL;
    }
    if (wf.error != WFERR_OK) {
        Py_XDECREF(wf.str);
        if (wf.error == WFERR_NOMEMORY)
            PyErr_NoMemory();
        else
            PyErr_SetString(PyExc_ValueError,
              (wf.error==WFERR_UNMARSHALLABLE)?"unmarshallable object"
               :"object too deeply nested to marshal");
        return NULL;
    }
    return wf.str;
}

/* And an interface for Python programs... */

static PyObject *
marshal_dump(PyObject *self, PyObject *args)
{
    /* XXX Quick hack -- need to do this differently */
    PyObject *x;
    PyObject *f;
    int version = Py_MARSHAL_VERSION;
    PyObject *s;
    PyObject *res;
    _Py_IDENTIFIER(write);

    if (!PyArg_ParseTuple(args, "OO|i:dump", &x, &f, &version))
        return NULL;
    s = PyMarshal_WriteObjectToString(x, version);
    if (s == NULL)
        return NULL;
    res = _PyObject_CallMethodId(f, &PyId_write, "O", s);
    Py_DECREF(s);
    return res;
}

PyDoc_STRVAR(dump_doc,
"dump(value, file[, version])\n\
\n\
Write the value on the open file. The value must be a supported type.\n\
The file must be an open file object such as sys.stdout or returned by\n\
open() or os.popen(). It must be opened in binary mode ('wb' or 'w+b').\n\
\n\
If the value has (or contains an object that has) an unsupported type, a\n\
ValueError exception is raised — but garbage data will also be written\n\
to the file. The object will not be properly read back by load()\n\
\n\
The version argument indicates the data format that dump should use.");

static PyObject *
marshal_load(PyObject *self, PyObject *f)
{
    PyObject *data, *result;
    _Py_IDENTIFIER(read);
    RFILE rf;

    /*
     * Make a call to the read method, but read zero bytes.
     * This is to ensure that the object passed in at least
     * has a read method which returns bytes.
     * This can be removed if we guarantee good error handling
     * for r_string()
     */
    data = _PyObject_CallMethodId(f, &PyId_read, "i", 0);
    if (data == NULL)
        return NULL;
    if (!PyBytes_Check(data)) {
        PyErr_Format(PyExc_TypeError,
                     "f.read() returned not bytes but %.100s",
                     data->ob_type->tp_name);
        result = NULL;
    }
    else {
        rf.depth = 0;
        rf.fp = NULL;
        rf.readable = f;
        rf.current_filename = NULL;
        if ((rf.refs = PyList_New(0)) != NULL) {
            result = read_object(&rf);
            Py_DECREF(rf.refs);
        } else
            result = NULL;
    }
    Py_DECREF(data);
    return result;
}

PyDoc_STRVAR(load_doc,
"load(file)\n\
\n\
Read one value from the open file and return it. If no valid value is\n\
read (e.g. because the data has a different Python version’s\n\
incompatible marshal format), raise EOFError, ValueError or TypeError.\n\
The file must be an open file object opened in binary mode ('rb' or\n\
'r+b').\n\
\n\
Note: If an object containing an unsupported type was marshalled with\n\
dump(), load() will substitute None for the unmarshallable type.");


static PyObject *
marshal_dumps(PyObject *self, PyObject *args)
{
    PyObject *x;
    int version = Py_MARSHAL_VERSION;
    if (!PyArg_ParseTuple(args, "O|i:dumps", &x, &version))
        return NULL;
    return PyMarshal_WriteObjectToString(x, version);
}

PyDoc_STRVAR(dumps_doc,
"dumps(value[, version])\n\
\n\
Return the string that would be written to a file by dump(value, file).\n\
The value must be a supported type. Raise a ValueError exception if\n\
value has (or contains an object that has) an unsupported type.\n\
\n\
The version argument indicates the data format that dumps should use.");


static PyObject *
marshal_loads(PyObject *self, PyObject *args)
{
    RFILE rf;
    Py_buffer p;
    char *s;
    Py_ssize_t n;
    PyObject* result;
    if (!PyArg_ParseTuple(args, "y*:loads", &p))
        return NULL;
    s = p.buf;
    n = p.len;
    rf.fp = NULL;
    rf.readable = NULL;
    rf.current_filename = NULL;
    rf.ptr = s;
    rf.end = s + n;
    rf.depth = 0;
    if ((rf.refs = PyList_New(0)) == NULL)
        return NULL;
    result = read_object(&rf);
    PyBuffer_Release(&p);
    Py_DECREF(rf.refs);
    return result;
}

PyDoc_STRVAR(loads_doc,
"loads(bytes)\n\
\n\
Convert the bytes object to a value. If no valid value is found, raise\n\
EOFError, ValueError or TypeError. Extra characters in the input are\n\
ignored.");

static PyMethodDef marshal_methods[] = {
    {"dump",            marshal_dump,   METH_VARARGS,   dump_doc},
    {"load",            marshal_load,   METH_O,         load_doc},
    {"dumps",           marshal_dumps,  METH_VARARGS,   dumps_doc},
    {"loads",           marshal_loads,  METH_VARARGS,   loads_doc},
    {NULL,              NULL}           /* sentinel */
};


PyDoc_STRVAR(module_doc,
"This module contains functions that can read and write Python values in\n\
a binary format. The format is specific to Python, but independent of\n\
machine architecture issues.\n\
\n\
Not all Python object types are supported; in general, only objects\n\
whose value is independent from a particular invocation of Python can be\n\
written and read by this module. The following types are supported:\n\
None, integers, floating point numbers, strings, bytes, bytearrays,\n\
tuples, lists, sets, dictionaries, and code objects, where it\n\
should be understood that tuples, lists and dictionaries are only\n\
supported as long as the values contained therein are themselves\n\
supported; and recursive lists and dictionaries should not be written\n\
(they will cause infinite loops).\n\
\n\
Variables:\n\
\n\
version -- indicates the format that the module uses. Version 0 is the\n\
    historical format, version 1 shares interned strings and version 2\n\
    uses a binary format for floating point numbers.\n\
    Version 3 shares common object references (New in version 3.4).\n\
\n\
Functions:\n\
\n\
dump() -- write value to a file\n\
load() -- read value from a file\n\
dumps() -- write value to a string\n\
loads() -- read value from a string");



static struct PyModuleDef marshalmodule = {
    PyModuleDef_HEAD_INIT,
    "marshal",
    module_doc,
    0,
    marshal_methods,
    NULL,
    NULL,
    NULL,
    NULL
};

PyMODINIT_FUNC
PyMarshal_Init(void)
{
    PyObject *mod = PyModule_Create(&marshalmodule);
    if (mod == NULL)
        return NULL;
    PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION);
    return mod;
}