Loading python classes using pickle gives error: init missing arguments

I have a class which contains some basic information as well as other classes, when saving this class
the attribute buildings gives error upon loading
TypeError: Building.__init__() missing 2 required positional arguments: 'name' and 'jobs'
without the saving and loading function it works perfectly fine.

the code for the classes is-

class Kingdom:
    def __init__(self, total_water=100_000, water_add=667) -> None:
        self.people = []
        self.unemployed_people = []
        self.buildings = []
        self.resources = []
        self.total_water = total_water
        self.water_added = water_add

    def add_building(self, name, x, y):
        "this function will return -1 if the kingdon does not have the required resouces"
        for value in building_info[name]["cost"]:
            for i, item in enumerate(self.resources):
                new_item = item - value
                if not isinstance(new_item, int):
                    self.resources[i] = new_item
                    break
            else:
                return -1
        width, height = assets[name].get_size()
        self.buildings.append(Building(x, y, width, height, name, building_info[name]["jobs"]))

    def display(self, window, x_offset=0, y_offset=0, resource_display_y_offset=0):
        for building in self.buildings:
            building.display(window, x_offset, y_offset)

        # items
        for i, item in enumerate(self.resources):
            blit_text(
                window,
                item.name + "   " + str(item.count),
                (
                    0,
                    i * text_size + text_size * 0.2 * i - 5 + resource_display_y_offset,
                ),
                size=text_size,
            ).get_width()
            try:
                window.blit(
                    assets[item.name],
                    (
                        resource_div_rect.x - default_item_size * 2,
                        i * text_size + text_size * 0.2 * i + resource_display_y_offset,
                    ),
                )
            except KeyError:
                window.blit(
                    assets["Missing Item"],
                    (
                        resource_div_rect.x - default_item_size * 2,
                        i * text_size + text_size * 0.2 * i + resource_display_y_offset,
                    ),
                )

    def tick(self):
        self.total_water += self.water_added
        for person in self.people:
            remaining_resources = person.job.work(self.resources)
            if not isinstance(remaining_resources, int):
                for i, item in enumerate(remaining_resources):
                    if item.name == "water" and self.total_water < item.count:
                        remaining_resources.pop(i)
                        break
                    if item.name == "water":
                        self.total_water -= item.count
                        break
                self.resources = remaining_resources
        for i, item in enumerate(self.resources):
            if item.name == "person":
                for j in range(item.count):
                    self.unemployed_people.append(Person())
                self.resources.pop(i)

    def employ_all_people(self):
        for i, person in enumerate(self.unemployed_people):
            for building in self.buildings:
                if building.jobs > 0:
                    self.unemployed_people.pop(i)
                    self.people.append(Person(building))
                    building.jobs -= 1
                    break


class Person:
    def __init__(self, job=None) -> None:
        self.job = job


class Item:
    def __init__(self, name, count, tag=None) -> None:
        self.name = name
        self.count = count
        self.tag = tag

    def __add__(self, other):
        """This function will return -1 if it cannot add the values"""
        if isinstance(other, int) or isinstance(other, float):
            return Item(self.name, self.count + other, self.tag)
        if not isinstance(other, Item):
            return -1
        if self.name == other.name or (
            (self.tag == other.tag or self.tag == other.name or self.name == other.tag)
            and self.tag is not None
        ):
            return Item(self.name, self.count + other.count, self.tag)
        return -1

    def __sub__(self, other):
        """This function will return -1 if it cannot subtract the values"""
        if (
            isinstance(other, int) or isinstance(other, float)
        ) and self.count > other.count:
            return Item(self.name, self.count - other, self.tag)
        if not isinstance(other, Item):
            return -1
        if (
            self.name == other.name
            or (
                (
                    self.tag == other.tag
                    or self.tag == other.name
                    or self.name == other.tag
                )
                and self.tag is not None
            )
        ) and self.count > other.count:
            return Item(self.name, self.count - other.count, self.tag)
        return -1

    def __repr__(self) -> str:
        return (
            "{name: "
            + str(self.name)
            + ", count: "
            + str(self.count)
            + ",  tag: "
            + str(self.tag)
            + "}"
        )


