Skip to content

Commit

Permalink
bpo-34392: Add sys. _is_interned() (GH-8755)
Browse files Browse the repository at this point in the history
  • Loading branch information
serhiy-storchaka committed Dec 4, 2023
1 parent 0e732d0 commit dee7bee
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 1 deletion.
12 changes: 12 additions & 0 deletions Doc/library/sys.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1205,6 +1205,18 @@ always available.

.. versionadded:: 3.12

.. function:: _is_interned(string)

Return :const:`True` if the given string is "interned", :const:`False`
otherwise.

.. versionadded:: 3.13

.. impl-detail::

It is not guaranteed to exist in all implementations of Python.


.. data:: last_type
last_value
last_traceback
Expand Down
7 changes: 7 additions & 0 deletions Doc/whatsnew/3.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,13 @@ sqlite3
object is not :meth:`closed <sqlite3.Connection.close>` explicitly.
(Contributed by Erlend E. Aasland in :gh:`105539`.)

sys
---

* Add the :func:`sys._is_interned` function to test if the string was interned.
This function is not guaranteed to exist in all implementations of Python.
(Contributed by Serhiy Storchaka in :gh:`78573`.)

tkinter
-------

Expand Down
14 changes: 14 additions & 0 deletions Lib/test/test_sys.py
Original file line number Diff line number Diff line change
Expand Up @@ -691,11 +691,23 @@ def test_43581(self):
self.assertEqual(sys.__stdout__.encoding, sys.__stderr__.encoding)

def test_intern(self):
has_is_interned = (test.support.check_impl_detail(cpython=True)
or hasattr(sys, '_is_interned'))
self.assertRaises(TypeError, sys.intern)
self.assertRaises(TypeError, sys.intern, b'abc')
if has_is_interned:
self.assertRaises(TypeError, sys._is_interned)
self.assertRaises(TypeError, sys._is_interned, b'abc')
s = "never interned before" + str(random.randrange(0, 10**9))
self.assertTrue(sys.intern(s) is s)
if has_is_interned:
self.assertIs(sys._is_interned(s), True)
s2 = s.swapcase().swapcase()
if has_is_interned:
self.assertIs(sys._is_interned(s2), False)
self.assertTrue(sys.intern(s2) is s)
if has_is_interned:
self.assertIs(sys._is_interned(s2), False)

# Subclasses of string can't be interned, because they
# provide too much opportunity for insane things to happen.
Expand All @@ -707,6 +719,8 @@ def __hash__(self):
return 123

self.assertRaises(TypeError, sys.intern, S("abc"))
if has_is_interned:
self.assertIs(sys._is_interned(S("abc")), False)

@requires_subinterpreters
def test_subinterp_intern_dynamically_allocated(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added :func:`sys._is_interned`.
36 changes: 35 additions & 1 deletion Python/clinic/sysmodule.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions Python/sysmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,23 @@ sys_intern_impl(PyObject *module, PyObject *s)
}


/*[clinic input]
sys._is_interned -> bool
string: unicode
/
Return True if the given string is "interned".
[clinic start generated code]*/

static int
sys__is_interned_impl(PyObject *module, PyObject *string)
/*[clinic end generated code: output=c3678267b4e9d7ed input=039843e17883b606]*/
{
return PyUnicode_CHECK_INTERNED(string);
}


/*
* Cached interned string objects used for calling the profile and
* trace functions.
Expand Down Expand Up @@ -2462,6 +2479,7 @@ static PyMethodDef sys_methods[] = {
SYS_GETWINDOWSVERSION_METHODDEF
SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF
SYS_INTERN_METHODDEF
SYS__IS_INTERNED_METHODDEF
SYS_IS_FINALIZING_METHODDEF
SYS_MDEBUG_METHODDEF
SYS_SETSWITCHINTERVAL_METHODDEF
Expand Down

0 comments on commit dee7bee

Please sign in to comment.