Skip to content

Natively support more types with pre-defined optional hooks #641

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
makukha opened this issue Mar 29, 2025 · 3 comments
Open

Natively support more types with pre-defined optional hooks #641

makukha opened this issue Mar 29, 2025 · 3 comments

Comments

@makukha
Copy link

makukha commented Mar 29, 2025

cattrs comes with a rich set of converters, but the variety of types supported by those converters out of the box is limited. Adding custom structure/unstructure hooks is pretty straightforward and well documented, and in most cases could be as trivial as in the example below. However, as an end user, I would be happy to have something even more simple, something that I wouldn't copy-paste from one project to another :)

A few ideas come to my mind:

  1. What about adding a standalone function or a Converter method register_extra_hooks(converter, cls, structure=True, unstructure=True) (and its variant without first argument, defaulting to global_converter) that will cover less frequently used types from stdlib, like uuid, zoneinfo, ipaddress, re.Pattern, etc? This won't require any overhead in default case, but will enable one liner
register_extra_hooks(converter, ZoneInfo)

instead of

@converter.register_structure_hook
def structure_zoneinfo(value: Any, _) -> ZoneInfo:
    return ZoneInfo(str(value))

@converter.register_unstructure_hook
def unstructure_zoneinfo(value: ZoneInfo) -> str:
    return str(value)
  1. This new function could be even generalized to accept multiple types, like
register_extra_hooks(IPv4Address, ZoneInfo)
  1. It is possible to support non-stdlib modules in this function, by e.g. checking __module__ string or using inspect.getmodule() before importing third-party module itself.

  2. Extra hooks could be registered by third-party libraries with e.g. pluggy.

Does anything of the mentioned above sound reasonable?

@Tinche
Copy link
Member

Tinche commented Mar 30, 2025

I think it's a cool idea. cattrs already has the concept of strategies, so this would be an additional strategy (extra_stdlib_types, to be concise?).

If you're willing to contribute this, I'd be happy to provide guidance and reviews!

@makukha
Copy link
Author

makukha commented Mar 30, 2025

@Tinche hank you for your support, I'd be happy to work on this feature!

For the strategy name, I mentioned that existing strategies' names start with a verb:

  • configure_tagged_union
  • include_subclasses
  • use_class_methods
  • configure_union_passthrough

So what do you think about one of these names for the new strategy:

  • register_extra_types
  • configure_extra_types
  • ???

I could start with few stdlib types, and then add support for arbitrary pluggable types to the same strategy.

@Tinche
Copy link
Member

Tinche commented Apr 12, 2025

Sorry for the delayed response, hectic weeks at work.

Let's go with register_extra_types.

I could start with few stdlib types, and then add support for arbitrary pluggable types to the same strategy.

Sounds good. We should be careful not to go overboard with third party libraries, but some (like numpy maybe) I would be willing to support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants