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
+
+- 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))
+
+
+@pytest.fixture
+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)
-@ErrorFinder.register_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)")
+
+
+@pytest.mark.parametrize(
+ '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)