Hello community, here is the log from the commit of package python-parso for openSUSE:Factory checked in at 2019-07-08 14:59:34 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-parso (Old) and /work/SRC/openSUSE:Factory/.python-parso.new.4615 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-parso" Mon Jul 8 14:59:34 2019 rev:8 rq:713046 version:0.5.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-parso/python-parso.changes 2019-04-22 12:22:51.840861961 +0200 +++ /work/SRC/openSUSE:Factory/.python-parso.new.4615/python-parso.changes 2019-07-08 14:59:35.086403902 +0200 @@ -1,0 +2,9 @@ +Tue Jul 2 09:42:44 UTC 2019 - Marketa Calabkova <[email protected]> + +- update to 0.5.0 + * comp_for is now called sync_comp_for for all Python versions to + be compatible with the Python 3.8 Grammar + * Added .pyi stubs for a lot of the parso API + * Small FileIO changes + +------------------------------------------------------------------- Old: ---- parso-0.4.0.tar.gz New: ---- parso-0.5.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-parso.spec ++++++ --- /var/tmp/diff_new_pack.x6EgYO/_old 2019-07-08 14:59:35.706404839 +0200 +++ /var/tmp/diff_new_pack.x6EgYO/_new 2019-07-08 14:59:35.706404839 +0200 @@ -18,7 +18,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-parso -Version: 0.4.0 +Version: 0.5.0 Release: 0 Summary: An autocompletion tool for Python License: MIT AND Python-2.0 ++++++ parso-0.4.0.tar.gz -> parso-0.5.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/CHANGELOG.rst new/parso-0.5.0/CHANGELOG.rst --- old/parso-0.4.0/CHANGELOG.rst 2019-04-05 19:01:55.000000000 +0200 +++ new/parso-0.5.0/CHANGELOG.rst 2019-06-20 21:27:50.000000000 +0200 @@ -3,6 +3,14 @@ Changelog --------- +0.5.0 (2019-06-20) +++++++++++++++++++ + +- **Breaking Change** comp_for is now called sync_comp_for for all Python + versions to be compatible with the Python 3.8 Grammar +- Added .pyi stubs for a lot of the parso API +- Small FileIO changes + 0.4.0 (2019-04-05) ++++++++++++++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/PKG-INFO new/parso-0.5.0/PKG-INFO --- old/parso-0.4.0/PKG-INFO 2019-04-05 19:10:01.000000000 +0200 +++ new/parso-0.5.0/PKG-INFO 2019-06-20 22:11:18.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: parso -Version: 0.4.0 +Version: 0.5.0 Summary: A Python Parser Home-page: https://github.com/davidhalter/parso Author: David Halter @@ -106,6 +106,14 @@ Changelog --------- + 0.5.0 (2019-06-20) + ++++++++++++++++++ + + - **Breaking Change** comp_for is now called sync_comp_for for all Python + versions to be compatible with the Python 3.8 Grammar + - Added .pyi stubs for a lot of the parso API + - Small FileIO changes + 0.4.0 (2019-04-05) ++++++++++++++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/conftest.py new/parso-0.5.0/conftest.py --- old/parso-0.4.0/conftest.py 2019-04-05 19:01:55.000000000 +0200 +++ new/parso-0.5.0/conftest.py 2019-06-20 21:27:50.000000000 +0200 @@ -14,7 +14,7 @@ collect_ignore = ["setup.py"] VERSIONS_2 = '2.6', '2.7' -VERSIONS_3 = '3.3', '3.4', '3.5', '3.6', '3.7' +VERSIONS_3 = '3.3', '3.4', '3.5', '3.6', '3.7', '3.8' @pytest.fixture(scope='session') @@ -155,3 +155,9 @@ def works_ge_py35(each_version): version_info = parse_version_string(each_version) return Checker(each_version, version_info >= (3, 5)) + + [email protected] +def works_ge_py38(each_version): + version_info = parse_version_string(each_version) + return Checker(each_version, version_info >= (3, 8)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/parso/__init__.py new/parso-0.5.0/parso/__init__.py --- old/parso-0.4.0/parso/__init__.py 2019-04-05 19:01:55.000000000 +0200 +++ new/parso-0.5.0/parso/__init__.py 2019-06-20 21:27:50.000000000 +0200 @@ -43,7 +43,7 @@ from parso.utils import split_lines, python_bytes_to_unicode -__version__ = '0.4.0' +__version__ = '0.5.0' def parse(code=None, **kwargs): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/parso/cache.py new/parso-0.5.0/parso/cache.py --- old/parso-0.4.0/parso/cache.py 2019-04-05 19:01:55.000000000 +0200 +++ new/parso-0.5.0/parso/cache.py 2019-06-20 21:27:50.000000000 +0200 @@ -18,7 +18,7 @@ LOG = logging.getLogger(__name__) -_PICKLE_VERSION = 31 +_PICKLE_VERSION = 32 """ Version number (integer) for file system cache. @@ -82,9 +82,8 @@ """ Returns a module or None, if it fails. """ - try: - p_time = file_io.get_last_modified() - except FileNotFoundError: + p_time = file_io.get_last_modified() + if p_time is None: return None try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/parso/file_io.py new/parso-0.5.0/parso/file_io.py --- old/parso-0.4.0/parso/file_io.py 2019-04-05 19:01:55.000000000 +0200 +++ new/parso-0.5.0/parso/file_io.py 2019-06-20 21:27:50.000000000 +0200 @@ -14,10 +14,13 @@ def get_last_modified(self): """ - Returns float - timestamp - Might raise FileNotFoundError + Returns float - timestamp or None, if path doesn't exist. """ - return os.path.getmtime(self.path) + try: + return os.path.getmtime(self.path) + except OSError: + # Might raise FileNotFoundError, OSError for Python 2 + return None def __repr__(self): return '%s(%s)' % (self.__class__.__name__, self.path) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/parso/normalizer.py new/parso-0.5.0/parso/normalizer.py --- old/parso-0.4.0/parso/normalizer.py 2019-04-05 19:01:55.000000000 +0200 +++ new/parso-0.5.0/parso/normalizer.py 2019-06-20 21:27:50.000000000 +0200 @@ -41,8 +41,8 @@ except AttributeError: return self.visit_leaf(node) else: - with self.visit_node(node): - return ''.join(self.visit(child) for child in children) + with self.visit_node(node): + return ''.join(self.visit(child) for child in children) @contextmanager def visit_node(self, node): @@ -147,7 +147,6 @@ return '<%s: %s>' % (self.__class__.__name__, self.code) - class Rule(object): code = None message = None diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/parso/python/errors.py new/parso-0.5.0/parso/python/errors.py --- old/parso-0.4.0/parso/python/errors.py 2019-04-05 19:01:55.000000000 +0200 +++ new/parso-0.5.0/parso/python/errors.py 2019-06-20 21:27:50.000000000 +0200 @@ -953,20 +953,17 @@ self.add_issue(node, message=message) [email protected]_rule(type='comp_for') @ErrorFinder.register_rule(type='sync_comp_for') class _CompForRule(_CheckAssignmentRule): message = "asynchronous comprehension outside of an asynchronous function" def is_issue(self, node): - # Some of the nodes here are already used, so no else if - if node.type != 'comp_for' or self._normalizer.version < (3, 8): - # comp_for was replaced by sync_comp_for in Python 3.8. - expr_list = node.children[1 + int(node.children[0] == 'async')] - if expr_list.type != 'expr_list': # Already handled. - self._check_assignment(expr_list) + expr_list = node.children[1] + print(expr_list) + if expr_list.type != 'expr_list': # Already handled. + self._check_assignment(expr_list) - return node.children[0] == 'async' \ + return node.parent.children[0] == 'async' \ and not self._normalizer.context.is_async_funcdef() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/parso/python/grammar27.txt new/parso-0.5.0/parso/python/grammar27.txt --- old/parso-0.4.0/parso/python/grammar27.txt 2019-04-05 19:01:55.000000000 +0200 +++ new/parso-0.5.0/parso/python/grammar27.txt 2019-06-20 21:27:50.000000000 +0200 @@ -107,7 +107,7 @@ NAME | NUMBER | strings) strings: STRING+ listmaker: test ( list_for | (',' test)* [','] ) -testlist_comp: test ( comp_for | (',' test)* [','] ) +testlist_comp: test ( sync_comp_for | (',' test)* [','] ) lambdef: 'lambda' [varargslist] ':' test trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME subscriptlist: subscript (',' subscript)* [','] @@ -115,8 +115,8 @@ sliceop: ':' [test] exprlist: expr (',' expr)* [','] testlist: test (',' test)* [','] -dictorsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) | - (test (comp_for | (',' test)* [','])) ) +dictorsetmaker: ( (test ':' test (sync_comp_for | (',' test ':' test)* [','])) | + (test (sync_comp_for | (',' test)* [','])) ) classdef: 'class' NAME ['(' [testlist] ')'] ':' suite @@ -125,14 +125,14 @@ |'**' test) # The reason that keywords are test nodes instead of NAME is that using NAME # results in an ambiguity. ast.c makes sure it's a NAME. -argument: test [comp_for] | test '=' test +argument: test [sync_comp_for] | test '=' test list_iter: list_for | list_if list_for: 'for' exprlist 'in' testlist_safe [list_iter] list_if: 'if' old_test [list_iter] -comp_iter: comp_for | comp_if -comp_for: 'for' exprlist 'in' or_test [comp_iter] +comp_iter: sync_comp_for | comp_if +sync_comp_for: 'for' exprlist 'in' or_test [comp_iter] comp_if: 'if' old_test [comp_iter] testlist1: test (',' test)* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/parso/python/grammar33.txt new/parso-0.5.0/parso/python/grammar33.txt --- old/parso-0.4.0/parso/python/grammar33.txt 2019-04-05 19:01:55.000000000 +0200 +++ new/parso-0.5.0/parso/python/grammar33.txt 2019-06-20 21:27:50.000000000 +0200 @@ -105,15 +105,15 @@ '{' [dictorsetmaker] '}' | NAME | NUMBER | strings | '...' | 'None' | 'True' | 'False') strings: STRING+ -testlist_comp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] ) +testlist_comp: (test|star_expr) ( sync_comp_for | (',' (test|star_expr))* [','] ) trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME subscriptlist: subscript (',' subscript)* [','] subscript: test | [test] ':' [test] [sliceop] sliceop: ':' [test] exprlist: (expr|star_expr) (',' (expr|star_expr))* [','] testlist: test (',' test)* [','] -dictorsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) | - (test (comp_for | (',' test)* [','])) ) +dictorsetmaker: ( (test ':' test (sync_comp_for | (',' test ':' test)* [','])) | + (test (sync_comp_for | (',' test)* [','])) ) classdef: 'class' NAME ['(' [arglist] ')'] ':' suite @@ -122,9 +122,9 @@ |'**' test) # The reason that keywords are test nodes instead of NAME is that using NAME # results in an ambiguity. ast.c makes sure it's a NAME. -argument: test [comp_for] | test '=' test # Really [keyword '='] test -comp_iter: comp_for | comp_if -comp_for: 'for' exprlist 'in' or_test [comp_iter] +argument: test [sync_comp_for] | test '=' test # Really [keyword '='] test +comp_iter: sync_comp_for | comp_if +sync_comp_for: 'for' exprlist 'in' or_test [comp_iter] comp_if: 'if' test_nocond [comp_iter] # not used in grammar, but may appear in "node" passed from Parser to Compiler diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/parso/python/grammar34.txt new/parso-0.5.0/parso/python/grammar34.txt --- old/parso-0.4.0/parso/python/grammar34.txt 2019-04-05 19:01:55.000000000 +0200 +++ new/parso-0.5.0/parso/python/grammar34.txt 2019-06-20 21:27:50.000000000 +0200 @@ -105,15 +105,15 @@ '{' [dictorsetmaker] '}' | NAME | NUMBER | strings | '...' | 'None' | 'True' | 'False') strings: STRING+ -testlist_comp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] ) +testlist_comp: (test|star_expr) ( sync_comp_for | (',' (test|star_expr))* [','] ) trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME subscriptlist: subscript (',' subscript)* [','] subscript: test | [test] ':' [test] [sliceop] sliceop: ':' [test] exprlist: (expr|star_expr) (',' (expr|star_expr))* [','] testlist: test (',' test)* [','] -dictorsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) | - (test (comp_for | (',' test)* [','])) ) +dictorsetmaker: ( (test ':' test (sync_comp_for | (',' test ':' test)* [','])) | + (test (sync_comp_for | (',' test)* [','])) ) classdef: 'class' NAME ['(' [arglist] ')'] ':' suite @@ -122,9 +122,9 @@ |'**' test) # The reason that keywords are test nodes instead of NAME is that using NAME # results in an ambiguity. ast.c makes sure it's a NAME. -argument: test [comp_for] | test '=' test # Really [keyword '='] test -comp_iter: comp_for | comp_if -comp_for: 'for' exprlist 'in' or_test [comp_iter] +argument: test [sync_comp_for] | test '=' test # Really [keyword '='] test +comp_iter: sync_comp_for | comp_if +sync_comp_for: 'for' exprlist 'in' or_test [comp_iter] comp_if: 'if' test_nocond [comp_iter] # not used in grammar, but may appear in "node" passed from Parser to Compiler diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/parso/python/grammar35.txt new/parso-0.5.0/parso/python/grammar35.txt --- old/parso-0.4.0/parso/python/grammar35.txt 2019-04-05 19:01:55.000000000 +0200 +++ new/parso-0.5.0/parso/python/grammar35.txt 2019-06-20 21:27:50.000000000 +0200 @@ -112,7 +112,7 @@ '{' [dictorsetmaker] '}' | NAME | NUMBER | strings | '...' | 'None' | 'True' | 'False') strings: STRING+ -testlist_comp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] ) +testlist_comp: (test|star_expr) ( sync_comp_for | (',' (test|star_expr))* [','] ) trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME subscriptlist: subscript (',' subscript)* [','] subscript: test | [test] ':' [test] [sliceop] @@ -120,9 +120,9 @@ exprlist: (expr|star_expr) (',' (expr|star_expr))* [','] testlist: test (',' test)* [','] dictorsetmaker: ( ((test ':' test | '**' expr) - (comp_for | (',' (test ':' test | '**' expr))* [','])) | + (sync_comp_for | (',' (test ':' test | '**' expr))* [','])) | ((test | star_expr) - (comp_for | (',' (test | star_expr))* [','])) ) + (sync_comp_for | (',' (test | star_expr))* [','])) ) classdef: 'class' NAME ['(' [arglist] ')'] ':' suite @@ -137,13 +137,13 @@ # Illegal combinations and orderings are blocked in ast.c: # multiple (test comp_for) arguments are blocked; keyword unpackings # that precede iterable unpackings are blocked; etc. -argument: ( test [comp_for] | +argument: ( test [sync_comp_for] | test '=' test | '**' test | '*' test ) -comp_iter: comp_for | comp_if -comp_for: 'for' exprlist 'in' or_test [comp_iter] +comp_iter: sync_comp_for | comp_if +sync_comp_for: 'for' exprlist 'in' or_test [comp_iter] comp_if: 'if' test_nocond [comp_iter] # not used in grammar, but may appear in "node" passed from Parser to Compiler diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/parso/python/grammar36.txt new/parso-0.5.0/parso/python/grammar36.txt --- old/parso-0.4.0/parso/python/grammar36.txt 2019-04-05 19:01:55.000000000 +0200 +++ new/parso-0.5.0/parso/python/grammar36.txt 2019-06-20 21:27:50.000000000 +0200 @@ -140,7 +140,8 @@ '*' test ) comp_iter: comp_for | comp_if -comp_for: ['async'] 'for' exprlist 'in' or_test [comp_iter] +sync_comp_for: 'for' exprlist 'in' or_test [comp_iter] +comp_for: ['async'] sync_comp_for comp_if: 'if' test_nocond [comp_iter] # not used in grammar, but may appear in "node" passed from Parser to Compiler diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/parso/python/grammar37.txt new/parso-0.5.0/parso/python/grammar37.txt --- old/parso-0.4.0/parso/python/grammar37.txt 2019-04-05 19:01:55.000000000 +0200 +++ new/parso-0.5.0/parso/python/grammar37.txt 2019-06-20 21:27:50.000000000 +0200 @@ -138,7 +138,8 @@ '*' test ) comp_iter: comp_for | comp_if -comp_for: ['async'] 'for' exprlist 'in' or_test [comp_iter] +sync_comp_for: 'for' exprlist 'in' or_test [comp_iter] +comp_for: ['async'] sync_comp_for comp_if: 'if' test_nocond [comp_iter] # not used in grammar, but may appear in "node" passed from Parser to Compiler diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/parso/python/grammar38.txt new/parso-0.5.0/parso/python/grammar38.txt --- old/parso-0.4.0/parso/python/grammar38.txt 2019-04-05 19:01:55.000000000 +0200 +++ new/parso-0.5.0/parso/python/grammar38.txt 2019-06-20 21:27:50.000000000 +0200 @@ -20,13 +20,25 @@ funcdef: 'def' NAME parameters ['->' test] ':' suite parameters: '(' [typedargslist] ')' -typedargslist: (tfpdef ['=' test] (',' tfpdef ['=' test])* [',' [ +typedargslist: ( + (tfpdef ['=' test] (',' tfpdef ['=' test])* ',' '/' [',' [ tfpdef ['=' test] ( + ',' tfpdef ['=' test])* ([',' [ + '*' [tfpdef] (',' tfpdef ['=' test])* [',' ['**' tfpdef [',']]] + | '**' tfpdef [',']]]) + | '*' [tfpdef] (',' tfpdef ['=' test])* ([',' ['**' tfpdef [',']]]) + | '**' tfpdef [',']]] ) +| (tfpdef ['=' test] (',' tfpdef ['=' test])* [',' [ '*' [tfpdef] (',' tfpdef ['=' test])* [',' ['**' tfpdef [',']]] | '**' tfpdef [',']]] | '*' [tfpdef] (',' tfpdef ['=' test])* [',' ['**' tfpdef [',']]] | '**' tfpdef [',']) +) tfpdef: NAME [':' test] -varargslist: (vfpdef ['=' test] (',' vfpdef ['=' test])* [',' [ +varargslist: vfpdef ['=' test ](',' vfpdef ['=' test])* ',' '/' [',' [ (vfpdef ['=' test] (',' vfpdef ['=' test])* [',' [ + '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]] + | '**' vfpdef [',']]] + | '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]] + | '**' vfpdef [',']) ]] | (vfpdef ['=' test] (',' vfpdef ['=' test])* [',' [ '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]] | '**' vfpdef [',']]] | '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]] @@ -69,8 +81,8 @@ compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef | decorated | async_stmt async_stmt: 'async' (funcdef | with_stmt | for_stmt) -if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] -while_stmt: 'while' test ':' suite ['else' ':' suite] +if_stmt: 'if' namedexpr_test ':' suite ('elif' namedexpr_test ':' suite)* ['else' ':' suite] +while_stmt: 'while' namedexpr_test ':' suite ['else' ':' suite] for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] try_stmt: ('try' ':' suite ((except_clause ':' suite)+ @@ -83,6 +95,7 @@ except_clause: 'except' [test ['as' NAME]] suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT +namedexpr_test: test [':=' test] test: or_test ['if' or_test 'else' test] | lambdef test_nocond: or_test | lambdef_nocond lambdef: 'lambda' [varargslist] ':' test @@ -108,7 +121,7 @@ '[' [testlist_comp] ']' | '{' [dictorsetmaker] '}' | NAME | NUMBER | strings | '...' | 'None' | 'True' | 'False') -testlist_comp: (test|star_expr) ( comp_for | (',' (test|star_expr))* [','] ) +testlist_comp: (namedexpr_test|star_expr) ( comp_for | (',' (namedexpr_test|star_expr))* [','] ) trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME subscriptlist: subscript (',' subscript)* [','] subscript: test | [test] ':' [test] [sliceop] @@ -134,6 +147,7 @@ # multiple (test comp_for) arguments are blocked; keyword unpackings # that precede iterable unpackings are blocked; etc. argument: ( test [comp_for] | + test ':=' test | test '=' test | '**' test | '*' test ) @@ -153,5 +167,5 @@ fstring: FSTRING_START fstring_content* FSTRING_END fstring_content: FSTRING_STRING | fstring_expr fstring_conversion: '!' NAME -fstring_expr: '{' testlist [ fstring_conversion ] [ fstring_format_spec ] '}' +fstring_expr: '{' testlist ['='] [ fstring_conversion ] [ fstring_format_spec ] '}' fstring_format_spec: ':' fstring_content* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/parso/python/parser.py new/parso-0.5.0/parso/python/parser.py --- old/parso-0.4.0/parso/python/parser.py 2019-04-05 19:01:55.000000000 +0200 +++ new/parso-0.5.0/parso/python/parser.py 2019-06-20 21:27:50.000000000 +0200 @@ -39,13 +39,13 @@ 'for_stmt': tree.ForStmt, 'while_stmt': tree.WhileStmt, 'try_stmt': tree.TryStmt, - 'comp_for': tree.CompFor, + 'sync_comp_for': tree.SyncCompFor, # Not sure if this is the best idea, but IMO it's the easiest way to # avoid extreme amounts of work around the subtle difference of 2/3 # grammar in list comoprehensions. - 'list_for': tree.CompFor, + 'list_for': tree.SyncCompFor, # Same here. This just exists in Python 2.6. - 'gen_for': tree.CompFor, + 'gen_for': tree.SyncCompFor, 'decorator': tree.Decorator, 'lambdef': tree.Lambda, 'old_lambdef': tree.Lambda, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/parso/python/tokenize.py new/parso-0.5.0/parso/python/tokenize.py --- old/parso-0.4.0/parso/python/tokenize.py 2019-04-05 19:01:55.000000000 +0200 +++ new/parso-0.5.0/parso/python/tokenize.py 2019-06-20 21:27:50.000000000 +0200 @@ -120,6 +120,8 @@ fstring_string_single_line = _compile(r'(?:[^{}\r\n]+|\{\{|\}\})+') fstring_string_multi_line = _compile(r'(?:[^{}]+|\{\{|\}\})+') +fstring_format_spec_single_line = _compile(r'[^{}\r\n]+') +fstring_format_spec_multi_line = _compile(r'[^{}]+') def _create_token_collection(version_info): @@ -151,6 +153,8 @@ Octnumber = '0[oO]?[0-7]+' Decnumber = r'(?:0+|[1-9][0-9]*)' Intnumber = group(Hexnumber, Binnumber, Octnumber, Decnumber) + if version_info[0] < 3: + Intnumber += '[lL]?' Exponent = r'[eE][-+]?[0-9]+' Pointfloat = group(r'[0-9]+\.[0-9]*', r'\.[0-9]+') + maybe(Exponent) Expfloat = r'[0-9]+' + Exponent @@ -186,9 +190,13 @@ Bracket = '[][(){}]' - special_args = [r'\r\n?', r'\n', r'[:;.,@]'] + special_args = [r'\r\n?', r'\n', r'[;.,@]'] if version_info >= (3, 0): special_args.insert(0, r'\.\.\.') + if version_info >= (3, 8): + special_args.insert(0, ":=?") + else: + special_args.insert(0, ":") Special = group(*special_args) Funny = group(Operator, Bracket, Special) @@ -281,7 +289,10 @@ return len(self.quote) == 3 def is_in_expr(self): - return (self.parentheses_count - self.format_spec_count) > 0 + return self.parentheses_count > self.format_spec_count + + def is_in_format_spec(self): + return not self.is_in_expr() and self.format_spec_count def _close_fstring_if_necessary(fstring_stack, string, start_pos, additional_prefix): @@ -303,10 +314,18 @@ def _find_fstring_string(endpats, fstring_stack, line, lnum, pos): tos = fstring_stack[-1] allow_multiline = tos.allow_multiline() - if allow_multiline: - match = fstring_string_multi_line.match(line, pos) + if tos.is_in_format_spec(): + if allow_multiline: + regex = fstring_format_spec_multi_line + else: + regex = fstring_format_spec_single_line else: - match = fstring_string_single_line.match(line, pos) + if allow_multiline: + regex = fstring_string_multi_line + else: + regex = fstring_string_single_line + + match = regex.match(line, pos) if match is None: return tos.previous_lines, pos @@ -575,7 +594,8 @@ if paren_level: paren_level -= 1 elif token == ':' and fstring_stack \ - and fstring_stack[-1].parentheses_count == 1: + and fstring_stack[-1].parentheses_count \ + - fstring_stack[-1].format_spec_count == 1: fstring_stack[-1].format_spec_count += 1 yield PythonToken(OP, token, spos, prefix) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/parso/python/tree.py new/parso-0.5.0/parso/python/tree.py --- old/parso-0.4.0/parso/python/tree.py 2019-04-05 19:01:55.000000000 +0200 +++ new/parso-0.5.0/parso/python/tree.py 2019-06-20 21:27:50.000000000 +0200 @@ -43,6 +43,7 @@ """ import re +from collections import Mapping from parso._compatibility import utf8_repr, unicode from parso.tree import Node, BaseNode, Leaf, ErrorNode, ErrorLeaf, \ @@ -55,7 +56,7 @@ _RETURN_STMT_CONTAINERS = set(['suite', 'simple_stmt']) | _FLOW_CONTAINERS _FUNC_CONTAINERS = set(['suite', 'simple_stmt', 'decorated']) | _FLOW_CONTAINERS _GET_DEFINITION_TYPES = set([ - 'expr_stmt', 'comp_for', 'with_stmt', 'for_stmt', 'import_name', + 'expr_stmt', 'sync_comp_for', 'with_stmt', 'for_stmt', 'import_name', 'import_from', 'param' ]) _IMPORTS = set(['import_name', 'import_from']) @@ -442,7 +443,7 @@ recurse(child) recurse(self) - self._used_names = dct + self._used_names = UsedNamesMapping(dct) return self._used_names @@ -466,6 +467,9 @@ :rtype: list of :class:`Decorator` """ decorated = self.parent + if decorated.type == 'async_funcdef': + decorated = decorated.parent + if decorated.type == 'decorated': if decorated.children[0].type == 'decorators': return decorated.children[0].children @@ -545,7 +549,8 @@ if param_children[0] == '*' \ and (len(param_children) == 1 or param_children[1] == ',') \ - or check_python2_nested_param(param_children[0]): + or check_python2_nested_param(param_children[0]) \ + or param_children[0] == '/': for p in param_children: p.parent = parent new_children += param_children @@ -1158,6 +1163,13 @@ index -= 2 except ValueError: pass + try: + keyword_only_index = self.parent.children.index('/') + if index > keyword_only_index: + # Skip the ` /, ` + index -= 2 + except ValueError: + pass return index - 1 def get_parent_function(self): @@ -1189,8 +1201,8 @@ return '<%s: %s>' % (type(self).__name__, str(self._tfpdef()) + default) -class CompFor(PythonBaseNode): - type = 'comp_for' +class SyncCompFor(PythonBaseNode): + type = 'sync_comp_for' __slots__ = () def get_defined_names(self): @@ -1198,4 +1210,33 @@ Returns the a list of `Name` that the comprehension defines. """ # allow async for - return _defined_names(self.children[self.children.index('for') + 1]) + return _defined_names(self.children[1]) + + +# This is simply here so an older Jedi version can work with this new parso +# version. Can be deleted in the next release. +CompFor = SyncCompFor + + +class UsedNamesMapping(Mapping): + """ + This class exists for the sole purpose of creating an immutable dict. + """ + def __init__(self, dct): + self._dict = dct + + def __getitem__(self, key): + return self._dict[key] + + def __len__(self): + return len(self._dict) + + def __iter__(self): + return iter(self._dict) + + def __hash__(self): + return id(self) + + def __eq__(self, other): + # Comparing these dicts does not make sense. + return self is other diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/parso.egg-info/PKG-INFO new/parso-0.5.0/parso.egg-info/PKG-INFO --- old/parso-0.4.0/parso.egg-info/PKG-INFO 2019-04-05 19:10:01.000000000 +0200 +++ new/parso-0.5.0/parso.egg-info/PKG-INFO 2019-06-20 22:11:18.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: parso -Version: 0.4.0 +Version: 0.5.0 Summary: A Python Parser Home-page: https://github.com/davidhalter/parso Author: David Halter @@ -106,6 +106,14 @@ Changelog --------- + 0.5.0 (2019-06-20) + ++++++++++++++++++ + + - **Breaking Change** comp_for is now called sync_comp_for for all Python + versions to be compatible with the Python 3.8 Grammar + - Added .pyi stubs for a lot of the parso API + - Small FileIO changes + 0.4.0 (2019-04-05) ++++++++++++++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/test/failing_examples.py new/parso-0.5.0/test/failing_examples.py --- old/parso-0.4.0/test/failing_examples.py 2019-04-05 19:01:55.000000000 +0200 +++ new/parso-0.5.0/test/failing_examples.py 2019-06-20 21:27:50.000000000 +0200 @@ -146,7 +146,7 @@ # Now nested parsing "f'{continue}'", "f'{1;1}'", - "f'{a=3}'", + "f'{a;}'", "f'{b\"\" \"\"}'", ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/test/test_fstring.py new/parso-0.5.0/test/test_fstring.py --- old/parso-0.4.0/test/test_fstring.py 2019-04-05 19:01:55.000000000 +0200 +++ new/parso-0.5.0/test/test_fstring.py 2019-06-20 21:27:50.000000000 +0200 @@ -7,7 +7,7 @@ @pytest.fixture def grammar(): - return load_grammar(version='3.6') + return load_grammar(version='3.8') @pytest.mark.parametrize( @@ -21,6 +21,9 @@ '{1:1.{32}}', '{1::>4}', '{foo} {bar}', + '{x:{y}}', + '{x:{y:}}', + '{x:{y:1}}', # Escapes '{{}}', @@ -28,6 +31,10 @@ '{{{1}', '1{{2{{3', '}}', + + # New Python 3.8 syntax f'{a=}' + '{a=}', + '{a()=}', ] ) def test_valid(code, grammar): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/test/test_parser.py new/parso-0.5.0/test/test_parser.py --- old/parso-0.4.0/test/test_parser.py 2019-04-05 19:01:55.000000000 +0200 +++ new/parso-0.5.0/test/test_parser.py 2019-06-20 21:27:50.000000000 +0200 @@ -189,3 +189,22 @@ check(child) check(parse("if foo:\n bar", version=each_version)) + + +def test_named_expression(works_ge_py38): + works_ge_py38.parse("(a := 1, a + 1)") + + [email protected]( + 'param_code', [ + 'a=1, /', + 'a, /', + 'a=1, /, b=3', + 'a, /, b', + 'a, /, b', + 'a, /, *, b', + 'a, /, **kwargs', + ] +) +def test_positional_only_arguments(works_ge_py38, param_code): + works_ge_py38.parse("def x(%s): pass" % param_code) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/parso-0.4.0/test/test_pgen2.py new/parso-0.5.0/test/test_pgen2.py --- old/parso-0.4.0/test/test_pgen2.py 2019-04-05 19:01:55.000000000 +0200 +++ new/parso-0.5.0/test/test_pgen2.py 2019-06-20 21:27:50.000000000 +0200 @@ -190,6 +190,19 @@ works_in_py2.parse("07") +def test_long_notation(works_in_py2): + works_in_py2.parse("0xFl") + works_in_py2.parse("0xFL") + works_in_py2.parse("0b1l") + works_in_py2.parse("0B1L") + works_in_py2.parse("0o7l") + works_in_py2.parse("0O7L") + works_in_py2.parse("0l") + works_in_py2.parse("0L") + works_in_py2.parse("10l") + works_in_py2.parse("10L") + + def test_new_binary_notation(each_version): _parse("""0b101010""", each_version) _invalid_syntax("""0b0101021""", each_version)
