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)


Reply via email to