Coder Social home page Coder Social logo

zifeo / dataconf Goto Github PK

View Code? Open in Web Editor NEW
79.0 79.0 14.0 447 KB

Simple dataclasses configuration management for Python with hocon/json/yaml/properties/env-vars/dict/cli support.

License: Mozilla Public License 2.0

Python 100.00%
dataclasses deserialization env-vars hocon json parsing properties python serialization yaml

dataconf's Introduction

Hi there ๐Ÿ‘‹

I am currently a fractional Chief Technology Officer at KiWi and Exponent. I previously served as Smood's CTO and CDO after exiting my first start-up in foodtech. Prior to that, I studied neuro, computer & data sciences at EPFL and worked at Amazon, CERN and the Eclipse Foundation.

I spend most of my time building efficient systems, growing both people and the engineering capabilities of organizations. When I am not coaching or consulting, I chase security bounties and occasionally write about technology, engineering and systems of all kinds.

dataconf's People

Contributors

bakobako avatar dependabot[bot] avatar dwsmith1983 avatar github-actions[bot] avatar jmdacruz avatar jpoppe avatar lannuttia avatar slyons avatar szevzol avatar zifeo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

dataconf's Issues

Support mypy imports

Description

mypy report error when importing dataconf

Expected Behavior

mypy checks pass without any error without the need to use ignore_missing_imports = True option

Actual Behavior

error: Skipping analyzing "dataconf": module is installed, but missing library stubs or py.typed marker  [import]

Parsing dictionaries with Any

It appears that Any can cause some problems.

from dataclasses import dataclass, field
import dataconf
from typing import Any, Dict, Text


@dataclass
class Test:
    name: Text
    items: Dict[Text, Any] = field(default_factory=dict)


config = """
name: letters
items: {
    a: d, 
    b: e, 
    c: f
}
"""

conf = dataconf.string(config, Test)

Traceback:

AttributeError                            Traceback (most recent call last)
/var/folders/kh/n0p_nl6d7sg0hfqljfwmlhcr0000gq/T/ipykernel_6851/3484491678.py in <module>
----> 1 conf = dataconf.string(config, Test)

~/opt/anaconda3/lib/python3.8/site-packages/dataconf/main.py in string(s, clazz)
     65 
     66 def string(s: str, clazz):
---> 67     return multi.string(s).on(clazz)
     68 
     69 

~/opt/anaconda3/lib/python3.8/site-packages/dataconf/main.py in on(self, clazz)
     50         for nxt in nxts:
     51             conf = ConfigTree.merge_configs(conf, nxt)
---> 52         return parse(conf, clazz)
     53 
     54 

~/opt/anaconda3/lib/python3.8/site-packages/dataconf/main.py in parse(conf, clazz)
     12 def parse(conf: ConfigTree, clazz):
     13     try:
---> 14         return utils.__parse(conf, clazz, "")
     15     except pyparsing.ParseSyntaxException as e:
     16         raise MalformedConfigException(

~/opt/anaconda3/lib/python3.8/site-packages/dataconf/utils.py in __parse(value, clazz, path)
     66 
     67             if not isinstance(val, _MISSING_TYPE):
---> 68                 fs[f.name] = __parse(val, f.type, f"{path}.{f.name}")
     69 
     70             elif is_optional(f.type):

~/opt/anaconda3/lib/python3.8/site-packages/dataconf/utils.py in __parse(value, clazz, path)
    107         left, right = args
    108         try:
--> 109             return __parse(value, left if right is NoneType else right, path)
    110         except TypeConfigException:
    111             # cannot parse Optional

~/opt/anaconda3/lib/python3.8/site-packages/dataconf/utils.py in __parse(value, clazz, path)
    101             )
    102         if value is not None:
--> 103             return {k: __parse(v, args[1], f"{path}.{k}") for k, v in value.items()}
    104         return None
    105 

~/opt/anaconda3/lib/python3.8/site-packages/dataconf/utils.py in <dictcomp>(.0)
    101             )
    102         if value is not None:
--> 103             return {k: __parse(v, args[1], f"{path}.{k}") for k, v in value.items()}
    104         return None
    105 

