Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions Doc/library/ftplib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -524,14 +524,9 @@ FTP_TLS objects
:class:`!FTP_TLS` class inherits from :class:`FTP`,
defining these additional methods and attributes:

.. attribute:: FTP_TLS.ssl_version

The SSL version to use (defaults to :data:`ssl.PROTOCOL_SSLv23`).

.. method:: FTP_TLS.auth()

Set up a secure control connection by using TLS or SSL, depending on what
is specified in the :attr:`ssl_version` attribute.
Set up a secure control connection by using TLS.

.. versionchanged:: 3.4
The method now supports hostname check with
Expand All @@ -548,7 +543,7 @@ FTP_TLS objects

.. method:: FTP_TLS.prot_p()

Set up secure data connection.
Set up secure data connection by using TLS.

.. method:: FTP_TLS.prot_c()

Expand Down
15 changes: 14 additions & 1 deletion Doc/library/stdtypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1844,6 +1844,14 @@ expression support in the :mod:`re` module).
lowercase letter ``'ß'`` is equivalent to ``"ss"``. Since it is already
lowercase, :meth:`lower` would do nothing to ``'ß'``; :meth:`casefold`
converts it to ``"ss"``.
For example:

.. doctest::

>>> 'straße'.lower()
'straße'
>>> 'straße'.casefold()
'strasse'

The casefolding algorithm is `described in section 3.13.3 'Default Case
Folding' of the Unicode Standard
Expand Down Expand Up @@ -2300,7 +2308,12 @@ expression support in the :mod:`re` module).
.. method:: str.lower()

Return a copy of the string with all the cased characters [4]_ converted to
lowercase.
lowercase. For example:

.. doctest::

>>> 'Lower Method Example'.lower()
'lower method example'

The lowercasing algorithm used is `described in section 3.13.2 'Default Case
Conversion' of the Unicode Standard
Expand Down
31 changes: 16 additions & 15 deletions Include/exports.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@
#define Py_EXPORTED_SYMBOL
#define Py_LOCAL_SYMBOL
#endif
/* module init functions outside the core must be exported */
#if defined(Py_BUILD_CORE)
#define _PyINIT_EXPORTED_SYMBOL Py_EXPORTED_SYMBOL
#else
#define _PyINIT_EXPORTED_SYMBOL __declspec(dllexport)
#endif
#else
/*
* If we only ever used gcc >= 5, we could use __has_attribute(visibility)
Expand All @@ -52,19 +58,16 @@
#define Py_EXPORTED_SYMBOL
#define Py_LOCAL_SYMBOL
#endif
#define _PyINIT_EXPORTED_SYMBOL Py_EXPORTED_SYMBOL
#endif

/* only get special linkage if built as shared or platform is Cygwin */
#if defined(Py_ENABLE_SHARED) || defined(__CYGWIN__)
# if defined(HAVE_DECLSPEC_DLL)
# if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
# define PyAPI_FUNC(RTYPE) Py_EXPORTED_SYMBOL RTYPE
# define PyAPI_DATA(RTYPE) extern Py_EXPORTED_SYMBOL RTYPE
/* module init functions inside the core need no external linkage */
/* except for Cygwin to handle embedding */
# if defined(__CYGWIN__)
# define _PyINIT_FUNC_DECLSPEC Py_EXPORTED_SYMBOL
# else /* __CYGWIN__ */
# if !defined(__CYGWIN__)
# define _PyINIT_FUNC_DECLSPEC
# endif /* __CYGWIN__ */
# else /* Py_BUILD_CORE */
Expand All @@ -77,12 +80,6 @@
# define PyAPI_FUNC(RTYPE) Py_IMPORTED_SYMBOL RTYPE
# endif /* !__CYGWIN__ */
# define PyAPI_DATA(RTYPE) extern Py_IMPORTED_SYMBOL RTYPE
/* module init functions outside the core must be exported */
# if defined(__cplusplus)
# define _PyINIT_FUNC_DECLSPEC extern "C" Py_EXPORTED_SYMBOL
# else /* __cplusplus */
# define _PyINIT_FUNC_DECLSPEC Py_EXPORTED_SYMBOL
# endif /* __cplusplus */
# endif /* Py_BUILD_CORE */
# endif /* HAVE_DECLSPEC_DLL */
#endif /* Py_ENABLE_SHARED */
Expand All @@ -96,13 +93,17 @@
#endif
#ifndef _PyINIT_FUNC_DECLSPEC
# if defined(__cplusplus)
# define _PyINIT_FUNC_DECLSPEC extern "C" Py_EXPORTED_SYMBOL
# define _PyINIT_FUNC_DECLSPEC extern "C" _PyINIT_EXPORTED_SYMBOL
# else /* __cplusplus */
# define _PyINIT_FUNC_DECLSPEC Py_EXPORTED_SYMBOL
# define _PyINIT_FUNC_DECLSPEC _PyINIT_EXPORTED_SYMBOL
# endif /* __cplusplus */
#endif

