Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-parso for openSUSE:Factory checked in at 2026-05-12 19:26:09 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-parso (Old) and /work/SRC/openSUSE:Factory/.python-parso.new.1966 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-parso" Tue May 12 19:26:09 2026 rev:25 rq:1352316 version:0.8.7 Changes: -------- --- /work/SRC/openSUSE:Factory/python-parso/python-parso.changes 2026-03-17 19:02:22.151386378 +0100 +++ /work/SRC/openSUSE:Factory/.python-parso.new.1966/python-parso.changes 2026-05-12 19:26:21.594320291 +0200 @@ -1,0 +2,6 @@ +Sun May 3 19:10:50 UTC 2026 - Dirk Müller <[email protected]> + +- update to 0.8.7: + * Add PEP 695 type parameter syntax + +------------------------------------------------------------------- Old: ---- parso-0.8.6.tar.gz New: ---- parso-0.8.7.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-parso.spec ++++++ --- /var/tmp/diff_new_pack.7JGT0H/_old 2026-05-12 19:26:22.318350298 +0200 +++ /var/tmp/diff_new_pack.7JGT0H/_new 2026-05-12 19:26:22.318350298 +0200 @@ -18,7 +18,7 @@ %{?sle15_python_module_pythons} Name: python-parso -Version: 0.8.6 +Version: 0.8.7 Release: 0 Summary: An autocompletion tool for Python License: MIT AND Python-2.0 @@ -61,11 +61,12 @@ # Python 3.12 and newer also changes how f-strings are parsed python312_args=("-k" "not test_python_exception_matches") python313_args=("-k" "not test_python_exception_matches") +python314_args=("-k" "not test_python_exception_matches") %pytest "${$python_args[@]}" %files %{python_files} %license LICENSE.txt -%doc AUTHORS.txt CHANGELOG.rst README.rst +%doc CHANGELOG.rst README.rst %{python_sitelib}/parso-%{version}.dist-info %{python_sitelib}/parso/ ++++++ parso-0.8.6.tar.gz -> parso-0.8.7.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.8.6/CHANGELOG.rst new/parso-0.8.7/CHANGELOG.rst --- old/parso-0.8.6/CHANGELOG.rst 2026-02-09 16:45:03.000000000 +0100 +++ new/parso-0.8.7/CHANGELOG.rst 2026-05-02 01:12:26.000000000 +0200 @@ -6,6 +6,11 @@ Unreleased ++++++++++ +0.8.7 (2026-05-02) +++++++++++++++++++ + +- Add PEP 695 type parameter syntax + 0.8.6 (2026-02-09) ++++++++++++++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.8.6/PKG-INFO new/parso-0.8.7/PKG-INFO --- old/parso-0.8.6/PKG-INFO 2026-02-09 16:45:19.737467500 +0100 +++ new/parso-0.8.7/PKG-INFO 2026-05-02 01:12:57.445762400 +0200 @@ -1,6 +1,6 @@ -Metadata-Version: 2.4 +Metadata-Version: 2.1 Name: parso -Version: 0.8.6 +Version: 0.8.7 Summary: A Python Parser Home-page: https://github.com/davidhalter/parso Author: David Halter @@ -30,29 +30,10 @@ Classifier: Topic :: Utilities Classifier: Typing :: Typed Requires-Python: >=3.6 +Provides-Extra: qa +Provides-Extra: testing License-File: LICENSE.txt License-File: AUTHORS.txt -Provides-Extra: testing -Requires-Dist: pytest; extra == "testing" -Requires-Dist: docopt; extra == "testing" -Provides-Extra: qa -Requires-Dist: flake8==5.0.4; extra == "qa" -Requires-Dist: zuban==0.5.1; extra == "qa" -Requires-Dist: types-setuptools==67.2.0.1; extra == "qa" -Dynamic: author -Dynamic: author-email -Dynamic: classifier -Dynamic: description -Dynamic: home-page -Dynamic: keywords -Dynamic: license -Dynamic: license-file -Dynamic: maintainer -Dynamic: maintainer-email -Dynamic: platform -Dynamic: provides-extra -Dynamic: requires-python -Dynamic: summary ################################################################### parso - A Python Parser @@ -160,6 +141,11 @@ Unreleased ++++++++++ +0.8.7 (2026-05-02) +++++++++++++++++++ + +- Add PEP 695 type parameter syntax + 0.8.6 (2026-02-09) ++++++++++++++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.8.6/conftest.py new/parso-0.8.7/conftest.py --- old/parso-0.8.6/conftest.py 2026-02-09 16:45:03.000000000 +0100 +++ new/parso-0.8.7/conftest.py 2026-05-02 01:12:26.000000000 +0200 @@ -145,3 +145,15 @@ def works_ge_py39(each_version): version_info = parse_version_string(each_version) return Checker(each_version, version_info >= (3, 9)) + + [email protected] +def works_ge_py312(each_version): + version_info = parse_version_string(each_version) + return Checker(each_version, version_info >= (3, 12)) + + [email protected] +def works_ge_py313(each_version): + version_info = parse_version_string(each_version) + return Checker(each_version, version_info >= (3, 13)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.8.6/parso/__init__.py new/parso-0.8.7/parso/__init__.py --- old/parso-0.8.6/parso/__init__.py 2026-02-09 16:45:03.000000000 +0100 +++ new/parso-0.8.7/parso/__init__.py 2026-05-02 01:12:26.000000000 +0200 @@ -43,7 +43,7 @@ from parso.utils import split_lines, python_bytes_to_unicode -__version__ = '0.8.6' +__version__ = '0.8.7' def parse(code=None, **kwargs): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.8.6/parso/python/grammar312.txt new/parso-0.8.7/parso/python/grammar312.txt --- old/parso-0.8.6/parso/python/grammar312.txt 2026-02-09 16:45:03.000000000 +0100 +++ new/parso-0.8.7/parso/python/grammar312.txt 2026-05-02 01:12:26.000000000 +0200 @@ -17,7 +17,11 @@ decorated: decorators (classdef | funcdef | async_funcdef) async_funcdef: 'async' funcdef -funcdef: 'def' NAME parameters ['->' test] ':' suite +funcdef: 'def' NAME [type_params] parameters ['->' test] ':' suite + +type_params: '[' type_param (',' type_param)* [','] ']' +type_param: NAME [type_param_bound] | '*' NAME | '**' NAME +type_param_bound: ':' test parameters: '(' [typedargslist] ')' typedargslist: ( @@ -131,7 +135,7 @@ ((test [':=' test] | star_expr) (comp_for | (',' (test [':=' test] | star_expr))* [','])) ) -classdef: 'class' NAME ['(' [arglist] ')'] ':' suite +classdef: 'class' NAME [type_params] ['(' [arglist] ')'] ':' suite arglist: argument (',' argument)* [','] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.8.6/parso/python/grammar313.txt new/parso-0.8.7/parso/python/grammar313.txt --- old/parso-0.8.6/parso/python/grammar313.txt 2026-02-09 16:45:03.000000000 +0100 +++ new/parso-0.8.7/parso/python/grammar313.txt 2026-05-02 01:12:26.000000000 +0200 @@ -17,7 +17,12 @@ decorated: decorators (classdef | funcdef | async_funcdef) async_funcdef: 'async' funcdef -funcdef: 'def' NAME parameters ['->' test] ':' suite +funcdef: 'def' NAME [type_params] parameters ['->' test] ':' suite + +type_params: '[' type_param (',' type_param)* [','] ']' +type_param: NAME [type_param_bound] [type_param_default] | '*' NAME [type_param_default] | '**' NAME [type_param_default] +type_param_bound: ':' test +type_param_default: '=' test parameters: '(' [typedargslist] ')' typedargslist: ( @@ -131,7 +136,7 @@ ((test [':=' test] | star_expr) (comp_for | (',' (test [':=' test] | star_expr))* [','])) ) -classdef: 'class' NAME ['(' [arglist] ')'] ':' suite +classdef: 'class' NAME [type_params] ['(' [arglist] ')'] ':' suite arglist: argument (',' argument)* [','] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.8.6/parso/python/grammar314.txt new/parso-0.8.7/parso/python/grammar314.txt --- old/parso-0.8.6/parso/python/grammar314.txt 2026-02-09 16:45:03.000000000 +0100 +++ new/parso-0.8.7/parso/python/grammar314.txt 2026-05-02 01:12:26.000000000 +0200 @@ -17,7 +17,12 @@ decorated: decorators (classdef | funcdef | async_funcdef) async_funcdef: 'async' funcdef -funcdef: 'def' NAME parameters ['->' test] ':' suite +funcdef: 'def' NAME [type_params] parameters ['->' test] ':' suite + +type_params: '[' type_param (',' type_param)* [','] ']' +type_param: NAME [type_param_bound] [type_param_default] | '*' NAME [type_param_default] | '**' NAME [type_param_default] +type_param_bound: ':' test +type_param_default: '=' test parameters: '(' [typedargslist] ')' typedargslist: ( @@ -131,7 +136,7 @@ ((test [':=' test] | star_expr) (comp_for | (',' (test [':=' test] | star_expr))* [','])) ) -classdef: 'class' NAME ['(' [arglist] ')'] ':' suite +classdef: 'class' NAME [type_params] ['(' [arglist] ')'] ':' suite arglist: argument (',' argument)* [','] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.8.6/parso/python/tree.py new/parso-0.8.7/parso/python/tree.py --- old/parso-0.8.6/parso/python/tree.py 2026-02-09 16:45:03.000000000 +0100 +++ new/parso-0.8.7/parso/python/tree.py 2026-05-02 01:12:26.000000000 +0200 @@ -479,13 +479,13 @@ Returns the `arglist` node that defines the super classes. It returns None if there are no arguments. """ - if self.children[2] != '(': # Has no parentheses - return None - else: - if self.children[3] == ')': # Empty parentheses - return None - else: - return self.children[3] + for i, child in enumerate(self.children): + if child == '(': + next_child = self.children[i + 1] + if next_child == ')': + return None + return next_child + return None def _create_params(parent, argslist_list): @@ -552,15 +552,21 @@ def __init__(self, children): super().__init__(children) - parameters = self.children[2] # After `def foo` + parameters = self._find_parameters() parameters_children = parameters.children[1:-1] - # If input parameters list already has Param objects, keep it as is; - # otherwise, convert it to a list of Param objects. if not any(isinstance(child, Param) for child in parameters_children): - parameters.children[1:-1] = _create_params(parameters, parameters_children) + parameters.children[1:-1] = _create_params( + parameters, parameters_children + ) + + def _find_parameters(self): + for child in self.children: + if child.type == 'parameters': + return child + raise Exception("A function should always have parameters") def _get_param_nodes(self): - return self.children[2].children + return self._find_parameters().children def get_params(self): """ @@ -633,13 +639,10 @@ """ Returns the test node after `->` or `None` if there is no annotation. """ - try: - if self.children[3] == "->": - return self.children[4] - assert self.children[3] == ":" - return None - except IndexError: - return None + for i, child in enumerate(self.children): + if child == '->': + return self.children[i + 1] + return None class Lambda(Function): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.8.6/parso.egg-info/PKG-INFO new/parso-0.8.7/parso.egg-info/PKG-INFO --- old/parso-0.8.6/parso.egg-info/PKG-INFO 2026-02-09 16:45:19.000000000 +0100 +++ new/parso-0.8.7/parso.egg-info/PKG-INFO 2026-05-02 01:12:57.000000000 +0200 @@ -1,6 +1,6 @@ -Metadata-Version: 2.4 +Metadata-Version: 2.1 Name: parso -Version: 0.8.6 +Version: 0.8.7 Summary: A Python Parser Home-page: https://github.com/davidhalter/parso Author: David Halter @@ -30,29 +30,10 @@ Classifier: Topic :: Utilities Classifier: Typing :: Typed Requires-Python: >=3.6 +Provides-Extra: qa +Provides-Extra: testing License-File: LICENSE.txt License-File: AUTHORS.txt -Provides-Extra: testing -Requires-Dist: pytest; extra == "testing" -Requires-Dist: docopt; extra == "testing" -Provides-Extra: qa -Requires-Dist: flake8==5.0.4; extra == "qa" -Requires-Dist: zuban==0.5.1; extra == "qa" -Requires-Dist: types-setuptools==67.2.0.1; extra == "qa" -Dynamic: author -Dynamic: author-email -Dynamic: classifier -Dynamic: description -Dynamic: home-page -Dynamic: keywords -Dynamic: license -Dynamic: license-file -Dynamic: maintainer -Dynamic: maintainer-email -Dynamic: platform -Dynamic: provides-extra -Dynamic: requires-python -Dynamic: summary ################################################################### parso - A Python Parser @@ -160,6 +141,11 @@ Unreleased ++++++++++ +0.8.7 (2026-05-02) +++++++++++++++++++ + +- Add PEP 695 type parameter syntax + 0.8.6 (2026-02-09) ++++++++++++++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.8.6/parso.egg-info/requires.txt new/parso-0.8.7/parso.egg-info/requires.txt --- old/parso-0.8.6/parso.egg-info/requires.txt 2026-02-09 16:45:19.000000000 +0100 +++ new/parso-0.8.7/parso.egg-info/requires.txt 2026-05-02 01:12:57.000000000 +0200 @@ -1,9 +1,9 @@ [qa] flake8==5.0.4 -zuban==0.5.1 types-setuptools==67.2.0.1 +zuban==0.5.1 [testing] -pytest docopt +pytest diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.8.6/test/test_parser.py new/parso-0.8.7/test/test_parser.py --- old/parso-0.8.6/test/test_parser.py 2026-02-09 16:45:03.000000000 +0100 +++ new/parso-0.8.7/test/test_parser.py 2026-05-02 01:12:26.000000000 +0200 @@ -206,3 +206,64 @@ ) def test_decorator_expression(works_ge_py39, expression): works_ge_py39.parse("@%s\ndef x(): pass" % expression) + + [email protected]( + 'code', [ + 'class Foo[T]: pass', + 'class Foo[T: str]: pass', + 'class Foo[T, U]: pass', + 'class Foo[T: str, U: int]: pass', + 'class Foo[T](Base): pass', + 'class Foo[T: str](Base, Mixin): pass', + 'class Foo[*Ts]: pass', + 'class Foo[**P]: pass', + ] +) +def test_pep695_generic_class(works_ge_py312, code): + works_ge_py312.parse(code) + + [email protected]( + 'code', [ + 'def foo[T](x: T) -> T: pass', + 'def foo[T: int](x: T) -> T: pass', + 'def foo[T, U](x: T, y: U): pass', + 'def foo[*Ts](*args): pass', + 'def foo[**P](*args): pass', + ] +) +def test_pep695_generic_function(works_ge_py312, code): + works_ge_py312.parse(code) + + +def test_pep695_class_get_super_arglist(works_ge_py312): + module = works_ge_py312.parse('class Foo[T](Bar, Baz): pass') + if module is None: + return + classdef = module.children[0] + arglist = classdef.get_super_arglist() + assert arglist is not None + assert 'Bar' in arglist.get_code() + assert 'Baz' in arglist.get_code() + + +def test_pep695_class_no_bases(works_ge_py312): + module = works_ge_py312.parse('class Foo[T]: pass') + if module is None: + return + classdef = module.children[0] + assert classdef.get_super_arglist() is None + + [email protected]( + 'code', [ + 'class Foo[T = int]: pass', + 'class Foo[T: str = "default"]: pass', + 'class Foo[*Ts = tuple[int, ...]]: pass', + 'class Foo[**P = None]: pass', + 'def foo[T = int](x: T) -> T: pass', + ] +) +def test_pep696_type_param_defaults(works_ge_py313, code): + works_ge_py313.parse(code)
