sometimes I want to have some constant values that are part of a set
|Reported by:||glyph||Owned by:||exarkun|
(diff, github, buildbot, log)
Twisted contains several piles of named constants that represent interesting constant values that belong to a set. Some examples include: HTTP methods, HTTP response codes, SMTP response codes, OSCAR SNAC codes, AMP special keys (ASK, ANSWER, COMMAND), IRC RPL codes, sftp file flags, and telnet negotiation options.
These are all represented in idiosyncratic and incompatible ways. Many of them are just integers bound to names. Many of them need some kind of bi-directional mapping between a string and an integer, or some associated descriptive text. In some cases we automate that mapping construction, in others we do it by hand.
I'd like to have a single idiom for representing this type of value, one which repr()s to the FQPN of the code's definition (or something similar) so it's easy to look up when debugging, but also contains the information relevant to the protocol (the numeric code, the bytes to send, etc) as a documented attribute.
For some of these, for example telnet negotiation options and conch's FXF_* flags, it may also be helpful to define some kind of "bitwise" operations, so that "FXF_WRITE | FXF_CREAT | FXF_TRUNC" actually looks like something meaningful, and not just '26', when printed. Of course, there should also be an easy way to get 26 (or should I say, 0x1A) out of that combined value as well as an individual one. For example, if FXF_WRITE.asInt() → 2, then (FXF_WRITE | FXF_CREAT | FXF_TRUNC).asInt() → 26. (And no, we don't necessarily need to use '|' and '&' but it may make sense to do so.)
Some other useful functionality: there should be an object representing the total set of statuses or codes or flags, so that it's easy to ask, "is this a value I understand", or, "I have an integer / some bytes / a byte, please give me the associated status object for that value".
This ticket is to implement the library which these different use-cases would use. It is probably not a good idea to try to do this in isolation, since it would be hard to get right without lots of specific reference to use-cases, but rather, to take the opportunity to implement this when some maintenance on such codes comes up.