diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c12d9527..de7dd0b0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -64,7 +64,7 @@ jobs: castxml-epic: 1 cppstd: "-std=c++11" - - os: macos-latest + - os: macos-12 compiler: xcode version: "default" python-version: "3.8" @@ -90,7 +90,7 @@ jobs: run: | wget -q -O - https://data.kitware.com/api/v1/file/hashsum/sha512/bdbb67a10c5f8d1b738cd19cb074f409d4803e8077cb8c1072ef4eaf738fa871a73643f9c8282d58cae28d188df842c82ad6620b6d590b0396a0172a27438dce/download | tar zxf - -C ~/ - name: Setup castxml for Mac - if: matrix.os == 'macos-latest' + if: matrix.os == 'macos-12' run: | wget -q -O - https://data.kitware.com/api/v1/file/hashsum/sha512/5d937e938f7b882a3a3e7941e68f8312d0898aaf2082e00003dd362b1ba70b98b0a08706a1be28e71652a6a0f1e66f89768b5eaa20e5a100592d5b3deefec3f0/download | tar zxf - -C ~/ - name: Setup castxml config @@ -102,12 +102,3 @@ jobs: coverage run -m unittests.test_all coverage combine coverage xml - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 - with: - token: ${{ secrets.CODECOV_TOKEN }} - file: coverage.xml - flags: unittests - env_vars: OS,PYTHON - name: codecov-umbrella - fail_ci_if_error: true diff --git a/CHANGELOG.md b/CHANGELOG.md index db53506c..a27edbe0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,16 @@ Changes ======= +Version 2.5.0 +------------- + +1. Add support for new cxx versions in cxx_standard class + +2. Deprecate utils.is_str + +3. pyproject.toml improvements + + Version 2.4.0 ------------- diff --git a/pyproject.toml b/pyproject.toml index 7d4bce6e..de3e3f10 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,6 @@ [build-system] -requires = ["setuptools", "wheel"] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" [project] name = "pygccxml" @@ -17,7 +18,7 @@ keywords = [ "CastXML", "gccxml", ] -version = "2.4.0" +version = "2.5.0" classifiers = [ "Development Status :: 5 - Production/Stable", diff --git a/src/pygccxml/declarations/container_traits.py b/src/pygccxml/declarations/container_traits.py index 92ad175b..d4f6658e 100644 --- a/src/pygccxml/declarations/container_traits.py +++ b/src/pygccxml/declarations/container_traits.py @@ -522,7 +522,7 @@ def remove_defaults(self, type_or_string): """ name = type_or_string - if not utils.is_str(type_or_string): + if not isinstance(type_or_string, str): name = self.class_declaration(type_or_string).name if not self.remove_defaults_impl: return name @@ -705,7 +705,7 @@ def find_container_traits(cls_or_string): declarations.container_traits: a container traits """ - if utils.is_str(cls_or_string): + if isinstance(cls_or_string, str): if not templates.is_instantiation(cls_or_string): return None name = templates.name(cls_or_string) diff --git a/src/pygccxml/declarations/type_traits.py b/src/pygccxml/declarations/type_traits.py index eef8fe7a..bc9be8de 100644 --- a/src/pygccxml/declarations/type_traits.py +++ b/src/pygccxml/declarations/type_traits.py @@ -507,7 +507,7 @@ def is_std_string(type_): """ - if utils.is_str(type_): + if isinstance(type_, str): return type_ in string_equivalences type_ = remove_alias(type_) @@ -522,7 +522,7 @@ def is_std_wstring(type_): """ - if utils.is_str(type_): + if isinstance(type_, str): return type_ in wstring_equivalences type_ = remove_alias(type_) @@ -537,7 +537,7 @@ def is_std_ostream(type_): """ - if utils.is_str(type_): + if isinstance(type_, str): return type_ in ostream_equivalences type_ = remove_alias(type_) @@ -552,7 +552,7 @@ def is_std_wostream(type_): """ - if utils.is_str(type_): + if isinstance(type_, str): return type_ in wostream_equivalences type_ = remove_alias(type_) diff --git a/src/pygccxml/parser/config.py b/src/pygccxml/parser/config.py index e2b9eea4..e2db56d8 100644 --- a/src/pygccxml/parser/config.py +++ b/src/pygccxml/parser/config.py @@ -22,7 +22,6 @@ from ConfigParser import SafeConfigParser as ConfigParser except ImportError: from configparser import ConfigParser -from .. import utils class parser_configuration_t(object): @@ -383,7 +382,7 @@ def load_xml_generator_configuration(configuration, **defaults): """ parser = configuration - if utils.is_str(configuration): + if isinstance(configuration, str): parser = ConfigParser() parser.read(configuration) diff --git a/src/pygccxml/parser/linker.py b/src/pygccxml/parser/linker.py index b7aeda3b..1677e27f 100644 --- a/src/pygccxml/parser/linker.py +++ b/src/pygccxml/parser/linker.py @@ -4,7 +4,6 @@ # See http://www.boost.org/LICENSE_1_0.txt from pygccxml import declarations -from .. import utils class linker_t( @@ -304,7 +303,7 @@ def visit_member_variable_type(self): self.__link_compound_type() def visit_declarated(self): - if utils.is_str(self.__inst.declaration): + if isinstance(self.__inst.declaration, str): self.__inst.declaration = self.__decls[self.__inst.declaration] def visit_restrict(self): diff --git a/src/pygccxml/parser/project_reader.py b/src/pygccxml/parser/project_reader.py index a6287907..d7bf7c99 100644 --- a/src/pygccxml/parser/project_reader.py +++ b/src/pygccxml/parser/project_reader.py @@ -187,7 +187,7 @@ def __init__(self, config, cache=None, decl_factory=None): self.__dcache = None if isinstance(cache, declarations_cache.cache_base_t): self.__dcache = cache - elif utils.is_str(cache): + elif isinstance(cache, str): self.__dcache = declarations_cache.file_cache_t(cache) else: self.__dcache = declarations_cache.dummy_cache_t() @@ -221,7 +221,7 @@ def get_os_file_names(files): fnames = [] for f in files: - if utils.is_str(f): + if isinstance(f, str): fnames.append(f) elif isinstance(f, file_configuration_t): if f.content_type in ( diff --git a/src/pygccxml/parser/scanner.py b/src/pygccxml/parser/scanner.py index 4368a84a..63f9cbd7 100644 --- a/src/pygccxml/parser/scanner.py +++ b/src/pygccxml/parser/scanner.py @@ -334,7 +334,7 @@ def startElement(self, name, attrs): self.__update_membership(attrs) self.__read_attributes(obj, attrs) - elif utils.is_str(obj): + elif isinstance(obj, str): self.__files[element_id] = os.path.normpath(obj) diff --git a/src/pygccxml/utils/utils.py b/src/pygccxml/utils/utils.py index 21bb5d3c..7a9deb5a 100644 --- a/src/pygccxml/utils/utils.py +++ b/src/pygccxml/utils/utils.py @@ -26,6 +26,11 @@ def is_str(string): bool: True or False """ + warnings.warn( + "The is_str function is deprecated. \ + Use isinstance(string, str) instead.", + DeprecationWarning) + if sys.version_info[:2] >= (3, 0): return isinstance(string, str) @@ -50,35 +55,12 @@ def find_xml_generator(name="castxml", search_path=None): """ - if sys.version_info[:2] >= (3, 3): - path = _find_xml_generator_for_python_greater_equals_33( - name, search_path=search_path) - else: - path = _find_xml_generator_for_legacy_python(name) - + path = shutil.which(name, path=search_path) if path == "" or path is None: raise Exception("No c++ parser found. Please install castxml.") return path.rstrip(), name -def _find_xml_generator_for_python_greater_equals_33(name, search_path=None): - return shutil.which(name, path=search_path) - - -def _find_xml_generator_for_legacy_python(name): - if platform.system() == "Windows": - command = "where" - else: - command = "which" - p = subprocess.Popen([command, name], stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - path = p.stdout.read().decode("utf-8") - p.wait() - p.stdout.close() - p.stderr.close() - return path.rstrip() - - def _create_logger_(name): """Implementation detail, creates a logger.""" logger = logging.getLogger(name) @@ -295,8 +277,12 @@ class cxx_standard(object): '-std=c++17': 201703, '-std=gnu++1z': 201703, '-std=gnu++17': 201703, - '-std=c++2a': float('inf'), - '-std=gnu++2a': float('inf'), + '-std=c++2a': 202002, + '-std=gnu++2a': 202002, + '-std=c++20': 202002, + '-std=gnu++20': 202002, + '-std=c++23': float('inf'), + '-std=gnu++23': float('inf'), } def __init__(self, cflags): diff --git a/unittests/find_container_traits_tester.py b/unittests/find_container_traits_tester.py index c6eebce5..1571c373 100644 --- a/unittests/find_container_traits_tester.py +++ b/unittests/find_container_traits_tester.py @@ -9,7 +9,6 @@ from pygccxml import parser from pygccxml import declarations -from pygccxml import utils class Test(parser_test_case.parser_test_case_t): @@ -30,7 +29,7 @@ def setUp(self): self.global_ns = Test.global_ns def __cmp_traits(self, typedef, expected, partial_name, key_type=None): - if utils.is_str(typedef): + if isinstance(typedef, str): typedef = self.global_ns.typedef(typedef) traits = declarations.find_container_traits(typedef) self.assertTrue( diff --git a/unittests/misc/profile_parser.py b/unittests/misc/profile_parser.py deleted file mode 100644 index 47ab3eb3..00000000 --- a/unittests/misc/profile_parser.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright 2014-2017 Insight Software Consortium. -# Copyright 2004-2009 Roman Yakovenko. -# Distributed under the Boost Software License, Version 1.0. -# See http://www.boost.org/LICENSE_1_0.txt - -import os -import hotshot -import hotshot.stats - -import autoconfig -import test_parser - -if __name__ == "__main__": - statistics_file = os.path.join(autoconfig.data_directory, 'profile.stat') - profile = hotshot.Profile(statistics_file) - profile.runcall(test_parser.run_suite) - profile.close() - statistics = hotshot.stats.load(statistics_file) - statistics.strip_dirs() - statistics.sort_stats('time', 'calls') - statistics.print_stats(20) diff --git a/unittests/misc/test_performance.py b/unittests/misc/test_performance.py deleted file mode 100644 index d5a135ce..00000000 --- a/unittests/misc/test_performance.py +++ /dev/null @@ -1,160 +0,0 @@ -# Copyright 2014-2017 Insight Software Consortium. -# Copyright 2004-2009 Roman Yakovenko. -# Distributed under the Boost Software License, Version 1.0. -# See http://www.boost.org/LICENSE_1_0.txt - -import os -import sys -import timeit -import hotshot -import hotshot.stats - -this_module_dir_path = os.path.abspath( - os.path.dirname(sys.modules[__name__].__file__)) - -sys.path.insert(1, os.path.join(this_module_dir_path, '../../')) -sys.path.insert(2, os.path.join(this_module_dir_path, '../')) - -import autoconfig # nopep8 -from pygccxml import parser # nopep8 -from pygccxml import declarations # nopep8 - -dcache_file_name = os.path.join(autoconfig.data_directory, 'pygccxml.cache') -if os.path.exists(dcache_file_name): - os.remove(dcache_file_name) - - -def test_on_windows_dot_h(): - he = r"2003\Vc7\PlatformSDK\Include\windows.h" - windows_header = r"D:\Program Files\Microsoft Visual Studio .NET " + he - clock_prev = timeit.default_timer() - dcache = parser.file_cache_t(dcache_file_name) - reader = parser.source_reader_t( - parser.xml_generator_configuration_t( - xml_generator_path=autoconfig.generator_path), - dcache) - reader.read_file(windows_header) - dcache.flush() - clock_now = timeit.default_timer() - print('without cache: %f seconds' % (clock_now - clock_prev)) - - clock_prev = timeit.default_timer() - dcache = parser.file_cache_t(dcache_file_name) - reader = parser.source_reader_t( - parser.xml_generator_configuration_t( - xml_generator_path=autoconfig.generator_path), - dcache) - reader.read_file(windows_header) - clock_now = timeit.default_timer() - print('with cache : %f seconds' % (clock_now - clock_prev)) - -######################################################################### -# testing include_std.hpp - - -def test_source_on_include_std_dot_hpp(): - include_std_header = os.path.join( - autoconfig.data_directory, - 'include_std.hpp') - clock_prev = timeit.default_timer() - dcache = parser.file_cache_t(dcache_file_name) - reader = parser.source_reader_t( - parser.xml_generator_configuration_t( - xml_generator_path=autoconfig.generator_path), - dcache) - reader.read_file(include_std_header) - dcache.flush() - clock_now = timeit.default_timer() - print('without cache: %f seconds' % (clock_now - clock_prev)) - - clock_prev = timeit.default_timer() - dcache = parser.file_cache_t(dcache_file_name) - reader = parser.source_reader_t( - parser.xml_generator_configuration_t( - xml_generator_path=autoconfig.generator_path), - dcache) - reader.read_file(include_std_header) - clock_now = timeit.default_timer() - print('with cache : %f seconds' % (clock_now - clock_prev)) - - -######################################################################### -# testing include_std.hpp -def test_project_on_include_std_dot_hpp(): - include_std_header = os.path.join( - autoconfig.data_directory, - 'include_std.hpp') - clock_prev = timeit.default_timer() - dcache = parser.file_cache_t(dcache_file_name) - reader = parser.project_reader_t( - parser.xml_generator_configuration_t( - xml_generator_path=autoconfig.generator_path), - dcache) - reader.read_files([include_std_header]) - dcache.flush() - clock_now = timeit.default_timer() - print('without cache: %f seconds' % (clock_now - clock_prev)) - - clock_prev = timeit.default_timer() - dcache = parser.file_cache_t(dcache_file_name) - reader = parser.project_reader_t( - parser.xml_generator_configuration_t( - xml_generator_path=autoconfig.generator_path), - dcache) - reader.read_files([include_std_header]) - clock_now = timeit.default_timer() - print('with cache : %f seconds' % (clock_now - clock_prev)) - - -def profile_project(): - include_std_header = os.path.join( - autoconfig.data_directory, - 'include_std.hpp') - reader = parser.project_reader_t( - parser.xml_generator_configuration_t( - xml_generator_path=autoconfig.generator_path)) - reader.read_files([include_std_header]) - - -def profile_project2(): - he = r"2003\Vc7\PlatformSDK\Include\windows.h" - include_std_header = r"D:\Program Files\Microsoft Visual Studio .NET " + he - reader = parser.project_reader_t( - parser.xml_generator_configuration_t( - xml_generator_path=autoconfig.generator_path)) - reader.read_files([include_std_header]) - - -def test_on_big_file(file_name, count): - file_name = os.path.join(autoconfig.data_directory, file_name) - for i in range(count): - reader = parser.project_reader_t( - parser.xml_generator_configuration_t( - xml_generator_path=autoconfig.generator_path)) - decls = reader.read_files([parser.create_gccxml_fc(file_name)]) - global_ns = declarations.get_global_namespace(decls) - global_ns.init_optimizer() - - -if __name__ == "__main__": - - # test_on_windows_dot_h() - # test_source_on_include_std_dot_hpp() - # test_project_on_include_std_dot_hpp() - print('running') - prof = hotshot.Profile('parser.prof') - prof.runcall(lambda: test_on_big_file('itkImage.xml', 1)) - stats = hotshot.stats.load("parser.prof") - stats.sort_stats('time', 'calls') - stats.print_stats(30) - print('running - done') - # print 'loading file' - # pdata = pstats.Stats('pygccxml.profile') - # print 'loading file - done' - # print 'striping dirs' - # pdata.strip_dirs() - # print 'striping dirs - done' - # print 'sorting stats' - # pdata.sort_stats('time').print_stats(476) - # print 'sorting stats - done' - # pdata.print_callers('find_all_declarations') diff --git a/unittests/misc/timeit_test_parser.py b/unittests/misc/timeit_test_parser.py deleted file mode 100644 index 148c261a..00000000 --- a/unittests/misc/timeit_test_parser.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright 2014-2017 Insight Software Consortium. -# Copyright 2004-2009 Roman Yakovenko. -# Distributed under the Boost Software License, Version 1.0. -# See http://www.boost.org/LICENSE_1_0.txt - -from timeit import Timer - -stmt = """ -import unittest -from test_parser import create_suite -unittest.TextTestRunner(verbosity=2).run( create_suite() ) -""" - -timer = Timer(stmt) -print(timer.timeit(3))