[Python-modules-commits] [fparser] 01/06: upstream release 0.0.6
Alastair McKinstry
mckinstry at moszumanska.debian.org
Wed Dec 20 09:54:20 UTC 2017
This is an automated email from the git hooks/post-receive script.
mckinstry pushed a commit to branch debian/master
in repository fparser.
commit 96418942ba2a6bce7155cd839ecb881ace30c468
Author: Alastair McKinstry <mckinstry at debian.org>
Date: Wed Dec 13 12:53:04 2017 +0000
upstream release 0.0.6
---
CHANGELOG.md | 43 +-
__init__.py | 63 -
doc/conf.py | 20 +-
doc/fparser.rst | 5 +-
setup.py | 4 +-
src/__init__.py | 63 -
src/fparser/Fortran2003.py | 504 ++++---
src/fparser/api.py | 86 +-
src/fparser/base_classes.py | 131 +-
src/fparser/block_statements.py | 77 +-
src/fparser/parsefortran.py | 54 +-
src/fparser/pattern_tools.py | 22 +-
src/fparser/readfortran.py | 98 +-
src/fparser/scripts/f2003.py | 10 +-
src/fparser/scripts/parse.py | 4 +-
src/fparser/scripts/read.py | 4 +-
src/fparser/setup.py | 69 -
src/fparser/sourceinfo.py | 2 +-
src/fparser/splitline.py | 378 ++---
src/fparser/statements.py | 832 +++++++----
src/fparser/tests/__init__.py | 0
.../tests/{ => fparser2}/test_Fortran2003.py | 1507 +++++++++++---------
src/fparser/tests/fparser2/test_base_classses.py | 91 ++
src/fparser/tests/fparser2/test_deferred_method.py | 78 +
src/fparser/tests/logging_utils.py | 84 ++
src/fparser/tests/test_api.py | 14 +-
src/fparser/tests/test_base_classes.py | 72 +
src/fparser/tests/test_blank_lines.py | 2 +-
src/fparser/tests/test_issue11.py | 2 +-
src/fparser/tests/test_issue25.py | 2 +-
src/fparser/tests/test_issue26.py | 2 +-
src/fparser/tests/test_issue33.py | 2 +-
src/fparser/tests/test_issue5.py | 4 +-
src/fparser/tests/test_issue7.py | 42 +-
src/fparser/tests/test_mod_private.py | 6 +-
src/fparser/tests/test_parser.py | 986 ++++++++-----
src/fparser/tests/test_readfortran.py | 75 +
src/fparser/tests/test_select.py | 22 +-
.../tests/{test_api.py => test_splitline.py} | 184 +--
src/fparser/tests/test_utils.py | 10 +-
src/fparser/typedecl_statements.py | 61 +-
src/fparser/utils.py | 36 +-
42 files changed, 3378 insertions(+), 2373 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5499de0..6b249dd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,47 @@
# Change log for the fparser package #
Original code by Pearu Peterson.
-Modifications by Andrew Porter and Rupert Ford of the Science
-and Technology Facilities Council, UK.
+
+Modifications by:
+
+* R. W. Ford, Science & Technology Facilities Council, UK
+* M. Hambley, UK Met Office
+* J. Henrichs, Australia Bureau of Meteorology
+* I. Kavcic, UK Met Office
+* A. R. Porter, Science & Technology Facilities Council, UK
+* P. Vitt, University of Siegen, Germany
+
+## Release 0.0.6 (04/12/2017) ##
+
+04/12/2017 PRs #61 and #62. Remove the dependence on numpy.
+
+24/11/2017 PR #60. Add fparser2 support for the 'deferred' attribute on a
+ procedure declaration.
+
+24/11/2017 PR #54. Add support for array initialisation using square
+ brackets in fparser1, e.g. 'integer :: a(2) = [x, y]'
+
+09/11/2017 Issue #40 and PR #56 bug fix for missing comma when
+ generating "USE, intrinsic :: ..."
+
+21/10/2017 issue #36 and PR #47 generate correct open statement in
+ fparser2 when the 'UNIT' keyword is not provided
+
+20/10/2017 PR #49 pep8, pylint and nose->pytest changes for test_parse.py
+
+20/10/2017 issue #43 and PR #48 add support for Python 3.
+
+19/10/2017 issue #45 and PR #46 - bug fix for optional '::'
+ between MODULE PROCEDURE and <procedure name>
+
+13/10/2017 issue #41 and PR #42 - removed __init__.py files from
+ directories that do not contain package code
+
+28/09/2017 issue #35 pr #39 add support for the 'opened' option
+ in the inquire statement in fparser2.
+
+06/09/2017 issue #34 pr #37 Fix a format statement parsing
+ bug in fparser2
## Release 0.0.5 (20/06/2017) ##
diff --git a/__init__.py b/__init__.py
deleted file mode 100644
index 1814d85..0000000
--- a/__init__.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Modified work Copyright (c) 2017 Science and Technology Facilities Council
-# Original work Copyright (c) 1999-2008 Pearu Peterson
-
-# All rights reserved.
-
-# Modifications made as part of the fparser project are distributed
-# under the following license:
-
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-
-# 3. Neither the name of the copyright holder nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# --------------------------------------------------------------------
-
-# The original software (in the f2py project) was distributed under
-# the following license:
-
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-
-# a. Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# b. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-# c. Neither the name of the F2PY project nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
-# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-# DAMAGE.
diff --git a/doc/conf.py b/doc/conf.py
index 182c6d6..6586f3d 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -115,17 +115,17 @@ source_suffix = '.rst'
master_doc = 'index'
# General information about the project.
-project = u'fparser'
-copyright = u'2017, Science and Technology Facilities Council'
+project = 'fparser'
+copyright = '2017, Science and Technology Facilities Council'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
-version = '0.0.5'
+version = '0.0.6'
# The full version, including alpha/beta/rc tags.
-release = '0.0.5'
+release = '0.0.6'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -268,8 +268,8 @@ latex_elements = {
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
- ('index', 'fparser.tex', u'fparser Documentation',
- u'Andrew Porter, Rupert Ford and Pearu Peterson', 'manual'),
+ ('index', 'fparser.tex', 'fparser Documentation',
+ 'Andrew Porter, Rupert Ford and Pearu Peterson', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
@@ -298,8 +298,8 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
- ('index', 'fparser', u'fparser Documentation',
- [u'Andrew Porter, Rupert Ford and Pearu Peterson'], 1)
+ ('index', 'fparser', 'fparser Documentation',
+ ['Andrew Porter, Rupert Ford and Pearu Peterson'], 1)
]
# If true, show URL addresses after external links.
@@ -312,8 +312,8 @@ man_pages = [
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
- ('index', 'fparser', u'fparser Documentation',
- u'Andrew Porter, Rupert Ford and Pearu Peterson', 'fparser', 'One line description of project.',
+ ('index', 'fparser', 'fparser Documentation',
+ 'Andrew Porter, Rupert Ford and Pearu Peterson', 'fparser', 'One line description of project.',
'Miscellaneous'),
]
diff --git a/doc/fparser.rst b/doc/fparser.rst
index 933b651..f70c49b 100644
--- a/doc/fparser.rst
+++ b/doc/fparser.rst
@@ -80,9 +80,8 @@ order to support some of the aspects of more recent versions of
Fortran (see :ref:`beyond_f90`). In order to use it you will need to
have installed the fparser package which is available from the Python
Packagage Index (pypi) or github (https://github.com/stfc/fparser). In
-turn fparser requires the numpy and nose packages. When installing
-using pip these dependencies should be installed automatically for
-you.
+turn fparser requires the "nose" and "six" packages. When installing using pip
+these dependencies should be installed automatically for you.
Once installed, you should be able to open the python interpreter and
try it out, e.g.:
diff --git a/setup.py b/setup.py
index 539d732..dffe732 100644
--- a/setup.py
+++ b/setup.py
@@ -102,7 +102,7 @@ CLASSIFIERS = [
MAJOR = 0
MINOR = 0
-MICRO = 5
+MICRO = 6
VERSION = '%d.%d.%d' % (MAJOR, MINOR, MICRO)
if __name__ == '__main__':
@@ -119,7 +119,7 @@ if __name__ == '__main__':
classifiers=CLASSIFIERS,
packages=PACKAGES,
package_dir={"": "src"},
- install_requires=['numpy', 'nose'],
+ install_requires=['nose', 'six'],
# We need the following line to ensure we get the fparser/log.config
# file installed.
include_package_data=True)
diff --git a/src/__init__.py b/src/__init__.py
deleted file mode 100644
index 1814d85..0000000
--- a/src/__init__.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Modified work Copyright (c) 2017 Science and Technology Facilities Council
-# Original work Copyright (c) 1999-2008 Pearu Peterson
-
-# All rights reserved.
-
-# Modifications made as part of the fparser project are distributed
-# under the following license:
-
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-
-# 3. Neither the name of the copyright holder nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# --------------------------------------------------------------------
-
-# The original software (in the f2py project) was distributed under
-# the following license:
-
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-
-# a. Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# b. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-# c. Neither the name of the F2PY project nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
-# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-# DAMAGE.
diff --git a/src/fparser/Fortran2003.py b/src/fparser/Fortran2003.py
index 461836e..c0beb81 100644
--- a/src/fparser/Fortran2003.py
+++ b/src/fparser/Fortran2003.py
@@ -71,9 +71,9 @@
import re
import logging
-from splitline import string_replace_map
-import pattern_tools as pattern
-from readfortran import FortranReaderBase
+from .splitline import string_replace_map
+from . import pattern_tools as pattern
+from .readfortran import FortranReaderBase
logger = logging.getLogger("fparser")
@@ -92,11 +92,65 @@ def show_result(func):
def new_func(cls, string, **kws):
r = func(cls, string, **kws)
if r is not None and isinstance(r, StmtBase):
- print '%s(%r) -> %r' % (cls.__name__, string, str(r))
+ print('%s(%r) -> %r' % (cls.__name__, string, str(r)))
return r
return new_func
-class Base(object):
+
+class ComparableMixin(object):
+ """ Mixin class to provide rich comparison operators.
+
+ This mixin provides a set of rich comparison operators. Each class using
+ this mixin has to provide a _cmpkey() method that returns a key of objects
+ that can be compared.
+
+ See also http://python3porting.com/preparing.html#richcomparisons
+ """
+ # pylint: disable=too-few-public-methods
+
+ def _compare(self, other, method):
+ """ Call the method, if other is able to be used within it.
+
+ :param object other: The other object to compare with
+ :type other: object
+ :param method: The method to call to compare self and other.
+ :type method: LambdaType
+ :return: NotImplemented, when the comparison for the given type
+ combination can't be performed.
+ :rtype: :py:type:`NotImplementedType`
+ """
+ try:
+ # This routine's purpose is to access the protected method _cmpkey()
+ # from client classes, therefore:
+ # pylint: disable=protected-access
+ return method(self._cmpkey(), other._cmpkey())
+ except (AttributeError, TypeError):
+ # _cmpkey not implemented, or return different type,
+ # so I can't compare with "other".
+ # According to the Python Language Reference Manual
+ # (http://www.network-theory.co.uk/docs/pylang/Coercionrules.html)
+ # return NotImplemented
+ return NotImplemented
+
+ def __lt__(self, other):
+ return self._compare(other, lambda s, o: s < o)
+
+ def __le__(self, other):
+ return self._compare(other, lambda s, o: s <= o)
+
+ def __eq__(self, other):
+ return self._compare(other, lambda s, o: s == o)
+
+ def __ge__(self, other):
+ return self._compare(other, lambda s, o: s >= o)
+
+ def __gt__(self, other):
+ return self._compare(other, lambda s, o: s > o)
+
+ def __ne__(self, other):
+ return self._compare(other, lambda s, o: s != o)
+
+class Base(ComparableMixin):
""" Base class for Fortran 2003 syntax rules.
All Base classes have the following attributes:
@@ -107,8 +161,16 @@ class Base(object):
subclasses = {}
@show_result
- def __new__(cls, string, parent_cls = None):
+ def __new__(cls, string, parent_cls=None):
"""
+ Create a new instance of this object.
+
+ :param cls: the class of object to create
+ :type cls: :py:type:`type`
+ :param string: (source of) Fortran string to parse
+ :type string: str or :py:class:`FortranReaderBase`
+ :param parent_cls: the parent class of this object
+ :type parent_cls: :py:type:`type`
"""
if parent_cls is None:
parent_cls = [cls]
@@ -140,7 +202,7 @@ class Base(object):
# restore readers content when no match is found.
try:
result = cls.match(string)
- except NoMatchError, msg:
+ except NoMatchError as msg:
if str(msg)=='%s: %r' % (cls.__name__, string): # avoid recursion 1.
raise
@@ -160,17 +222,14 @@ class Base(object):
#print '%s:%s: %r' % (cls.__name__,subcls.__name__,string)
try:
obj = subcls(string, parent_cls = parent_cls)
- except NoMatchError, msg:
+ except NoMatchError as msg:
obj = None
if obj is not None:
return obj
-
else:
- raise AssertionError,`result`
+ raise AssertionError(repr(result))
errmsg = '%s: %r' % (cls.__name__, string)
- #if isinstance(string, FortranReaderBase) and string.fifo_item:
- # errmsg += ' while reaching %s' % (string.fifo_item[-1])
- raise NoMatchError, errmsg
+ raise NoMatchError(errmsg)
## def restore_reader(self):
## self._item.reader.put_item(self._item)
@@ -183,17 +242,14 @@ class Base(object):
return '%s(%s)' % (self.__class__.__name__, ', '.join(map(repr,
self.items)))
- def compare(self, other):
- return cmp(self.items,other.items)
-
def __str__(self): return self.tostr()
def __repr__(self): return self.torepr()
- def __cmp__(self, other):
- if self is other: return 0
- if not isinstance(other, self.__class__): return cmp(self.__class__, other.__class__)
- return self.compare(other)
+ def _cmpkey(self):
+ """ Provides a key of objects to be used for comparing.
+ """
+ return self.items
def tofortran(self, tab='', isfix=None):
return tab + str(self)
@@ -224,7 +280,7 @@ content : tuple
enable_select_type_construct_hook = False,
enable_case_construct_hook = False
):
- assert isinstance(reader,FortranReaderBase),`reader`
+ assert isinstance(reader, FortranReaderBase), repr(reader)
content = []
if startcls is not None:
try:
@@ -363,11 +419,15 @@ content : tuple
def init(self, content):
self.content = content
return
- def compare(self, other):
- return cmp(self.content,other.content)
+
+ def _cmpkey(self):
+ """ Provides a key of objects to be used for comparing.
+ """
+ return self.content
def tostr(self):
return self.tofortran()
+
def torepr(self):
return '%s(%s)' % (self.__class__.__name__,', '.join(map(repr, self.content)))
@@ -426,8 +486,11 @@ class SequenceBase(Base):
else: s = ' ' + s + ' '
return s.join(map(str, self.items))
def torepr(self): return '%s(%r, %r)' % (self.__class__.__name__, self.separator, self.items)
- def compare(self, other):
- return cmp((self.separator,self.items),(other.separator,self.items))
+
+ def _cmpkey(self):
+ """ Provides a key of objects to be used for comparing.
+ """
+ return (self.separator, self.items)
class UnaryOpBase(Base):
"""
@@ -523,37 +586,48 @@ class SeparatorBase(Base):
s += ' %s' % (self.items[1])
return s
+
class KeywordValueBase(Base):
"""
::
<keyword-value-base> = [ <lhs> = ] <rhs>
"""
- def match(lhs_cls, rhs_cls, string, require_lhs = True, upper_lhs = False):
- if require_lhs and '=' not in string: return
+ @staticmethod
+ def match(lhs_cls, rhs_cls, string, require_lhs=True, upper_lhs=False):
+ if require_lhs and '=' not in string:
+ return
if isinstance(lhs_cls, (list, tuple)):
for s in lhs_cls:
- try:
- obj = KeywordValueBase.match(s, rhs_cls, string, require_lhs=require_lhs, upper_lhs=upper_lhs)
- except NoMatchError:
- obj = None
- if obj is not None: return obj
+ obj = KeywordValueBase.match(s, rhs_cls, string,
+ require_lhs=require_lhs,
+ upper_lhs=upper_lhs)
+ if obj:
+ return obj
return obj
- lhs,rhs = string.split('=',1)
- lhs = lhs.rstrip()
+ if "=" in string:
+ lhs, rhs = string.split('=', 1)
+ lhs = lhs.rstrip()
+ else:
+ lhs = None
+ rhs = string.rstrip()
rhs = rhs.lstrip()
- if not rhs: return
+ if not rhs:
+ return
if not lhs:
- if require_lhs: return
+ if require_lhs:
+ return
return None, rhs_cls(rhs)
if isinstance(lhs_cls, str):
if upper_lhs:
lhs = lhs.upper()
- if lhs_cls!=lhs: return
+ if lhs_cls != lhs:
+ return
return lhs, rhs_cls(rhs)
- return lhs_cls(lhs),rhs_cls(rhs)
- match = staticmethod(match)
+ return lhs_cls(lhs), rhs_cls(rhs)
+
def tostr(self):
- if self.items[0] is None: return str(self.items[1])
+ if self.items[0] is None:
+ return str(self.items[1])
return '%s = %s' % tuple(self.items)
class BracketBase(Base):
@@ -565,7 +639,7 @@ class BracketBase(Base):
def match(brackets, cls, string, require_cls=True):
''' The generic match method for all types of bracketed
expressions '''
- bracket_len = len(brackets)/2
+ bracket_len = len(brackets)//2
left = brackets[:bracket_len]
right = brackets[-bracket_len:]
@@ -625,8 +699,11 @@ class NumberBase(Base):
def tostr(self):
if self.items[1] is None: return str(self.items[0])
return '%s_%s' % tuple(self.items)
- def compare(self, other):
- return cmp(self.items[0], other.items[0])
+
+ def _cmpkey(self):
+ """ Provides a key of objects to be used for comparing.
+ """
+ return self.items[0]
class CallBase(Base):
"""
@@ -701,8 +778,11 @@ string
return
def tostr(self): return str(self.string)
def torepr(self): return '%s(%r)' % (self.__class__.__name__, self.string)
- def compare(self, other):
- return cmp(self.string,other.string)
+
+ def _cmpkey(self):
+ """ Provides a key of objects to be used for comparing.
+ """
+ return self.string
class STRINGBase(StringBase):
"""
@@ -1870,7 +1950,7 @@ class Component_Decl(Base): # R442
if newline.startswith('='):
init = Component_Initialization(newline)
else:
- assert newline=='',`newline`
+ assert newline=='', repr(newline)
return name, array_spec, char_length, init
match = staticmethod(match)
def tostr(self):
@@ -2009,7 +2089,7 @@ class Specific_Binding(StmtBase): # R451
if line.startswith('('):
i = line.find(')')
if i==-1: return
- iname = Interface_Name(line[1:-1].strip())
+ iname = Interface_Name(line[1:i].strip())
line = line[i+1:].lstrip()
l = None
i = line.find('::')
@@ -2074,10 +2154,13 @@ class Binding_Attr(STRINGBase): # R453
<binding-attr> = PASS [ ( <arg-name> ) ]
| NOPASS
| NON_OVERRIDABLE
+ | DEFERRED
| <access-spec>
"""
subclass_names = ['Access_Spec', 'Binding_PASS_Arg_Name']
- def match(string): return STRINGBase.match(['PASS', 'NOPASS', 'NON_OVERRIDABLE'], string)
+ def match(string):
+ return STRINGBase.match(['PASS', 'NOPASS',
+ 'NON_OVERRIDABLE', 'DEFERRED'], string)
match = staticmethod(match)
class Final_Binding(StmtBase, WORDClsBase): # R454
@@ -2465,7 +2548,7 @@ class Entity_Decl(Base): # R504
elif newline:
return
else:
- assert newline=='',`newline, string`
+ assert newline=='', repr((newline, string))
return name, array_spec, char_length, init
match = staticmethod(match)
def tostr(self):
@@ -3188,7 +3271,7 @@ items : (Namelist_Group_Name, Namelist_Group_Object_List)-tuple
parts = line.split('/')
items = []
fst = parts.pop(0)
- assert not fst,`fst, parts`
+ assert not fst, repr((fst, parts))
while len(parts)>=2:
name,lst = parts[:2]
del parts[:2]
@@ -3197,7 +3280,7 @@ items : (Namelist_Group_Name, Namelist_Group_Object_List)-tuple
if lst.endswith(','):
lst = lst[:-1].rstrip()
items.append((Namelist_Group_Name(name),Namelist_Group_Object_List(lst)))
- assert not parts,`parts`
+ assert not parts, repr(parts)
return tuple(items)
def tostr(self):
@@ -3551,7 +3634,7 @@ class Allocate_Stmt(StmtBase): # R623
opts = None
if i!=-1:
j = line[:i].rfind(',')
- assert j!=-1,`i,j,line`
+ assert j !=- 1, repr((i, j, line))
opts = Alloc_Opt_List(repmap(line[j+1:].lstrip()))
line = line[:j].rstrip()
return spec, Allocation_List(repmap(line)), opts
@@ -3694,7 +3777,7 @@ class Deallocate_Stmt(StmtBase): # R635
opts = None
if i!=-1:
j = line[:i].rfind(',')
- assert j!=-1,`i,j,line`
+ assert j != -1, repr((i, j, line))
opts = Dealloc_Opt_List(repmap(line[j+1:].lstrip()))
line = line[:j].rstrip()
return Allocate_Object_List(repmap(line)), opts
@@ -3782,7 +3865,7 @@ class Defined_Op(STRINGBase): # R703, 723
subclass_names = []
def match(string):
if pattern.non_defined_binary_op.match(string):
- raise NoMatchError,'%s: %r' % (Defined_Unary_Op.__name__, string)
+ raise NoMatchError('%s: %r' % (Defined_Unary_Op.__name__, string))
return STRINGBase.match(pattern.abs_defined_op, string)
match = staticmethod(match)
@@ -4034,13 +4117,13 @@ class Pointer_Assignment_Stmt(StmtBase): # R735
l = repmap(lhs[i+1:-1].strip())
try:
return Data_Pointer_Object(o), Bounds_Spec_List(l), Data_Target(rhs)
- except NoMatchError, msg:
+ except NoMatchError as msg:
return Data_Pointer_Object(o), Bounds_Remapping_List(l), Data_Target(rhs)
else:
lhs = repmap(lhs)
try:
return Data_Pointer_Object(lhs), None, Data_Target(rhs)
- except NoMatchError, msg:
+ except NoMatchError as msg:
return Proc_Pointer_Object(lhs), None, Proc_Target(rhs)
def tostr(self):
@@ -4351,7 +4434,7 @@ class Forall_Triplet_Spec(Base): # R755
if i==-1: return
n = Index_Name(repmap(line[:i].rstrip()))
line = line[i+1:].lstrip()
- s = map(lambda s: repmap(s.strip()), line.split(':'))
+ s = [repmap(s.strip()) for s in line.split(':')]
if len(s)==2:
return n, Subscript(s[0]), Subscript(s[1]), None
if len(s)==3:
@@ -5016,7 +5099,8 @@ class Loop_Control(Base): # R830
var,rhs = line.split('=')
rhs = [s.strip() for s in rhs.lstrip().split(',')]
if not 2<=len(rhs)<=3: return
- return Variable(repmap(var.rstrip())),map(Scalar_Int_Expr, map(repmap,rhs))
+ return Variable(repmap(var.rstrip())), \
+ list(map(Scalar_Int_Expr, list(map(repmap,rhs))))
match = staticmethod(match)
def tostr(self):
if len(self.items)==1: return ', WHILE (%s)' % (self.items[0])
@@ -5303,6 +5387,7 @@ class Internal_File_Variable(Base): # R903
"""
subclass_names = ['Char_Variable']
+
class Open_Stmt(StmtBase, CALLBase): # R904
"""
<open-stmt> = OPEN ( <connect-spec-list> )
@@ -5311,10 +5396,15 @@ class Open_Stmt(StmtBase, CALLBase): # R904
use_names = ['Connect_Spec_List']
@staticmethod
def match(string):
- return CALLBase.match('OPEN', Connect_Spec_List, string, require_rhs=True)
+ # The Connect_Spec_List class is generated automatically
+ # by code at the end of this module
+ return CALLBase.match('OPEN', Connect_Spec_List, string,
+ require_rhs=True)
-class Connect_Spec(KeywordValueBase): # R905
+
+class Connect_Spec(KeywordValueBase):
"""
+ R905
<connect-spec> = [ UNIT = ] <file-unit-number>
| ACCESS = <scalar-default-char-expr>
| ACTION = <scalar-default-char-expr>
@@ -5336,26 +5426,40 @@ class Connect_Spec(KeywordValueBase): # R905
| STATUS = <scalar-default-char-expr>
"""
subclass_names = []
- use_names = ['File_Unit_Number', 'Scalar_Default_Char_Expr', 'Label', 'File_Name_Expr', 'Iomsg_Variable',
+ use_names = ['File_Unit_Number', 'Scalar_Default_Char_Expr', 'Label',
+ 'File_Name_Expr', 'Iomsg_Variable',
'Scalar_Int_Expr', 'Scalar_Int_Variable']
+
+ @staticmethod
def match(string):
- for (k,v) in [\
- (['ACCESS','ACTION','ASYNCHRONOUS','BLANK','DECIMAL','DELIM','ENCODING',
- 'FORM','PAD','POSITION','ROUND','SIGN','STATUS'], Scalar_Default_Char_Expr),
- ('ERR', Label),
- ('FILE',File_Name_Expr),
- ('IOSTAT', Scalar_Int_Variable),
- ('IOMSG', Iomsg_Variable),
- ('RECL', Scalar_Int_Expr),
- ('UNIT', File_Unit_Number),
- ]:
+ '''
+ :param str string: Fortran code to check for a match
+ :return: 2-tuple containing the keyword and value or None if the
+ supplied string is not a match
+ :rtype: 2-tuple containing keyword (e.g. "UNIT") and associated value
+ '''
+ if "=" not in string:
+ # The only argument which need not be named is the unit number
+ return 'UNIT', File_Unit_Number(string)
+ # We have a keyword-value pair. Check whether it is valid...
+ for (keyword, value) in [
+ (['ACCESS', 'ACTION', 'ASYNCHRONOUS', 'BLANK', 'DECIMAL',
+ 'DELIM', 'ENCODING', 'FORM', 'PAD', 'POSITION', 'ROUND',
+ 'SIGN', 'STATUS'], Scalar_Default_Char_Expr),
+ ('ERR', Label),
+ ('FILE', File_Name_Expr),
+ ('IOSTAT', Scalar_Int_Variable),
+ ('IOMSG', Iomsg_Variable),
+ ('RECL', Scalar_Int_Expr),
+ ('UNIT', File_Unit_Number)]:
try:
- obj = KeywordValueBase.match(k, v, string, upper_lhs = True)
+ obj = KeywordValueBase.match(keyword, value, string,
+ upper_lhs=True)
except NoMatchError:
obj = None
- if obj is not None: return obj
- return 'UNIT', File_Unit_Number
- match = staticmethod(match)
+ if obj is not None:
+ return obj
+ return None
class File_Name_Expr(Base): # R906
@@ -5407,6 +5511,7 @@ class Close_Spec(KeywordValueBase): # R909
return 'UNIT', File_Unit_Number(string)
match = staticmethod(match)
+
class Read_Stmt(StmtBase): # R910
"""
:F03R:`910`::
@@ -5421,34 +5526,47 @@ items : (Io_Control_Spec_List, Format, Input_Item_List)
use_names = ['Io_Control_Spec_List', 'Input_Item_List', 'Format']
@staticmethod
def match(string):
- if string[:4].upper()!='READ': return
+ if string[:4].upper() != 'READ':
+ return
line = string[4:].lstrip()
if line.startswith('('):
line, repmap = string_replace_map(line)
- i = line.find(')')
- if i==-1: return
- l = line[1:i].strip()
- if not l: return
- if i==len(line)-1:
- return Io_Control_Spec_List(repmap(l)),None,None
- return Io_Control_Spec_List(repmap(l)), None, Input_Item_List(repmap(line[i+1:].lstrip()))
- if not line: return
- c = line[0].upper()
- if 'A'<=c<='Z' or c=='_' or '0'<=c<='9': return
+ idx = line.find(')')
+ if idx == -1:
+ return
+ trimline = line[1:idx].strip()
+ if not trimline:
+ return
+ if idx == len(line) - 1:
+ return Io_Control_Spec_List(repmap(trimline)), None, None
+ return Io_Control_Spec_List(repmap(trimline)), None, \
+ Input_Item_List(repmap(line[idx+1:].lstrip()))
+ if not line:
+ return
+ char = line[0].upper()
+ # No parentheses therefore first argument must be a format
+ # specifier (either a string or a line/label number
+ if 'A' <= char <= 'Z' or char == '_':
+ return
line, repmap = string_replace_map(line.lstrip())
- i = line.find(',')
- if i==-1: return Format(repmap(line)),None,None
- l = repmap(line[i+1:].lstrip())
- if not l: return
- return None, Format(repmap(line[:i].rstrip())), Output_Item_List(l)
+ # There must be a comma betwee the format specifier and the following
+ # list of values/variables
+ idx = line.find(',')
+ if idx == -1:
+ return None
+ trimline = repmap(line[idx+1:].lstrip())
+ if not trimline:
+ return
+ return (None, Format(repmap(line[:idx].rstrip())),
+ Output_Item_List(trimline))
def tostr(self):
if self.items[0] is not None:
- assert self.items[1] is None,`self.items`
+ assert self.items[1] is None, repr(self.items)
if self.items[2] is None:
return 'READ(%s)' % (self.items[0])
return 'READ(%s) %s' % (self.items[0], self.items[2])
- assert self.items[1] is not None, `self.items`
+ assert self.items[1] is not None, repr(self.items)
if self.items[2] is None:
return 'READ %s' % (self.items[1])
return 'READ %s, %s' % (self.items[1], self.items[2])
@@ -5506,42 +5624,51 @@ items : (Format, Output_Item_List)
if not l: return
return Format(repmap(line[:i].rstrip())), Output_Item_List(l)
match = staticmethod(match)
+
def tostr(self):
if self.items[1] is None: return 'PRINT %s' % (self.items[0])
return 'PRINT %s, %s' % tuple(self.items)
+
class Io_Control_Spec_List(SequenceBase): # R913-list
"""
<io-control-spec-list> is a list taking into account C910, C917, C918
"""
subclass_names = []
use_names = ['Io_Control_Spec']
+ @staticmethod
def match(string):
line, repmap = string_replace_map(string)
splitted = line.split(',')
- if not splitted: return
lst = []
- for i in range(len(splitted)):
- p = splitted[i].strip()
- if i==0:
- if '=' not in p: p = 'UNIT=%s' % (repmap(p))
- else: p = repmap(p)
- elif i==1:
- if '=' not in p:
- p = repmap(p)
- try:
- f = Format(p)
- # todo: make sure that f is char-expr, if not, raise NoMatchError
- p = 'FMT=%s' % (Format(p))
- except NoMatchError:
- p = 'NML=%s' % (Namelist_Group_Name(p))
- else:
- p = repmap(p)
+ unit_is_positional = False
+ for idx in range(len(splitted)):
+ spec = splitted[idx].strip()
+ spec = repmap(spec)
+ if idx == 0 and "=" not in spec:
+ # Must be a unit number. However, we do not prepend "UNIT="
+ # to it in case the following Io_Control_Spec is positional
+ # (and therefore either a Format or Namelist spec).
+ lst.append(Io_Control_Spec(spec))
+ unit_is_positional = True
+ elif idx == 1 and "=" not in spec:
+ if not unit_is_positional:
+ # Cannot have a positional argument following a
+ # named argument
+ return
+ # Without knowing the type of the variable named in spec
+ # we have no way of knowing whether this is a format or
+ # a namelist specifier. However, if it is a character
+ # constant or "*" then it must be a Format spec and we can
+ # prepend "FMT=" to it.
+ spec = spec.lstrip().rstrip()
+ if Char_Literal_Constant.match(spec) or \
+ StringBase.match("*", spec):
+ spec = "FMT={0}".format(spec)
+ lst.append(Io_Control_Spec(spec))
else:
- p = repmap(p)
- lst.append(Io_Control_Spec(p))
+ lst.append(Io_Control_Spec(spec))
return ',', tuple(lst)
- match = staticmethod(match)
class Io_Control_Spec(KeywordValueBase): # R913
"""
@@ -5567,28 +5694,34 @@ class Io_Control_Spec(KeywordValueBase): # R913
| SIZE = <scalar-int-variable>
"""
subclass_names = []
- use_names = ['Io_Unit', 'Format', 'Namelist_Group_Name', 'Scalar_Default_Char_Expr',
- 'Scalar_Char_Initialization_Expr', 'Label', 'Scalar_Int_Variable',
+ use_names = ['Io_Unit', 'Format', 'Namelist_Group_Name',
+ 'Scalar_Default_Char_Expr',
+ 'Scalar_Char_Initialization_Expr', 'Label',
+ 'Scalar_Int_Variable',
'Iomsg_Variable', 'Scalar_Int_Expr']
+ @staticmethod
def match(string):
- for (k,v) in [\
... 10724 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/fparser.git
More information about the Python-modules-commits
mailing list