#define PyMODINIT_FUNC _PyINIT_FUNC_DECLSPEC PyObject*
#define PyMODEXPORT_FUNC _PyINIT_FUNC_DECLSPEC PyModuleDef_Slot*
#ifndef PyMODINIT_FUNC
#define PyMODINIT_FUNC _PyINIT_FUNC_DECLSPEC PyObject*
#endif
#ifndef PyMODEXPORT_FUNC
#define PyMODEXPORT_FUNC _PyINIT_FUNC_DECLSPEC PyModuleDef_Slot*
#endif

#endif /* Py_EXPORTS_H */
3 changes: 2 additions & 1 deletion Lib/pydoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2004,10 +2004,11 @@ def interact(self):
while True:
try:
request = self.getline('help> ')
if not request: break
except (KeyboardInterrupt, EOFError):
break
request = request.strip()
if not request:
continue # back to the prompt

# Make sure significant trailing quoting marks of literals don't
# get deleted while cleaning input
Expand Down
7 changes: 6 additions & 1 deletion Lib/test/test_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@
ctypes = None
from test.support import (cpython_only,
check_impl_detail, requires_debug_ranges,
gc_collect, Py_GIL_DISABLED)
gc_collect, Py_GIL_DISABLED, late_deletion)
from test.support.script_helper import assert_python_ok
from test.support import threading_helper, import_helper
from test.support.bytecode_helper import instructions_with_positions
Expand Down Expand Up @@ -1555,6 +1555,11 @@ def myfree(ptr):

FREE_FUNC = freefunc(myfree)
FREE_INDEX = RequestCodeExtraIndex(FREE_FUNC)
# Make sure myfree sticks around at least as long as the interpreter,
# since we (currently) can't unregister the function and leaving a
# dangling pointer will cause a crash on deallocation of code objects if
# something else uses co_extras, like test_capi.test_misc.
late_deletion(myfree)

class CoExtra(unittest.TestCase):
def get_func(self):
Expand Down
37 changes: 37 additions & 0 deletions Lib/test/test_pydoc/test_pydoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2147,10 +2147,47 @@ def test_url_requests(self):


class TestHelper(unittest.TestCase):
def mock_interactive_session(self, inputs):
"""
Given a list of inputs, run an interactive help session. Returns a string
of what would be shown on screen.
"""
input_iter = iter(inputs)

def mock_getline(prompt):
output.write(prompt)
next_input = next(input_iter)
output.write(next_input + os.linesep)
return next_input

with captured_stdout() as output:
helper = pydoc.Helper(output=output)
with unittest.mock.patch.object(helper, "getline", mock_getline):
helper.interact()

# handle different line endings across platforms consistently
return output.getvalue().strip().splitlines(keepends=False)

def test_keywords(self):
self.assertEqual(sorted(pydoc.Helper.keywords),
sorted(keyword.kwlist))

def test_interact_empty_line_continues(self):
# gh-138568: test pressing Enter without input should continue in help session
self.assertEqual(
self.mock_interactive_session(["", " ", "quit"]),
["help> ", "help> ", "help> quit"],
)

def test_interact_quit_commands_exit(self):
quit_commands = ["quit", "q", "exit"]
for quit_cmd in quit_commands:
with self.subTest(quit_command=quit_cmd):
self.assertEqual(
self.mock_interactive_session([quit_cmd]),
[f"help> {quit_cmd}"],
)


class PydocWithMetaClasses(unittest.TestCase):
def tearDown(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:c:macro:`PyMODINIT_FUNC` (and the new :c:macro:`PyMODEXPORT_FUNC`) now adds
a linkage declaration (``__declspec(dllexport)``) on Windows.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Adjusted the built-in :func:`help` function so that empty inputs are ignored in
interactive mode.
Loading