Transcrypt: pass client side JS object as dict?

I have a class definition that starts like below.

class Ace11():
    def __init__(self, register_list):
        """
        Parse and validate the list of dicts.
        """
        self.required_keys = """
            briefdescription defaultvalue flatname rnum rtype where
            """.strip().split()
        self.registers = register_list
        ## Validate
        for d in self.registers:
            if not isinstance(d, dict):
                raise TypeError("{d} is not a dict.".format(**locals()))

            for k in self.required_keys:
                if not k in d.keys():
                    raise ValueError("Key {k} missing from {d}"
                                     .format(**locals()))

      

When I try to instantiate client-side using a var containing an array of objects, the TypeError is thrown, presumably because isinstance is very literal about what a dict is and what is not. I would like to keep validation because the same code is useful on the server side.

What is the correct way to handle this?

+3


source to share


1 answer


The problem is that JS objects are by nature not complete dicts, they miss a number of methods. But they can be converted to dicts by the constructor dict ()

. This is very fast as no data is copied, only the prototype is modified to include the required dict methods.

Of course, the method isinstance

can be changed to return True to isinstance (<anyJsObject>, dict)

. But that would make it impossible to distinguish between dict and object. Therefore, methods can be called by things that the object does not have. This beats the purpose of the typecheck type.

Since you want the code on the server and client to be identical, you could convert the JS objects to yours register_list

in a dict before calling.

But validation will no longer make sense (at least on the client), since all elements register_list

will certainly be determined in this case.



So, you can just leave a check, but you say you want to keep the check.

A more sophisticated alternative is to use the same source code, but do one kind of check for Transcrypt and another type for CPython:

from org.transcrypt.stubs.browser import __envir__

if __envir__.executor_name == __envir__.transpiler_name:
    <do Transcrypt validation and, possibly, conversion, or nothing at all>
else:
    <do CPython validation>

      

You can, for example, in Transcrypt, check that something is a JS object and then convert it to a dict by calling its dict constructor.

+4


source







All Articles