I'm facing a pretty random problem in Python (3.10.7) right now: I have a list of dictionaries that I want to convert into a list of Python objects. Using list comprehension or a basic for-loop, I expect to create a new list of objects - one for each element in the list of dicts.
This is the list of dicts I receive:
events = [
{
"event_key": "test.test.test_one",
"timestamp": "2022-01-01T01:01:00"
},
{
"event_key": "test.test.test_two",
"timestamp": "2022-01-01T02:02:00"
}
]
And this is the list I would expect:
[
Event(key="test.test.test_one", timestamp="2022-01-01T01:01:00"),
Event(key="test.test.test_two", timestamp="2022-01-01T02:02:00"),
]
But what I get is this:
[
Event(key="test.test.test_two", timestamp="2022-01-01T02:02:00"),
Event(key="test.test.test_two", timestamp="2022-01-01T02:02:00"),
]
To convert the list of dicts, I use list comprehension as follows:
events_list = [Event(event["event_key"], event["timestamp"]) for event in events]
I also tried the most basic way using this code:
events_list = []
for event in events:
key = event["event_key"]
timestamp = event["timestamp"]
event = Event(key=key, timestamp=timestamp)
events_list.append(event)
Inserting a print statement for the attributes or class during the for-loop shows me that the loop and mapping work correctly, but once the item is appended to the list it seems like the new value overwrites the existing ones + appends the new item at the end.
As asked in the comments, here is the custom class as well as the value objects:
class EventKey:
key_pattern = re.compile(r"^([a-z_]+\.){2,}[a-z_]+$")
def __get__(self, obj, objType=None):
return self.value
def __set__(self, obj, value):
if not isinstance(value, str):
raise TypeError("Event key must be a string")
if not self.key_pattern.match(value):
raise ValueError("Event key is not a valid format")
self.value = value
class EventTimestamp:
pattern = re.compile(r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}([Z]|)$")
def __get__(self, obj, objType=None):
return self.value
def __set__(self, obj, value):
if not isinstance(value, str):
raise TypeError("Event timestamp must be a string")
if not self.pattern.match(value):
raise ValueError("Event timestamp is not a valid format")
try:
datetime.datetime.fromisoformat(value.replace("Z", "+00:00"))
except ValueError:
raise ValueError("Event timestamp is not a valid format")
self.value = value
class Event:
key: EventKey = EventKey()
timestamp: EventTimestamp = EventTimestamp()
def __init__(self, key: EventKey, timestamp: EventTimestamp):
self.timestamp = timestamp
self.key = key
def to_dict(self):
return {"event_key": self.key, "timestamp": self.timestamp}
Help is very much appreciated as this issue is slowly driving me crazy.