automated terminal push
This commit is contained in:
491
cdk-env/lib/python3.12/site-packages/jsii/_kernel/__init__.py
Normal file
491
cdk-env/lib/python3.12/site-packages/jsii/_kernel/__init__.py
Normal file
@@ -0,0 +1,491 @@
|
||||
import datetime
|
||||
import inspect
|
||||
import itertools
|
||||
from types import FunctionType, MethodType, BuiltinFunctionType, LambdaType
|
||||
|
||||
from typing import Callable, cast, Any, List, Optional, Sequence, Type
|
||||
|
||||
import functools
|
||||
|
||||
import attr
|
||||
import enum
|
||||
|
||||
from ..errors import JSIIError
|
||||
from .. import _reference_map
|
||||
from .._utils import Singleton
|
||||
from .providers import BaseProvider, ProcessProvider
|
||||
from .types import (
|
||||
EnumRef,
|
||||
LoadRequest,
|
||||
BeginRequest,
|
||||
BeginResponse,
|
||||
Callback,
|
||||
CallbacksRequest,
|
||||
CompleteRequest,
|
||||
CompleteRequest,
|
||||
CompleteResponse,
|
||||
CreateRequest,
|
||||
CreateResponse,
|
||||
DeleteRequest,
|
||||
EndRequest,
|
||||
EnumRef,
|
||||
GetRequest,
|
||||
GetResponse,
|
||||
InvokeRequest,
|
||||
InvokeResponse,
|
||||
GetScriptCommandRequest,
|
||||
GetScriptCommandResponse,
|
||||
InvokeScriptRequest,
|
||||
InvokeScriptResponse,
|
||||
KernelResponse,
|
||||
LoadRequest,
|
||||
ObjRef,
|
||||
Override,
|
||||
SetRequest,
|
||||
SetResponse,
|
||||
StaticGetRequest,
|
||||
StaticInvokeRequest,
|
||||
StaticSetRequest,
|
||||
StatsRequest,
|
||||
)
|
||||
from .._utils import Singleton
|
||||
|
||||
|
||||
_nothing = object()
|
||||
|
||||
|
||||
class Object:
|
||||
__jsii_type__ = "Object"
|
||||
|
||||
|
||||
def _get_overides(klass: Type, obj: Any) -> List[Override]:
|
||||
overrides: List[Override] = []
|
||||
|
||||
# We need to inspect each item in the MRO, until we get to our Type, at that
|
||||
# point we'll bail, because those methods are not the overriden methods, but the
|
||||
# "real" methods.
|
||||
jsii_name = getattr(klass, "__jsii_type__", "Object")
|
||||
jsii_classes = [
|
||||
next(
|
||||
(
|
||||
m
|
||||
for m in type(obj).mro()
|
||||
if getattr(m, "__jsii_declared_type__", None) == jsii_name
|
||||
),
|
||||
Object,
|
||||
)
|
||||
] + list(
|
||||
itertools.chain.from_iterable(
|
||||
(getattr(m, "__jsii_ifaces__", []) for m in type(obj).mro())
|
||||
)
|
||||
)
|
||||
for mro_klass in type(obj).mro():
|
||||
if getattr(mro_klass, "__jsii_declared_type__", None) is not None:
|
||||
# There is a jsii declared type, so we reached a "well known" object,
|
||||
# and nothing from now on is an override.
|
||||
break
|
||||
if mro_klass is Object or mro_klass is object:
|
||||
break
|
||||
|
||||
for name, item in mro_klass.__dict__.items():
|
||||
# Ignore all "special" members (name starting with __)...
|
||||
if name.startswith("__"):
|
||||
continue
|
||||
|
||||
# We're only interested in things that also exist on the JSII class or
|
||||
# interfaces, and which are themselves, jsii members.
|
||||
for jsii_class in jsii_classes:
|
||||
original = getattr(jsii_class, name, _nothing)
|
||||
if original is not _nothing:
|
||||
if inspect.isfunction(item) and hasattr(original, "__jsii_name__"):
|
||||
if any(
|
||||
entry.method == cast(Any, original).__jsii_name__
|
||||
for entry in overrides
|
||||
):
|
||||
# Don't re-register an override we already discovered through a previous type
|
||||
continue
|
||||
overrides.append(
|
||||
Override(
|
||||
method=cast(Any, original).__jsii_name__, cookie=name
|
||||
)
|
||||
)
|
||||
break
|
||||
elif inspect.isdatadescriptor(item) and hasattr(
|
||||
getattr(original, "fget", None), "__jsii_name__"
|
||||
):
|
||||
if any(
|
||||
entry.property == cast(Any, original).fget.__jsii_name__
|
||||
for entry in overrides
|
||||
):
|
||||
# Don't re-register an override we already discovered through a previous type
|
||||
continue
|
||||
overrides.append(
|
||||
Override(
|
||||
property=cast(Any, original).fget.__jsii_name__,
|
||||
cookie=name,
|
||||
)
|
||||
)
|
||||
break
|
||||
|
||||
return overrides
|
||||
|
||||
|
||||
def _recursize_dereference(kernel: "Kernel", d: Any) -> Any:
|
||||
if isinstance(d, dict):
|
||||
return {k: _recursize_dereference(kernel, v) for k, v in d.items()}
|
||||
elif isinstance(d, list):
|
||||
return [_recursize_dereference(kernel, i) for i in d]
|
||||
elif isinstance(d, ObjRef):
|
||||
return _reference_map.resolve_reference(kernel, d)
|
||||
elif isinstance(d, EnumRef):
|
||||
return _recursize_dereference(kernel, d.ref)(d.member)
|
||||
else:
|
||||
return d
|
||||
|
||||
|
||||
def _dereferenced(fn: Callable) -> Callable:
|
||||
@functools.wraps(fn)
|
||||
def wrapped(kernel: "Kernel", *args: Any, **kwargs: Any):
|
||||
return _recursize_dereference(kernel, fn(kernel, *args, **kwargs))
|
||||
|
||||
return wrapped
|
||||
|
||||
|
||||
# We need to recurse through our data structure and look for anything that the JSII
|
||||
# doesn't natively handle. These items will be created as "Object" types in the JSII.
|
||||
def _make_reference_for_native(kernel: "Kernel", d: Any) -> Any:
|
||||
if isinstance(d, dict):
|
||||
return {
|
||||
"$jsii.map": {
|
||||
k: _make_reference_for_native(kernel, v) for k, v in d.items()
|
||||
}
|
||||
}
|
||||
|
||||
elif isinstance(d, list):
|
||||
return [_make_reference_for_native(kernel, i) for i in d]
|
||||
|
||||
if getattr(d, "__jsii_type__", None) is not None:
|
||||
typeFqn = getattr(d, "__jsii_type__")
|
||||
|
||||
if isinstance(d, enum.Enum):
|
||||
return {"$jsii.enum": f"{typeFqn}/{d.value}"}
|
||||
|
||||
# Ugly delayed import here because I can't solve the cyclic
|
||||
# package dependency right now :(.
|
||||
from .._runtime import python_jsii_mapping
|
||||
|
||||
mapping = python_jsii_mapping(d)
|
||||
if mapping is not None: # This means we are handling a data_type (aka Struct)
|
||||
return {
|
||||
"$jsii.struct": {
|
||||
"fqn": typeFqn,
|
||||
"data": {
|
||||
jsii_name: _make_reference_for_native(
|
||||
kernel, getattr(d, python_name)
|
||||
)
|
||||
for python_name, jsii_name in mapping.items()
|
||||
},
|
||||
}
|
||||
}
|
||||
return d
|
||||
|
||||
elif isinstance(d, (int, type(None), str, float, bool, datetime.datetime)):
|
||||
return d
|
||||
|
||||
elif isinstance(d, (FunctionType, MethodType, BuiltinFunctionType, LambdaType)):
|
||||
# Whether a given object is a function-like object.
|
||||
# We won't use iscallable() since objects may implement __call__()
|
||||
# but we still want to serialize them as normal.
|
||||
raise JSIIError(
|
||||
"Cannot pass function as argument here (did you mean to call this function?): %r"
|
||||
% d
|
||||
)
|
||||
|
||||
else:
|
||||
kernel.create(d.__class__, d)
|
||||
_reference_map.register_reference(d)
|
||||
return d
|
||||
|
||||
|
||||
def _handle_callback(kernel: "Kernel", callback: Callback) -> Any:
|
||||
# need to handle get, set requests here as well as invoke requests
|
||||
if callback.invoke:
|
||||
obj = _reference_map.resolve_id(callback.invoke.objref.ref)
|
||||
method = getattr(obj, callback.cookie)
|
||||
hydrated_args = [
|
||||
_recursize_dereference(kernel, a) for a in callback.invoke.args or []
|
||||
]
|
||||
|
||||
# If keyword arguments are accepted, we may need to turn a struct into keywords...
|
||||
kwargs = {} # No keyword arguments by default
|
||||
params = inspect.signature(method).parameters
|
||||
params_kwargs = [
|
||||
name
|
||||
for (name, param) in params.items()
|
||||
if param.kind == inspect.Parameter.KEYWORD_ONLY
|
||||
]
|
||||
if len(params_kwargs) > 0:
|
||||
params_pos_count = len(
|
||||
[
|
||||
param
|
||||
for param in params.values()
|
||||
if param.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD
|
||||
or param.kind == inspect.Parameter.POSITIONAL_ONLY
|
||||
]
|
||||
)
|
||||
if len(hydrated_args) > params_pos_count:
|
||||
struct = hydrated_args.pop()
|
||||
kwargs = {
|
||||
name: getattr(struct, name)
|
||||
for name in params_kwargs
|
||||
if hasattr(struct, name)
|
||||
}
|
||||
|
||||
return method(*hydrated_args, **kwargs)
|
||||
elif callback.get:
|
||||
obj = _reference_map.resolve_id(callback.get.objref.ref)
|
||||
return getattr(obj, callback.cookie)
|
||||
elif callback.set:
|
||||
obj = _reference_map.resolve_id(callback.set.objref.ref)
|
||||
hydrated_value = _recursize_dereference(kernel, callback.set.value)
|
||||
return setattr(obj, callback.cookie, hydrated_value)
|
||||
else:
|
||||
raise JSIIError("Callback does not contain invoke|get|set")
|
||||
|
||||
|
||||
def _callback_till_result(
|
||||
kernel: "Kernel", response: Callback, response_type: Type[KernelResponse]
|
||||
) -> Any:
|
||||
while isinstance(response, Callback):
|
||||
try:
|
||||
result = _handle_callback(kernel, response)
|
||||
except Exception as exc:
|
||||
response = kernel.sync_complete(
|
||||
response.cbid, str(exc), None, response_type
|
||||
)
|
||||
else:
|
||||
response = kernel.sync_complete(response.cbid, None, result, response_type)
|
||||
|
||||
if isinstance(response, InvokeResponse):
|
||||
return response.result
|
||||
elif isinstance(response, GetResponse):
|
||||
return response.value
|
||||
else:
|
||||
return response
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class Statistics:
|
||||
object_count: int
|
||||
|
||||
|
||||
class Kernel(metaclass=Singleton):
|
||||
# This class translates between the Pythonic interface for the kernel, and the
|
||||
# Kernel Provider interface that maps more directly to the JSII Kernel interface.
|
||||
# It currently only supports the idea of a process kernel provider, however it
|
||||
# should be possible to move to other providers in the future.
|
||||
|
||||
# TODO: We don't currently have any error handling, but we need to. This should
|
||||
# probably live at the provider layer though, maybe with something catching
|
||||
# them at this layer to translate it to something more Pythonic, depending
|
||||
# on what the provider layer looks like.
|
||||
|
||||
def __init__(self, provider_class: Type[BaseProvider] = ProcessProvider) -> None:
|
||||
self.provider = provider_class()
|
||||
|
||||
# TODO: Do we want to return anything from this method? Is the return value useful
|
||||
# to anyone?
|
||||
def load(self, name: str, version: str, tarball: str) -> None:
|
||||
self.provider.load(LoadRequest(name=name, version=version, tarball=tarball))
|
||||
|
||||
def getBinScriptCommand(
|
||||
self, pkgname: str, script: str, args: Optional[Sequence[str]] = None
|
||||
) -> GetScriptCommandResponse:
|
||||
if args is None:
|
||||
args = []
|
||||
|
||||
return self.provider.getScriptCommand(
|
||||
GetScriptCommandRequest(
|
||||
assembly=pkgname,
|
||||
script=script,
|
||||
args=_make_reference_for_native(self, args),
|
||||
)
|
||||
)
|
||||
|
||||
def invokeBinScript(
|
||||
self, pkgname: str, script: str, args: Optional[Sequence[str]] = None
|
||||
) -> InvokeScriptResponse:
|
||||
if args is None:
|
||||
args = []
|
||||
|
||||
return self.provider.invokeBinScript(
|
||||
InvokeScriptRequest(
|
||||
assembly=pkgname,
|
||||
script=script,
|
||||
args=_make_reference_for_native(self, args),
|
||||
)
|
||||
)
|
||||
|
||||
# TODO: Is there a way to say that obj has to be an instance of klass?
|
||||
def create(self, klass: Type, obj: Any, args: Optional[List[Any]] = None) -> ObjRef:
|
||||
if args is None:
|
||||
args = []
|
||||
|
||||
response = self.provider.create(
|
||||
CreateRequest(
|
||||
fqn=klass.__jsii_type__ or "Object",
|
||||
args=_make_reference_for_native(self, args),
|
||||
overrides=_get_overides(klass, obj),
|
||||
interfaces=[
|
||||
iface.__jsii_type__
|
||||
for iface in getattr(klass, "__jsii_ifaces__", [])
|
||||
],
|
||||
)
|
||||
)
|
||||
if isinstance(response, Callback):
|
||||
obj.__jsii_ref__ = _callback_till_result(self, response, CreateResponse)
|
||||
else:
|
||||
obj.__jsii_ref__ = response
|
||||
|
||||
# Register this to the reference map already (so it's available within the rest of the __init__)
|
||||
_reference_map.register_reference(obj)
|
||||
|
||||
return obj.__jsii_ref__
|
||||
|
||||
def delete(self, ref: ObjRef) -> None:
|
||||
self.provider.delete(DeleteRequest(objref=ref))
|
||||
|
||||
@_dereferenced
|
||||
def get(self, obj: Any, property: str) -> Any:
|
||||
response = self.provider.get(
|
||||
GetRequest(objref=obj.__jsii_ref__, property=property)
|
||||
)
|
||||
if isinstance(response, Callback):
|
||||
return _callback_till_result(self, response, GetResponse)
|
||||
else:
|
||||
return response.value
|
||||
|
||||
def set(self, obj: Any, property: str, value: Any) -> None:
|
||||
response = self.provider.set(
|
||||
SetRequest(
|
||||
objref=obj.__jsii_ref__,
|
||||
property=property,
|
||||
value=_make_reference_for_native(self, value),
|
||||
)
|
||||
)
|
||||
if isinstance(response, Callback):
|
||||
_callback_till_result(self, response, SetResponse)
|
||||
|
||||
@_dereferenced
|
||||
def sget(self, klass: Type, property: str) -> Any:
|
||||
return self.provider.sget(
|
||||
StaticGetRequest(fqn=klass.__jsii_type__, property=property)
|
||||
).value
|
||||
|
||||
def sset(self, klass: Type, property: str, value: Any) -> None:
|
||||
self.provider.sset(
|
||||
StaticSetRequest(
|
||||
fqn=klass.__jsii_type__,
|
||||
property=property,
|
||||
value=_make_reference_for_native(self, value),
|
||||
)
|
||||
)
|
||||
|
||||
@_dereferenced
|
||||
def invoke(self, obj: Any, method: str, args: Optional[List[Any]] = None) -> Any:
|
||||
if args is None:
|
||||
args = []
|
||||
|
||||
response = self.provider.invoke(
|
||||
InvokeRequest(
|
||||
objref=obj.__jsii_ref__,
|
||||
method=method,
|
||||
args=_make_reference_for_native(self, args),
|
||||
)
|
||||
)
|
||||
if isinstance(response, Callback):
|
||||
return _callback_till_result(self, response, InvokeResponse)
|
||||
else:
|
||||
return response.result
|
||||
|
||||
@_dereferenced
|
||||
def sinvoke(
|
||||
self, klass: Type, method: str, args: Optional[List[Any]] = None
|
||||
) -> Any:
|
||||
if args is None:
|
||||
args = []
|
||||
|
||||
response = self.provider.sinvoke(
|
||||
StaticInvokeRequest(
|
||||
fqn=klass.__jsii_type__,
|
||||
method=method,
|
||||
args=_make_reference_for_native(self, args),
|
||||
)
|
||||
)
|
||||
if isinstance(response, Callback):
|
||||
return _callback_till_result(self, response, InvokeResponse)
|
||||
else:
|
||||
return response.result
|
||||
|
||||
@_dereferenced
|
||||
def complete(self, cbid: str, err: Optional[str], result: Any) -> Any:
|
||||
return self.provider.complete(
|
||||
CompleteRequest(
|
||||
cbid=cbid, err=err, result=_make_reference_for_native(self, result)
|
||||
)
|
||||
)
|
||||
|
||||
def sync_complete(
|
||||
self,
|
||||
cbid: str,
|
||||
err: Optional[str],
|
||||
result: Any,
|
||||
response_type: Type[KernelResponse],
|
||||
) -> Any:
|
||||
return self.provider.sync_complete(
|
||||
CompleteRequest(
|
||||
cbid=cbid, err=err, result=_make_reference_for_native(self, result)
|
||||
),
|
||||
response_type=response_type,
|
||||
)
|
||||
|
||||
@_dereferenced
|
||||
def ainvoke(self, obj: Any, method: str, args: Optional[List[Any]] = None) -> Any:
|
||||
if args is None:
|
||||
args = []
|
||||
|
||||
promise = self.provider.begin(
|
||||
BeginRequest(
|
||||
objref=obj.__jsii_ref__,
|
||||
method=method,
|
||||
args=_make_reference_for_native(self, args),
|
||||
)
|
||||
)
|
||||
if isinstance(promise, Callback):
|
||||
promise = _callback_till_result(self, promise, BeginResponse)
|
||||
|
||||
callbacks = self.provider.callbacks(CallbacksRequest()).callbacks
|
||||
while callbacks:
|
||||
for callback in callbacks:
|
||||
try:
|
||||
result = _handle_callback(self, callback)
|
||||
except Exception as exc:
|
||||
# TODO: Maybe we want to print the whole traceback here?
|
||||
complete = self.provider.complete(
|
||||
CompleteRequest(cbid=callback.cbid, err=str(exc))
|
||||
)
|
||||
else:
|
||||
complete = self.provider.complete(
|
||||
CompleteRequest(cbid=callback.cbid, result=result)
|
||||
)
|
||||
|
||||
assert complete.cbid == callback.cbid
|
||||
|
||||
callbacks = self.provider.callbacks(CallbacksRequest()).callbacks
|
||||
|
||||
return self.provider.end(EndRequest(promiseid=promise.promiseid)).result
|
||||
|
||||
def stats(self):
|
||||
resp = self.provider.stats(StatsRequest())
|
||||
|
||||
return Statistics(object_count=resp.objectCount)
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,5 @@
|
||||
from .base import BaseProvider
|
||||
from .process import ProcessProvider
|
||||
|
||||
|
||||
__all__ = ["BaseProvider", "ProcessProvider"]
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,100 @@
|
||||
import abc
|
||||
|
||||
from typing import Optional, Union, Type
|
||||
|
||||
from ..types import (
|
||||
LoadRequest,
|
||||
LoadResponse,
|
||||
CreateRequest,
|
||||
CreateResponse,
|
||||
GetRequest,
|
||||
GetResponse,
|
||||
InvokeRequest,
|
||||
InvokeResponse,
|
||||
GetScriptCommandRequest,
|
||||
GetScriptCommandResponse,
|
||||
InvokeScriptRequest,
|
||||
InvokeScriptResponse,
|
||||
DeleteRequest,
|
||||
DeleteResponse,
|
||||
SetRequest,
|
||||
SetResponse,
|
||||
StaticGetRequest,
|
||||
StaticInvokeRequest,
|
||||
StaticSetRequest,
|
||||
BeginRequest,
|
||||
BeginResponse,
|
||||
EndRequest,
|
||||
EndResponse,
|
||||
CallbacksRequest,
|
||||
CallbacksResponse,
|
||||
CompleteRequest,
|
||||
CompleteResponse,
|
||||
StatsRequest,
|
||||
StatsResponse,
|
||||
Callback,
|
||||
CompleteRequest,
|
||||
KernelResponse,
|
||||
)
|
||||
|
||||
|
||||
class BaseProvider(metaclass=abc.ABCMeta):
|
||||
# The API provided by this Provider is not very pythonic, however it is done to map
|
||||
# this API as closely to the JSII runtime as possible. Higher level abstractions
|
||||
# that layer ontop of the Provider will provide a translation layer that make this
|
||||
# much more Pythonic.
|
||||
|
||||
@abc.abstractmethod
|
||||
def load(self, request: LoadRequest) -> LoadResponse: ...
|
||||
|
||||
@abc.abstractmethod
|
||||
def getScriptCommand(
|
||||
self, request: GetScriptCommandRequest
|
||||
) -> GetScriptCommandResponse: ...
|
||||
|
||||
@abc.abstractmethod
|
||||
def invokeBinScript(self, request: InvokeScriptRequest) -> InvokeScriptResponse: ...
|
||||
|
||||
@abc.abstractmethod
|
||||
def create(self, request: CreateRequest) -> CreateResponse: ...
|
||||
|
||||
@abc.abstractmethod
|
||||
def get(self, request: GetRequest) -> GetResponse: ...
|
||||
|
||||
@abc.abstractmethod
|
||||
def set(self, request: SetRequest) -> SetResponse: ...
|
||||
|
||||
@abc.abstractmethod
|
||||
def sget(self, request: StaticGetRequest) -> GetResponse: ...
|
||||
|
||||
@abc.abstractmethod
|
||||
def sset(self, request: StaticSetRequest) -> SetResponse: ...
|
||||
|
||||
@abc.abstractmethod
|
||||
def invoke(self, request: InvokeRequest) -> Union[InvokeResponse, Callback]: ...
|
||||
|
||||
@abc.abstractmethod
|
||||
def sinvoke(self, request: StaticInvokeRequest) -> InvokeResponse: ...
|
||||
|
||||
@abc.abstractmethod
|
||||
def complete(self, request: CompleteRequest) -> CompleteResponse: ...
|
||||
|
||||
@abc.abstractmethod
|
||||
def sync_complete(
|
||||
self, request: CompleteRequest, response_type: Type[KernelResponse]
|
||||
) -> Union[InvokeResponse, GetResponse]: ...
|
||||
|
||||
@abc.abstractmethod
|
||||
def delete(self, request: DeleteRequest) -> DeleteResponse: ...
|
||||
|
||||
@abc.abstractmethod
|
||||
def begin(self, request: BeginRequest) -> BeginResponse: ...
|
||||
|
||||
@abc.abstractmethod
|
||||
def end(self, request: EndRequest) -> EndResponse: ...
|
||||
|
||||
@abc.abstractmethod
|
||||
def callbacks(self, request: CallbacksRequest) -> CallbacksResponse: ...
|
||||
|
||||
@abc.abstractmethod
|
||||
def stats(self, request: Optional[StatsRequest] = None) -> StatsResponse: ...
|
||||
@@ -0,0 +1,424 @@
|
||||
import atexit
|
||||
import base64
|
||||
import datetime
|
||||
import contextlib
|
||||
import enum
|
||||
import json
|
||||
import os
|
||||
import os.path
|
||||
import pathlib
|
||||
import platform
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import threading
|
||||
|
||||
from typing import TYPE_CHECKING, Type, Union, Mapping, IO, Any, AnyStr, Optional
|
||||
|
||||
import attr
|
||||
import cattr # type: ignore
|
||||
import dateutil.parser
|
||||
|
||||
import jsii._embedded.jsii
|
||||
|
||||
from ...__meta__ import __jsii_runtime_version__
|
||||
from ..._compat import importlib_resources
|
||||
from ..._utils import memoized_property
|
||||
from .base import BaseProvider
|
||||
from ..types import (
|
||||
ObjRef,
|
||||
EnumRef,
|
||||
Override,
|
||||
KernelRequest,
|
||||
KernelResponse,
|
||||
LoadRequest,
|
||||
LoadResponse,
|
||||
CreateRequest,
|
||||
CreateResponse,
|
||||
DeleteRequest,
|
||||
DeleteResponse,
|
||||
GetRequest,
|
||||
GetResponse,
|
||||
InvokeRequest,
|
||||
InvokeResponse,
|
||||
GetScriptCommandRequest,
|
||||
GetScriptCommandResponse,
|
||||
InvokeScriptRequest,
|
||||
InvokeScriptResponse,
|
||||
SetRequest,
|
||||
SetResponse,
|
||||
StaticGetRequest,
|
||||
StaticInvokeRequest,
|
||||
StaticSetRequest,
|
||||
BeginRequest,
|
||||
BeginResponse,
|
||||
EndRequest,
|
||||
EndResponse,
|
||||
CallbacksRequest,
|
||||
CallbacksResponse,
|
||||
CompleteRequest,
|
||||
CompleteResponse,
|
||||
StatsRequest,
|
||||
StatsResponse,
|
||||
Callback,
|
||||
CompleteRequest,
|
||||
CompleteResponse,
|
||||
)
|
||||
from ...errors import ErrorType, JSIIError, JavaScriptError
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class _HelloResponse:
|
||||
hello: str
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class _OkayResponse:
|
||||
# We could technically mark this as KernelResponse, because we know that
|
||||
# it is going to be one of those. However, we can't disambiguate the different
|
||||
# types because some of them have the same keys as each other, so the only way
|
||||
# to know what type the result is expected to be, is to know what method is
|
||||
# being called. Thus we'll expect Any here, and structure this value separately.
|
||||
ok: Any
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class _ErrorResponse:
|
||||
error: str
|
||||
stack: str
|
||||
name: str
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class _CallbackResponse:
|
||||
callback: Callback
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class _CompleteRequest:
|
||||
complete: CompleteRequest
|
||||
|
||||
|
||||
_ProcessResponse = Union[_OkayResponse, _ErrorResponse, _CallbackResponse]
|
||||
|
||||
|
||||
def _with_api_key(api_name, asdict):
|
||||
def unstructurer(value):
|
||||
unstructured = asdict(value)
|
||||
unstructured["api"] = api_name
|
||||
|
||||
return unstructured
|
||||
|
||||
return unstructurer
|
||||
|
||||
|
||||
def _with_reference(data, type_):
|
||||
if not isinstance(data, type_):
|
||||
return type_(ref=data.ref)
|
||||
return data
|
||||
|
||||
|
||||
def _unstructure_ref(value):
|
||||
return {"$jsii.byref": value.ref}
|
||||
|
||||
|
||||
def _unstructure_enum(member):
|
||||
return {"$jsii.enum": f"{member.__class__.__jsii_type__}/{member.value}"}
|
||||
|
||||
|
||||
def ohook(d):
|
||||
if d.keys() == {"$jsii.byref"} or d.keys() == {"$jsii.byref", "$jsii.interfaces"}:
|
||||
return ObjRef(ref=d["$jsii.byref"], interfaces=d.get("$jsii.interfaces"))
|
||||
if d.keys() == {"$jsii.date"}:
|
||||
return dateutil.parser.isoparse(d["$jsii.date"])
|
||||
if d.keys() == {"$jsii.enum"}:
|
||||
ref, member = d["$jsii.enum"].rsplit("/", 1)
|
||||
return EnumRef(ref=ObjRef(ref=ref + "@"), member=member)
|
||||
if d.keys() == {"$jsii.map"}:
|
||||
return d["$jsii.map"]
|
||||
return d
|
||||
|
||||
|
||||
def jdefault(obj):
|
||||
if hasattr(obj, "__jsii_ref__"):
|
||||
return _unstructure_ref(obj.__jsii_ref__)
|
||||
if isinstance(obj, datetime.datetime) and obj.tzinfo is not None:
|
||||
return {"$jsii.date": obj.isoformat()}
|
||||
elif isinstance(obj, datetime.datetime):
|
||||
raise TypeError("Naive datetimes are not supported, please add a timzone.")
|
||||
raise TypeError("Don't know how to convert object to JSON: %r" % obj)
|
||||
|
||||
|
||||
class _NodeProcess:
|
||||
def __init__(self):
|
||||
self._serializer = cattr.Converter()
|
||||
self._serializer.register_unstructure_hook(enum.Enum, _unstructure_enum)
|
||||
self._serializer.register_unstructure_hook(
|
||||
LoadRequest,
|
||||
_with_api_key("load", self._serializer.unstructure_attrs_asdict),
|
||||
)
|
||||
self._serializer.register_unstructure_hook(
|
||||
GetScriptCommandRequest,
|
||||
_with_api_key(
|
||||
"getBinScriptCommand", self._serializer.unstructure_attrs_asdict
|
||||
),
|
||||
)
|
||||
self._serializer.register_unstructure_hook(
|
||||
InvokeScriptRequest,
|
||||
_with_api_key("invokeBinScript", self._serializer.unstructure_attrs_asdict),
|
||||
)
|
||||
self._serializer.register_unstructure_hook(
|
||||
CreateRequest,
|
||||
_with_api_key("create", self._serializer.unstructure_attrs_asdict),
|
||||
)
|
||||
self._serializer.register_unstructure_hook(
|
||||
DeleteRequest,
|
||||
_with_api_key("del", self._serializer.unstructure_attrs_asdict),
|
||||
)
|
||||
self._serializer.register_unstructure_hook(
|
||||
GetRequest, _with_api_key("get", self._serializer.unstructure_attrs_asdict)
|
||||
)
|
||||
self._serializer.register_unstructure_hook(
|
||||
StaticGetRequest,
|
||||
_with_api_key("sget", self._serializer.unstructure_attrs_asdict),
|
||||
)
|
||||
self._serializer.register_unstructure_hook(
|
||||
SetRequest, _with_api_key("set", self._serializer.unstructure_attrs_asdict)
|
||||
)
|
||||
self._serializer.register_unstructure_hook(
|
||||
StaticSetRequest,
|
||||
_with_api_key("sset", self._serializer.unstructure_attrs_asdict),
|
||||
)
|
||||
self._serializer.register_unstructure_hook(
|
||||
InvokeRequest,
|
||||
_with_api_key("invoke", self._serializer.unstructure_attrs_asdict),
|
||||
)
|
||||
self._serializer.register_unstructure_hook(
|
||||
StaticInvokeRequest,
|
||||
_with_api_key("sinvoke", self._serializer.unstructure_attrs_asdict),
|
||||
)
|
||||
self._serializer.register_unstructure_hook(
|
||||
BeginRequest,
|
||||
_with_api_key("begin", self._serializer.unstructure_attrs_asdict),
|
||||
)
|
||||
self._serializer.register_unstructure_hook(
|
||||
EndRequest, _with_api_key("end", self._serializer.unstructure_attrs_asdict)
|
||||
)
|
||||
self._serializer.register_unstructure_hook(
|
||||
CallbacksRequest,
|
||||
_with_api_key("callbacks", self._serializer.unstructure_attrs_asdict),
|
||||
)
|
||||
self._serializer.register_unstructure_hook(
|
||||
CompleteRequest,
|
||||
_with_api_key("complete", self._serializer.unstructure_attrs_asdict),
|
||||
)
|
||||
self._serializer.register_unstructure_hook(
|
||||
StatsRequest,
|
||||
_with_api_key("stats", self._serializer.unstructure_attrs_asdict),
|
||||
)
|
||||
self._serializer.register_unstructure_hook(
|
||||
Override, self._serializer.unstructure_attrs_asdict
|
||||
)
|
||||
self._serializer.register_unstructure_hook(ObjRef, _unstructure_ref)
|
||||
self._serializer.register_structure_hook(ObjRef, _with_reference)
|
||||
|
||||
self._ctx_stack = contextlib.ExitStack()
|
||||
|
||||
def __del__(self):
|
||||
self.stop()
|
||||
|
||||
def _jsii_runtime(self) -> str:
|
||||
tmpdir = self._ctx_stack.enter_context(tempfile.TemporaryDirectory())
|
||||
resources = {
|
||||
resname: os.path.join(tmpdir, filename.replace("/", os.sep))
|
||||
for resname, filename in jsii._embedded.jsii.EMBEDDED_FILES.items()
|
||||
}
|
||||
|
||||
for resname, filename in resources.items():
|
||||
pathlib.Path(os.path.dirname(filename)).mkdir(exist_ok=True)
|
||||
with open(filename, "wb") as fp:
|
||||
fp.write(
|
||||
importlib_resources.files(jsii._embedded.jsii)
|
||||
.joinpath(resname)
|
||||
.read_bytes()
|
||||
)
|
||||
|
||||
# Return our first path, which should be the path for jsii-runtime.js
|
||||
return resources[jsii._embedded.jsii.ENTRYPOINT]
|
||||
|
||||
def _next_message(self) -> Mapping[Any, Any]:
|
||||
assert self._process.stdout is not None
|
||||
return json.loads(self._process.stdout.readline(), object_hook=ohook)
|
||||
|
||||
def start(self):
|
||||
environ = os.environ.copy()
|
||||
environ["JSII_AGENT"] = f"Python/{platform.python_version()}"
|
||||
|
||||
jsii_node = environ.get("JSII_NODE", "node")
|
||||
jsii_runtime = environ.get("JSII_RUNTIME", self._jsii_runtime())
|
||||
|
||||
self._process = subprocess.Popen(
|
||||
[
|
||||
jsii_node,
|
||||
"--max-old-space-size=4069",
|
||||
jsii_runtime,
|
||||
],
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
env=environ,
|
||||
)
|
||||
|
||||
self.sink_thread = threading.Thread(
|
||||
name="process.stderr_sink",
|
||||
target=stderr_sink,
|
||||
# Trailing comma here is important (this is a 1-value tuple, not a value between parentheses)
|
||||
args=(self._process.stderr,),
|
||||
# Thread is a daemon so it does not hold the VM from shutting down
|
||||
daemon=True,
|
||||
)
|
||||
self.sink_thread.start()
|
||||
|
||||
# Clean this process up at exit, so it terminates "gracefully"
|
||||
atexit.register(self.stop)
|
||||
|
||||
self.handshake()
|
||||
|
||||
def stop(self) -> None:
|
||||
# This process is closing already, un-registering the hook to not fire twice
|
||||
atexit.unregister(self.stop)
|
||||
|
||||
assert self._process.stdin is not None
|
||||
if not self._process.stdin.closed:
|
||||
self._process.stdin.write(b'{"exit":0}\n')
|
||||
# Close the process' STDIN, singaling we are done with it
|
||||
self._process.stdin.close()
|
||||
|
||||
try:
|
||||
self._process.wait(timeout=5)
|
||||
except subprocess.TimeoutExpired:
|
||||
self._process.terminate()
|
||||
|
||||
if self.sink_thread.is_alive():
|
||||
self.sink_thread.join(timeout=5)
|
||||
|
||||
self._ctx_stack.close()
|
||||
|
||||
def handshake(self) -> None:
|
||||
# Get the version of the runtime that we're using.
|
||||
resp: _HelloResponse = self._serializer.structure(
|
||||
self._next_message(), _HelloResponse
|
||||
)
|
||||
|
||||
# TODO: Replace with proper error.
|
||||
assert (
|
||||
resp.hello == f"@jsii/runtime@{__jsii_runtime_version__}"
|
||||
# Transparently allow development versions of the runtime to be used.
|
||||
or resp.hello == f"@jsii/runtime@0.0.0"
|
||||
), f"Invalid JSII Runtime Version: {resp.hello!r}"
|
||||
|
||||
def send(
|
||||
self, request: KernelRequest, response_type: Type[KernelResponse]
|
||||
) -> KernelResponse:
|
||||
req_dict = self._serializer.unstructure(request)
|
||||
data = json.dumps(req_dict, default=jdefault).encode("utf8")
|
||||
|
||||
# Send our data, ensure that it is framed with a trailing \n
|
||||
assert self._process.stdin is not None
|
||||
self._process.stdin.write(b"%b\n" % (data,))
|
||||
self._process.stdin.flush()
|
||||
|
||||
resp: _ProcessResponse = self._serializer.structure(
|
||||
self._next_message(), _ProcessResponse
|
||||
)
|
||||
|
||||
if isinstance(resp, _OkayResponse):
|
||||
return self._serializer.structure(resp.ok, response_type)
|
||||
elif isinstance(resp, _CallbackResponse):
|
||||
return resp.callback
|
||||
else:
|
||||
if resp.name == ErrorType.JSII_FAULT.value:
|
||||
raise JSIIError(resp.error) from JavaScriptError(resp.stack)
|
||||
raise RuntimeError(resp.error) from JavaScriptError(resp.stack)
|
||||
|
||||
|
||||
class ProcessProvider(BaseProvider):
|
||||
@memoized_property
|
||||
def _process(self) -> _NodeProcess:
|
||||
process = _NodeProcess()
|
||||
process.start()
|
||||
|
||||
return process
|
||||
|
||||
def load(self, request: LoadRequest) -> LoadResponse:
|
||||
return self._process.send(request, LoadResponse)
|
||||
|
||||
def getScriptCommand(
|
||||
self, request: GetScriptCommandRequest
|
||||
) -> GetScriptCommandResponse:
|
||||
return self._process.send(request, GetScriptCommandResponse)
|
||||
|
||||
def invokeBinScript(self, request: InvokeScriptRequest) -> InvokeScriptResponse:
|
||||
return self._process.send(request, InvokeScriptResponse)
|
||||
|
||||
def create(self, request: CreateRequest) -> CreateResponse:
|
||||
return self._process.send(request, CreateResponse)
|
||||
|
||||
def get(self, request: GetRequest) -> GetResponse:
|
||||
return self._process.send(request, GetResponse)
|
||||
|
||||
def set(self, request: SetRequest) -> SetResponse:
|
||||
return self._process.send(request, SetResponse)
|
||||
|
||||
def sget(self, request: StaticGetRequest) -> GetResponse:
|
||||
return self._process.send(request, GetResponse)
|
||||
|
||||
def sset(self, request: StaticSetRequest) -> SetResponse:
|
||||
return self._process.send(request, SetResponse)
|
||||
|
||||
def invoke(self, request: InvokeRequest) -> Union[InvokeResponse, Callback]:
|
||||
return self._process.send(request, InvokeResponse)
|
||||
|
||||
def sinvoke(self, request: StaticInvokeRequest) -> InvokeResponse:
|
||||
return self._process.send(request, InvokeResponse)
|
||||
|
||||
def delete(self, request: DeleteRequest) -> DeleteResponse:
|
||||
return self._process.send(request, DeleteResponse)
|
||||
|
||||
def begin(self, request: BeginRequest) -> BeginResponse:
|
||||
return self._process.send(request, BeginResponse)
|
||||
|
||||
def end(self, request: EndRequest) -> EndResponse:
|
||||
return self._process.send(request, EndResponse)
|
||||
|
||||
def callbacks(self, request: CallbacksRequest) -> CallbacksResponse:
|
||||
return self._process.send(request, CallbacksResponse)
|
||||
|
||||
def complete(self, request: CompleteRequest) -> CompleteResponse:
|
||||
return self._process.send(request, CompleteResponse)
|
||||
|
||||
def sync_complete(
|
||||
self, request: CompleteRequest, response_type: Type[KernelResponse]
|
||||
) -> Union[InvokeResponse, GetResponse]:
|
||||
resp = self._process.send(_CompleteRequest(complete=request), response_type)
|
||||
return resp
|
||||
|
||||
def stats(self, request: Optional[StatsRequest] = None) -> StatsResponse:
|
||||
if request is None:
|
||||
request = StatsRequest()
|
||||
return self._process.send(request, StatsResponse)
|
||||
|
||||
|
||||
def stderr_sink(reader: IO[AnyStr]) -> None:
|
||||
# An empty string is used to signal EOF...
|
||||
for line in iter(reader.readline, b""):
|
||||
if line == b"":
|
||||
break
|
||||
try:
|
||||
console = json.loads(line)
|
||||
if console.get("stderr") is not None:
|
||||
sys.stderr.buffer.write(base64.b64decode(console["stderr"]))
|
||||
if console.get("stdout") is not None:
|
||||
sys.stdout.buffer.write(base64.b64decode(console["stdout"]))
|
||||
except:
|
||||
print(line, file=sys.stderr)
|
||||
238
cdk-env/lib/python3.12/site-packages/jsii/_kernel/types.py
Normal file
238
cdk-env/lib/python3.12/site-packages/jsii/_kernel/types.py
Normal file
@@ -0,0 +1,238 @@
|
||||
from typing import Any, Dict, Generic, List, Optional, Mapping, TypeVar, Union
|
||||
from typing_extensions import Protocol
|
||||
|
||||
import attr
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class ObjRef:
|
||||
ref: str
|
||||
interfaces: Optional[List[str]] = None
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class EnumRef:
|
||||
ref: ObjRef
|
||||
member: str
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class Override:
|
||||
method: Optional[str] = None
|
||||
property: Optional[str] = None
|
||||
cookie: Optional[str] = None
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class LoadRequest:
|
||||
name: str
|
||||
version: str
|
||||
tarball: str
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class LoadResponse:
|
||||
assembly: str
|
||||
types: int
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class GetScriptCommandRequest:
|
||||
assembly: str
|
||||
script: str
|
||||
args: List[Any] = attr.Factory(list)
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class GetScriptCommandResponse:
|
||||
command: str
|
||||
args: List[str] = attr.Factory(list)
|
||||
env: Dict[str, str] = attr.Factory(dict)
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class InvokeScriptRequest:
|
||||
assembly: str
|
||||
script: str
|
||||
args: List[Any] = attr.Factory(list)
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class InvokeScriptResponse:
|
||||
status: int
|
||||
stdout: str
|
||||
stderr: str
|
||||
signal: str
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class CreateRequest:
|
||||
fqn: str
|
||||
args: List[Any] = attr.Factory(list)
|
||||
overrides: List[Override] = attr.Factory(list)
|
||||
interfaces: Optional[List[str]] = None
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class CreateResponse(ObjRef): ...
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class DeleteRequest:
|
||||
objref: ObjRef
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class DeleteResponse: ...
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class GetRequest:
|
||||
objref: ObjRef
|
||||
property: str
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class StaticGetRequest:
|
||||
fqn: str
|
||||
property: str
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class GetResponse:
|
||||
value: Any = None
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class StaticSetRequest:
|
||||
fqn: str
|
||||
property: str
|
||||
value: str
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class SetRequest:
|
||||
objref: ObjRef
|
||||
property: str
|
||||
value: Any
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class SetResponse: ...
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class StaticInvokeRequest:
|
||||
fqn: str
|
||||
method: str
|
||||
args: Optional[List[Any]] = attr.Factory(list)
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class InvokeRequest:
|
||||
objref: ObjRef
|
||||
method: str
|
||||
args: Optional[List[Any]] = attr.Factory(list)
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class InvokeResponse:
|
||||
result: Any = None
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class BeginRequest:
|
||||
objref: ObjRef
|
||||
method: str
|
||||
args: Optional[List[Any]] = attr.Factory(list)
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class BeginResponse:
|
||||
promiseid: str
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class EndRequest:
|
||||
promiseid: str
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class EndResponse:
|
||||
result: Optional[Any] = None
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class Callback:
|
||||
cbid: str
|
||||
cookie: str
|
||||
invoke: Optional[InvokeRequest] = None
|
||||
get: Optional[GetRequest] = None
|
||||
set: Optional[SetRequest] = None
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class CallbacksRequest: ...
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class CallbacksResponse:
|
||||
callbacks: List[Callback]
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class CompleteRequest:
|
||||
cbid: str
|
||||
err: Optional[str] = None
|
||||
result: Optional[Any] = None
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class CompleteResponse:
|
||||
cbid: str
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class NamingRequest:
|
||||
assembly: str
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class NamingResponse:
|
||||
naming: Mapping[str, Mapping[str, Optional[Any]]]
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class StatsRequest: ...
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True, frozen=True, slots=True)
|
||||
class StatsResponse:
|
||||
objectCount: int
|
||||
|
||||
|
||||
KernelRequest = Union[
|
||||
LoadRequest,
|
||||
CreateRequest,
|
||||
DeleteRequest,
|
||||
GetRequest,
|
||||
SetRequest,
|
||||
StaticGetRequest,
|
||||
InvokeRequest,
|
||||
InvokeScriptRequest,
|
||||
StaticInvokeRequest,
|
||||
StatsRequest,
|
||||
]
|
||||
|
||||
KernelResponse = Union[
|
||||
BeginResponse,
|
||||
LoadResponse,
|
||||
CreateResponse,
|
||||
DeleteResponse,
|
||||
GetResponse,
|
||||
InvokeResponse,
|
||||
InvokeScriptResponse,
|
||||
SetResponse,
|
||||
StatsResponse,
|
||||
Callback,
|
||||
]
|
||||
Reference in New Issue
Block a user