From a7be2cb9bbd644590f870041269784df03bcf490 Mon Sep 17 00:00:00 2001 From: "simon.chupin" Date: Wed, 18 Aug 2021 15:14:47 +0200 Subject: [PATCH] Tools: update idf_size.py types to pep-484 format --- tools/ci/check_copyright_ignore.txt | 1 - tools/idf_size.py | 152 ++++++++++++---------------- tools/test_idf_size/test.sh | 129 +++++++++++------------ 3 files changed, 131 insertions(+), 151 deletions(-) diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index ba948ef930..6912b54dfc 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -4148,7 +4148,6 @@ tools/idf_py_actions/global_options.py tools/idf_py_actions/serial_ext.py tools/idf_py_actions/tools.py tools/idf_py_actions/uf2_ext.py -tools/idf_size.py tools/kconfig/conf.c tools/kconfig/confdata.c tools/kconfig/expand_env.c diff --git a/tools/idf_size.py b/tools/idf_size.py index 09178d5828..b4daa30524 100755 --- a/tools/idf_size.py +++ b/tools/idf_size.py @@ -6,19 +6,8 @@ # Includes information which is not shown in "xtensa-esp32-elf-size", # or easy to parse from "xtensa-esp32-elf-objdump" or raw map files. # -# Copyright 2017-2021 Espressif Systems (Shanghai) CO LTD -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 # from __future__ import division, print_function, unicode_literals @@ -28,15 +17,13 @@ import json import os.path import re import sys +from typing import Any, Callable, Collection, Dict, Iterable, List, Optional, TextIO, Tuple, Union from future.utils import iteritems -try: - from typing import Any, Callable, Collection, Dict, Iterable, List, Optional, TextIO, Tuple, Union - Section = Dict[str, Union[str, int]] - SectionDict = Dict[str, Section] -except ImportError: - pass +Section = Dict[str, Union[str, int]] +SectionDict = Dict[str, Section] + try: basestring @@ -50,7 +37,6 @@ GLOBAL_JSON_SEPARATORS = (',', ': ') class MemRegions(object): # Regions determined by the chip target. - # DIRAM is not added here. The DIRAM is indicated by the `secondary_addr` of each MemRegDef (DRAM_ID, IRAM_ID, CACHE_D_ID, CACHE_I_ID, RTC_FAST_D_ID, RTC_FAST_I_ID, RTC_SLOW_D_ID) = range(7) @@ -59,15 +45,14 @@ class MemRegions(object): class Region(object): # Helper class to store region information - def __init__(self, start, length, region, section=None): - # type: (MemRegions.Region, int, int, MemRegions.MemRegDef, Optional[str]) -> None + def __init__(self, start: int, length: int, region: 'MemRegions.MemRegDef', section: Optional[str]=None) -> None: self.start = start self.len = length self.region = region self.section = section @staticmethod - def get_mem_regions(target): # type: (str) -> List + def get_mem_regions(target: str) -> List: # The target specific memory structure is deduced from soc_memory_types defined in # $IDF_PATH/components/soc/**/soc_memory_layout.c files. @@ -124,13 +109,12 @@ class MemRegions(object): else: raise RuntimeError('Target not detected.') - def __init__(self, target): # type: (MemRegions, str) -> None + def __init__(self, target: str) -> None: self.chip_mem_regions = self.get_mem_regions(target) if not self.chip_mem_regions: raise RuntimeError('Target {} is not implemented in idf_size'.format(target)) - def _get_first_region(self, start, length): - # type: (int, int) -> Tuple[Union[MemRegions.MemRegDef, None], int] + def _get_first_region(self, start: int, length: int) -> Tuple[Union['MemRegions.MemRegDef', None], int]: for region in self.chip_mem_regions: # type: ignore if region.primary_addr <= start < region.primary_addr + region.length: return (region, length) @@ -140,7 +124,7 @@ class MemRegions(object): print('Check whether the LD file is compatible with the definitions in get_mem_regions in idf_size.py') return (None, length) - def _get_regions(self, start, length, name=None): # type: (int, int, Optional[str]) -> List + def _get_regions(self, start: int, length: int, name: Optional[str]=None) -> List: ret = [] while length > 0: (region, cur_len) = self._get_first_region(start, length) @@ -155,7 +139,7 @@ class MemRegions(object): return ret - def fit_segments_into_regions(self, segments): # type: (MemRegions, Dict) -> List + def fit_segments_into_regions(self, segments: Dict) -> List: region_list = [] for segment in segments.values(): @@ -164,7 +148,7 @@ class MemRegions(object): return region_list - def fit_sections_into_regions(self, sections): # type: (MemRegions, Dict) -> List + def fit_sections_into_regions(self, sections: Dict) -> List: region_list = [] for section in sections.values(): @@ -187,7 +171,7 @@ class LinkingSections(object): }.items()} @staticmethod - def in_section(section, section_name_or_list): # type: (str, Union[str, Iterable]) -> bool + def in_section(section: str, section_name_or_list: Union[str, Iterable]) -> bool: if isinstance(section_name_or_list, basestring): section_name_or_list = [section_name_or_list] @@ -197,18 +181,18 @@ class LinkingSections(object): return False @staticmethod - def filter_sections(sections): # type: (Dict) -> Dict + def filter_sections(sections: Dict) -> Dict: return {k: v for k, v in sections.items() if LinkingSections.in_section(k, LinkingSections._section_type_dict.keys())} @staticmethod - def get_display_name_order(section_name_list): # type: (List[str]) -> Tuple[List[str], List[str]] + def get_display_name_order(section_name_list: List[str]) -> Tuple[List[str], List[str]]: ''' Return two lists, in the suggested display order. First list is the reordered section_name_list, second list is the suggested display name, corresponding to the first list ''' - def get_name_score(name): # type: (str) -> int + def get_name_score(name: str) -> int: score_dict = { '.dram': 30, '.iram': 20, @@ -241,6 +225,7 @@ class LinkingSections(object): continue memory_name = '' + split_name = section.split('.') if len(split_name) > 1: # If the section has a memory type, update the type and try to display the type properly @@ -261,7 +246,7 @@ class LinkingSections(object): return ordered_name_list, display_name_list -def scan_to_header(f, header_line): # type: (Iterable, str) -> None +def scan_to_header(f: Iterable, header_line: str) -> None: """ Scan forward in a file until you reach 'header_line', then return """ for line in f: if line.strip() == header_line: @@ -269,14 +254,14 @@ def scan_to_header(f, header_line): # type: (Iterable, str) -> None raise RuntimeError("Didn't find line '%s' in file" % header_line) -def format_json(json_object): # type: (Dict) -> str +def format_json(json_object: Dict) -> str: return json.dumps(json_object, allow_nan=True, indent=GLOBAL_JSON_INDENT, separators=GLOBAL_JSON_SEPARATORS) + os.linesep -def load_map_data(map_file): # type: (TextIO) -> Tuple[str, Dict, Dict] +def load_map_data(map_file: TextIO) -> Tuple[str, Dict, Dict]: segments = load_segments(map_file) detected_chip = detect_target_chip(map_file) sections = load_sections(map_file) @@ -289,7 +274,7 @@ def load_map_data(map_file): # type: (TextIO) -> Tuple[str, Dict, Dict] return detected_chip, segments, sections -def load_segments(map_file): # type: (TextIO) -> Dict +def load_segments(map_file: TextIO) -> Dict: """ Memory Configuration section is the total size of each segment """ result = {} # type: Dict[Any, Dict] scan_to_header(map_file, 'Memory Configuration') @@ -312,7 +297,7 @@ def load_segments(map_file): # type: (TextIO) -> Dict raise RuntimeError('End of file while scanning memory configuration?') -def detect_target_chip(map_file): # type: (Iterable) -> str +def detect_target_chip(map_file: Iterable) -> str: ''' Detect target chip based on the target archive name in the linker script part of the MAP file ''' scan_to_header(map_file, 'Linker script and memory map') @@ -340,7 +325,7 @@ def detect_target_chip(map_file): # type: (Iterable) -> str raise RuntimeError('Target not detected') -def load_sections(map_file): # type: (TextIO) -> Dict +def load_sections(map_file: TextIO) -> Dict: """ Load section size information from the MAP file. Returns a dict of 'sections', where each key is a section name and the value @@ -372,7 +357,7 @@ def load_sections(map_file): # type: (TextIO) -> Dict # Extract archive and object_file from the file_info field RE_FILE = re.compile(r'((?P[^ ]+\.a)?\(?(?P[^ ]+\.(o|obj))\)?)') - def dump_src_line(src): # type: (Dict) -> str + def dump_src_line(src: Dict) -> str: return '%s(%s) addr: 0x%08x, size: 0x%x+%d' % (src['sym_name'], src['file'], src['address'], src['size'], src['fill']) sections = {} # type: Dict[Any, Dict] @@ -481,13 +466,13 @@ def load_sections(map_file): # type: (TextIO) -> Dict return sections -def check_target(target, map_file): # type: (str, TextIO) -> None +def check_target(target: str, map_file: TextIO) -> None: if target is None: raise RuntimeError('The target chip cannot be detected for {}. ' 'Please report the issue.'.format(map_file.name)) -def main(): # type: () -> None +def main() -> None: parser = argparse.ArgumentParser(description='idf_size - a tool to print size information from an IDF MAP file') parser.add_argument( @@ -576,7 +561,7 @@ class StructureForSummary(object): used_diram_ratio = 0. used_flash_text, used_flash_rodata, used_flash_other, used_flash, total_size = (0, ) * 5 - def __sub__(self, rhs): # type: (StructureForSummary) -> StructureForSummary + def __sub__(self, rhs: 'StructureForSummary') -> 'StructureForSummary': assert isinstance(rhs, StructureForSummary) ret = self for key in StructureForSummary.get_required_items(): @@ -584,33 +569,33 @@ class StructureForSummary(object): return ret - def get_dram_overflowed(self): # type: (StructureForSummary) -> bool + def get_dram_overflowed(self) -> bool: return self.used_dram_ratio > 1.0 - def get_iram_overflowed(self): # type: (StructureForSummary) -> bool + def get_iram_overflowed(self) -> bool: return self.used_iram_ratio > 1.0 - def get_diram_overflowed(self): # type: (StructureForSummary) -> bool + def get_diram_overflowed(self) -> bool: return self.used_diram_ratio > 1.0 @classmethod - def get_required_items(cls): # type: (Any) -> List + def get_required_items(cls: Any) -> List: whole_list = list(filter(lambda x: not (x.startswith('__') or x.endswith('__') or callable(getattr(cls, x))), dir(cls))) return whole_list @staticmethod - def get(segments, sections): # type: (List, List) -> StructureForSummary + def get(segments: List, sections: List) -> 'StructureForSummary': - def get_size(sections): # type: (Iterable) -> int + def get_size(sections: Iterable) -> int: return sum([x.len for x in sections]) - def in_diram(x): # type: (MemRegions.Region) -> bool + def in_diram(x: MemRegions.Region) -> bool: return x.region.type in (MemRegions.DRAM_ID, MemRegions.IRAM_ID) and x.region.secondary_addr > 0 - def in_dram(x): # type: (MemRegions.Region) -> bool + def in_dram(x: MemRegions.Region) -> bool: return x.region.type == MemRegions.DRAM_ID and x.region.secondary_addr == 0 # type: ignore - def in_iram(x): # type: (MemRegions.Region) -> bool + def in_iram(x: MemRegions.Region) -> bool: return x.region.type == MemRegions.IRAM_ID and x.region.secondary_addr == 0 # type: ignore r = StructureForSummary() @@ -626,7 +611,7 @@ class StructureForSummary(object): if r.diram_total == 0: r.diram_total = r.dram_total + r.iram_total - def filter_in_section(sections, section_to_check): # type: (Iterable[MemRegions.Region], str) -> List[MemRegions.Region] + def filter_in_section(sections: Iterable[MemRegions.Region], section_to_check: str) -> List[MemRegions.Region]: return list(filter(lambda x: LinkingSections.in_section(x.section, section_to_check), sections)) # type: ignore dram_sections = list(filter(in_dram, sections)) @@ -700,7 +685,7 @@ class StructureForSummary(object): r.total_size = r.used_dram - r.used_dram_bss + r.used_iram + r.used_diram - r.used_diram_bss + r.used_flash return r - def get_json_dic(self): # type: (StructureForSummary) -> collections.OrderedDict + def get_json_dic(self) -> collections.OrderedDict: ret = collections.OrderedDict([ ('dram_data', self.used_dram_data), ('dram_bss', self.used_dram_bss), @@ -741,7 +726,7 @@ class StructureForSummary(object): return ret -def get_structure_for_target(segments, sections, target): # type: (Dict, Dict, str) -> StructureForSummary +def get_structure_for_target(segments: Dict, sections: Dict, target: str) -> StructureForSummary: """ Return StructureForSummary for spasific target """ @@ -752,10 +737,10 @@ def get_structure_for_target(segments, sections, target): # type: (Dict, Dict, return current -def get_summary(path, segments, sections, target, - as_json=False, - path_diff='', segments_diff=None, sections_diff=None, target_diff='', print_suggestions=True): - # type: (str, Dict, Dict, str, bool, str, Optional[Dict], Optional[Dict], str, bool) -> str +def get_summary(path: str, segments: Dict, sections: Dict, target: str, + as_json: bool=False, + path_diff: str='', segments_diff: Optional[Dict]=None, sections_diff: Optional[Dict]=None, + target_diff: str='', print_suggestions: bool=True) -> str: if segments_diff is None: segments_diff = {} if sections_diff is None: @@ -790,11 +775,11 @@ def get_summary(path, segments, sections, target, title = '' name = '' - def __init__(self, title, name): # type: (LineDef, str, str) -> None + def __init__(self, title: str, name: str) -> None: self.title = title self.name = name - def format_line(self): # type: (LineDef) -> Tuple[str, str, str, str] + def format_line(self) -> Tuple[str, str, str, str]: return (self.title + ': {%s:>7} bytes' % self.name, '{%s:>7}' % self.name, '{%s:+}' % self.name, @@ -806,14 +791,14 @@ def get_summary(path, segments, sections, target, total = '' warning_message = '' - def __init__(self, title, name, remain, ratio, total, warning_message): # type: (HeadLineDef, str, str, str, str, str, str) -> None + def __init__(self, title: str, name: str, remain: str, ratio: str, total: str, warning_message: str) -> None: super(HeadLineDef, self).__init__(title, name) self.remain = remain self.ratio = ratio self.total = total self.warning_message = warning_message - def format_line(self): # type: (HeadLineDef) -> Tuple[str, str, str, str] + def format_line(self) -> Tuple[str, str, str, str]: return ('%s: {%s:>7} bytes ({%s:>7} remain, {%s:.1%%} used)%s' % (self.title, self.name, self.remain, self.ratio, self.warning_message), '{%s:>7}' % self.name, '{%s:+}' % self.name, @@ -821,7 +806,7 @@ def get_summary(path, segments, sections, target, class TotalLineDef(LineDef): - def format_line(self): # type: (TotalLineDef) -> Tuple[str, str, str, str] + def format_line(self) -> Tuple[str, str, str, str]: return (self.title + ': {%s:>7} bytes (.bin may be padded larger)' % self.name, '{%s:>7}' % self.name, '{%s:+}' % self.name, @@ -858,7 +843,7 @@ def get_summary(path, segments, sections, target, TotalLineDef('Total image size', 'total_size') ] - def convert_to_fmt_dict(summary, suffix=''): # type: (StructureForSummary, str) -> Dict + def convert_to_fmt_dict(summary: StructureForSummary, suffix: str='') -> Dict: required_items = StructureForSummary.get_required_items() return dict([(key + suffix, getattr(summary, key)) for key in required_items]) @@ -869,8 +854,7 @@ def get_summary(path, segments, sections, target, lf = '{:60}{:>15}{:>15} {}' # Width for a, b, c, d columns - def print_in_columns(a, b='', c='', d=''): - # type: (str, Optional[str], Optional[str], Optional[str]) -> str + def print_in_columns(a: str, b: Optional[str]='', c: Optional[str]='', d: Optional[str]='') -> str: return lf.format(a, b, c, d).rstrip() + os.linesep output = '' @@ -900,7 +884,7 @@ def get_summary(path, segments, sections, target, return output -def check_is_dict_sort(non_sort_list): # type: (List) -> List +def check_is_dict_sort(non_sort_list: List) -> List: ''' sort with keeping the order data, bss, other, iram, diram, ram_st_total, flash_text, flash_rodata, flash_total ''' @@ -924,7 +908,7 @@ def check_is_dict_sort(non_sort_list): # type: (List) -> List class StructureForDetailedSizes(object): @staticmethod - def sizes_by_key(sections, key, include_padding=False): # type: (SectionDict, str, Optional[bool]) -> Dict[str, Dict[str, int]] + def sizes_by_key(sections: SectionDict, key: str, include_padding: Optional[bool]=False) -> Dict[str, Dict[str, int]]: """ Takes a dict of sections (from load_sections) and returns a dict keyed by 'key' with aggregate output size information. @@ -944,7 +928,7 @@ class StructureForDetailedSizes(object): return result @staticmethod - def get(sections, by_key): # type: (SectionDict, str) -> collections.OrderedDict + def get(sections: SectionDict, by_key: str) -> collections.OrderedDict: # Get the detailed structure before using the filter to remove undesired sections, # to show entries without desired sections sizes = StructureForDetailedSizes.sizes_by_key(sections, by_key) @@ -970,7 +954,7 @@ class StructureForDetailedSizes(object): return collections.OrderedDict(s) -def get_detailed_sizes(sections, key, header, as_json=False, sections_diff=None): # type: (Dict, str, str, bool, Dict) -> str +def get_detailed_sizes(sections: Dict, key: str, header: str, as_json: bool=False, sections_diff: Dict=None) -> str: key_name_set = set() current = StructureForDetailedSizes.get(sections, key) @@ -1004,13 +988,12 @@ def get_detailed_sizes(sections, key, header, as_json=False, sections_diff=None) else: output = format_json(current) else: - def _get_header_format(disp_list=display_name_list): # type: (List) -> str + def _get_header_format(disp_list: List=display_name_list) -> str: len_list = [len(x) for x in disp_list] len_list.insert(0, 24) return ' '.join(['{:>%d}' % x for x in len_list]) + os.linesep - def _get_output(data, selection, key_list=ordered_key_list, disp_list=display_name_list): - # type: (Dict[str, Dict[str, int]], Collection, List, List) -> str + def _get_output(data: Dict[str, Dict[str, int]], selection: Collection, key_list: List=ordered_key_list, disp_list: List=display_name_list) -> str: header_format = _get_header_format(disp_list) output = header_format.format(header, *disp_list) @@ -1025,14 +1008,14 @@ def get_detailed_sizes(sections, key, header, as_json=False, sections_diff=None) # k remains the same pass - def get_section_size(section_dict): # type: (Dict) -> Callable[[str], int] + def get_section_size(section_dict: Dict) -> Callable[[str], int]: return lambda x: section_dict.get(x, 0) section_size_list = map(get_section_size(section_dict=v), key_list) output += header_format.format(k[:24], *(section_size_list)) return output - def _get_header_format_diff(disp_list=display_name_list, columns=False): # type: (List, bool) -> str + def _get_header_format_diff(disp_list: List=display_name_list, columns: bool=False) -> str: if columns: len_list = (24, ) + (7, ) * 3 * len(disp_list) return '|'.join(['{:>%d}' % x for x in len_list]) + os.linesep @@ -1040,8 +1023,7 @@ def get_detailed_sizes(sections, key, header, as_json=False, sections_diff=None) len_list = (24, ) + (23, ) * len(disp_list) return ' '.join(['{:>%d}' % x for x in len_list]) + os.linesep - def _get_output_diff(curr, ref, key_list=ordered_key_list, disp_list=display_name_list): - # type: (Dict, Dict, List, List) -> str + def _get_output_diff(curr: Dict, ref: Dict, key_list: List=ordered_key_list, disp_list: List=display_name_list) -> str: # First header without Current/Ref/Diff columns header_format = _get_header_format_diff(columns=False) output = header_format.format(header, *disp_list) @@ -1069,8 +1051,7 @@ def get_detailed_sizes(sections, key, header, as_json=False, sections_diff=None) # k remains the same pass - def _get_items(name, section_dict=v, section_dict_ref=v2): - # type: (str, Dict, Dict) -> Tuple[str, str, str] + def _get_items(name: str, section_dict: Dict=v, section_dict_ref: Dict=v2) -> Tuple[str, str, str]: a = section_dict.get(name, 0) b = section_dict_ref.get(name, 0) diff = a - b @@ -1110,7 +1091,7 @@ def get_detailed_sizes(sections, key, header, as_json=False, sections_diff=None) class StructureForArchiveSymbols(object): @staticmethod - def get(archive, sections): # type: (str, Dict) -> Dict + def get(archive: str, sections: Dict) -> Dict: interested_sections = LinkingSections.filter_sections(sections) result = dict([(t, {}) for t in interested_sections]) # type: Dict[str, Dict[str, int]] @@ -1135,7 +1116,7 @@ class StructureForArchiveSymbols(object): return section_symbols -def get_archive_symbols(sections, archive, as_json=False, sections_diff=None): # type: (Dict, str, bool, Dict) -> str +def get_archive_symbols(sections: Dict, archive: str, as_json: bool=False, sections_diff: Dict=None) -> str: diff_en = sections_diff is not None current = StructureForArchiveSymbols.get(archive, sections) reference = StructureForArchiveSymbols.get(archive, sections_diff) if sections_diff else {} @@ -1157,10 +1138,10 @@ def get_archive_symbols(sections, archive, as_json=False, sections_diff=None): else: output = format_json(current) else: - def _get_item_pairs(name, section): # type: (str, collections.OrderedDict) -> collections.OrderedDict + def _get_item_pairs(name: str, section: collections.OrderedDict) -> collections.OrderedDict: return collections.OrderedDict([(key.replace(name + '.', ''), val) for key, val in iteritems(section)]) - def _get_output(section_symbols): # type: (Dict) -> str + def _get_output(section_symbols: Dict) -> str: output = '' for t, s in iteritems(section_symbols): output += '{}Symbols from section: {}{}'.format(os.linesep, t, os.linesep) @@ -1175,8 +1156,7 @@ def get_archive_symbols(sections, archive, as_json=False, sections_diff=None): output = 'Symbols within the archive: {} (Not all symbols may be reported){}'.format(archive, os.linesep) if diff_en: - def _generate_line_tuple(curr, ref, name): - # type: (collections.OrderedDict, collections.OrderedDict, str) -> Tuple[str, int, int, str] + def _generate_line_tuple(curr: collections.OrderedDict, ref: collections.OrderedDict, name: str) -> Tuple[str, int, int, str]: cur_val = curr.get(name, 0) ref_val = ref.get(name, 0) diff_val = cur_val - ref_val diff --git a/tools/test_idf_size/test.sh b/tools/test_idf_size/test.sh index 6ede78cf63..4c6b798099 100755 --- a/tools/test_idf_size/test.sh +++ b/tools/test_idf_size/test.sh @@ -1,129 +1,130 @@ #!/usr/bin/env bash -{ coverage debug sys \ - && coverage erase &> output \ + +{ python -m coverage debug sys \ + && python -m coverage erase &> output \ && echo -e "\n***\nRunning idf_size.py..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map &>> output \ && echo -e "\n***\nRunning idf_size.py on bootloader..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py bootloader.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py bootloader.map &>> output \ && echo -e "\n***\nRunning idf_size.py with overflow..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py overflow.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py overflow.map &>> output \ && echo -e "\n***\nRunning idf_size.py --archives..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --archives app.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --archives app.map &>> output \ && echo -e "\n***\nRunning idf_size.py --files..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --files app.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --files app.map &>> output \ && echo -e "\n***\nRunning idf_size.py --archive_details..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --archive_details libdriver.a app.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --archive_details libdriver.a app.map &>> output \ && echo -e "\n***\nRunning idf_size.py diff with bootloader..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app.map --diff bootloader.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --diff bootloader.map &>> output \ && echo -e "\n***\nRunning idf_size.py diff with itself..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app.map --diff app.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --diff app.map &>> output \ && echo -e "\n***\nRunning idf_size.py diff with another app..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app.map --diff app2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --diff app2.map &>> output \ && echo -e "\n***\nRunning idf_size.py diff with app in reverse order..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app2.map --diff app.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app2.map --diff app.map &>> output \ && echo -e "\n***\nRunning idf_size.py diff --archives with bootloader..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app.map --archives --diff bootloader.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --archives --diff bootloader.map &>> output \ && echo -e "\n***\nRunning idf_size.py diff --archives with itself..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app.map --archives --diff app.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --archives --diff app.map &>> output \ && echo -e "\n***\nRunning idf_size.py diff --archives with another app..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app.map --archives --diff app2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --archives --diff app2.map &>> output \ && echo -e "\n***\nRunning idf_size.py diff --archives with app in reverse order..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app2.map --archives --diff app.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app2.map --archives --diff app.map &>> output \ && echo -e "\n***\nRunning idf_size.py diff --files with bootloader..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app.map --files --diff bootloader.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --files --diff bootloader.map &>> output \ && echo -e "\n***\nRunning idf_size.py diff --files with itself..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app.map --files --diff app.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --files --diff app.map &>> output \ && echo -e "\n***\nRunning idf_size.py diff --files with another app..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app.map --files --diff app2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --files --diff app2.map &>> output \ && echo -e "\n***\nRunning idf_size.py diff --files with app in reverse order..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app2.map --files --diff app.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app2.map --files --diff app.map &>> output \ && echo -e "\n***\nRunning idf_size.py diff --archive_details with bootloader..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app.map --archive_details libdriver.a --diff bootloader.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --archive_details libdriver.a --diff bootloader.map &>> output \ && echo -e "\n***\nRunning idf_size.py diff --archive_details with bootloader..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app.map --archive_details libc.a --diff bootloader.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --archive_details libc.a --diff bootloader.map &>> output \ && echo -e "\n***\nRunning idf_size.py diff --archive_details with itself..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app.map --archive_details libdriver.a --diff app.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --archive_details libdriver.a --diff app.map &>> output \ && echo -e "\n***\nRunning idf_size.py diff --archive_details with another app..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app.map --archive_details libdriver.a --diff app2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --archive_details libdriver.a --diff app2.map &>> output \ && echo -e "\n***\nRunning idf_size.py diff --archive_details with app in reverse order..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app2.map --archive_details libdriver.a --diff app.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app2.map --archive_details libdriver.a --diff app.map &>> output \ && echo -e "\n***\nRunning idf_size.py diff --archive_details with another app..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app.map --archive_details libfreertos.a --diff app2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --archive_details libfreertos.a --diff app2.map &>> output \ && echo -e "\n***\nRunning idf_size.py for esp32s2..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 app_esp32s2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 app_esp32s2.map &>> output \ && echo -e "\n***\nRunning idf_size.py for esp32s2 with overflow..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 overflow_esp32s2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 overflow_esp32s2.map &>> output \ && echo -e "\n***\nRunning idf_size.py for esp32s2 (target autodetected)..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app_esp32s2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app_esp32s2.map &>> output \ && echo -e "\n***\nRunning idf_size.py on bootloader for esp32s2..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 bootloader_esp32s2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 bootloader_esp32s2.map &>> output \ && echo -e "\n***\nRunning idf_size.py on bootloader for esp32s2 (target autodetected)..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py bootloader_esp32s2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py bootloader_esp32s2.map &>> output \ && echo -e "\n***\nRunning idf_size.py --archives for esp32s2..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 --archives app_esp32s2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 --archives app_esp32s2.map &>> output \ && echo -e "\n***\nRunning idf_size.py --files for esp32s2..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 --files app_esp32s2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 --files app_esp32s2.map &>> output \ && echo -e "\n***\nRunning idf_size.py --archive_details for esp32s2..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 --archive_details libdriver.a app_esp32s2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s2 --archive_details libdriver.a app_esp32s2.map &>> output \ && echo -e "\n***\nRunning idf_size.py diff with another app (different target)..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app.map --diff app_esp32s2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app.map --diff app_esp32s2.map &>> output \ && echo -e "\n***\nRunning idf_size.py for esp32h2..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --target esp32h2 app_esp32h2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32h2 app_esp32h2.map &>> output \ && echo -e "\n***\nRunning idf_size.py for esp32h2 (target autodetected)..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app_esp32h2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app_esp32h2.map &>> output \ && echo -e "\n***\nRunning idf_size.py --archives for esp32h2..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --target esp32h2 --archives app_esp32h2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32h2 --archives app_esp32h2.map &>> output \ && echo -e "\n***\nRunning idf_size.py --files for esp32h2..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --target esp32h2 --files app_esp32h2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32h2 --files app_esp32h2.map &>> output \ && echo -e "\n***\nRunning idf_size.py --archive_details for esp32h2..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --target esp32h2 --archive_details libdriver.a app_esp32h2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32h2 --archive_details libdriver.a app_esp32h2.map &>> output \ && echo -e "\n***\nRunning idf_size.py for esp32c3..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --target esp32c3 app_esp32c3.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32c3 app_esp32c3.map &>> output \ && echo -e "\n***\nRunning idf_size.py for esp32c3 with overflow..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --target esp32c3 overflow_esp32c3.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32c3 overflow_esp32c3.map &>> output \ && echo -e "\n***\nRunning idf_size.py for esp32c3 (target autodetected)..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app_esp32c3.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app_esp32c3.map &>> output \ && echo -e "\n***\nRunning idf_size.py --archives for esp32c3..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --target esp32c3 --archives app_esp32c3.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32c3 --archives app_esp32c3.map &>> output \ && echo -e "\n***\nRunning idf_size.py --files for esp32c3..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --target esp32c3 --files app_esp32c3.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32c3 --files app_esp32c3.map &>> output \ && echo -e "\n***\nRunning idf_size.py --archive_details for esp32c3..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --target esp32c3 --archive_details libdriver.a app_esp32c3.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32c3 --archive_details libdriver.a app_esp32c3.map &>> output \ && echo -e "\n***\nRunning idf_size.py for esp32s3..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s3 app_esp32s3.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s3 app_esp32s3.map &>> output \ && echo -e "\n***\nRunning idf_size.py for esp32s3 with overflow..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s3 overflow_esp32s3.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s3 overflow_esp32s3.map &>> output \ && echo -e "\n***\nRunning idf_size.py for esp32s3 (target autodetected)..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py app_esp32s3.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py app_esp32s3.map &>> output \ && echo -e "\n***\nRunning idf_size.py --archives for esp32s3..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s3 --archives app_esp32s3.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s3 --archives app_esp32s3.map &>> output \ && echo -e "\n***\nRunning idf_size.py --files for esp32s3..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s3 --files app_esp32s3.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s3 --files app_esp32s3.map &>> output \ && echo -e "\n***\nRunning idf_size.py --archive_details for esp32s3..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s3 --archive_details libdriver.a app_esp32s3.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --target esp32s3 --archive_details libdriver.a app_esp32s3.map &>> output \ && echo -e "\n***\nProducing JSON output..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --json app.map &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --json --archives app.map &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --json --files app.map &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --json --archive_details libdriver.a app.map &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --json app.map --diff app2.map &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --json --archives app.map --diff app2.map &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --json --files app.map --diff app2.map &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --json --archive_details libdriver.a app.map --diff app2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json app.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --archives app.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --files app.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --archive_details libdriver.a app.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json app.map --diff app2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --archives app.map --diff app2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --files app.map --diff app2.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --archive_details libdriver.a app.map --diff app2.map &>> output \ && echo -e "\n***\nProducing JSON file output..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py --json --output-file output.json app.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py --json --output-file output.json app.map &>> output \ && echo -e "\n***\nProducing text file output..." &>> output \ - && coverage run -a $IDF_PATH/tools/idf_size.py -o output.txt app.map &>> output \ + && python -m coverage run -a $IDF_PATH/tools/idf_size.py -o output.txt app.map &>> output \ && echo -e "\n***\nRunning idf_size_tests.py..." &>> output \ - && coverage run -a $IDF_PATH/tools/test_idf_size/test_idf_size.py &>> output \ + && python -m coverage run -a $IDF_PATH/tools/test_idf_size/test_idf_size.py &>> output \ && echo -e "\n\nComparing expected output..." \ && diff -Z output expected_output \ && echo -e "\n\nComparing expected json output..." \ && diff -Z output.json expected_output.json \ && echo -e "\n\nComparing expected text output..." \ && diff -Z output.txt expected_output.txt \ - && coverage report \ + && python -m coverage report \ ; } || { echo 'The test for idf_size has failed. Please examine the artifacts.' ; exit 1; } # Note: "diff -Z is used because some versions of Python print trailing whitespace for JSON pretty-printing, and some don't