""" explore2.py: Script to explore the OSCON schedule feed >>> from osconfeed import load >>> raw_feed = load() >>> feed = FrozenJSON(raw_feed) >>> len(feed.Schedule.speakers) 357 >>> sorted(feed.Schedule.keys()) ['conferences', 'events', 'speakers', 'venues'] >>> feed.Schedule.speakers[-1].name 'Carina C. Zona' >>> talk = feed.Schedule.events[40] >>> talk.name 'There *Will* Be Bugs' >>> talk.speakers [3471, 5199] >>> talk.flavor Traceback (most recent call last): ... KeyError: 'flavor' """ # BEGIN EXPLORE2 from collections import abc class FrozenJSON: """A read-only façade for navigating a JSON-like object using attribute notation """ def __new__(cls, arg): # <1> if isinstance(arg, abc.Mapping): return super().__new__(cls) # <2> elif isinstance(arg, abc.MutableSequence): # <3> return [cls(item) for item in arg] else: return arg def __init__(self, mapping): self.__data = {} for key, value in mapping.items(): if iskeyword(key): key += '_' self.__data[key] = value def __getattr__(self, name): if hasattr(self.__data, name): return getattr(self.__data, name) else: return FrozenJSON(self.__data[name]) # <4> # END EXPLORE2