{"action":"created","issue":{"url":"https://api.github.com/repos/bigjason/django-choices/issues/32","repository_url":"https://api.github.com/repos/bigjason/django-choices","labels_url":"https://api.github.com/repos/bigjason/django-choices/issues/32/labels{/name}","comments_url":"https://api.github.com/repos/bigjason/django-choices/issues/32/comments","events_url":"https://api.github.com/repos/bigjason/django-choices/issues/32/events","html_url":"https://github.com/bigjason/django-choices/issues/32","id":139474631,"number":32,"title":"ChoiceItem naming convention","user":{"login":"tedmiston","id":366688,"avatar_url":"https://avatars.githubusercontent.com/u/366688?v=3","gravatar_id":"","url":"https://api.github.com/users/tedmiston","html_url":"https://github.com/tedmiston","followers_url":"https://api.github.com/users/tedmiston/followers","following_url":"https://api.github.com/users/tedmiston/following{/other_user}","gists_url":"https://api.github.com/users/tedmiston/gists{/gist_id}","starred_url":"https://api.github.com/users/tedmiston/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tedmiston/subscriptions","organizations_url":"https://api.github.com/users/tedmiston/orgs","repos_url":"https://api.github.com/users/tedmiston/repos","events_url":"https://api.github.com/users/tedmiston/events{/privacy}","received_events_url":"https://api.github.com/users/tedmiston/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/bigjason/django-choices/labels/Documentation","name":"Documentation","color":"009800"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2016-03-09T04:46:46Z","updated_at":"2016-03-09T22:37:13Z","closed_at":null,"body":"I've noticed there are two naming styles used: CamelCase and snake_case.\r\n\r\nFor example, `Person.PersonType.Customer` vs. `Book.BookTypes.short_story`.\r\n\r\n(Side thought: *_Type* vs *_Types*)\r\n\r\nFrom `README.rst`:\r\n\r\n```\r\nclass Person(models.Model):\r\n    # Choices\r\n    class PersonType(DjangoChoices):\r\n        Customer = ChoiceItem(\"C\")\r\n        Employee = ChoiceItem(\"E\")\r\n        Groundhog = ChoiceItem(\"G\")\r\n    ...\r\n```\r\n\r\nFrom `docs/index.rst`:\r\n\r\n```\r\nclass Book(models.Model):\r\n\r\n    class BookTypes(DjangoChoices):\r\n        short_story = ChoiceItem('short', 'Short story')\r\n        novel = ChoiceItem('novel', 'Novel')\r\n        non_fiction = ChoiceItem('non_fiction', 'Non fiction')\r\n    ...\r\n```\r\n\r\nPersonally I think camel casing \"feels more right\" given that I'm interacting with the choice items instances like a class type as opposed to like variables.  (And this is the convention I've followed personally.)\r\n\r\nBut [enum in Python 3](https://docs.python.org/3/library/enum.html) takes the other approach.\r\n\r\nI'd like to hear your thoughts on which style you'd prefer.  I think as a user of the library it would be simpler if there were one obvious right way to avoid having to guess.  I'm happy to contribute a PR.\r\n\r\n-Taylor"},"comment":{"url":"https://api.github.com/repos/bigjason/django-choices/issues/comments/194545657","html_url":"https://github.com/bigjason/django-choices/issues/32#issuecomment-194545657","issue_url":"https://api.github.com/repos/bigjason/django-choices/issues/32","id":194545657,"user":{"login":"tedmiston","id":366688,"avatar_url":"https://avatars.githubusercontent.com/u/366688?v=3","gravatar_id":"","url":"https://api.github.com/users/tedmiston","html_url":"https://github.com/tedmiston","followers_url":"https://api.github.com/users/tedmiston/followers","following_url":"https://api.github.com/users/tedmiston/following{/other_user}","gists_url":"https://api.github.com/users/tedmiston/gists{/gist_id}","starred_url":"https://api.github.com/users/tedmiston/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tedmiston/subscriptions","organizations_url":"https://api.github.com/users/tedmiston/orgs","repos_url":"https://api.github.com/users/tedmiston/repos","events_url":"https://api.github.com/users/tedmiston/events{/privacy}","received_events_url":"https://api.github.com/users/tedmiston/received_events","type":"User","site_admin":false},"created_at":"2016-03-09T22:37:12Z","updated_at":"2016-03-09T22:37:12Z","body":"Cool.  This raises a great point.  I guess the reason CamelCase \"felt right\" is that I'm thinking about them like subclasses, but you're right -- that's not what they *are*.\r\n\r\nI think you're not alone with UPPERCASE, because after all, we're defining constants (or at least pseudo-constants), and that is consistent with PEP 8.\r\n\r\nThank you for digging into Django as a point of reference.  Based on this I was curious to dig deeper into Python.  Warning: long post ahead.\r\n\r\n---\r\n\r\n## PEP 435\r\n\r\nParticularly, after confirming there is no guideline for this in PEP 8, I started with *PEP 0435 -- Adding an Enum type to the Python standard library*.  The convention used throughout the document is snake_case, though it is never explicitly called out or prescribed.  So then I wondered: Where did it come from?\r\n\r\nAlso, the [discussion mentions](https://www.python.org/dev/peps/pep-0435/#status-of-discussions) a previously rejected PEP for enums and also Guido's proposal to just add `flufl.enum` to stdlib.  Okay, let's look there.\r\n\r\n## `flufl.enum`\r\n\r\nIn [its examples](http://fluflenum.readthedocs.org/en/latest/docs/using.html#class-syntax), `flufl.enum` uses snake_case.  I still found this odd because we define an enum as a collection of related constants.  The documentation [is consistent with this definition](http://fluflenum.readthedocs.org/en/latest/docs/using.html?highlight=constant) even if the naming convention is not:\r\n\r\n> An enumeration is a set of symbolic names bound to unique, constant values, called enumeration items.\r\n\r\nand\r\n\r\n> The properties of an enumeration are useful for defining an immutable, related set of constant values that have a defined sequence but no inherent semantic meaning.\r\n\r\nSo if they're constants, we should name them `LIKE_A_CONSTANT`, right?\r\n\r\nThe motivation for flufl.enum mentions that it is lifted from PEP 354, the original (rejected) PEP for enums.\r\n\r\n## PEP 354\r\n\r\nSo I dug into *PEP 0354 -- Enumerations in Python*.  It also uses snake_case, but digging deeper there's [a note that it was inspired by something else](https://www.python.org/dev/peps/pep-0354/#implementation):\r\n\r\n> This design is based partly on a recipe [2] from the Python Cookbook.\r\n\r\nWhere [2] is [First Class Enums in Python](http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/413486) written by Zoran Isailovski in 2005, using an abbreviated CamelCase convention.\r\n\r\n## Earlier\r\n\r\nZoran's snippet uses this style:\r\n\r\n```\r\n...\r\nDays = Enum('Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su')\r\nprint Days\r\nprint Days.Mo\r\n...\r\n```\r\n\r\nThat implementation also makes reference to two earlier implementations: One by [Will Ware in 2001](http://code.activestate.com/recipes/67107/) using UPPERCASE; the other by [Samuel Reynolds in 2004](http://code.activestate.com/recipes/305271/) using CamelCase.\r\n\r\n(At this point I tell myself we've come full circle.)\r\n\r\n## `enum` itself\r\n\r\nFinally, I decide we'll look back to `enum` in the Python 3 docs, but even it uses multiple styles.\r\n\r\nEx. [8.13.2. Creating an Enum](https://docs.python.org/3.4/library/enum.html#creating-an-enum)\r\n\r\n```\r\nfrom enum import Enum\r\nclass Color(Enum):\r\n    red = 1\r\n    green = 2\r\n    blue = 3\r\n```\r\n\r\nEx. [8.13.13.4. Planet](https://docs.python.org/3.4/library/enum.html#planet)\r\n\r\n```\r\nclass Planet(Enum):\r\n    MERCURY = (3.303e+23, 2.4397e6)\r\n    VENUS   = (4.869e+24, 6.0518e6)\r\n    ...\r\n```\r\n\r\n## Conclusion\r\n\r\nAfter all this, I'm somewhat split between snake_case and UPPERCASE.\r\n\r\nI think UPPERCASE better represents constant-ness, but for a reason I wasn't able to find, the community at some point picked up using snake_case for naming constants defined inside enums.\r\n\r\nOf course, as you've shown Django chooses to use UPPERCASE in their own examples.  And since this is a Django-specific library, I feel inclined to follow their convention, especially having explicitly documented rationale.\r\n\r\nPerhaps it's just that the greater Python community hasn't questioned the enum naming convention in detail.\r\n\r\nI'm not sure whether this changes your conclusion, but at least I feel more informed.\r\n"}}