idf-build-apps 2.5.3__py3-none-any.whl → 2.6.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,11 @@
1
- # SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
3
  import logging
4
4
  import os
5
- import pickle
6
5
  import typing as t
7
6
  from hashlib import sha512
8
7
 
8
+ from esp_bool_parser import BoolStmt, parse_bool_expr
9
9
  from pyparsing import (
10
10
  ParseException,
11
11
  )
@@ -23,10 +23,6 @@ from ..utils import (
23
23
  from ..yaml import (
24
24
  parse,
25
25
  )
26
- from .if_parser import (
27
- BOOL_EXPR,
28
- BoolStmt,
29
- )
30
26
 
31
27
  LOGGER = logging.getLogger(__name__)
32
28
 
@@ -34,7 +30,8 @@ LOGGER = logging.getLogger(__name__)
34
30
  class IfClause:
35
31
  def __init__(self, stmt: str, temporary: bool = False, reason: t.Optional[str] = None) -> None:
36
32
  try:
37
- self.stmt: BoolStmt = BOOL_EXPR.parseString(stmt)[0]
33
+ self.stmt: BoolStmt = parse_bool_expr(stmt)
34
+ self._stmt: str = stmt
38
35
  except (ParseException, InvalidIfClause) as ex:
39
36
  raise InvalidIfClause(f'Invalid if clause: {stmt}. {ex}')
40
37
 
@@ -51,6 +48,9 @@ class IfClause:
51
48
  f' reason: lack of ci runners'
52
49
  )
53
50
 
51
+ def __repr__(self):
52
+ return f'IfClause(stmt={self._stmt!r}, temporary={self.temporary!r}, reason={self.reason!r})'
53
+
54
54
  def get_value(self, target: str, config_name: str) -> t.Any:
55
55
  return self.stmt.get_value(target, config_name)
56
56
 
@@ -69,6 +69,14 @@ class SwitchClause:
69
69
  return content
70
70
  return self.default_clause
71
71
 
72
+ def __repr__(self) -> str:
73
+ return (
74
+ f'SwitchClause('
75
+ f'if_clauses={self.if_clauses!r}, '
76
+ f'contents={self.contents!r}, '
77
+ f'default_clause={self.default_clause!r})'
78
+ )
79
+
72
80
 
73
81
  class FolderRule:
74
82
  DEFAULT_BUILD_TARGETS = SUPPORTED_TARGETS
@@ -153,7 +161,7 @@ class FolderRule:
153
161
  self.depends_components,
154
162
  self.depends_filepatterns,
155
163
  ]:
156
- sha.update(pickle.dumps(obj, protocol=4)) # protocol 4 by default is set in Python 3.8
164
+ sha.update(repr(obj).encode())
157
165
 
158
166
  return sha.hexdigest()
159
167
 
@@ -1,141 +1,6 @@
1
- # SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
1
+ # SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
2
2
  # SPDX-License-Identifier: Apache-2.0
3
- import logging
4
- import os.path
5
- import typing as t
6
- from pathlib import (
7
- Path,
8
- )
9
3
 
10
- from pyparsing import (
11
- CaselessLiteral,
12
- Char,
13
- Combine,
14
- Group,
15
- Literal,
16
- MatchFirst,
17
- OneOrMore,
18
- Optional,
19
- ParseException,
20
- ParseResults,
21
- QuotedString,
22
- Word,
23
- alphas,
24
- hexnums,
25
- nums,
26
- )
4
+ import esp_bool_parser
27
5
 
