Skip to content

bpo-34392: Add sys. _is_interned() #8755

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Dec 4, 2023
Merged
12 changes: 12 additions & 0 deletions Doc/library/sys.rst
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,18 @@ always available.
value of :func:`intern` around to benefit from it.


.. function:: _is_interned(string)

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

.. versionadded:: 3.8

.. impl-detail::

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


.. function:: is_finalizing()

Return :const:`True` if the Python interpreter is
Expand Down
16 changes: 16 additions & 0 deletions Lib/test/test_sys.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,11 +504,25 @@ def test_43581(self):
def test_intern(self):
global numruns
numruns += 1
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(numruns)
if has_is_interned:
self.assertIs(sys._is_interned(s), False)
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 @@ -520,6 +534,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)

def test_sys_flags(self):
self.assertTrue(sys.flags)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added :func:`sys.isinterned`.
34 changes: 33 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 @@ -447,6 +447,23 @@ Return the string itself or the previously interned string object with the\n\
same value.");


/*[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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: Currently sys.internmakes a PyUnicode_CheckExact(s) over the string so interning a subclass of a string gives a TypeError back. This returns False. Does it make sense to do a exact check to mirror the interface of sys.intern?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know.

}


/*
* Cached interned string objects used for calling the profile and
* trace functions. Initialized by trace_init().
Expand Down Expand Up @@ -1557,6 +1574,7 @@ static PyMethodDef sys_methods[] = {
METH_NOARGS, enablelegacywindowsfsencoding_doc },
#endif /* MS_WINDOWS */
{"intern", sys_intern, METH_VARARGS, intern_doc},
SYS__IS_INTERNED_METHODDEF
{"is_finalizing", sys_is_finalizing, METH_NOARGS, is_finalizing_doc},
#ifdef USE_MALLOPT
{"mdebug", sys_mdebug, METH_VARARGS},
Expand Down