class Building(pg.Rect):
    def __init__(self, x, y, width, height, name, jobs):
        super().__init__(x, y, width, height)
        self.name = name
        self.jobs = jobs
        self.manual = True

    def display(self, window, x_offset, y_offset):
        if self.x - x_offset < resource_div_rect.x:
            return
        if self.bottom - y_offset > div_rect.y:
            return
        window.blit(assets[self.name], (self.x - x_offset, self.y - y_offset))

    def work(self, resources, called_as_click=False):
        "this function will return -1 if there are insufficent resoureces"
        if self.manual and not called_as_click:
            return -1

        for item in building_info[self.name]["in"]:
            for i, value in enumerate(resources):
                new_item = value - item
                if not isinstance(new_item, int):
                    resources[i] = new_item
                    break
            else:
                return -1
        for item in building_info[self.name]["out"]:
            for i, value in enumerate(resources):
                new_item = value + item
                if not isinstance(new_item, int):
                    resources[i] = new_item
                    break
            else:
                resources.append(item)
        return resources

The full code repository for anyone interested is – https://github.com/IGR2020/PaperCiv
Note it doesn’t have a bugged code

I tried to make the name and job arguments default, and it loaded it but now the arguments were defaulted so I could not change the building data.
I save the data using file = open and data = pickle.load method, it works on other types of data just fine.

Also if there is some other way to save a list of the kingdom class with all the other classes which are a part of it to memory please suggest it.

The saving and loading code is –

save_name = "main.pkl"
# loading world data / creating new world
if isfile(f"kingdom data/{save_name}"):
    file = open(f"kingdom data/{save_name}", "rb")
    kingdoms = pickle.load(file)
    file.close()
    main_kingdom = kingdoms["Main"]

else:
    kingdoms = {"Main": Kingdom()}
    main_kingdom = kingdoms["Main"]
    main_kingdom.resources = [
        Item("wheat", 100, "food"),
        Item("water", 100),
        Item("wood", 50),
        Item("person", 1),
    ]

then the saving code is in the quit condition of the game loop –

for event in pg.event.get():
        if event.type == pg.QUIT:

            # saving current world data
            file = open(f"kingdom data/{save_name}", "wb")
            pickle.dump(kingdoms, file)
            file.close()

            run = False

The error comes after I open the app then place anyone building (i.e the well) then I quit and reopen the app and the error comes into play.
The full code – https://github.com/IGR2020/PaperCiv/tree/Saving-and-Loading
This does have the bugged code.

Here is the MRE –

import pygame as pg
import pickle


class Kingdom:
    def __init__(self, total_water=100_000, water_add=667) -> None:
        self.people = []
        self.unemployed_people = []
        self.buildings = []
        self.resources = []
        self.total_water = total_water
        self.water_added = water_add


class Person:
    def __init__(self, job=None) -> None:
        self.job = job


class Item:
    def __init__(self, name, count, tag=None) -> None:
        self.name = name
        self.count = count
        self.tag = tag


class Building(pg.Rect):
    def __init__(self, x, y, width, height, name, jobs):
        super().__init__(x, y, width, height)
        self.name = name
        self.jobs = jobs
        self.manual = True

kingdom = Kingdom()
kingdom.buildings.append(Building(0, 0, 0, 0, 0, 0))
file = open("main.pkl", "wb")
pickle.dump(kingdom, file)
file.close()
file = open("main.pkl", "rb")
kingdom = pickle.load(file)
file.close()

My computer model is DELL Inspiron Intel Core i5 7th Gen 7200U, This code is running outside of a virtual environment, using pygame 2.5.2 and python 3.12.2 on windows 10. I hope a solution can be found using this MRE.

You can’t inherit from pygame.Rect – it has some custom pickling behaviour that interferes with your adding extra arguments to the __init__ function. Maybe you could instead store a pygame.Rect inside your Building?

class Building:
    def __init__(self, x, y, width, height, name, jobs):
        self.rect = pg.Rect(x, y, width, height)
        self.name = name
        self.jobs = jobs
        self.manual = True

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật