-
-
Notifications
You must be signed in to change notification settings - Fork 374
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
User-supplied metadata for attr.ib #63
Comments
This might be an interesting feature to somehow support. I myself am working on a library that would benefit from metadata like this (types in my case). First of all, there are some technical issues, in that Secondly, you can already do this, but it's not that straightforward. You'd have to define your own subclass of Also take a look at http://attrs.readthedocs.io/en/stable/extending.html. |
I think it would be very attrs to expect metadata to be a proper class. :) Since I want attrs to be extensible, I’m rather positively inclined to such an feature. |
Yeah, was thinking about how attr might play with type annotations... Re: immutability - maybe Another option if true immutability is really needed for Attributes would be a But basically, having some way to associate arbitrary info that attracts itself doesn't use/care about seems useful. |
Hmm, going the other direction, why require metadata to be any particular type in the first place? Could just be a slot for any user supplied object, without any implied semantics, kinda like how annotations (used to) work. |
What I want for my personal use is something like go struct tags.http://stackoverflow.com/questions/10858787/what-are-the-uses-for-tags-in-go
I'll fork and try how I like something like this for my own use. I think the first class attribute annotations solve this for me as well, but I need a placeholder for now and the + 'tag' may temporarily hold me over |
The second style is covered by my The first style ( Attribute annotations certainly complement this, and I'd like to see attr On Aug 30, 2016 10:59 AM, "Paul Gruenbacher" [email protected]
|
Yes, adding a metadata attribute to Pretty syntax is, then, easy:
@hynek Thoughts? |
I'm my example there's actually no need to reach deep down for _CountingAttr (and it doesn't have optional parameters anyway), just wrapping Also just for clarification, |
so um is everyone on board with |
I can put together a PR. Do you want to assert it's hashable? We don't check for any of the other fields. |
I couldn’t care less what people put in there; it’s a 100% user’s field. I just thought there might be breakage if it isn’t. OTOH this way is completely non-composable, right? A dict would be freer—multiple extensions could make us of it. Can anyone come up with use cases that might matter? |
Yes, at first glance it's non-composable. This was what was tripping me up mentally at the beginning and why I mentioned the lamentable lack of frozendict in an earlier comment. So let's consider a likely example of composing metadata. You're using two libraries which make use of some custom metadata. Let's pretend one of the libraries wants to know the Python type of your field, and the other wants to know what name to use to for the field when dumping to JSON. Option one, with a dict:
Option two, with classes:
Option two is more boilerplatey, and composes as much as classes compose (which if you're using simple attrs classes, is quite enough). Option two also has the benefits of structured data, so if you mistype 'as_json' instead of 'as_json_name', it'll blow up right away instead of not working silently, and if two libraries expect the same attribute name in their metadata it'll blow up early too. The dict approach isn't 100% composable either, the fields would have to be prefixed with their library name or namespaced in some other way to avoid clashes? If you're mixing in more metadata, 3+, it'd be more complex and I would probably make my own wrapper for attr.ib with some logic inside. Another solution would be to use a list of metadata? ¯\ (ツ)_/¯ |
paging @glyph :) |
I really liked @Tinche 's idea for composing the metadata option 2. I'd suggest |
I am very much in favor of @Tinche's Option 1 in my own code; I can never imagine writing something like Option 2 but I can imagine other folks on this thread will want to. From where I sit, it's not attr's business to dictate how the Along those lines, metadata shouldn't be in the hash & recommended-read-only but not enforced. |
FWIW option two made me throw up a little. 🙈 Attrs will never contain anything that requires you to do multiple inheritance. 😱 |
Yes, mixins are... an acquired taste. Can we come up with something better than both options? Or, you know, just let the field be free and let the ecosystem and your own conscience dictate what you put in it. |
Scrapy has a dict The nice thing about a dict is that it's basically a namespace, as opposed On Thu, Sep 1, 2016 at 4:18 PM, Tin Tvrtković [email protected]
Pete Fein | wearpants.org | @wearpants |
Brainstorming a little more.
My gut feeling is really against shortening 'Metadata' to 'Meta' since it makes me think of metaclasses. (For example, from Python 3.5
|
I don't like the idea of using classes like this. It seems rather heavyweight when all we need is namespacing, and attributes should almost always be data rather than behavior. In particular I do not like using Since I hate the vague use of the term "heavyweight", let me be specific :). It's a lot of typing to declare a class with fields and a docstring and such when If all the metadata needs to be supplied at attribute-construction time, then the possibility of namespace collisions is fairly minimal, and there's always the possibility of, e.g.: from typebla.attr import attr_type # To be a little diverse.
from jsonbla import to_json_name
@attr.s
class MyClass():
x = attr.ib(metadata={attr_type: int, to_json_name: 'X'})
attr.get_metadata(MyClass, TypeMetadata)
>>> TypeMetadata(type=int)
attr.get_metadata(MyClass, JsonMetadata)
>>> JsonMetadata(to_json_name='X')
attr.get_metadata(MyClass, SomeOtherMetadata)
>>> None if you want to get fancy and cooperate with other libraries. All in all though, I don't know. I can't think of a solution that fits together really neatly for me and doesn't require a huge amount of ceremony in the default "easy" case. "any hashable object" at least allows for polite libraries to namespace, quick-and-dirty prototypes work, and makes |
IOW we’re agreeing it should be a dict? Maybe we define a class MetaData() that is basically a dict but allows for nicer syntax: @attr.s
class C:
x = attr.ib(metadata=MetaData(attr_type=int, to_json_name="X") and gives us some wiggle space, if want to implement magic? |
Okay, going with the dict idea as the most user-friendly. I think the magic can be done when converting |
You can also just do |
I don't like the idea of having a type-with-kwargs as the type of the parameter though, because it makes it slightly harder to do namespacing; I want to be able to have fully qualified Python names ("i.e. strings with dots in") as keys in this dictionary. |
OK whatever, dict it is. |
How about I put together a PR for this and we can continue the discussion there? |
Less talk more rock On Sep 17, 2016 10:43 AM, "Tin Tvrtković" [email protected] wrote:
|
fixed by #96 |
It might be desirable to allow user-supplied metadata dict as part of an Attribute for use later during introspection. Something like:
(above example is assuming attrs populates metadata with an empty dict if not provided.
Perhaps this is encourages more metaprogramming than is healthy, but I had a need for this in my first use of attrs; the alternative was keeping an explicit list of special attribute names, which is not very DRY. Just looking for design/desirability feedback before working on a patch.
The text was updated successfully, but these errors were encountered: