PyLibMS 3.3.1__tar.gz → 3.3.2__tar.gz

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.
Files changed (71) hide show
  1. {pylibms-3.3.1 → pylibms-3.3.2}/PKG-INFO +3 -3
  2. {pylibms-3.3.1 → pylibms-3.3.2}/PyLibMS.egg-info/PKG-INFO +3 -3
  3. {pylibms-3.3.1 → pylibms-3.3.2}/README.md +2 -2
  4. {pylibms-3.3.1 → pylibms-3.3.2}/lms/common/lms_datatype.py +1 -1
  5. {pylibms-3.3.1 → pylibms-3.3.2}/lms/message/definitions/field/lms_field.py +9 -6
  6. {pylibms-3.3.1 → pylibms-3.3.2}/lms/message/msbt.py +7 -11
  7. {pylibms-3.3.1 → pylibms-3.3.2}/lms/message/section/atr1.py +1 -1
  8. {pylibms-3.3.1 → pylibms-3.3.2}/lms/message/section/txt2.py +5 -5
  9. {pylibms-3.3.1 → pylibms-3.3.2}/lms/project/msbpread.py +1 -1
  10. {pylibms-3.3.1 → pylibms-3.3.2}/pyproject.toml +1 -1
  11. {pylibms-3.3.1 → pylibms-3.3.2}/LICENSE +0 -0
  12. {pylibms-3.3.1 → pylibms-3.3.2}/MANIFEST.in +0 -0
  13. {pylibms-3.3.1 → pylibms-3.3.2}/PyLibMS.egg-info/SOURCES.txt +0 -0
  14. {pylibms-3.3.1 → pylibms-3.3.2}/PyLibMS.egg-info/dependency_links.txt +0 -0
  15. {pylibms-3.3.1 → pylibms-3.3.2}/PyLibMS.egg-info/requires.txt +0 -0
  16. {pylibms-3.3.1 → pylibms-3.3.2}/PyLibMS.egg-info/top_level.txt +0 -0
  17. {pylibms-3.3.1 → pylibms-3.3.2}/lms/__init__.py +0 -0
  18. {pylibms-3.3.1 → pylibms-3.3.2}/lms/common/__init__.py +0 -0
  19. {pylibms-3.3.1 → pylibms-3.3.2}/lms/common/lms_exceptions.py +0 -0
  20. {pylibms-3.3.1 → pylibms-3.3.2}/lms/common/lms_fileinfo.py +0 -0
  21. {pylibms-3.3.1 → pylibms-3.3.2}/lms/common/stream/fileinfo.py +0 -0
  22. {pylibms-3.3.1 → pylibms-3.3.2}/lms/common/stream/hashtable.py +0 -0
  23. {pylibms-3.3.1 → pylibms-3.3.2}/lms/common/stream/section.py +0 -0
  24. {pylibms-3.3.1 → pylibms-3.3.2}/lms/fileio/encoding.py +0 -0
  25. {pylibms-3.3.1 → pylibms-3.3.2}/lms/fileio/io.py +0 -0
  26. {pylibms-3.3.1 → pylibms-3.3.2}/lms/message/__init__.py +0 -0
  27. {pylibms-3.3.1 → pylibms-3.3.2}/lms/message/definitions/__init__.py +0 -0
  28. {pylibms-3.3.1 → pylibms-3.3.2}/lms/message/definitions/field/__init__.py +0 -0
  29. {pylibms-3.3.1 → pylibms-3.3.2}/lms/message/definitions/field/io.py +0 -0
  30. {pylibms-3.3.1 → pylibms-3.3.2}/lms/message/definitions/lms_messagetext.py +0 -0
  31. {pylibms-3.3.1 → pylibms-3.3.2}/lms/message/msbtentry.py +0 -0
  32. {pylibms-3.3.1 → pylibms-3.3.2}/lms/message/msbtio.py +0 -0
  33. {pylibms-3.3.1 → pylibms-3.3.2}/lms/message/section/__init__.py +0 -0
  34. {pylibms-3.3.1 → pylibms-3.3.2}/lms/message/section/nli1.py +0 -0
  35. {pylibms-3.3.1 → pylibms-3.3.2}/lms/message/section/tsy1.py +0 -0
  36. {pylibms-3.3.1 → pylibms-3.3.2}/lms/message/tag/__init__.py +0 -0
  37. {pylibms-3.3.1 → pylibms-3.3.2}/lms/message/tag/io/param_io.py +0 -0
  38. {pylibms-3.3.1 → pylibms-3.3.2}/lms/message/tag/io/tag_io.py +0 -0
  39. {pylibms-3.3.1 → pylibms-3.3.2}/lms/message/tag/lms_tag.py +0 -0
  40. {pylibms-3.3.1 → pylibms-3.3.2}/lms/message/tag/lms_tagexceptions.py +0 -0
  41. {pylibms-3.3.1 → pylibms-3.3.2}/lms/project/__init__.py +0 -0
  42. {pylibms-3.3.1 → pylibms-3.3.2}/lms/project/definitions/__init__.py +0 -0
  43. {pylibms-3.3.1 → pylibms-3.3.2}/lms/project/definitions/attribute.py +0 -0
  44. {pylibms-3.3.1 → pylibms-3.3.2}/lms/project/definitions/color.py +0 -0
  45. {pylibms-3.3.1 → pylibms-3.3.2}/lms/project/definitions/style.py +0 -0
  46. {pylibms-3.3.1 → pylibms-3.3.2}/lms/project/definitions/tag.py +0 -0
  47. {pylibms-3.3.1 → pylibms-3.3.2}/lms/project/msbp.py +0 -0
  48. {pylibms-3.3.1 → pylibms-3.3.2}/lms/project/section/ali2.py +0 -0
  49. {pylibms-3.3.1 → pylibms-3.3.2}/lms/project/section/ati2.py +0 -0
  50. {pylibms-3.3.1 → pylibms-3.3.2}/lms/project/section/clr1.py +0 -0
  51. {pylibms-3.3.1 → pylibms-3.3.2}/lms/project/section/string.py +0 -0
  52. {pylibms-3.3.1 → pylibms-3.3.2}/lms/project/section/syl3.py +0 -0
  53. {pylibms-3.3.1 → pylibms-3.3.2}/lms/project/section/tag2.py +0 -0
  54. {pylibms-3.3.1 → pylibms-3.3.2}/lms/project/section/tgg2.py +0 -0
  55. {pylibms-3.3.1 → pylibms-3.3.2}/lms/project/section/tgp2.py +0 -0
  56. {pylibms-3.3.1 → pylibms-3.3.2}/lms/titleconfig/__init__.py +0 -0
  57. {pylibms-3.3.1 → pylibms-3.3.2}/lms/titleconfig/config.py +0 -0
  58. {pylibms-3.3.1 → pylibms-3.3.2}/lms/titleconfig/definitions/__init__.py +0 -0
  59. {pylibms-3.3.1 → pylibms-3.3.2}/lms/titleconfig/definitions/attribute.py +0 -0
  60. {pylibms-3.3.1 → pylibms-3.3.2}/lms/titleconfig/definitions/tags.py +0 -0
  61. {pylibms-3.3.1 → pylibms-3.3.2}/lms/titleconfig/definitions/value.py +0 -0
  62. {pylibms-3.3.1 → pylibms-3.3.2}/lms/titleconfig/presets/Badge Arcade.yaml +0 -0
  63. {pylibms-3.3.1 → pylibms-3.3.2}/lms/titleconfig/presets/Brain Age Concentration Training.yaml +0 -0
  64. {pylibms-3.3.1 → pylibms-3.3.2}/lms/titleconfig/presets/Kirby Planet Robobot.yaml +0 -0
  65. {pylibms-3.3.1 → pylibms-3.3.2}/lms/titleconfig/presets/Super Mario 3D Land.yaml +0 -0
  66. {pylibms-3.3.1 → pylibms-3.3.2}/lms/titleconfig/presets/Super Mario 3D World + Bowsers Fury.yaml +0 -0
  67. {pylibms-3.3.1 → pylibms-3.3.2}/lms/titleconfig/presets/Super Mario Odyssey.yaml +0 -0
  68. {pylibms-3.3.1 → pylibms-3.3.2}/lms/titleconfig/presets/The Legend of Zelda Echos of Wisdom.yaml +0 -0
  69. {pylibms-3.3.1 → pylibms-3.3.2}/lms/titleconfig/presets/The Legend of Zelda a Link Between Worlds.yaml +0 -0
  70. {pylibms-3.3.1 → pylibms-3.3.2}/lms/titleconfig/presets/Tomodachi Life.yaml +0 -0
  71. {pylibms-3.3.1 → pylibms-3.3.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyLibMS
3
- Version: 3.3.1
3
+ Version: 3.3.2
4
4
  Summary: Python library built for the libMessageStudio (LMS) proprietary file formats from Nintendo. Supports MSBT, MSBP, and soon to be MSBF.
5
5
  Author: AbdyyEee
6
6
  License: Copyright 2025 AbdyyEee
@@ -20,7 +20,7 @@ Requires-Dist: PyYAML>=6.0.1
20
20
  Dynamic: license-file
21
21
 
22
22
  # PylibMS
23
- PylibMS is a library built in Python 3.10+ for the libMessageStudio (LMS) proprietary file formats from Nintendo. It supports the following:
23
+ PylibMS is a library built in Python 3.12+ for the libMessageStudio (LMS) proprietary file formats (`msbt`, `msbp`, `msbf`) from Nintendo. It supports the following:
24
24
 
25
25
  * Full reading and writing of MSBT files.
26
26
  * Full reading of MSBP files.
@@ -35,7 +35,7 @@ This library is designed to support LMS revision 3.0 and above, with the associa
35
35
  * Mobile (Specific titles only)
36
36
  * Nintendo Switch
37
37
 
38
- MSBF is in current in the works.
38
+ MSBF is currently in the works.
39
39
 
40
40
  # Features and Usage
41
41
  Simple preview of the library is below. See [the wiki](https://github.com/AbdyyEee/PylibMS/wiki) for more explanations and examples.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PyLibMS
3
- Version: 3.3.1
3
+ Version: 3.3.2
4
4
  Summary: Python library built for the libMessageStudio (LMS) proprietary file formats from Nintendo. Supports MSBT, MSBP, and soon to be MSBF.
5
5
  Author: AbdyyEee
6
6
  License: Copyright 2025 AbdyyEee
@@ -20,7 +20,7 @@ Requires-Dist: PyYAML>=6.0.1
20
20
  Dynamic: license-file
21
21
 
22
22
  # PylibMS
23
- PylibMS is a library built in Python 3.10+ for the libMessageStudio (LMS) proprietary file formats from Nintendo. It supports the following:
23
+ PylibMS is a library built in Python 3.12+ for the libMessageStudio (LMS) proprietary file formats (`msbt`, `msbp`, `msbf`) from Nintendo. It supports the following:
24
24
 
25
25
  * Full reading and writing of MSBT files.
26
26
  * Full reading of MSBP files.
@@ -35,7 +35,7 @@ This library is designed to support LMS revision 3.0 and above, with the associa
35
35
  * Mobile (Specific titles only)
36
36
  * Nintendo Switch
37
37
 
38
- MSBF is in current in the works.
38
+ MSBF is currently in the works.
39
39
 
40
40
  # Features and Usage
41
41
  Simple preview of the library is below. See [the wiki](https://github.com/AbdyyEee/PylibMS/wiki) for more explanations and examples.
@@ -1,5 +1,5 @@
1
1
  # PylibMS
2
- PylibMS is a library built in Python 3.10+ for the libMessageStudio (LMS) proprietary file formats from Nintendo. It supports the following:
2
+ PylibMS is a library built in Python 3.12+ for the libMessageStudio (LMS) proprietary file formats (`msbt`, `msbp`, `msbf`) from Nintendo. It supports the following:
3
3
 
4
4
  * Full reading and writing of MSBT files.
5
5
  * Full reading of MSBP files.
@@ -14,7 +14,7 @@ This library is designed to support LMS revision 3.0 and above, with the associa
14
14
  * Mobile (Specific titles only)
15
15
  * Nintendo Switch
16
16
 
17
- MSBF is in current in the works.
17
+ MSBF is currently in the works.
18
18
 
19
19
  # Features and Usage
20
20
  Simple preview of the library is below. See [the wiki](https://github.com/AbdyyEee/PylibMS/wiki) for more explanations and examples.
@@ -25,7 +25,7 @@ def is_number_datatype(value: object, datatype: LMS_DataType) -> TypeGuard[int |
25
25
  LMS_DataType.INT16,
26
26
  LMS_DataType.INT32,
27
27
  LMS_DataType.FLOAT32,
28
- ) and isinstance(value, (int, float))
28
+ ) and isinstance(value, int)
29
29
 
30
30
 
31
31
  def is_list_datatype(value: object, datatype: LMS_DataType) -> TypeGuard[str]:
@@ -15,8 +15,7 @@ type FieldValue = int | str | float | bool | bytes
15
15
  @dataclass(frozen=True)
16
16
  class LMS_FieldMap:
17
17
  """
18
- A wrapper for a dictionary of LMS_Field objects for controlled access, validation
19
- and abstraction from the dict object.
18
+ A wrapper for a basic ``dict[str, LMS_Field]``. Difference is validation upon modification of a field.
20
19
  """
21
20
 
22
21
  fields: dict[str, LMS_Field]
@@ -52,8 +51,10 @@ class LMS_FieldMap:
52
51
  @classmethod
53
52
  def from_string_dict(cls, data: dict[str, str], definitions: list[ValueDefinition]):
54
53
  fields = {}
54
+ casted_value = None
55
55
 
56
56
  for definition in definitions:
57
+ # These datatypes do not require any casting
57
58
  if definition.datatype in (LMS_DataType.STRING, LMS_DataType.LIST):
58
59
  fields[definition.name] = LMS_Field(data[definition.name], definition)
59
60
  continue
@@ -64,7 +65,7 @@ class LMS_FieldMap:
64
65
  casted_value = bytes.fromhex(value)
65
66
  case LMS_DataType.BOOL:
66
67
  if value not in ("false", "true"):
67
- raise ValueError("Value must be true or false for bool type.")
68
+ raise ValueError("Invalid boolean value!")
68
69
  casted_value = value.strip().lower() == "true"
69
70
  case LMS_DataType.FLOAT32:
70
71
  casted_value = float(value)
@@ -115,7 +116,7 @@ class LMS_Field:
115
116
 
116
117
  @property
117
118
  def list_items(self) -> list[str]:
118
- """The list items bound to the field instance. Only is valid for `LMS_Datatype.LIST` values."""
119
+ """The list items bound to the field instance. Only is valid for ``LMS_Datatype.LIST`` values."""
119
120
  return self._definition.list_items
120
121
 
121
122
  @value.setter
@@ -141,7 +142,8 @@ def _verify_value(
141
142
  case LMS_DataType.LIST if isinstance(value, str):
142
143
  if value not in definition.list_items:
143
144
  raise ValueError(
144
- f"The value of '{value}' provided for field '{definition.name}' is not in the list {definition.list_items}."
145
+ f"""The value of '{value}' provided for field '{definition.name}' is not a
146
+ valid item in the list {definition.list_items}."""
145
147
  )
146
148
  else:
147
149
  return
@@ -172,5 +174,6 @@ def _verify_number_is_in_range(
172
174
  ):
173
175
  if not min_value <= value <= max_value:
174
176
  raise ValueError(
175
- f"The value '{value}' of type '{definition.datatype}' provided for field '{definition.name}' is out of range of ({min_value}, {max_value})"
177
+ f"""The value '{value}' of type '{definition.datatype}' provided for field '{definition.name}'
178
+ is out of range of ({min_value}, {max_value})"""
176
179
  )
@@ -43,19 +43,15 @@ class MSBT:
43
43
 
44
44
  self.size_per_attribute = 0
45
45
 
46
- self._slot_count = MSBT.DEFAULT_SLOT_COUNT
46
+ self.slot_count = MSBT.DEFAULT_SLOT_COUNT
47
47
 
48
48
  self.uses_encoded_attributes = True
49
49
  self.attr_string_table: bytes | None = None
50
50
 
51
51
  self._unsupported_section_map = unsupported_section_map or {}
52
52
 
53
- # Some MSBTs store labels with NLI1 over LBL1
54
- # This flag creates a MSBT instance with NLI1 preferred over LBL1
55
- self.uses_nli1 = uses_nli1
56
-
57
53
  # Store the section list so that the order of any and all sections is preserved when writing
58
- self._section_list: list[str] = section_list or ["LBL1" if not self.uses_nli1 else "NLI1"]
54
+ self._section_list: list[str] = section_list or ["LBL1" if not uses_nli1 else "NLI1"]
59
55
 
60
56
  self._attribute_config = attribute_config
61
57
  self._tag_config = tag_config
@@ -103,11 +99,6 @@ class MSBT:
103
99
  """Tuple of all the MSBT entries."""
104
100
  return tuple(self._entries)
105
101
 
106
- @property
107
- def slot_count(self) -> int:
108
- """The slot count for the MSBT instance."""
109
- return self._slot_count
110
-
111
102
  @property
112
103
  def section_list(self) -> tuple[str, ...]:
113
104
  """The list of sections with order preserved."""
@@ -118,6 +109,11 @@ class MSBT:
118
109
  """The list of unsupported sections."""
119
110
  return tuple(self._unsupported_section_map.keys())
120
111
 
112
+ @property
113
+ def uses_nli1(self) -> bool:
114
+ """If the MSBT contains the NLI1 section."""
115
+ return self.section_exists("NLI1")
116
+
121
117
  @property
122
118
  def contains_attributes(self) -> bool:
123
119
  """If the MSBT contains attributes."""
@@ -39,7 +39,7 @@ def read_encoded_atr1(reader: FileReader, section_size: int) -> ATR1Data:
39
39
 
40
40
  def read_decoded_atr1(reader: FileReader, config: AttributeConfig) -> ATR1Data:
41
41
  # String table as a list is not necessary for decoded attributes
42
- # It is easier to save all changes from the user by when writing
42
+ # It is easier to save all changes from the user when writing
43
43
  # to recreate the table from all the string parameters in every attribute
44
44
  string_table = None
45
45
 
@@ -19,23 +19,23 @@ def read_txt2(
19
19
  for offset in reader.read_offset_array(message_count):
20
20
  reader.seek(offset)
21
21
 
22
- text, message_segments = b"", []
22
+ text, text_segments = b"", []
23
23
  while (data := reader.read_bytes(encoding.width)) != encoding.terminator:
24
24
  is_closing_tag = data == tag_close
25
25
 
26
26
  if data == tag_start or is_closing_tag:
27
- message_segments.append(text.decode(encoding_format))
27
+ text_segments.append(text.decode(encoding_format))
28
28
  tag = read_tag(reader, config, is_closing_tag, suppress_tag_errors)
29
- message_segments.append(tag)
29
+ text_segments.append(tag)
30
30
  text = b""
31
31
  else:
32
32
  text += data
33
33
 
34
34
  # Add the remaining text in case there were no control tags
35
35
  if text:
36
- message_segments.append(text.decode(encoding_format))
36
+ text_segments.append(text.decode(encoding_format))
37
37
 
38
- message = LMS_MessageText(message_segments, config)
38
+ message = LMS_MessageText(text_segments, config)
39
39
  messages.append(message)
40
40
 
41
41
  return messages
@@ -62,7 +62,7 @@ def read_msbp(stream: BinaryIO | bytes) -> MSBP:
62
62
  for magic, _ in read_section_data(reader, file_info.section_count):
63
63
  match magic:
64
64
  case "CLB1" | "ALB1" | "SLB1":
65
- # Set the name attributes of last read item
65
+ # Set the name attribute of last read item
66
66
  labels, _ = read_labels(reader)
67
67
  for i in labels:
68
68
  items[i].name = labels[i]
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "PyLibMS"
7
- version = "3.3.1"
7
+ version = "3.3.2"
8
8
  requires-python = ">=3.12"
9
9
  description = "Python library built for the libMessageStudio (LMS) proprietary file formats from Nintendo. Supports MSBT, MSBP, and soon to be MSBF."
10
10
  readme = "README.md"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes