FourCIPP 1.3.0__py3-none-any.whl → 1.5.0__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.
fourcipp/fourc_input.py CHANGED
@@ -496,6 +496,7 @@ class FourCInput:
496
496
  validate_sections_only: bool = False,
497
497
  convert_to_native_types: bool = True,
498
498
  sort_function: Callable[[dict], dict] | None = _sort_by_section_names,
499
+ use_fourcipp_yaml_style: bool = True,
499
500
  ) -> None:
500
501
  """Dump object to yaml.
501
502
 
@@ -506,6 +507,7 @@ class FourCInput:
506
507
  Requiredness of the sections themselves is ignored.
507
508
  convert_to_native_types: Convert all sections to native Python types
508
509
  sort_function: Function to sort the sections.
510
+ use_fourcipp_yaml_style: If FourCIPP yaml style is to be used
509
511
  """
510
512
 
511
513
  if validate or validate_sections_only:
@@ -520,7 +522,7 @@ class FourCInput:
520
522
  if convert_to_native_types:
521
523
  self.convert_to_native_types()
522
524
 
523
- dump_yaml(self.inlined, input_file_path, sort_function)
525
+ dump_yaml(self.inlined, input_file_path, sort_function, use_fourcipp_yaml_style)
524
526
 
525
527
  def validate(
526
528
  self,
fourcipp/utils/cli.py CHANGED
@@ -34,9 +34,12 @@ from fourcipp.utils.configuration import (
34
34
  show_config,
35
35
  )
36
36
  from fourcipp.utils.typing import Path
37
+ from fourcipp.utils.yaml_io import dump_yaml, load_yaml
37
38
 
38
39
 
39
- def modify_input_with_defaults(input_path: Path, overwrite: bool) -> None:
40
+ def modify_input_with_defaults(
41
+ input_path: Path, overwrite: bool
42
+ ) -> None: # pragma: no cover
40
43
  """Apply user defaults to an input file located at input_path.
41
44
 
42
45
  Args:
@@ -62,6 +65,24 @@ def modify_input_with_defaults(input_path: Path, overwrite: bool) -> None:
62
65
  logger.info(f"Input file incl. user defaults is now '{output_filename}'.")
63
66
 
64
67
 
68
+ def format_file(
69
+ input_file: str, sort_sections: bool = False
70
+ ) -> None: # pragma: no cover
71
+ """Formatting file.
72
+
73
+ Args:
74
+ input_file: File to format
75
+ sort_sections: Sort sections
76
+ """
77
+ if sort_sections:
78
+ # Requires reading the config
79
+ fourc_input = FourCInput.from_4C_yaml(input_file)
80
+ fourc_input.dump(input_file, use_fourcipp_yaml_style=True)
81
+ else:
82
+ # No config required, is purely a style question
83
+ dump_yaml(load_yaml(input_file), input_file, use_fourcipp_yaml_style=True)
84
+
85
+
65
86
  def main() -> None:
66
87
  """Main CLI interface."""
67
88
  # Set up the logger
@@ -110,6 +131,23 @@ def main() -> None:
110
131
  type=str,
111
132
  )
112
133
 
134
+ # Format parser
135
+ format_parser = subparsers.add_parser(
136
+ "format",
137
+ help="Format the file in fourcipp style. This sorts the sections and uses the flow styles from FourCIPP",
138
+ )
139
+
140
+ format_parser.add_argument(
141
+ "input-file",
142
+ help=f"4C input file.",
143
+ type=str,
144
+ )
145
+
146
+ format_parser.add_argument(
147
+ "--sort-sections",
148
+ action="store_true",
149
+ help=f"Overwrite existing input file.",
150
+ )
113
151
  # Replace "-" with "_" for variable names
114
152
  kwargs: dict = {}
115
153
  for key, value in vars(main_parser.parse_args(sys.argv[1:])).items():
@@ -126,3 +164,5 @@ def main() -> None:
126
164
  input_path = pathlib.Path(kwargs.pop("input_file"))
127
165
  overwrite = kwargs.pop("overwrite")
128
166
  modify_input_with_defaults(input_path, overwrite)
167
+ case "format":
168
+ format_file(**kwargs)
fourcipp/utils/yaml_io.py CHANGED
@@ -63,13 +63,17 @@ def load_yaml(path_to_yaml_file: Path) -> dict:
63
63
 
64
64
 
65
65
  def dict_to_yaml_string(
66
- data: dict, sort_function: Callable[[dict], dict] | None = None
66
+ data: dict,
67
+ sort_function: Callable[[dict], dict] | None = None,
68
+ use_fourcipp_yaml_style: bool = True,
67
69
  ) -> str:
68
70
  """Dump dict as yaml.
69
71
 
72
+ The FourCIPP yaml style sets flow
70
73
  Args:
71
74
  data: Data to dump.
72
75
  sort_function: Function to sort the data.
76
+ use_fourcipp_yaml_style: If FourCIPP yaml style is to be used
73
77
 
74
78
  Returns:
75
79
  YAML string representation of the data
@@ -81,11 +85,60 @@ def dict_to_yaml_string(
81
85
  # Convert dictionary into a ryml tree
82
86
  tree = ryml.parse_in_arena(bytearray(json.dumps(data).encode("utf8")))
83
87
 
84
- # remove all style bits to enable a YAML style output
88
+ def check_is_vector(tree: ryml.Tree, node_id: int) -> bool:
89
+ """Check if sequence is of ints, floats or sequence there of.
90
+
91
+ In 4C metadata terms, list of strings, bools, etc. could also be vectors.
92
+ For the sake of simplicity these are omitted.
93
+
94
+ Args:
95
+ tree (ryml.Tree): Tree to check
96
+ node_id (int): Node id
97
+
98
+ Returns:
99
+ returns if entry is a vector
100
+ """
101
+
102
+ for sub_node, _ in ryml.walk(tree, node_id):
103
+ # Ignore the root node
104
+ if sub_node == node_id:
105
+ continue
106
+
107
+ # If sequence contains a dict
108
+ if tree.is_map(sub_node):
109
+ return False
110
+
111
+ # If sequence contains a sequence
112
+ elif tree.is_seq(sub_node):
113
+ if not check_is_vector(tree, sub_node):
114
+ return False
115
+
116
+ # Else it's a value
117
+ else:
118
+ val = tree.val(sub_node).tobytes().decode("ascii")
119
+ is_not_numeric = (
120
+ tree.is_val_quoted(sub_node) # string
121
+ or tree.val_is_null(sub_node) # null
122
+ or val == "true" # bool
123
+ or val == "false" # bool
124
+ )
125
+ if is_not_numeric:
126
+ return False
127
+
128
+ return True
129
+
130
+ # Change style bits to avoid JSON output and format vectors correctly
85
131
  # see https://github.com/biojppm/rapidyaml/issues/520
86
- for node_id, _ in ryml.walk(tree):
87
- if tree.is_map(node_id) or tree.is_seq(node_id):
132
+ for node_id, depth in ryml.walk(tree):
133
+ if tree.is_map(node_id):
88
134
  tree.set_container_style(node_id, ryml.NOTYPE)
135
+ elif tree.is_seq(node_id):
136
+ if (
137
+ not use_fourcipp_yaml_style # do not do special formatting
138
+ or depth == 1 # is a section
139
+ or not check_is_vector(tree, node_id) # is not a vector
140
+ ):
141
+ tree.set_container_style(node_id, ryml.NOTYPE)
89
142
 
90
143
  if tree.has_key(node_id):
91
144
  tree.set_key_style(node_id, ryml.NOTYPE)
@@ -97,15 +150,17 @@ def dump_yaml(
97
150
  data: dict,
98
151
  path_to_yaml_file: Path,
99
152
  sort_function: Callable[[dict], dict] | None = None,
153
+ use_fourcipp_yaml_style: bool = True,
100
154
  ) -> None:
101
155
  """Dump yaml to file.
102
156
 
103
157
  Args:
104
158
  data: Data to dump.
105
159
  path_to_yaml_file: Yaml file path
106
- sort_function: Function to sort the data.
160
+ sort_function: Function to sort the data
161
+ use_fourcipp_yaml_style: If FourCIPP yaml style is to be used
107
162
  """
108
163
  pathlib.Path(path_to_yaml_file).write_text(
109
- dict_to_yaml_string(data, sort_function),
164
+ dict_to_yaml_string(data, sort_function, use_fourcipp_yaml_style),
110
165
  encoding="utf-8",
111
166
  )
fourcipp/version.py CHANGED
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '1.3.0'
32
- __version_tuple__ = version_tuple = (1, 3, 0)
31
+ __version__ = version = '1.5.0'
32
+ __version_tuple__ = version_tuple = (1, 5, 0)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: FourCIPP
3
- Version: 1.3.0
3
+ Version: 1.5.0
4
4
  Summary: A streamlined Python Parser for 4C input files
5
5
  Author: FourCIPP Authors
6
6
  License: The MIT License (MIT)
@@ -1,8 +1,8 @@
1
1
  fourcipp/__init__.py,sha256=4pz7DVXErSbUcLqPTaHnQfdJzKkpfZDivBqbHbTgpRE,1388
2
- fourcipp/fourc_input.py,sha256=w37dzvfuzGXv0EdzfGABKjmAwxx-4Ba7dTyzjyk_ApI,23803
3
- fourcipp/version.py,sha256=0Oc4EBzGTJOvXX0Vym4evglW1NQPpe8RLn8TdxsKzfs,704
4
- fourcipp/config/4C_metadata.yaml,sha256=3n3Uj24iblvsfqUI-8H2LYMHOROjeHl68Nok0F22Unc,11868927
5
- fourcipp/config/4C_schema.json,sha256=67giZGZSKXkjO_NCbZzx-blVdGB6BFXRbHrXkmqB_T4,16412275
2
+ fourcipp/fourc_input.py,sha256=TXVP-N_FTadt4L8MPH3VZXeT7i5uy7Btz3H-N0pxMr0,23948
3
+ fourcipp/version.py,sha256=sfeo6QRBwy3wEFaKhAEbFPpF98FLjoe4Car1c6NnghQ,704
4
+ fourcipp/config/4C_metadata.yaml,sha256=A2cJVUA_PMZ3Y_mGP-M3VhpQhLbSn1a1oh3gfGpJ9GQ,11868923
5
+ fourcipp/config/4C_schema.json,sha256=wDRSORrXQpg8cIhIOxeD2GTqfewUE4ygbPSeluSH7b0,16412271
6
6
  fourcipp/config/config.yaml,sha256=n2c2a6E4HKfAdNWOQz1kLUuf5p4NLxIddaAi2t5eM38,460
7
7
  fourcipp/legacy_io/__init__.py,sha256=y6aTjgUe61OQSl1NMiZ-fQAGTab_xNT1eJTnaTnsIkc,5744
8
8
  fourcipp/legacy_io/element.py,sha256=b8--f3IR9nB68R25mk4DHHOBdDLqASewtAdPZAkA2t4,3971
@@ -11,7 +11,7 @@ fourcipp/legacy_io/node.py,sha256=e7m0W7dai_b1XgaqD37k3QS44ySCas3HetmyTLS9_78,35
11
11
  fourcipp/legacy_io/node_topology.py,sha256=hqGGzhyNhFX-BMW8SzztfzM8zoZLLltVScMv-p4hDH0,5394
12
12
  fourcipp/legacy_io/particle.py,sha256=0rxwdiMnHI1QUGZPqWgsxqyslrxB7aq7qxgNMb_y_rk,2166
13
13
  fourcipp/utils/__init__.py,sha256=ccdlf4taJ0mKLg_ru8ilXEa72PoO9N2UIxHNHDEtQmY,1151
14
- fourcipp/utils/cli.py,sha256=43Nmy9tnoQzwWMZwpktWVv3T3a3y4qDzfuDB1bHogbA,4658
14
+ fourcipp/utils/cli.py,sha256=I0N6mcJQGX7seLtXpfrPJA5EWrmhgOph_gHrrxEs6JE,5801
15
15
  fourcipp/utils/configuration.py,sha256=HDrvHrH4K5mdienzVsAt_sh9j2Pv81bxWBqqbeNb1KE,6461
16
16
  fourcipp/utils/converter.py,sha256=D40YQ96WqPEEpB7fwAB5XC2v-jRki4v1sIJ-ngO08nU,5194
17
17
  fourcipp/utils/dict_utils.py,sha256=uC0uaBNP3Wh2v3kFy9JHnAYARMukAN4cl40pmiBT13Y,12891
@@ -19,10 +19,10 @@ fourcipp/utils/metadata.py,sha256=98jz9Gm8qdvZ-b1jwYObNJTaiMQWwbknvS70Nv6Gwhk,12
19
19
  fourcipp/utils/not_set.py,sha256=04C_3axe2cupBYgfpgDAcGs1zHVzG3I58UGO58TH05A,2017
20
20
  fourcipp/utils/typing.py,sha256=8iX9PuKe8B1WJ3vEjiM5ZfefvgYnaZDiSdB7Nx9SrVw,1625
21
21
  fourcipp/utils/validation.py,sha256=FejHOj1MddaU7gEpMN-f8Mz3rYjflakd1qcsKnctHqA,5292
22
- fourcipp/utils/yaml_io.py,sha256=yShbQ7d_zv_tGK_3ym3NilrfL7HpsEt_8JvDqZYnuFY,3606
23
- fourcipp-1.3.0.dist-info/licenses/LICENSE,sha256=lkSOHdH9IZ8c3Vnz0fFjqls1cRlmLADBP8QEIwUlH3o,1082
24
- fourcipp-1.3.0.dist-info/METADATA,sha256=4G6YxfZlgnnDMV19Yz3UblMfxHpnMCAqWonlpsgmdcY,7947
25
- fourcipp-1.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
- fourcipp-1.3.0.dist-info/entry_points.txt,sha256=44XBG4bwhuq1EwOZ0U055HYP8_qN6_d30ecVsa5Igng,53
27
- fourcipp-1.3.0.dist-info/top_level.txt,sha256=oZ6jgFFmvi157VwGUEFuKT3D8oS5mOkpOVx8zZURZrQ,9
28
- fourcipp-1.3.0.dist-info/RECORD,,
22
+ fourcipp/utils/yaml_io.py,sha256=bs78Mc3fIz0kK5wgwwu89OhaDpLzECTRBQtIpnifTqk,5559
23
+ fourcipp-1.5.0.dist-info/licenses/LICENSE,sha256=lkSOHdH9IZ8c3Vnz0fFjqls1cRlmLADBP8QEIwUlH3o,1082
24
+ fourcipp-1.5.0.dist-info/METADATA,sha256=drGpZmzC-ufasdYWbwoXz_DoU-gOw7bLoP11yxlTwLo,7947
25
+ fourcipp-1.5.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
+ fourcipp-1.5.0.dist-info/entry_points.txt,sha256=44XBG4bwhuq1EwOZ0U055HYP8_qN6_d30ecVsa5Igng,53
27
+ fourcipp-1.5.0.dist-info/top_level.txt,sha256=oZ6jgFFmvi157VwGUEFuKT3D8oS5mOkpOVx8zZURZrQ,9
28
+ fourcipp-1.5.0.dist-info/RECORD,,