~/opt/anaconda3/lib/python3.8/site-packages/dataconf/utils.py in __parse(value, clazz, path)
    155 
    156     child_failures = []
--> 157     for child_clazz in sorted(clazz.__subclasses__(), key=lambda c: c.__name__):
    158         if is_dataclass(child_clazz):
    159             try:

AttributeError: '_SpecialForm' object has no attribute '__subclasses__'

pyhocon can't parse nested YAML maps

I discovered this while trying to use dataconf to parse a YAML config file with one level of nesting.

For example, adding the following to test_parse.py:

    def test_yaml_nested(self) -> None:

        @dataclass
        class B:
            c: Text

        @dataclass
        class A:
            b: B

        conf = """
        b:
          c: test
        """
        assert loads(conf, A) == A(b=B(c="test"))

This test should pass, but results in the following test failure:

=================================================== FAILURES ====================================================
__________________________________________ TestParser.test_yaml_nested __________________________________________

self = <tests.test_parse.TestParser object at 0x7f440c099f90>

    def test_yaml_nested(self) -> None:
    
        @dataclass
        class B:
            c: Text
    
        @dataclass
        class A:
            b: B
    
        conf = """
        b:
          c: test
        """
>       assert loads(conf, A) == A(b=B(c="test"))

tests/test_parse.py:298: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
dataconf/main.py:102: in loads
    return string(s, clazz, **kwargs)
dataconf/main.py:82: in string
    return multi.string(s, **kwargs).on(clazz)
dataconf/main.py:67: in on
    return parse(conf, clazz, self.strict, **self.kwargs)
dataconf/main.py:17: in parse
    return utils.__parse(conf, clazz, "", strict, ignore_unexpected)
