quick-ini 4.0__tar.gz → 4.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quick_ini
3
- Version: 4.0
3
+ Version: 4.1
4
4
  Summary: A library for reading from and writing to .ini formatted files
5
5
  Author-email: OllieZ-Mods <socksinthewash@gmail.com>
6
6
  License-Expression: MIT
@@ -38,7 +38,7 @@ pip install quick_ini
38
38
  ```python
39
39
  from quick_ini import QuickIni
40
40
 
41
- # Load from file
41
+ # Load from file, before any get_value() or get_all() (those raise RuntimeError otherwise)
42
42
  QuickIni.load_file("config.ini")
43
43
 
44
44
  # Load from URL
@@ -13,7 +13,7 @@ pip install quick_ini
13
13
  ```python
14
14
  from quick_ini import QuickIni
15
15
 
16
- # Load from file
16
+ # Load from file, before any get_value() or get_all() (those raise RuntimeError otherwise)
17
17
  QuickIni.load_file("config.ini")
18
18
 
19
19
  # Load from URL
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "quick_ini"
7
- version = "4.0"
7
+ version = "4.1"
8
8
  description = "A library for reading from and writing to .ini formatted files"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -17,6 +17,7 @@ class QuickIni:
17
17
  error_message: str = ""
18
18
  web_file: str | None = None
19
19
  sync_report: dict[str, Any] | None = None
20
+ load_called: bool = False
20
21
 
21
22
  @staticmethod
22
23
  def grab_from_url(url:str, timeout:float = 10) -> bool:
@@ -323,6 +324,8 @@ class QuickIni:
323
324
  """
324
325
  QuickIni.parsed_ini = {}
325
326
  QuickIni.auto_type_convert_g = auto_type_convert
327
+ # Set even if loading fails, the caller gets False and reading falls back to defaults
328
+ QuickIni.load_called = True
326
329
 
327
330
  if(not QuickIni.sync_template(file_location, template)):
328
331
  # sync_template sets the error message
@@ -411,6 +414,15 @@ class QuickIni:
411
414
  QuickIni.loaded_file_path=file_location
412
415
  return True
413
416
 
417
+ @staticmethod
418
+ def check_loaded(call:str) -> None:
419
+ """
420
+ Raises a RuntimeError if load_file() was never called, so settings aren't silently read as defaults.
421
+ """
422
+ if(not QuickIni.load_called):
423
+ QuickIni.error_message = f"QuickIni.{call} was called before QuickIni.load_file()"
424
+ raise(RuntimeError(QuickIni.error_message))
425
+
414
426
  @staticmethod
415
427
  def get_value(name:str, default:Any = None, expected_type:type | None = None, section:str | None = None) -> Any:
416
428
  """
@@ -423,6 +435,8 @@ class QuickIni:
423
435
  section (str): The [section] the setting is in, None for keys above any section
424
436
  Return:
425
437
  Any: The value associated with the name
438
+ Raises:
439
+ RuntimeError: If load_file() was never called
426
440
  Example:
427
441
  >>> get_value("do_debug_logs", False)
428
442
  True
@@ -431,6 +445,7 @@ class QuickIni:
431
445
  """
432
446
  if(section):
433
447
  name = f"{section}.{name}"
448
+ QuickIni.check_loaded(f"get_value({name!r})")
434
449
  value:Any = QuickIni.parsed_ini.get(name, default)
435
450
  if(expected_type != None):
436
451
  if(not isinstance(value, expected_type)):
@@ -446,10 +461,13 @@ class QuickIni:
446
461
  section (str): Only return the settings in this [section], with the section prefix removed
447
462
  Return:
448
463
  dict[str, Any]: The settings, keys in a section are given as "section.key" when no section is passed
464
+ Raises:
465
+ RuntimeError: If load_file() was never called
449
466
  Example:
450
467
  >>> get_all("database")
451
468
  {'host': 'localhost', 'port': 5432}
452
469
  """
470
+ QuickIni.check_loaded(f"get_all({section!r})" if section else "get_all()")
453
471
  if(not section):
454
472
  return dict(QuickIni.parsed_ini)
455
473
  prefix = f"{section}."
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quick_ini
3
- Version: 4.0
3
+ Version: 4.1
4
4
  Summary: A library for reading from and writing to .ini formatted files
5
5
  Author-email: OllieZ-Mods <socksinthewash@gmail.com>
6
6
  License-Expression: MIT
@@ -38,7 +38,7 @@ pip install quick_ini
38
38
  ```python
39
39
  from quick_ini import QuickIni
40
40
 
41
- # Load from file
41
+ # Load from file, before any get_value() or get_all() (those raise RuntimeError otherwise)
42
42
  QuickIni.load_file("config.ini")
43
43
 
44
44
  # Load from URL
@@ -16,6 +16,7 @@ class TestQuickIni(unittest.TestCase):
16
16
  """Set up test fixtures before each test method."""
17
17
  # Clear any previous state
18
18
  QuickIni.parsed_ini = {}
19
+ QuickIni.load_called = False
19
20
  QuickIni.loaded_file_path = None
20
21
  QuickIni.auto_type_convert_g = True
21
22
  QuickIni.error_message = ""
@@ -473,6 +474,7 @@ class TestQuickIniFormats(unittest.TestCase):
473
474
 
474
475
  def setUp(self):
475
476
  QuickIni.parsed_ini = {}
477
+ QuickIni.load_called = False
476
478
  QuickIni.loaded_file_path = None
477
479
  QuickIni.auto_type_convert_g = True
478
480
  QuickIni.error_message = ""
@@ -496,6 +498,30 @@ class TestQuickIniFormats(unittest.TestCase):
496
498
  with open(path, encoding='utf-8') as f:
497
499
  return f.read()
498
500
 
501
+ # ===== LOADING FIRST =====
502
+
503
+ def test_get_value_before_load_raises(self):
504
+ with self.assertRaises(RuntimeError):
505
+ QuickIni.get_value("port", 8080)
506
+ self.assertEqual(QuickIni.get_last_error(), "QuickIni.get_value('port') was called before QuickIni.load_file()")
507
+
508
+ def test_get_value_section_before_load_names_key(self):
509
+ with self.assertRaises(RuntimeError):
510
+ QuickIni.get_value("port", section="database")
511
+ self.assertIn("'database.port'", QuickIni.get_last_error())
512
+
513
+ def test_get_all_before_load_raises(self):
514
+ with self.assertRaises(RuntimeError):
515
+ QuickIni.get_all()
516
+ with self.assertRaises(RuntimeError):
517
+ QuickIni.get_all("database")
518
+ self.assertIn("get_all('database')", QuickIni.get_last_error())
519
+
520
+ def test_failed_load_falls_back_to_defaults(self):
521
+ self.assertFalse(QuickIni.load_file("/no/such/config.ini"))
522
+ self.assertEqual(QuickIni.get_value("port", 8080), 8080)
523
+ self.assertEqual(QuickIni.get_all(), {})
524
+
499
525
  # ===== PARSING =====
500
526
 
501
527
  def test_spaces_around_equals(self):
@@ -667,6 +693,7 @@ port = 5432
667
693
 
668
694
  def setUp(self):
669
695
  QuickIni.parsed_ini = {}
696
+ QuickIni.load_called = False
670
697
  QuickIni.loaded_file_path = None
671
698
  QuickIni.auto_type_convert_g = True
672
699
  QuickIni.error_message = ""
File without changes
File without changes
File without changes
File without changes