28
- from ..constants import (
29
- ALL_TARGETS,
30
- IDF_PATH,
31
- )
32
-
33
- LOGGER = logging.getLogger(__name__)
34
-
35
- # Group for parsing literal suffix of a numbers, e.g. 100UL
36
- _literal_symbol = Group(CaselessLiteral('L') | CaselessLiteral('U'))
37
- _literal_suffix = OneOrMore(_literal_symbol)
38
-
39
- # Define name
40
- _name = Word(alphas, alphas + nums + '_')
41
-
42
- # Define value, either a hex, int or a string
43
- _hex_value = Combine(Literal('0x') + Word(hexnums) + Optional(_literal_suffix).suppress())('hex_value')
44
- _str_value = QuotedString('"')('str_value')
45
- _int_value = Word(nums)('int_value') + ~Char('.') + Optional(_literal_suffix)('literal_suffix')
46
-
47
- # Remove optional parenthesis around values
48
- _value = Optional('(').suppress() + MatchFirst([_hex_value, _str_value, _int_value])('value') + Optional(')').suppress()
49
-
50
- _define_expr = '#define' + Optional(_name)('name') + Optional(_value)
51
-
52
-
53
- def get_defines(header_path: str) -> t.List[str]:
54
- defines = []
55
- LOGGER.debug('Reading macros from %s...', header_path)
56
- with open(header_path) as f:
57
- output = f.read()
58
-
59
- for line in output.split('\n'):
60
- line = line.strip()
61
- if len(line):
62
- defines.append(line)
63
-
64
- return defines
65
-
66
-
67
- def parse_define(define_line: str) -> ParseResults:
68
- res = _define_expr.parseString(define_line)
69
-
70
- return res
71
-
72
-
73
- class SocHeader(dict):
74
- CAPS_HEADER_FILEPATTERN = '*_caps.h'
75
-
76
- def __init__(self, target: str) -> None:
77
- if target != 'linux':
78
- soc_header_dict = self._parse_soc_header(target)
79
- else:
80
- soc_header_dict = {}
81
-
82
- super().__init__(**soc_header_dict)
83
-
84
- @staticmethod
85
- def _get_dirs_from_candidates(candidates: t.List[str]) -> t.List[str]:
86
- dirs = []
87
- for d in candidates:
88
- if not os.path.isdir(d):
89
- LOGGER.debug('folder "%s" not found. Skipping...', os.path.abspath(d))
90
- else:
91
- dirs.append(d)
92
-
93
- return dirs
94
-
95
- @classmethod
96
- def _parse_soc_header(cls, target: str) -> t.Dict[str, t.Any]:
97
- soc_headers_dirs = cls._get_dirs_from_candidates(
98
- [
99
- # master c5 mp
100
- os.path.abspath(os.path.join(IDF_PATH, 'components', 'soc', target, 'mp', 'include', 'soc')),
101
- # other branches
102
- os.path.abspath(os.path.join(IDF_PATH, 'components', 'soc', target, 'include', 'soc')),
103
- # release/v4.2
104
- os.path.abspath(os.path.join(IDF_PATH, 'components', 'soc', 'soc', target, 'include', 'soc')),
105
- ]
106
- )
107
- esp_rom_headers_dirs = cls._get_dirs_from_candidates(
108
- [
109
- # master c5 mp
110
- os.path.abspath(os.path.join(IDF_PATH, 'components', 'esp_rom', target, 'mp', target)),
111
- # others
112
- os.path.abspath(os.path.join(IDF_PATH, 'components', 'esp_rom', target)),
113
- ]
114
- )
115
-
116
- header_files: t.List[str] = []
117
- for d in [*soc_headers_dirs, *esp_rom_headers_dirs]:
118
- LOGGER.debug('Checking dir %s', d)
119
- header_files += [str(p.resolve()) for p in Path(d).glob(cls.CAPS_HEADER_FILEPATTERN)]
120
-
121
- output_dict = {}
122
- for f in header_files:
123
- LOGGER.debug('Checking header file %s', f)
124
- for line in get_defines(f):
125
- try:
126
- res = parse_define(line)
127
- except ParseException:
128
- LOGGER.debug('Failed to parse: %s', line)
129
- continue
130
-
131
- if 'str_value' in res:
132
- output_dict[res.name] = res.str_value
133
- elif 'int_value' in res:
134
- output_dict[res.name] = int(res.int_value)
135
- elif 'hex_value' in res:
136
- output_dict[res.name] = int(res.hex_value, 16)
137
-
138
- return output_dict
139
-
140
-
141
- SOC_HEADERS: t.Dict[str, SocHeader] = {target: SocHeader(target) for target in ALL_TARGETS}
6
+ SOC_HEADERS = esp_bool_parser.SOC_HEADERS
File without changes
@@ -14,6 +14,7 @@ Modifications:
14
14
  - use toml instead of tomli when python < 3.11
15
15
  - stop using global variables
16
16
  - fix some warnings
17
+ - recursively find TOML file.
17
18
  """
18
19
 
19
20
  import os
@@ -25,8 +26,10 @@ from typing import Any, Dict, List, Optional, Tuple, Type, Union
25
26
  from pydantic_settings import InitSettingsSource
26
27
  from pydantic_settings.main import BaseSettings
27
28
 
29
+ from idf_build_apps.constants import IDF_BUILD_APPS_TOML_FN
30
+
28
31
  PathType = Union[Path, str, List[Union[Path, str]], Tuple[Union[Path, str], ...]]
29
- DEFAULT_PATH: PathType = Path('')
32
+ DEFAULT_PATH = Path('')
30
33
 
31
34
 
32
35
  class ConfigFileSourceMixin(ABC):
@@ -43,7 +46,7 @@ class ConfigFileSourceMixin(ABC):
43
46
  return kwargs
44
47
 
45
48
  @abstractmethod
46
- def _read_file(self, path: Path) -> Dict[str, Any]:
49
+ def _read_file(self, path: Optional[Path]) -> Dict[str, Any]:
47
50
  pass
48
51
 
49
52
 
@@ -55,24 +58,61 @@ class TomlConfigSettingsSource(InitSettingsSource, ConfigFileSourceMixin):
55
58
  def __init__(
56
59
  self,
57
60
  settings_cls: Type[BaseSettings],
58
- toml_file: Optional[PathType] = DEFAULT_PATH,
61
+ toml_file: Optional[Path] = DEFAULT_PATH,
59
62
  ):
60
- self.toml_file_path = toml_file if toml_file != DEFAULT_PATH else settings_cls.model_config.get('toml_file')
63
+ self.toml_file_path = self._pick_toml_file(
64
+ toml_file,
65
+ settings_cls.model_config.get('pyproject_toml_depth', sys.maxsize),
66
+ IDF_BUILD_APPS_TOML_FN,
67
+ )
61
68
  self.toml_data = self._read_files(self.toml_file_path)
62
69
  super().__init__(settings_cls, self.toml_data)
63
70
 
64
- def _read_file(self, file_path: Path) -> Dict[str, Any]:
71
+ def _read_file(self, path: Optional[Path]) -> Dict[str, Any]:
72
+ if not path or not path.is_file():
73
+ return {}
74
+
65
75
  if sys.version_info < (3, 11):
66
76
  import toml
67
77
 
68
- with open(file_path) as toml_file:
78
+ with open(path) as toml_file:
69
79
  return toml.load(toml_file)
70
80
  else:
71
81
  import tomllib
72
82
 
73
- with open(file_path, 'rb') as toml_file:
83
+ with open(path, 'rb') as toml_file:
74
84
  return tomllib.load(toml_file)
75
85
 
86
+ @staticmethod
87
+ def _pick_toml_file(provided: Optional[Path], depth: int, filename: str) -> Optional[Path]:
88
+ """
89
+ Pick a file path to use. If a file path is provided, use it. Otherwise, search up the directory tree for a
90
+ file with the given name.
91
+
92
+ :param provided: Explicit path provided when instantiating this class.
93
+ :param depth: Number of directories up the tree to check of a pyproject.toml.
94
+ """
95
+ if provided and Path(provided).is_file():
96
+ fp = provided.resolve()
97
+ print(f'Loading config file: {fp}')
98
+ return fp
99
+
100
+ rv = Path.cwd()
101
+ count = -1
102
+ while count < depth:
103
+ if str(rv) == rv.root:
104
+ break
105
+
106
+ fp = rv / filename
107
+ if fp.is_file():
108
+ print(f'Loading config file: {fp}')
109
+ return fp
110
+
111
+ rv = rv.parent
112
+ count += 1
113
+
114
+ return None
115
+
76
116
 
77
117
  class PyprojectTomlConfigSettingsSource(TomlConfigSettingsSource):
78
118
  """
@@ -84,37 +124,16 @@ class PyprojectTomlConfigSettingsSource(TomlConfigSettingsSource):
84
124
  settings_cls: Type[BaseSettings],
