mirror of
https://github.com/unmojang/meta.git
synced 2025-09-26 12:42:28 -04:00
feat: implement merge function for MetaBase
This commit is contained in:
parent
d5e359508b
commit
75006147dd
@ -49,3 +49,22 @@ def replace_old_launchermeta_url(url):
|
||||
return o._replace(netloc="piston-meta.mojang.com").geturl()
|
||||
|
||||
return url
|
||||
|
||||
|
||||
def get_all_bases(cls, bases=None):
|
||||
bases = bases or []
|
||||
bases.append(cls)
|
||||
for c in cls.__bases__:
|
||||
get_all_bases(c, bases)
|
||||
return tuple(bases)
|
||||
|
||||
|
||||
def merge_dict(base: dict, overlay: dict):
|
||||
for k, v in base.items():
|
||||
if isinstance(v, dict):
|
||||
merge_dict(v, overlay.setdefault(k, {}))
|
||||
else:
|
||||
if k not in overlay:
|
||||
overlay[k] = v
|
||||
|
||||
return overlay
|
||||
|
@ -1,10 +1,11 @@
|
||||
import copy
|
||||
from datetime import datetime
|
||||
from typing import Optional, List, Dict, Any, Iterator
|
||||
|
||||
import pydantic
|
||||
from pydantic import Field, validator
|
||||
|
||||
from ..common import serialize_datetime, replace_old_launchermeta_url
|
||||
from ..common import serialize_datetime, replace_old_launchermeta_url, get_all_bases, merge_dict
|
||||
|
||||
META_FORMAT_VERSION = 1
|
||||
|
||||
@ -119,6 +120,40 @@ class MetaBase(pydantic.BaseModel):
|
||||
with open(file_path, "w") as f:
|
||||
f.write(self.json())
|
||||
|
||||
def merge(self, other):
|
||||
"""
|
||||
Merge other object with self.
|
||||
- Concatenates lists
|
||||
- Combines sets
|
||||
- Merges dictionaries (other takes priority)
|
||||
- Recurses for all fields that are also MetaBase classes
|
||||
- Overwrites for any other field type (int, string, ...)
|
||||
"""
|
||||
assert type(other) is type(self)
|
||||
for key, field in self.__fields__.items():
|
||||
ours = getattr(self, key)
|
||||
theirs = getattr(other, key)
|
||||
if theirs is None:
|
||||
continue
|
||||
if ours is None:
|
||||
setattr(self, key, theirs)
|
||||
continue
|
||||
|
||||
if isinstance(ours, list):
|
||||
ours += theirs
|
||||
elif isinstance(ours, set):
|
||||
ours |= theirs
|
||||
elif isinstance(ours, dict):
|
||||
result = merge_dict(ours, copy.deepcopy(theirs))
|
||||
setattr(self, key, result)
|
||||
elif MetaBase in get_all_bases(field.type_):
|
||||
ours.merge(theirs)
|
||||
else:
|
||||
setattr(self, key, theirs)
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.json())
|
||||
|
||||
class Config:
|
||||
allow_population_by_field_name = True
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user