mirror of
https://github.com/unmojang/meta.git
synced 2025-09-26 20:52:21 -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 o._replace(netloc="piston-meta.mojang.com").geturl()
|
||||||
|
|
||||||
return url
|
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 datetime import datetime
|
||||||
from typing import Optional, List, Dict, Any, Iterator
|
from typing import Optional, List, Dict, Any, Iterator
|
||||||
|
|
||||||
import pydantic
|
import pydantic
|
||||||
from pydantic import Field, validator
|
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
|
META_FORMAT_VERSION = 1
|
||||||
|
|
||||||
@ -119,6 +120,40 @@ class MetaBase(pydantic.BaseModel):
|
|||||||
with open(file_path, "w") as f:
|
with open(file_path, "w") as f:
|
||||||
f.write(self.json())
|
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:
|
class Config:
|
||||||
allow_population_by_field_name = True
|
allow_population_by_field_name = True
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user