dataconf/utils.py:76: in __parse
    fs[f.name] = __parse(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

value = 'c: test', clazz = <class 'tests.test_parse.TestParser.test_yaml_nested.<locals>.B'>, path = '.b'
strict = True, ignore_unexpected = False

    def __parse(value: any, clazz: Type, path: str, strict: bool, ignore_unexpected: bool):
    
        if is_dataclass(clazz):
    
            if not isinstance(value, ConfigTree):
>               raise TypeConfigException(
                    f"expected type {clazz} at {path}, got {type(value)}"
                )
E               dataconf.exceptions.TypeConfigException: expected type <class 'tests.test_parse.TestParser.test_yaml_nested.<locals>.B'> at .b, got <class 'str'>

dataconf/utils.py:55: TypeConfigException
============================================ short test summary info ============================================
FAILED tests/test_parse.py::TestParser::test_yaml_nested - dataconf.exceptions.TypeConfigException: expected t...
========================================= 1 failed, 30 passed in 0.40s ==========================================

Changing the input to:

        conf = """
        b:
            {c: test}
        """

causes the test to pass, but I suspect this is because it is coincedentally also valid HOCON.

BUG: typing.Union is accepted with only two params

Hi guys,
the following report will refer to this line of code that unpacks typing.Union's arguments (args).

left, right = args

Error:
If you provide more than two args to typing.Union in a dataclasses.dataclass the parsing of the provided config will raise a "ValueError: too many values to unpack (expected 2)".
Expected behaviour of Union is that you can provide more than two args.

Example code to face the error:
One real life example of using more than two args...

from dataclasses import dataclass
from typing import List, Text, Union
from io import BytesIO
import pandas as pd
from pandas import _typing
import dataconf

PARQUET_PATH = "/path/to/empty.parquet"

str_conf = """
	path = {parquet_path}
""".format(
    length="multi-line", parquet_path=PARQUET_PATH
)


def create_empty_parquet() -> None:
    df = pd.DataFrame()
    df.to_parquet(PARQUET_PATH)


@dataclass
class Parquet:
    # The three args in Union will cause the ValueError
    # Remove the last and it will work
    # Text = classical path
    # ReadBuffer[bytes] = pandas.Buffer
    # BytesIO = used for testing
    path: Union[Text, _typing.ReadBuffer[bytes], BytesIO]
    cols: Union[List[str], None] = None

    def load_df(self) -> pd.DataFrame:
        return pd.read_parquet(path=self.path, columns=self.cols)


create_empty_parquet()
conf = dataconf.loads(str_conf, Parquet)

PS: I run Python 3.10

Error with `from __future__ import annotations`

from __future__ import annotations

import dataconf

from dataclasses import dataclass


@dataclass
class Model():
    token: str
    
dataconf.env("TEST_", Model)

Error:

Traceback (most recent call last):
  File "main.py", line 13, in <module>
    dataconf.env("ITBUTKA_", Model)
  File "/.venv/lib/python3.9/site-packages/dataconf/main.py", line 64, in env
    return multi.env(prefix, **kwargs).on(clazz)
  File "/.venv/lib/python3.9/site-packages/dataconf/main.py", line 57, in on
    return parse(conf, clazz, self.strict, **self.kwargs)
  File "/.venv/lib/python3.9/site-packages/dataconf/main.py", line 16, in parse
    return utils.__parse(conf, clazz, "", strict, ignore_unexpected)
  File "/.venv/lib/python3.9/site-packages/dataconf/utils.py", line 68, in __parse
    fs[f.name] = __parse(
  File "/.venv/lib/python3.9/site-packages/dataconf/utils.py", line 186, in __parse
    for child_clazz in sorted(clazz.__subclasses__(), key=lambda c: c.__name__):
AttributeError: 'str' object has no attribute '__subclasses__'

Process finished with exit code 1

Add timedelta support

I think it would be really useful if this library was able to support ISO 8601 Durations. I know that Pydantic supports converting an ISO 8601 Duration to a timedelta. Unfortunately, it appears that I am not actually able to get Pydantic to handle the ISO 8601 duration to timedelta conversion without this library trying to do the conversion and failing because it doesn't know how to make an ISO 8601 duration to a timedelta. I think this might be solvable by either making this library aware that a dataclass is a pydantic dataclass instead of a standard dataclass and disabling this libraries translation on it or just outright adding ISO 8601 duration translation support to this library.

Dump fails

Minimum failing example:

import dataconf
from dataclasses import dataclass

import pytest

@dataclass
class Config:
    experiment_name: str

def test_dump():
    original = Config('test_dump')
    dataconf.dump('tmp_config.yml', original, out='yaml')
    validate = dataconf.file('tmp_config.yml', Config)
    assert original == validate

The reason seems to be that it calls utils.generate from dumps() in main.py, which should be utils.__generate.

Can not pass sample codes from README.md.

I can not pass below sample codes from README.md.

@dataclass
class Example:
    hello: string
    world: string

os.environ['DC_WORLD'] = 'monde'

print(
    dataconf
    .multi
    .url('https://raw.githubusercontent.com/zifeo/dataconf/master/confs/simple.hocon')
    .env('DC')
    .on(Example)
)
# Example(hello='bonjour',world='monde')

First error is about below line.
hello: string =>no string

After replace string to str, I got below error msgs.

"
dataconf
../../../opt/anaconda3/envs/test/lib/python3.8/site-packages/dataconf/main.py:89: in on
conf = ConfigTree.merge_configs(conf, nxt)
../../../opt/anaconda3/envs/test/lib/python3.8/site-packages/pyhocon/config_tree.py:61: in merge_configs
a[key] = value
E TypeError: list indices must be integers or slices, not str
"

Defaults for nested data classes not working?

Consider the following example:

from dataclasses import dataclass, field
import dataconf


@dataclass
class Nested:
    nested_a: bool = False
    nested_b: str = field(default="")


@dataclass
class TopLevel:
    top_a: str
    top_b: str = field(default="some value")
    top_c: Nested = field(default_factory=Nested)


def main():
    config_string = """
    top_a: "some value"
    top_c: {}
    """
    c1 = dataconf.loads(config_string, TopLevel, loader=dataconf.YAML,
                        ignore_unexpected=True)

    config_string = """
    top_a: "some value"
    """
    c2 = dataconf.loads(config_string, TopLevel, loader=dataconf.YAML,
                        ignore_unexpected=True)

    print(c1, c2)


if __name__ == '__main__':
    main()

The first example for c1 seems to work fine, setting c1.top_c to the default value indicated on Nested, but the second example of c2 throws a weird exception:

expected type <class '__main__.Nested'> at .top_c, got <class '__main__.Nested'>
 ...
dataconf.exceptions.TypeConfigException: expected type <class '__main__.Nested'> at .top_c, got <class '__main__.Nested'>

Which is very confusing, as you can see, because it complains that __main__.Nested is not __main__.Nested

What am I missing? How should I go about defining nested data classes with default factories?

load when calling hocon file

In your parsing operation, you dont allow for optional parameters that are list or dicts.

    if origin is list:
        if len(args) != 1:
            raise MissingTypeException("excepted list with type information: List[?]")
        return [__parse(v, args[0], f"{path}[]") for v in value]

    if origin is dict:
        if len(args) != 2:
            raise MissingTypeException(
                "excepted dict with type information: Dict[?, ?]"
            )
        return {k: __parse(v, args[1], f"{path}.{k}") for k, v in value.items()}

Consider the following dataclass:

        @dataclass
        class Base:
            data_root: Text
            pipeline_name: Text
            data_type: Text
            production: bool
            conn: Optional[Conn] = None
            data_split: Optional[Dict[Text, int]] = None
            tfx_root: Optional[Text] = None
            metadata_root: Optional[Text] = None
            beam_args: Optional[List[Text]] = field(
                default_factory=lambda: ["--direct_running_mode=multi_processing", "--direct_num_workers=0"]
            )

An optional parameter with None shouldn't return a failure. We use HOCON configs all the time with case classes in JVM languages and optional parameter parsing should be able to be by passed if None is specified.

What is the intent of the test_missing_type?

    def test_missing_type(self) -> None:

        with pytest.raises(MissingTypeException):
            loads("", Dict)

        with pytest.raises(MissingTypeException):
            loads("", List)

I am not sure what these two should be testing.

Identical naming issues

I found that if we do sealed the trait behavior there is an issue if the class params are named the same. See my demo repo. Ideally, the identical name shouldn't cause an issue.

class InputType(metaclass=ABCMeta):
    pass
    
    
@dataclass
class CSV(InputType):
    file_path: Text
    sep: Text = ","
    
    def load_df(self) -> pd.DataFrame:
        return pd.read_csv(self.file_path, sep=self.sep)
    
    
@dataclass
class Parquet(InputType):
    file_paths: Text     # file_paths cannot be file_path
    engine: Text
        
    def load_df(self) -> pd.DataFrame:
        return pd.read_parquet(self.file_path, engine=self.engine)

Type error with `dataconf.dict`

Code:

config: BaseConfig = dataconf.dict(data, BaseConfig)

Error:

Argument of type "dict[str, Any]" cannot be assigned to parameter "obj" of type "str" in function "dict"
  "dict[str, Any]" is incompatible with "str"

obj must be dict[str, Any]

PEP-604 union annotations cause a crash

It appears that using PEP 604 -- writing Union[X, Y] as X | Y or Optional[X] as X | None causes a crash.

Minimal example:

from dataclasses import dataclass
from typing import Optional
from typing import Union

import dataconf


@dataclass
class Okay:
    foo: Union[str, int]


@dataclass
class Borked:
    foo: str | int


# These work
dataconf.dict({"foo": 123}, Okay)
dataconf.dict({"foo": "asdf"}, Okay)

# These crash
dataconf.dict({"foo": 123}, Borked)
dataconf.dict({"foo": "asdf"}, Borked)

Sample stack trace:

Traceback (most recent call last):
  File "<input>", line 6, in <module>
  File "...python3.11/site-packages/dataconf/main.py", line 100, in env
    return multi.env(prefix, **kwargs).on(clazz)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "...python3.11/site-packages/dataconf/main.py", line 93, in on
    return parse(conf, clazz, self.strict, **self.kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "...python3.11/site-packages/dataconf/main.py", line 26, in parse
    return utils.__parse(conf, clazz, "", strict, ignore_unexpected)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "...python3.11/site-packages/dataconf/utils.py", line 76, in __parse
    fs[f.name] = __parse(
                 ^^^^^^^^
  File "...python3.11/site-packages/dataconf/utils.py", line 210, in __parse
    subtype = value.pop("_type", default=None)
              ^^^^^^^^^
AttributeError: 'str' object has no attribute 'pop'

n.b. the exact error message depends on the value selected for the field. If the value for the field being loaded is an integer, value is an integer and the error is 'int' object has no attribute 'pop'.

Environment:

  • Python: 3.11.5
  • OS: MacOS
  • Packages:
    • dataconf == 2.2.1
    • pydantic == 2.3.0
    • pyhocon == 0.3.60

Parsing ENV not working for int/float/bool

Looks like ENV loading doesn't support int/float/bool , since this requires additional parsing.

Below example will raise exception, while would be expected to parse correctly.

from typing import Optional
import os
from dataclasses import dataclass
import dataconf


@dataclass
class Example:
    hello: Optional[str]
    world: str
    float_num: float
    int_num: int
    bool_var: bool


os.environ["DC_WORLD"] = "monde"
os.environ["DC_FLOAT_NUM"] = "1.3"
os.environ["DC_INT_NUM"] = "2"
os.environ["DC_BOOL_VAR"] = "true"

print(dataconf.env("DC", Example))

Actual:

Traceback (most recent call last):
  File "/Users/any/playground/dataconf_check.py", line 21, in <module>
    print(dataconf.env("DC", Example))
  File "/Users/any/.venv/lib/python3.9/site-packages/dataconf/main.py", line 59, in env
    return multi.env(prefix).on(clazz)
  File "/Users/any/.venv/lib/python3.9/site-packages/dataconf/main.py", line 52, in on
    return parse(conf, clazz)
  File "/Users/any/.venv/lib/python3.9/site-packages/dataconf/main.py", line 14, in parse
    return utils.__parse(conf, clazz, "")
  File "/Users/any/.venv/lib/python3.9/site-packages/dataconf/utils.py", line 68, in __parse
    fs[f.name] = __parse(val, f.type, f"{path}.{f.name}")
  File "/Users/any/.venv/lib/python3.9/site-packages/dataconf/utils.py", line 134, in __parse
    return __parse_type(
  File "/Users/any/.venv/lib/python3.9/site-packages/dataconf/utils.py", line 34, in __parse_type
    raise TypeConfigException(f"expected type {clazz} at {path}, got {type(value)}")
dataconf.exceptions.TypeConfigException: expected type <class 'float'> at .float_num, got <class 'str'>

Expected:

Example(hello=None, world='monde', float_num=1.3, int_num=2, bool_var=True)

Dash parsed to underscore in config read

I tried using the following config written in Hocon. In Scala, we use - and then in case class use _. With Python, this worked in json and yaml parsing but not with dataconf. @zifeo have you encountered this? This example is also in my demo repo here

json_str = """
{
  "doe": "a deer, a female deer",
  "ray": "a drop of golden sun",
  "pi": 3.14159,
  "xmas": true,
  "french_hens": 3,
  "calling-birds": [
     "huey",
     "dewey",
     "louie",
     "fred"
  ],
  "xmas-fifth-day": {
  "calling-birds": "four",
  "french-hens": 3,
  "golden-rings": 5,
  "partridges": {
    "count": 1,
    "location": "a pear tree"
  },
  "turtle-doves": "two"
  }
}
"""

Dependency Conflict When Attempting to Use With Moto

I am attempting to use this library alongside moto[glue] ~= 5.0 and am getting the following error:

ERROR: Cannot install dataconf==2.5.0 and moto[glue]==5.0.0 because these package versions have conflicting dependencies.

The conflict is caused by:
    moto[glue] 5.0.0 depends on pyparsing>=3.0.7; extra == "glue"
    dataconf 2.5.0 depends on pyparsing==2.4.7

To fix this you could try to:
1. loosen the range of package versions you've specified
2. remove package versions to allow pip attempt to solve the dependency conflict

ERROR: ResolutionImpossible: for help visit https://pip.pypa.io/en/latest/topics/dependency-resolution/#dealing-with-dependency-conflicts

This should be something that could be resolved by updating this project to pyparsing ~= 3.1

Add support for tuple types

It appears that dataconf does not support tuple types. This is an issue in the case that you want to pass a frozen dataclass instance created by dataconf into a function decorated with @functools.cache because lists are not hashable. I think that adding support for tuples would allow for the creation of frozen dataclass instances that are hashable because all of the fields within the dataclass would be hashable themselves.

Example fails from README

I am trying to run the string config example from the README. However, these seems to be a problem

System:

  • MacOS
  • Python 3.8
  • dataconf 0.14

I updated the config names to not use the protect names: str, float, list. The code I used:

conf = """
s = test
s = "dustin"
f = 2.2
l = [
    a
    b
]
nested {
    a = test
}
nested_list = [
    {
        a = test1
    }
]
duration = 2s
union = 1
"""

@dataclass
class Nested:
    a: Text  # update to typing Text

@dataclass
class Config:
    s: Text  # update to typing Text and removed protected names str -> s, float -> f, list -> l
    f: float
    l: List[str]
    nested: Nested
    nested_list: List[Nested]
    duration: Text
    union: Union[str, int]
    default_factory: Dict[Text, Text] = field(default_factory=dict)

print(dataconf.load(conf, Config))

Stack trace

---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
<ipython-input-18-6691f8676bf7> in <module>
     34     default_factory: Dict[str, str] = field(default_factory=dict)
     35 
---> 36 print(dataconf.load(conf, Config))

~/opt/anaconda3/lib/python3.8/site-packages/dataconf/utils.py in load(file, clazz)
    129 def load(file: str, clazz):
    130     try:
--> 131         conf = ConfigFactory.parse_file(file)
    132         return __parse(conf, clazz, "")
    133     except pyparsing.ParseSyntaxException as e:

~/opt/anaconda3/lib/python3.8/site-packages/pyhocon/config_parser.py in parse_file(cls, filename, encoding, required, resolve, unresolved_value)
    152         except IOError as e:
    153             if required:
--> 154                 raise e
    155             logger.warn('Cannot include file %s. File does not exist or cannot be read.', filename)
    156             return []

~/opt/anaconda3/lib/python3.8/site-packages/pyhocon/config_parser.py in parse_file(cls, filename, encoding, required, resolve, unresolved_value)
    147         """
    148         try:
--> 149             with codecs.open(filename, 'r', encoding=encoding) as fd:
    150                 content = fd.read()
    151                 return cls.parse_string(content, os.path.dirname(filename), resolve, unresolved_value)

~/opt/anaconda3/lib/python3.8/codecs.py in open(filename, mode, encoding, errors, buffering)
    903         # Force opening of the file in binary mode
    904         mode = mode + 'b'
--> 905     file = builtins.open(filename, mode, buffering)
    906     if encoding is None:
    907         return file

FileNotFoundError: [Errno 2] No such file or directory: '\ns = test\ns = "dustin"\nf = 2.2\nl = [\n    a\n    b\n]\nnested {\n    a = test\n}\nnested_list = [\n    {\n        a = test1\n    }\n]\nduration = 2s\nunion = 1\n'

Does the datacof support include in hocon format?

Does the datacof support include in hocon format?
If not, is ther any alternative to support this kind of ability?

My use case is:
basic.conf: some default settings.
normal.conf:
include basic.conf and reuse the attribute in basic.conf.

Thanks.

Possible bug with loader param in `.load` method

image

When using dataconf.load(<file_path>, <clazz>, loader=dataconf.YAML, the error above is returned. Digging through the lib code, I don't see the kwargs being used to parse or change the loader which might be causing the problem

Python 3.10 Import error with collections

With Python 3.10, we encounter an import error related to collections.

Similar issues:
rmartin16/qbittorrent-api#45
carbonblack/cbapi-python#298

[ImportError]
cannot import name 'Mapping' from 'collections' (/opt/hostedtoolcache/Python/3.10.0/x64/lib/python3.10/collections/__init__.py)

From this issue, they found an issue with

*rmartin Feb 2021
AttrDict finally broke with Python 3.10 since abstract base classes can no
longer be imported from collections but should use collections.abc instead.
Since AttrDict is abandoned, I've consolidated the code here for future use.
AttrMap and AttrDefault are left for posterity but commented out.
"""

from abc import ABCMeta
from abc import abstractmethod
from re import match as re_match

try:  # python 3
    from collections.abc import Mapping
    from collections.abc import MutableMapping
    from collections.abc import Sequence
except ImportError:  # python 2
    from collections import Mapping
    from collections import MutableMapping
    from collections import Sequence

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.