https://github.com/python/cpython/commit/46a2c11eaa8cbef6f73dd7050029bd8ff13026fc
commit: 46a2c11eaa8cbef6f73dd7050029bd8ff13026fc
branch: main
author: sobolevn <[email protected]>
committer: sobolevn <[email protected]>
date: 2026-05-09T08:33:09Z
summary:
gh-149530: Remove `symtable.Class.get_methods` deprecated method (#149531)
files:
A Misc/NEWS.d/next/Library/2026-05-08-06-56-57.gh-issue-149530.cl2AJ8.rst
M Doc/deprecations/pending-removal-in-3.16.rst
M Doc/library/symtable.rst
M Doc/tools/removed-ids.txt
M Doc/whatsnew/3.14.rst
M Doc/whatsnew/3.16.rst
M Lib/symtable.py
M Lib/test/test_symtable.py
M Misc/NEWS.d/3.14.0a1.rst
diff --git a/Doc/deprecations/pending-removal-in-3.16.rst
b/Doc/deprecations/pending-removal-in-3.16.rst
index b00c7002b03772..a64212e38e61cb 100644
--- a/Doc/deprecations/pending-removal-in-3.16.rst
+++ b/Doc/deprecations/pending-removal-in-3.16.rst
@@ -84,7 +84,7 @@ Pending removal in Python 3.16
* :mod:`symtable`:
- * The :meth:`Class.get_methods <symtable.Class.get_methods>` method
+ * The :meth:`!symtable.Class.get_methods` method
has been deprecated since Python 3.14.
* :mod:`sys`:
diff --git a/Doc/library/symtable.rst b/Doc/library/symtable.rst
index 52a722608db431..95f20b06b5aa1e 100644
--- a/Doc/library/symtable.rst
+++ b/Doc/library/symtable.rst
@@ -187,57 +187,6 @@ Examining Symbol Tables
A namespace of a class. This class inherits from :class:`SymbolTable`.
- .. method:: get_methods()
-
- Return a tuple containing the names of method-like functions declared
- in the class.
-
- Here, the term 'method' designates *any* function defined in the class
- body via :keyword:`def` or :keyword:`async def`.
-
- Functions defined in a deeper scope (e.g., in an inner class) are not
- picked up by :meth:`get_methods`.
-
- For example:
-
- .. testsetup:: symtable.Class.get_methods
-
- import warnings
- context = warnings.catch_warnings()
- context.__enter__()
- warnings.simplefilter("ignore", category=DeprecationWarning)
-
- .. testcleanup:: symtable.Class.get_methods
-
- context.__exit__()
-
- .. doctest:: symtable.Class.get_methods
-
- >>> import symtable
- >>> st = symtable.symtable('''
- ... def outer(): pass
- ...
- ... class A:
- ... def f():
- ... def w(): pass
- ...
- ... def g(self): pass
- ...
- ... @classmethod
- ... async def h(cls): pass
- ...
- ... global outer
- ... def outer(self): pass
- ... ''', 'test', 'exec')
- >>> class_A = st.get_children()[2]
- >>> class_A.get_methods()
- ('f', 'g', 'h')
-
- Although ``A().f()`` raises :exc:`TypeError` at runtime, ``A.f`` is still
- considered as a method-like function.
-
- .. deprecated-removed:: 3.14 3.16
-
.. class:: Symbol
diff --git a/Doc/tools/removed-ids.txt b/Doc/tools/removed-ids.txt
index 5e3ef2efe271fd..adac1b993047bc 100644
--- a/Doc/tools/removed-ids.txt
+++ b/Doc/tools/removed-ids.txt
@@ -5,3 +5,6 @@ c-api/allocation.html: deprecated-aliases
c-api/file.html: deprecated-api
library/asyncio-task.html: terminating-a-task-group
+
+# Removed APIs
+library/symtable.html: symtable.Class.get_methods
\ No newline at end of file
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index 0bb8858aea16fe..39d1d8da5367e5 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -2718,7 +2718,7 @@ New deprecations
(Contributed by Tian Gao in :gh:`124369` and :gh:`125951`.)
* :mod:`symtable`:
- Deprecate :meth:`symtable.Class.get_methods` due to the lack of interest,
+ Deprecate :meth:`!symtable.Class.get_methods` due to the lack of interest,
scheduled for removal in Python 3.16.
(Contributed by Bénédikt Tran in :gh:`119698`.)
diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst
index 4ddc836d9b29e4..d9beda92aba6a3 100644
--- a/Doc/whatsnew/3.16.rst
+++ b/Doc/whatsnew/3.16.rst
@@ -120,6 +120,12 @@ functools
* Calling the Python implementation of :func:`functools.reduce` with *function*
or *sequence* as keyword arguments has been deprecated since Python 3.14.
+symtable
+--------
+
+* The :meth:`!symtable.Class.get_methods` method
+ which has been deprecated since Python 3.14.
+
sysconfig
---------
diff --git a/Lib/symtable.py b/Lib/symtable.py
index c7152a70f5aa0b..9238437191c00f 100644
--- a/Lib/symtable.py
+++ b/Lib/symtable.py
@@ -240,41 +240,7 @@ def get_cells(self):
class Class(SymbolTable):
-
- __methods = None
-
- def get_methods(self):
- """Return a tuple of methods declared in the class.
- """
- import warnings
- typename = f'{self.__class__.__module__}.{self.__class__.__name__}'
- warnings.warn(f'{typename}.get_methods() is deprecated '
- f'and will be removed in Python 3.16.',
- DeprecationWarning, stacklevel=2)
-
- if self.__methods is None:
- d = {}
-
- def is_local_symbol(ident):
- flags = self._table.symbols.get(ident, 0)
- return ((flags >> SCOPE_OFF) & SCOPE_MASK) == LOCAL
-
- for st in self._table.children:
- # pick the function-like symbols that are local identifiers
- if is_local_symbol(st.name):
- match st.type:
- case _symtable.TYPE_FUNCTION:
- d[st.name] = 1
- case _symtable.TYPE_TYPE_PARAMETERS:
- # Get the function-def block in the annotation
- # scope 'st' with the same identifier, if any.
- scope_name = st.name
- for c in st.children:
- if c.name == scope_name and c.type ==
_symtable.TYPE_FUNCTION:
- d[scope_name] = 1
- break
- self.__methods = tuple(d)
- return self.__methods
+ pass
class Symbol:
diff --git a/Lib/test/test_symtable.py b/Lib/test/test_symtable.py
index c748243110df9f..8c03420c4c5e4b 100644
--- a/Lib/test/test_symtable.py
+++ b/Lib/test/test_symtable.py
@@ -2,8 +2,6 @@
Test the API of the symtable module.
"""
-import re
-import textwrap
import symtable
import warnings
import unittest
@@ -364,87 +362,6 @@ def test_name(self):
self.assertEqual(self.spam.lookup("x").get_name(), "x")
self.assertEqual(self.Mine.get_name(), "Mine")
- def test_class_get_methods(self):
- deprecation_mess = (
- re.escape('symtable.Class.get_methods() is deprecated '
- 'and will be removed in Python 3.16.')
- )
-
- with self.assertWarnsRegex(DeprecationWarning, deprecation_mess):
- self.assertEqual(self.Mine.get_methods(), ('a_method',))
-
- top = symtable.symtable(TEST_COMPLEX_CLASS_CODE, "?", "exec")
- this = find_block(top, "ComplexClass")
-
- with self.assertWarnsRegex(DeprecationWarning, deprecation_mess):
- self.assertEqual(this.get_methods(), (
- 'a_method', 'a_method_pep_695',
- 'an_async_method', 'an_async_method_pep_695',
- 'a_classmethod', 'a_classmethod_pep_695',
- 'an_async_classmethod', 'an_async_classmethod_pep_695',
- 'a_staticmethod', 'a_staticmethod_pep_695',
- 'an_async_staticmethod', 'an_async_staticmethod_pep_695',
- 'a_fakemethod', 'a_fakemethod_pep_695',
- 'an_async_fakemethod', 'an_async_fakemethod_pep_695',
- 'glob_unassigned_meth', 'glob_unassigned_meth_pep_695',
- 'glob_unassigned_async_meth',
'glob_unassigned_async_meth_pep_695',
- 'glob_assigned_meth', 'glob_assigned_meth_pep_695',
- 'glob_assigned_async_meth', 'glob_assigned_async_meth_pep_695',
- ))
-
- # Test generator expressions that are of type TYPE_FUNCTION
- # but will not be reported by get_methods() since they are
- # not functions per se.
- #
- # Other kind of comprehensions such as list, set or dict
- # expressions do not have the TYPE_FUNCTION type.
-
- def check_body(body, expected_methods):
- indented = textwrap.indent(body, ' ' * 4)
- top = symtable.symtable(f"class A:\n{indented}", "?", "exec")
- this = find_block(top, "A")
- with self.assertWarnsRegex(DeprecationWarning, deprecation_mess):
- self.assertEqual(this.get_methods(), expected_methods)
-
- # statements with 'genexpr' inside it
- GENEXPRS = (
- 'x = (x for x in [])',
- 'x = (x async for x in [])',
- 'type x[genexpr = (x for x in [])] = (x for x in [])',
- 'type x[genexpr = (x async for x in [])] = (x async for x in [])',
- 'genexpr = (x for x in [])',
- 'genexpr = (x async for x in [])',
- 'type genexpr[genexpr = (x for x in [])] = (x for x in [])',
- 'type genexpr[genexpr = (x async for x in [])] = (x async for x in
[])',
- )
-
- for gen in GENEXPRS:
- # test generator expression
- with self.subTest(gen=gen):
- check_body(gen, ())
-
- # test generator expression + variable named 'genexpr'
- with self.subTest(gen=gen, isvar=True):
- check_body('\n'.join((gen, 'genexpr = 1')), ())
- check_body('\n'.join(('genexpr = 1', gen)), ())
-
- for paramlist in ('()', '(x)', '(x, y)', '(z: T)'):
- for func in (
- f'def genexpr{paramlist}:pass',
- f'async def genexpr{paramlist}:pass',
- f'def genexpr[T]{paramlist}:pass',
- f'async def genexpr[T]{paramlist}:pass',
- ):
- with self.subTest(func=func):
- # test function named 'genexpr'
- check_body(func, ('genexpr',))
-
- for gen in GENEXPRS:
- with self.subTest(gen=gen, func=func):
- # test generator expression + function named 'genexpr'
- check_body('\n'.join((gen, func)), ('genexpr',))
- check_body('\n'.join((func, gen)), ('genexpr',))
-
def test_filename_correct(self):
### Bug tickler: SyntaxError file name correct whether error raised
### while parsing or building symbol table.
diff --git a/Misc/NEWS.d/3.14.0a1.rst b/Misc/NEWS.d/3.14.0a1.rst
index 5303bd89efff5b..79936955757280 100644
--- a/Misc/NEWS.d/3.14.0a1.rst
+++ b/Misc/NEWS.d/3.14.0a1.rst
@@ -2038,7 +2038,7 @@ Remove workarounds for non-IEEE 754 systems in
:mod:`cmath`.
.. nonce: WlygzR
.. section: Library
-Due to the lack of interest for :meth:`symtable.Class.get_methods`, the
+Due to the lack of interest for :meth:`!symtable.Class.get_methods`, the
method is marked as deprecated and will be removed in Python 3.16. Patch by
Bénédikt Tran.
@@ -2746,7 +2746,7 @@ situations.
.. nonce: rRrprk
.. section: Library
-Fix :meth:`symtable.Class.get_methods` and document its behaviour. Patch by
+Fix :meth:`!symtable.Class.get_methods` and document its behaviour. Patch by
Bénédikt Tran.
..
diff --git
a/Misc/NEWS.d/next/Library/2026-05-08-06-56-57.gh-issue-149530.cl2AJ8.rst
b/Misc/NEWS.d/next/Library/2026-05-08-06-56-57.gh-issue-149530.cl2AJ8.rst
new file mode 100644
index 00000000000000..2b74e8cdadd03c
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-05-08-06-56-57.gh-issue-149530.cl2AJ8.rst
@@ -0,0 +1,2 @@
+Removed :meth:`!symtable.Class.get_methods` which has been deprecated since
+3.14.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]