python-benedict icon indicating copy to clipboard operation
python-benedict copied to clipboard

Add type hints.

Open fabiocaccamo opened this issue 3 years ago • 5 comments

fabiocaccamo avatar Dec 03 '22 18:12 fabiocaccamo

It would be great to be able to define the key type and value type generically like Dict[str, str], e.g.:

from benedict import benedict
from pydantic import TypeAdapter  # just used for deep-checking equivalent to isinstance()

def example_function() -> benedict[str, int]:
    return benedict({'abc': 123})
    
TypeAdapter(benedict[str, int]).validate_python(example_function())
# this should succeed

But also separately I think it would be cool to be able to use them like TypedDicts as well, with hardcoded (total=True/False keys) that are always expected to be present, e.g.:

from benedict import TypedBenedict

class MyCustomBenedict(TypedBenedict, total=True):
    abc: int
    xyz: str
    
test1 = MyCustomBenedict({'abc': 123, 'xyz': 'test string'})
# this should work

test2 = MyCustomBenedict({'abc': 123, 'notallowed': 'something else'})
# this should raise an error because notallowed is not present in the spec

pirate avatar Oct 27 '24 23:10 pirate

I can do this at least in the generic form. TypedBenedict is also an interesting idea.

Tatsh avatar Apr 27 '25 02:04 Tatsh

I've been working on adding type hints. Issue with generic is it won't be very generic. A lot of the core functionality is reliant on the key type always being str. The values can be generic. Most functions will require that the key type always be str even though plausibly it could be bytes as well.

Tatsh avatar Apr 28 '25 18:04 Tatsh

I think it should still allow other types for the keys but then it's on the dev to know that they can't use some of the special features Benedict's provide.

I often use Benedict's for the parsing and serialization functions, those should still work with numeric keys i think.

pirate avatar Apr 28 '25 22:04 pirate

@pirate Please have a look at the PR. I have tried really hard to use abstract base classes and generics but I am not sure how far we can go with it. In the type system there is no way to type-ify the paths so unfortunately anything like some_dict['key1.key2'] is always going to return Any. There would have to be a Mypy plugin to get around this (and then that's limited to Mypy of course and won't work with Pyright). Types would have to be specified somewhere like a TypedBenedict class (which could include TypedDict entries). It gets crazy but it would be very useful.

If you have familiarity with making a Mypy plugin that would be great and we could make a separate package for that (e.g. mypy-benedict-plugin). The best example of a plugin is mypy_django_plugin.

Tatsh avatar Apr 29 '25 04:04 Tatsh

@Tatsh @pirate type annotations available in version 0.35.0.

fabiocaccamo avatar Sep 30 '25 22:09 fabiocaccamo

Amazing! Thank you. I don't deserve any credit for this it's all @Tatsh. Awesome work 👏

pirate avatar Oct 01 '25 23:10 pirate