85
125
  toml_file: Optional[Path] = None,
86
126
  ) -> None:
87
- self.toml_file_path = self._pick_pyproject_toml_file(
88
- toml_file, settings_cls.model_config.get('pyproject_toml_depth', 0)
127
+ self.toml_file_path = self._pick_toml_file(
128
+ toml_file,
129
+ settings_cls.model_config.get('pyproject_toml_depth', sys.maxsize),
130
+ 'pyproject.toml',
89
131
  )
90
132
  self.toml_table_header: Tuple[str, ...] = settings_cls.model_config.get(
91
- 'pyproject_toml_table_header', ('tool', 'pydantic-settings')
133
+ 'pyproject_toml_table_header',
134
+ ('tool', 'idf-build-apps'),
92
135
  )
93
136
  self.toml_data = self._read_files(self.toml_file_path)
94
137
  for key in self.toml_table_header:
95
138
  self.toml_data = self.toml_data.get(key, {})
96
139
  super(TomlConfigSettingsSource, self).__init__(settings_cls, self.toml_data)
97
-
98
- @staticmethod
99
- def _pick_pyproject_toml_file(provided: Optional[Path], depth: int) -> Path:
100
- """Pick a `pyproject.toml` file path to use.
101
-
102
- Args:
103
- provided: Explicit path provided when instantiating this class.
104
- depth: Number of directories up the tree to check of a pyproject.toml.
105
-
106
- """
107
- if provided:
108
- return provided.resolve()
109
- rv = Path.cwd() / 'pyproject.toml'
110
- count = 0
111
- if not rv.is_file():
112
- child = rv.parent.parent / 'pyproject.toml'
113
- while count < depth:
114
- if child.is_file():
115
- return child
116
- if str(child.parent) == rv.root:
117
- break # end discovery after checking system root once
118
- child = child.parent.parent / 'pyproject.toml'
119
- count += 1
120
- return rv
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: idf-build-apps
3
- Version: 2.5.3
3
+ Version: 2.6.1
4
4
  Summary: Tools for building ESP-IDF related apps.
5
5
  Author-email: Fu Hanxi <fuhanxi@espressif.com>
6
6
  Requires-Python: >=3.7
@@ -21,15 +21,17 @@ Requires-Dist: pydantic~=2.0
21
21
  Requires-Dist: pydantic_settings
22
22
  Requires-Dist: argcomplete>=3
23
23
  Requires-Dist: typing-extensions; python_version < '3.11'
24
+ Requires-Dist: esp-bool-parser>=0.1.2,<1
24
25
  Requires-Dist: sphinx ; extra == "doc"
25
26
  Requires-Dist: sphinx-rtd-theme ; extra == "doc"
26
27
  Requires-Dist: sphinx_copybutton ; extra == "doc"
27
28
  Requires-Dist: myst-parser ; extra == "doc"
28
29
  Requires-Dist: sphinxcontrib-mermaid ; extra == "doc"
29
30
  Requires-Dist: sphinx-argparse ; extra == "doc"
31
+ Requires-Dist: sphinx-tabs ; extra == "doc"
30
32
  Requires-Dist: pytest ; extra == "test"
31
33
  Requires-Dist: pytest-cov ; extra == "test"
32
- Project-URL: changelog, https://github.com/espressif/idf-build-apps/blob/master/CHANGELOG.md
34
+ Project-URL: changelog, https://github.com/espressif/idf-build-apps/blob/main/CHANGELOG.md
33
35
  Project-URL: documentation, https://docs.espressif.com/projects/idf-build-apps
34
36
  Project-URL: homepage, https://github.com/espressif/idf-build-apps
35
37
  Project-URL: repository, https://github.com/espressif/idf-build-apps
@@ -0,0 +1,27 @@
1
+ idf_build_apps/__init__.py,sha256=vUpvuUfhUex6RVt7a3vpSTczJJkHz8qSc2HqbwFW_80,650
2
+ idf_build_apps/__main__.py,sha256=8E-5xHm2MlRun0L88XJleNh5U50dpE0Q1nK5KqomA7I,182
3
+ idf_build_apps/app.py,sha256=F-MKOsaz7cJ0H2wsEE4gpO4kkkEdkyFmIZBHDoM2qgs,37359
4
+ idf_build_apps/args.py,sha256=zB08ctBXFz1UkPv4r7kE6E6sBezCFrrzt99HKRDiRTA,34821
5
+ idf_build_apps/autocompletions.py,sha256=g-bx0pzXoFKI0VQqftkHyGVWN6MLjuFOdozeuAf45yo,2138
6
+ idf_build_apps/constants.py,sha256=HU0rtKqhvLj9nMsy6XvyQMjMEBliNi9xaS2D8CQEPsE,2421
7
+ idf_build_apps/finder.py,sha256=hY6uSMB2s65MqMKIDBSHABOfa93mOLT7x5hlMxC43EQ,5794
8
+ idf_build_apps/log.py,sha256=pyvT7N4MWzGjIXph5mThQCGBiSt53RNPW0WrFfLr0Kw,2650
9
+ idf_build_apps/main.py,sha256=SZauvC_DNEsl1Twc5xQxHSSPt8sgYsNOZjN4UjHk0gQ,16569
10
+ idf_build_apps/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ idf_build_apps/session_args.py,sha256=2WDTy40IFAc0KQ57HaeBcYj_k10eUXRKkDOWLrFCaHY,2985
12
+ idf_build_apps/utils.py,sha256=s4D8P7QA17XcaCUQ_EoiNOW_VpU3cPQgiZVV9KQ8I30,10171
13
+ idf_build_apps/junit/__init__.py,sha256=IxvdaS6eSXp7kZxRuXqyZyGxuA_A1nOW1jF1HMi8Gns,231
14
+ idf_build_apps/junit/report.py,sha256=T7dVU3Sz5tqjfbcFW7wjsb65PDH6C2HFf73ePJqBhMs,6555
15
+ idf_build_apps/junit/utils.py,sha256=NXZxQD4tdbSVKjKMNx1kO2H3IoEiysXkDoDjLEf1RO8,1303
16
+ idf_build_apps/manifest/__init__.py,sha256=LYGR9doEKGPEdsJPuHnmJmV-qw2kuAipV0bodkhY_JE,399
17
+ idf_build_apps/manifest/manifest.py,sha256=5BIzNzGAk0w5qOCTMGsmvKcN4DQLwUi6JVGt2G4JKQs,14793
18
+ idf_build_apps/manifest/soc_header.py,sha256=_F6H5-HP6ateAqKUGlRGH-SUtQ8NJ1RI0hBeCFvsDYA,172
19
+ idf_build_apps/vendors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ idf_build_apps/vendors/pydantic_sources.py,sha256=cO316vq4wAw51O1-KsYz8jrhiI_lkCghiPCYyH0Ghik,4487
21
+ idf_build_apps/yaml/__init__.py,sha256=W-3z5no07RQ6eYKGyOAPA8Z2CLiMPob8DD91I4URjrA,162
22
+ idf_build_apps/yaml/parser.py,sha256=b3LvogO6do-eJPRsYzT-8xk8AT2MnXpLCzQutJqyC7M,2128
23
+ idf_build_apps-2.6.1.dist-info/entry_points.txt,sha256=3pVUirUEsb6jsDRikkQWNUt4hqLK2ci1HvW_Vf8b6uE,59
24
+ idf_build_apps-2.6.1.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
25
+ idf_build_apps-2.6.1.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
26
+ idf_build_apps-2.6.1.dist-info/METADATA,sha256=z7cnY1oC-PXymCxVYo7_Ao5LvPnFyzblDYVE_sUavbI,4693
27
+ idf_build_apps-2.6.1.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: flit 3.9.0
2
+ Generator: flit 3.10.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,240 +0,0 @@
1
- # SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
2
- # SPDX-License-Identifier: Apache-2.0
3
- import operator
4
- import os
5
- from ast import (
6
- literal_eval,
7
- )
8
- from typing import (
9
- Any,
10
- )
11
-
12
- from packaging.version import (
13
- Version,
14
- )
15
- from pyparsing import (
16
- Keyword,
17
- Literal,
18
- MatchFirst,
19
- ParseResults,
20
- QuotedString,
21
- Suppress,
22
- Word,
23
- alphas,
24
- delimitedList,
25
- hexnums,
26
- infixNotation,
27
- nums,
28
- opAssoc,
29
- )
30
-
31
- from ..constants import (
32
- IDF_VERSION,
33
- IDF_VERSION_MAJOR,
34
- IDF_VERSION_MINOR,
35
- IDF_VERSION_PATCH,
36
- )
37
- from ..utils import (
38
- InvalidIfClause,
39
- InvalidInput,
40
- to_version,
41
- )
42
- from .soc_header import (
43
- SOC_HEADERS,
44
- )
45
-
46
-
47
- class Stmt:
48
- """
49
- Statement
50
- """
51
-
52
- def get_value(self, target: str, config_name: str) -> Any:
53
- """
54
- Lazy calculated. All subclasses of `Stmt` should implement this function.
55
-
56
- :param target: ESP-IDF target
57
- :type target: str
58
- :param config_name: config name
59
- :type target: str
60
- :return: the value of the statement
61
- """
62
- raise NotImplementedError('Please implement this function in sub classes')
63
-
64
-
65
- class ChipAttr(Stmt):
66
- """
67
- Attributes defined in SOC Header Files and other keywords as followed:
68
-
69
- - IDF_TARGET: target
70
- - INCLUDE_DEFAULT: take the default build targets into account or not
71
- - IDF_VERSION_MAJOR: major version of ESP-IDF
72
- - IDF_VERSION_MINOR: minor version of ESP-IDF
73
- - IDF_VERSION_PATCH: patch version of ESP-IDF
74
- - CONFIG_NAME: config name defined in the config rules
75
- """
76
-
77
- def __init__(self, t: ParseResults):
78
- self.attr: str = t[0]
79
-
80
- def get_value(self, target: str, config_name: str) -> Any:
81
- from .manifest import FolderRule # lazy-load
82
-
83
- if self.attr == 'IDF_TARGET':
84
- return target
85
-
86
- if self.attr == 'INCLUDE_DEFAULT':
87
- return 1 if target in FolderRule.DEFAULT_BUILD_TARGETS else 0
88
-
89
- if self.attr == 'IDF_VERSION':
90
- return IDF_VERSION
91
-
92
- if self.attr == 'IDF_VERSION_MAJOR':
93
- return IDF_VERSION_MAJOR
94
-
95
- if self.attr == 'IDF_VERSION_MINOR':
96
- return IDF_VERSION_MINOR
97
-
98
- if self.attr == 'IDF_VERSION_PATCH':
99
- return IDF_VERSION_PATCH
100
-
101
- if self.attr == 'CONFIG_NAME':
102
- return config_name
103
-
104
- if self.attr in SOC_HEADERS[target]:
105
- return SOC_HEADERS[target][self.attr]
106
-
107
- # for non-keyword cap words, check if it is defined in the environment variables
108
- if self.attr in os.environ:
109
- return os.environ[self.attr]
110
-
111
- return 0 # default return 0 as false
112
-
113
-
114
- class Integer(Stmt):
115
- def __init__(self, t: ParseResults):
116
- self.expr: str = t[0]
117
-
118
- def get_value(self, target: str, config_name: str) -> Any: # noqa: ARG002
119
- return literal_eval(self.expr)
120
-
121
-
122
- class String(Stmt):
123
- def __init__(self, t: ParseResults):
124
- self.expr: str = t[0]
125
-
126
- def get_value(self, target: str, config_name: str) -> Any: # noqa: ARG002
127
- return literal_eval(f'"{self.expr}"') # double quotes is swallowed by QuotedString
128
-
129
-
130
- class List_(Stmt):
131
- def __init__(self, t: ParseResults):
132
- self.expr = t
133
-
134
- def get_value(self, target: str, config_name: str) -> Any:
135
- return [item.get_value(target, config_name) for item in self.expr]
136
-
137
-
138
- class BoolStmt(Stmt):
139
- _OP_DICT = {
140
- '==': operator.eq,
141
- '!=': operator.ne,
142
- '>': operator.gt,
143
- '>=': operator.ge,
144
- '<': operator.lt,
145
- '<=': operator.le,
146
- 'not in': lambda x, y: x not in y,
147
- 'in': lambda x, y: x in y,
148
- }
149
-
150
- def __init__(self, t: ParseResults):
151
- self.left: Stmt = t[0]
152
- self.comparison: str = t[1]
153
- self.right: Stmt = t[2]
154
-
155
- def get_value(self, target: str, config_name: str) -> Any:
156
- _l = self.left.get_value(target, config_name)
157
- _r = self.right.get_value(target, config_name)
158
-
159
- if self.comparison not in ['in', 'not in']:
160
- # will use version comparison if any of the operands is a Version
161
- if any(isinstance(x, Version) for x in [_l, _r]):
162
- _l = to_version(_l)
163
- _r = to_version(_r)
164
- else:
165
- # use str for "in" and "not in" operator
166
- if isinstance(_l, Version):
167
- _l = str(_l)
168
- if isinstance(_r, Version):
169
- _r = str(_r)
170
-
171
- if self.comparison in self._OP_DICT:
172
- return self._OP_DICT[self.comparison](_l, _r)
173
-
174
- raise InvalidInput(f'Unsupported comparison operator: "{self.comparison}"')
175
-
176
-
177
- class BoolExpr(Stmt):
178
- pass
179
-
180
-
181
- def _and(_l, _r):
182
- return _l and _r
183
-
184
-
185
- def _or(_l, _r):
186
- return _l or _r
187
-
188
-
189
- class BoolOrAnd(BoolExpr):
190
- def __init__(self, t: ParseResults):
191
- if len(t[0]) > 3:
192
- raise InvalidIfClause(
193
- 'Chaining "and"/"or" is not allowed. Please use paratheses instead. '
194
- 'For example: "a and b and c" should be "(a and b) and c".'
195
- )
196
- self.left: BoolStmt = t[0][0]
197
- self.right: BoolStmt = t[0][2]
198
-
199
- if t[0][1] == 'and':
200
- self.operation = _and
201
- if t[0][1] == 'or':
202
- self.operation = _or
203
-
204
- def get_value(self, target: str, config_name: str) -> Any:
205
- return self.operation(self.left.get_value(target, config_name), self.right.get_value(target, config_name))
206
-
207
-
208
- CAP_WORD = Word(alphas.upper(), nums + alphas.upper() + '_').setParseAction(ChipAttr)
209
-
210
- DECIMAL_NUMBER = Word(nums)
211
- HEX_NUMBER = Literal('0x') + Word(hexnums)
212
- INTEGER = (HEX_NUMBER | DECIMAL_NUMBER).setParseAction(Integer)
213
-
214
- STRING = QuotedString('"').setParseAction(String)
215
-
216
- LIST = Suppress('[') + delimitedList(INTEGER | STRING).setParseAction(List_) + Suppress(']')
217
-
218
- BOOL_OPERAND = CAP_WORD | INTEGER | STRING | LIST
219
-
220
- EQ = Keyword('==').setParseAction(lambda t: t[0])
221
- NE = Keyword('!=').setParseAction(lambda t: t[0])
222
- LE = Keyword('<=').setParseAction(lambda t: t[0])
223
- LT = Keyword('<').setParseAction(lambda t: t[0])
224
- GE = Keyword('>=').setParseAction(lambda t: t[0])
225
- GT = Keyword('>').setParseAction(lambda t: t[0])
226
- NOT_IN = Keyword('not in').setParseAction(lambda t: t[0])
227
- IN = Keyword('in').setParseAction(lambda t: t[0])
228
-
229
- BOOL_STMT = BOOL_OPERAND + (EQ | NE | LE | LT | GE | GT | NOT_IN | IN) + BOOL_OPERAND
230
- BOOL_STMT.setParseAction(BoolStmt)
231
-
232
- AND = Keyword('and')
233
- OR = Keyword('or')
234
-
235
- BOOL_EXPR = infixNotation(
236
- BOOL_STMT,
237
- [
238
- (MatchFirst((AND, OR)), 2, opAssoc.LEFT, BoolOrAnd),
239
- ],
240
- )
@@ -1,27 +0,0 @@
1
- idf_build_apps/__init__.py,sha256=NC4Y3XHI515eQBX8WScygPjZaCgogb4zOZjjg_UEyaY,650
2
- idf_build_apps/__main__.py,sha256=8E-5xHm2MlRun0L88XJleNh5U50dpE0Q1nK5KqomA7I,182
3
- idf_build_apps/app.py,sha256=F-MKOsaz7cJ0H2wsEE4gpO4kkkEdkyFmIZBHDoM2qgs,37359
4
- idf_build_apps/args.py,sha256=3lSzUZIkfJzzmhCJ8GICtKQQ1iY-dDotIOmmqwwUrF8,32762
5
- idf_build_apps/autocompletions.py,sha256=g-bx0pzXoFKI0VQqftkHyGVWN6MLjuFOdozeuAf45yo,2138
6
- idf_build_apps/constants.py,sha256=07ve2FtWuLBuc_6LFzbs1XncB1VNi9HJUqGjQQauRNM,3952
7
- idf_build_apps/finder.py,sha256=Wv0QYArXmVZZDslLxfPwGgt202s94112AlAHk0s3N1g,5710
8
- idf_build_apps/log.py,sha256=pyvT7N4MWzGjIXph5mThQCGBiSt53RNPW0WrFfLr0Kw,2650
9
- idf_build_apps/main.py,sha256=Z_hetbOavgCJZQPaP01_jx57fR1w0DefiFz0J2cCwp0,16498
10
- idf_build_apps/session_args.py,sha256=2WDTy40IFAc0KQ57HaeBcYj_k10eUXRKkDOWLrFCaHY,2985
11
- idf_build_apps/utils.py,sha256=s4D8P7QA17XcaCUQ_EoiNOW_VpU3cPQgiZVV9KQ8I30,10171
12
- idf_build_apps/junit/__init__.py,sha256=IxvdaS6eSXp7kZxRuXqyZyGxuA_A1nOW1jF1HMi8Gns,231
13
- idf_build_apps/junit/report.py,sha256=T7dVU3Sz5tqjfbcFW7wjsb65PDH6C2HFf73ePJqBhMs,6555
14
- idf_build_apps/junit/utils.py,sha256=j0PYhFTZjXtTwkENdeL4bFJcX24ktf1CsOOVXz65yNo,1297
15
- idf_build_apps/manifest/__init__.py,sha256=Q2-cb3ngNjnl6_zWhUfzZZB10f_-Rv2JYNck3Lk7UkQ,133
16
- idf_build_apps/manifest/if_parser.py,sha256=AAEyYPgcBWL2ToCmcvhx3fl8ebYdC5-LMvvDkYtWn8o,6546
17
- idf_build_apps/manifest/manifest.py,sha256=6F6Nt93eaoBOHlGHZtv2hHT8Zw0HmJf0d_MESlgye6M,14478
18
- idf_build_apps/manifest/soc_header.py,sha256=PzJ37xFspt5f0AXWvAFNA_avHZA9fMXHBrwDYLi3qEI,4344
19
- idf_build_apps/vendors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- idf_build_apps/vendors/pydantic_sources.py,sha256=2IN6opo6qjCwaqhERFbgA4PtEwqKaTtEkccy5_fYAT0,4130
21
- idf_build_apps/yaml/__init__.py,sha256=W-3z5no07RQ6eYKGyOAPA8Z2CLiMPob8DD91I4URjrA,162
22
- idf_build_apps/yaml/parser.py,sha256=b3LvogO6do-eJPRsYzT-8xk8AT2MnXpLCzQutJqyC7M,2128
23
- idf_build_apps-2.5.3.dist-info/entry_points.txt,sha256=3pVUirUEsb6jsDRikkQWNUt4hqLK2ci1HvW_Vf8b6uE,59
24
- idf_build_apps-2.5.3.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
25
- idf_build_apps-2.5.3.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
26
- idf_build_apps-2.5.3.dist-info/METADATA,sha256=XZLgJfyaJgEl6rULmN0zIeG9quKVH9EhuigO1hnQOvk,4610
27
- idf_build_apps-2.5.3.dist-info/RECORD,,