Repository: T4rk1n/precept

Issue:
[toml-config] Config with a default of type bool fail to dump
If a config default is of type bool and has a comment with less than 40 characters, it will throw an error when dumping the config using the `dump-configs` command. 

```
  File "precept/_configs.py", line 224, in dump
    section[key].comment(prop.comment)
AttributeError: 'bool' object has no attribute 'comment'
```


Discussion:

Patch:
diff --git a/.pylintrc b/.pylintrc
index 415b4c5..945108d 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -152,7 +152,8 @@ disable=print-statement,
         no-member,
         not-callable,
         import-outside-toplevel,
-        super-with-arguments
+        super-with-arguments,
+        too-many-nested-blocks
 
 # Enable the message, report, category or checker with the given id(s). You can
 # either give multiple identifier separated by comma (,) or put this option
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c3871e4..e6cb700 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,13 @@ Versions follows [semver](https://semver.org/).
 
 :warning: Expect breaking changes between minor versions prior to `1.0.0` while the api stabilize. 
 
+## [0.6.5]
+### Fixed
+
+- :bug: Fix Toml dump config of type `bool` with a default and a comment with less than 40 characters. #22
+- :bug: Fix Toml dump config of type `str` with no comment and no default. #23
+- :bug: Use repr in case of error instead of `__class__.__name__` which might exist if the given type is wrong.
+
 ## [0.6.4]
 ### Fixed
 
diff --git a/precept/_configs.py b/precept/_configs.py
index a399619..cfa4147 100644
--- a/precept/_configs.py
+++ b/precept/_configs.py
@@ -1,24 +1,22 @@
-import collections
 import abc
+import collections
+import configparser
+import copy
 import itertools
 import json
 import os
-import typing
-import configparser
 import textwrap
-import copy
+import typing
 from enum import auto
 
 import stringcase
 import tomlkit
-
 from ruamel import yaml
 from ruamel.yaml.comments import CommentedMap
 
 from ._tools import AutoNameEnum
 from .errors import ConfigError
 
-
 undefined = object()
 
 
@@ -221,9 +219,13 @@ class TomlConfigSerializer(BaseConfigSerializer):
                     else:
                         good = add_value(section, key, value)
                         if good:
-                            section[key].comment(prop.comment)
+                            if isinstance(value, bool):
+                                item = section.item(key)
+                            else:
+                                item = section[key]
+                            item.comment(prop.comment)
                 else:
-                    section.add(key, value)
+                    add_value(section, key, value)
 
         with open(path, 'w') as file:
             file.write(tomlkit.dumps(doc))
@@ -331,7 +333,7 @@ class ConfigProperty:
                     value = self.config_type(value)
             except TypeError as err:
                 raise ConfigError(
-                    f'Expected type {self.config_type.__name__} for {value}'
+                    f'Expected type {repr(self.config_type)} for {value}'
                 ) from err
 
         return value
diff --git a/precept/_version.py b/precept/_version.py
index 02f8497..e2f45ae 100644
--- a/precept/_version.py
+++ b/precept/_version.py
@@ -1,1 +1,1 @@
-__version__ = '0.6.4'
+__version__ = '0.6.5'
diff --git a/precept/console/_keyhandler.py b/precept/console/_keyhandler.py
index 1f58234..278c145 100644
--- a/precept/console/_keyhandler.py
+++ b/precept/console/_keyhandler.py
@@ -193,11 +193,11 @@ if __name__ == '__main__':  # pragma: no cover
                 stop()
             print(repr(msg), file=sys.stderr)
 
-        async with KeyHandler({}, default_handler=hand, loop=main_loop) as k:
+        async with KeyHandler({}, default_handler=hand) as k:
             k.print_keys()
             print('Type 10 chars')
             while not k.stop_event.is_set():
                 print('.', end='', flush=True)
-                await asyncio.sleep(1, loop=main_loop)
+                await asyncio.sleep(1)
 
     main_loop.run_until_complete(main())
diff --git a/precept/console/_printing.py b/precept/console/_printing.py
index cf7fd00..0b83ce5 100644
--- a/precept/console/_printing.py
+++ b/precept/console/_printing.py
@@ -1,6 +1,6 @@
 import asyncio
-import sys
 import math
+import sys
 
 from colorama import Style, Fore
 
@@ -97,21 +97,19 @@ async def progress_bar(
         include_value=True,
         dents=50,
         sleep_time=0.005,
-        loop=None,
         file=None,
         full_symbol='#',
         empty_symbol='-',
         start_symbol='[',
         end_symbol=']',
 ):
-    loop = loop or asyncio.get_event_loop()
     value = 0
 
     value_formatter = value_formatter or (lambda x, y: f'{x} / {y}')
 
     while value < max_value:
         value = value_func()
-        await asyncio.sleep(sleep_time, loop=loop)
+        await asyncio.sleep(sleep_time)
 
         progress = math.ceil(value / max_value * dents)
         progress_line = (


Test patch:
diff --git a/tests/test_configs.py b/tests/test_configs.py
index 134b282..aac555d 100644
--- a/tests/test_configs.py
+++ b/tests/test_configs.py
@@ -385,3 +385,43 @@ def test_multi_config_instances():
         cfg1.config_nested.double_nested.double
         != cfg2.config_nested.double_nested.double
     )
+
+
+def test_dump_config_str_no_default_no_comment():
+    config_file = './config.toml'
+
+    class Conf(Config):
+        config_str_no_default_or_comment = ConfigProperty(config_type=str)
+
+    class Cli(Precept):
+        config_class = Conf
+
+    cli = Cli(config_file=config_file, add_dump_config_command=True)
+    cli.config.config_format = ConfigFormat.TOML
+
+    try:
+        cli.start(f'dump-configs {config_file}')
+    finally:
+        if os.path.exists(config_file):
+            os.remove(config_file)
+
+
+def test_dump_config_str_bool_default_less_40_comment():
+    config_file = './config.toml'
+
+    class Conf(Config):
+        boolean_cfg = ConfigProperty(
+            config_type=bool, default=True, comment='less than 40'
+        )
+
+    class Cli(Precept):
+        config_class = Conf
+
+    cli = Cli(config_file=config_file, add_dump_config_command=True)
+    cli.config.config_format = ConfigFormat.TOML
+
+    try:
+        cli.start(f'dump-configs {config_file}')
+    finally:
+        if os.path.exists(config_file):
+            os.remove(config_file)