Skip to content
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

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

Merged
merged 11 commits into from Dec 4, 2023
12 changes: 12 additions & 0 deletions Doc/library/sys.rst
Expand Up @@ -1049,6 +1049,18 @@ always available.
.. versionadded:: 3.5


.. function:: _is_interned(string)

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

.. versionadded:: 3.12

.. impl-detail::

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


.. data:: last_type
last_value
last_traceback
Expand Down
16 changes: 16 additions & 0 deletions Lib/test/test_sys.py
Expand Up @@ -645,11 +645,25 @@ def test_43581(self):
def test_intern(self):
global INTERN_NUMRUNS
INTERN_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(INTERN_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 @@ -661,6 +675,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
@@ -0,0 +1 @@
Added :func:`sys._is_interned`.
39 changes: 38 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
Expand Up @@ -910,6 +910,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);
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.
Expand Down Expand Up @@ -1967,6 +1984,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