Pythonic Enumerated list with attribute lookup, and list of values

A common idiom I have is something like this: (the iterator doesnt work btw):

SUMMARY = 'summary'
REPORT = 'report'

class PDF_TYPES:
    summary = SUMMARY
    report = REPORT

    class __metaclass__(type):
        def __iter__(self):
            return iter(list(self.summary, self.report))

Firstly thats a lot of boilerplate for 2 values.

I would like to define some constants in a list and be able to:

  1. Refer to them individiually, e.g. REPORT as above
  2. Import the whole list from another module, and refer to them as PDF_TYPES.report etc. A dictionary would be import PDF_TYPES, REPORT; PDF_TYPES[REPORT], i.e. 2 imports to access one value is not nice.
  3. As a list, e.g. if x not in PDF_TYPES: raise ValueError(....).

I looked at dataclasses but they seem to be for instances of things, these are constants. A dictionary would be perfect except for the clunkiness in scneario 2, it doesnt have the attribute look up. What is the most pythonic way of achieving above 3 requirements?

Answer

Seems like an enum is what you’re describing

from enum import Enum
class PDF_TYPES(Enum):
    summary = 'summary'
    report = 'report'

then for example

>>> PDF_TYPES.summary
<PDF_TYPES.summary: 'summary'>

>>> for pdf_type in PDF_TYPES:
        print(pdf_type)
    
PDF_TYPES.summary
PDF_TYPES.report

Every enum entry has a .name and .value so if you want to check for containment you could use any

>>> any('report' == pdf_type.value for pdf_type in PDF_TYPES)
True
>>> any('foobar' == pdf_type.value for pdf_type in PDF_TYPES)
False