-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cannot froze a subclass #223
Comments
The root problem is you're calling the super of Then you're run into a recursion issue if you always try to set values via the super You probably want something more like: from box import Box
class toto(Box):
def __init__(self, *args, **kwargs):
super().__init__(*args, frozen_box=kwargs.pop("frozen_box", True), **kwargs)
truc = toto({"valeur": "me"}, frozen_box=True)
truc.valeur = "toto" # box.exceptions.BoxError: Box is frozen |
Thank you very much. So let's expand a bit my question. My final goal is to create a translator object. The user should simply provide a language and I programmatically fetch and sanitize the dictionary before serving it as a Box of Box, that's why I'm interested in using a subclass that does not expose modifying your small example I can do this : class toto(Box):
def __init__(self, valeur):
dict_ = {"valeur": "me"}
super().__init__(dict_, frozen_box=True) which work as expected. When I try to expand it to my real Translator object on the other end I get the foollowing error:
Do you have any clue where it's coming from ? super(Box, self).__init__(dict(**private_keys, **ms_boxes), frozen_box=True) It works but the "root" box is not frozen here is the skeleton of the class to help you understand what I try to do : class Translator(Box):
"""
The translator is a Python Box of boxes. It reads 2 Json files, the first one being the source language (usually English) and the second one the target language.
It will replace in the source dictionary every key that exist in both json dictionaries. Following this procedure, every message that is not translated can still be accessed in the source language.
To access the dictionary keys, instead of using [], you can simply use key name as in an object ex: translator.first_key.secondary_key.
There are no depth limits, just respect the snake_case convention when naming your keys in the .json files.
5 internal keys are created upon initialization (there name cannot be used as keys in the translation message):
- (str) _default : the default locale of the translator
- (str) _targeted : the initially requested language. Use to display debug information to the user agent
- (str) _target : the target locale of the translator
- (bool) _match : if the target language match the one requested one by user, used to trigger information in appBar
- (str) _folder : the path to the l10n folder
Args:
json_folder (str | pathlib.Path): The folder where the dictionaries are stored
target (str, optional): The language code (IETF BCP 47) of the target lang (it should be the same as the target dictionary). Default to either the language specified in the parameter file or the default one.
default (str, optional): The language code (IETF BCP 47) of the source lang. default to "en" (it should be the same as the source dictionary)
"""
_protected_keys = ["find_target", "search_key", "sanitize", "_update", "missing_keys", "available_locales", "merge_dict", "delete_empty"] + dir(Box)
"keys that cannot be used as var names as they are protected for methods"
def __init__(self, json_folder, target=None, default="en"):
# the name of the 5 variables that cannot be used as init keys
FORBIDDEN_KEYS = ["_folder", "_default", "_target", "_targeted", "_match"]
# init the box with the folder
folder = Path(json_folder)
# reading the default dict
default_dict = self.merge_dict(folder / default)
# create a dictionary in the target language
targeted, target = self.find_target(folder, target)
target = target or default
target_dict = self.merge_dict(folder / target)
# evaluate the matching of requested and obtained values
match = targeted == target
# create the composite dictionary
ms_dict = self._update(default_dict, target_dict)
# check if forbidden keys are being used, this will raise an error if any
[self.search_key(ms_dict, k) for k in FORBIDDEN_KEYS]
# unpack the dict as encaplsulated Boxes
ms_json = json.dumps(ms_dict)
ms_boxes = json.loads(ms_json, object_hook=lambda d: Box(**d, frozen_box=True))
private_keys = {"_folder": str(folder),"_default": default,"_targeted": targeted,"_target": target,"_match": match}
super().__init__(dict(**private_keys, **ms_boxes), frozen_box=True) |
There are several points within the box itself it may have to recreate a new instance of the same class and pass down the current set of settings, so you will always have to accept |
I tried the following:
and now I have a Path error:
Digging into it, it seems that init is launched twice and the second time |
To continue on my previous issue, I would like to froze a sublcass but I can't manage to make it work. As you manage to make it work in
BoxList
what am I missing ?The text was updated successfully, but these errors were encountered: