mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-28 20:14:45 +00:00
fix: incorrect typing & method resolution
This commit is contained in:
parent
21caf6fe7e
commit
a129141234
6 changed files with 178 additions and 79 deletions
|
@ -87,6 +87,13 @@ impl Context {
|
||||||
Some(FUNDAMENTAL_FORMAT),
|
Some(FUNDAMENTAL_FORMAT),
|
||||||
14,
|
14,
|
||||||
);
|
);
|
||||||
|
obj.register_builtin_py_impl(
|
||||||
|
FUNDAMENTAL_CALL,
|
||||||
|
func0(Obj),
|
||||||
|
Immutable,
|
||||||
|
Visibility::BUILTIN_PUBLIC,
|
||||||
|
Some(FUNDAMENTAL_CALL),
|
||||||
|
);
|
||||||
// Obj does not implement Eq
|
// Obj does not implement Eq
|
||||||
let mut complex = Self::builtin_mono_class(COMPLEX, 2);
|
let mut complex = Self::builtin_mono_class(COMPLEX, 2);
|
||||||
complex.register_superclass(Obj, &obj);
|
complex.register_superclass(Obj, &obj);
|
||||||
|
|
|
@ -351,8 +351,8 @@ impl Context {
|
||||||
)
|
)
|
||||||
.quantify();
|
.quantify();
|
||||||
let t_slice = no_var_func(
|
let t_slice = no_var_func(
|
||||||
vec![kw(KW_START, Int)],
|
vec![kw(KW_START, Int | NoneType)],
|
||||||
vec![kw(KW_STOP, Int), kw(KW_STEP, Int)],
|
vec![kw(KW_STOP, Int | NoneType), kw(KW_STEP, Int | NoneType)],
|
||||||
mono(SLICE),
|
mono(SLICE),
|
||||||
);
|
);
|
||||||
let t_sorted = nd_func(
|
let t_sorted = nd_func(
|
||||||
|
@ -975,6 +975,40 @@ impl Context {
|
||||||
Visibility::BUILTIN_PUBLIC,
|
Visibility::BUILTIN_PUBLIC,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
let t_exec = func(
|
||||||
|
vec![kw(KW_CODE, Str)],
|
||||||
|
None,
|
||||||
|
vec![
|
||||||
|
kw(KW_GLOBALS, mono(GENERIC_DICT)),
|
||||||
|
kw(KW_LOCALS, mono(GENERIC_DICT)),
|
||||||
|
],
|
||||||
|
None,
|
||||||
|
NoneType,
|
||||||
|
);
|
||||||
|
self.register_builtin_py_impl(
|
||||||
|
FUNC_EXEC,
|
||||||
|
t_exec,
|
||||||
|
Immutable,
|
||||||
|
Visibility::BUILTIN_PUBLIC,
|
||||||
|
Some(FUNC_EXEC),
|
||||||
|
);
|
||||||
|
let t_eval = func(
|
||||||
|
vec![kw(KW_CODE, Str)],
|
||||||
|
None,
|
||||||
|
vec![
|
||||||
|
kw(KW_GLOBALS, mono(GENERIC_DICT)),
|
||||||
|
kw(KW_LOCALS, mono(GENERIC_DICT)),
|
||||||
|
],
|
||||||
|
None,
|
||||||
|
NoneType,
|
||||||
|
);
|
||||||
|
self.register_builtin_py_impl(
|
||||||
|
FUNC_EVAL,
|
||||||
|
t_eval,
|
||||||
|
Immutable,
|
||||||
|
Visibility::BUILTIN_PUBLIC,
|
||||||
|
Some(FUNC_EVAL),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn init_builtin_operators(&mut self) {
|
pub(super) fn init_builtin_operators(&mut self) {
|
||||||
|
|
|
@ -547,6 +547,8 @@ const FUNC_HASATTR: &str = "hasattr";
|
||||||
const FUNC_GETATTR: &str = "getattr";
|
const FUNC_GETATTR: &str = "getattr";
|
||||||
const FUNC_SETATTR: &str = "setattr";
|
const FUNC_SETATTR: &str = "setattr";
|
||||||
const FUNC_DELATTR: &str = "delattr";
|
const FUNC_DELATTR: &str = "delattr";
|
||||||
|
const FUNC_EXEC: &str = "exec";
|
||||||
|
const FUNC_EVAL: &str = "eval";
|
||||||
const FUNC_NEARLY_EQ: &str = "nearly_eq";
|
const FUNC_NEARLY_EQ: &str = "nearly_eq";
|
||||||
const FUNC_RESOLVE_PATH: &str = "ResolvePath";
|
const FUNC_RESOLVE_PATH: &str = "ResolvePath";
|
||||||
const FUNC_RESOLVE_DECL_PATH: &str = "ResolveDeclPath";
|
const FUNC_RESOLVE_DECL_PATH: &str = "ResolveDeclPath";
|
||||||
|
@ -732,6 +734,8 @@ const KW_NUMBER: &str = "number";
|
||||||
const KW_ITERABLE1: &str = "iterable1";
|
const KW_ITERABLE1: &str = "iterable1";
|
||||||
const KW_ITERABLE2: &str = "iterable2";
|
const KW_ITERABLE2: &str = "iterable2";
|
||||||
const KW_CODE: &str = "code";
|
const KW_CODE: &str = "code";
|
||||||
|
const KW_GLOBALS: &str = "globals";
|
||||||
|
const KW_LOCALS: &str = "locals";
|
||||||
const KW_STOP: &str = "stop";
|
const KW_STOP: &str = "stop";
|
||||||
const KW_STEP: &str = "step";
|
const KW_STEP: &str = "step";
|
||||||
const KW_REQUIREMENT: &str = "Requirement";
|
const KW_REQUIREMENT: &str = "Requirement";
|
||||||
|
|
|
@ -273,6 +273,11 @@ impl Context {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ```erg
|
||||||
|
/// get_singular_ctxs_by_hir_expr(1) == Err
|
||||||
|
/// get_singular_ctxs_by_hir_expr(Int) == [<type Int>, <type Type>, ...]
|
||||||
|
/// get_singular_ctxs_by_hir_expr(math) == [<module math>]
|
||||||
|
/// ```
|
||||||
pub fn get_singular_ctxs_by_hir_expr(
|
pub fn get_singular_ctxs_by_hir_expr(
|
||||||
&self,
|
&self,
|
||||||
obj: &hir::Expr,
|
obj: &hir::Expr,
|
||||||
|
@ -1342,6 +1347,20 @@ impl Context {
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
if let Ok(singular_ctxs) = self.get_singular_ctxs_by_hir_expr(obj, namespace) {
|
||||||
|
for ctx in singular_ctxs {
|
||||||
|
if let Some(vi) = ctx.get_current_scope_non_param(&attr_name.name) {
|
||||||
|
self.validate_visibility(attr_name, vi, input, namespace)?;
|
||||||
|
return Ok(vi.clone());
|
||||||
|
}
|
||||||
|
for method_ctx in ctx.methods_list.iter() {
|
||||||
|
if let Some(vi) = method_ctx.get_current_scope_non_param(&attr_name.name) {
|
||||||
|
self.validate_visibility(attr_name, vi, input, namespace)?;
|
||||||
|
return Ok(vi.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
for ctx in self
|
for ctx in self
|
||||||
.get_nominal_super_type_ctxs(obj.ref_t())
|
.get_nominal_super_type_ctxs(obj.ref_t())
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
|
@ -1376,30 +1395,6 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Ok(singular_ctxs) = self.get_singular_ctxs_by_hir_expr(obj, namespace) {
|
|
||||||
for ctx in singular_ctxs {
|
|
||||||
if let Some(vi) = ctx.get_current_scope_non_param(&attr_name.name) {
|
|
||||||
self.validate_visibility(attr_name, vi, input, namespace)?;
|
|
||||||
return Ok(vi.clone());
|
|
||||||
}
|
|
||||||
for method_ctx in ctx.methods_list.iter() {
|
|
||||||
if let Some(vi) = method_ctx.get_current_scope_non_param(&attr_name.name) {
|
|
||||||
self.validate_visibility(attr_name, vi, input, namespace)?;
|
|
||||||
return Ok(vi.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Err(TyCheckError::singular_no_attr_error(
|
|
||||||
self.cfg.input.clone(),
|
|
||||||
line!() as usize,
|
|
||||||
attr_name.loc(),
|
|
||||||
namespace.name.to_string(),
|
|
||||||
obj.qual_name().as_deref().unwrap_or("?"),
|
|
||||||
obj.ref_t(),
|
|
||||||
attr_name.inspect(),
|
|
||||||
self.get_similar_attr_from_singular(obj, attr_name.inspect()),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
match self.get_attr_type_by_name(obj, attr_name, namespace) {
|
match self.get_attr_type_by_name(obj, attr_name, namespace) {
|
||||||
Triple::Ok(method) => {
|
Triple::Ok(method) => {
|
||||||
let def_t = self
|
let def_t = self
|
||||||
|
@ -1436,7 +1431,7 @@ impl Context {
|
||||||
);
|
);
|
||||||
return Ok(vi);
|
return Ok(vi);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
for patch in self.find_patches_of(obj.ref_t()) {
|
for patch in self.find_patches_of(obj.ref_t()) {
|
||||||
if let Some(vi) = patch.get_current_scope_non_param(&attr_name.name) {
|
if let Some(vi) = patch.get_current_scope_non_param(&attr_name.name) {
|
||||||
self.validate_visibility(attr_name, vi, input, namespace)?;
|
self.validate_visibility(attr_name, vi, input, namespace)?;
|
||||||
|
@ -1449,6 +1444,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
let coerced = self
|
let coerced = self
|
||||||
.coerce(obj.t(), &())
|
.coerce(obj.t(), &())
|
||||||
.map_err(|mut errs| errs.remove(0))?;
|
.map_err(|mut errs| errs.remove(0))?;
|
||||||
|
@ -1487,6 +1483,20 @@ impl Context {
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
if let Ok(singular_ctxs) = self.get_singular_ctxs_by_hir_expr(obj, namespace) {
|
||||||
|
for ctx in singular_ctxs {
|
||||||
|
if let Some(vi) = ctx.get_current_scope_callable(&attr_name.name) {
|
||||||
|
self.validate_visibility(attr_name, vi, input, namespace)?;
|
||||||
|
return Ok(vi.clone());
|
||||||
|
}
|
||||||
|
for method_ctx in ctx.methods_list.iter() {
|
||||||
|
if let Some(vi) = method_ctx.get_current_scope_callable(&attr_name.name) {
|
||||||
|
self.validate_visibility(attr_name, vi, input, namespace)?;
|
||||||
|
return Ok(vi.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
for ctx in self
|
for ctx in self
|
||||||
.get_nominal_super_type_ctxs(obj.ref_t())
|
.get_nominal_super_type_ctxs(obj.ref_t())
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
|
@ -1521,30 +1531,6 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Ok(singular_ctxs) = self.get_singular_ctxs_by_hir_expr(obj, namespace) {
|
|
||||||
for ctx in singular_ctxs {
|
|
||||||
if let Some(vi) = ctx.get_current_scope_callable(&attr_name.name) {
|
|
||||||
self.validate_visibility(attr_name, vi, input, namespace)?;
|
|
||||||
return Ok(vi.clone());
|
|
||||||
}
|
|
||||||
for method_ctx in ctx.methods_list.iter() {
|
|
||||||
if let Some(vi) = method_ctx.get_current_scope_callable(&attr_name.name) {
|
|
||||||
self.validate_visibility(attr_name, vi, input, namespace)?;
|
|
||||||
return Ok(vi.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Err(TyCheckError::singular_no_attr_error(
|
|
||||||
self.cfg.input.clone(),
|
|
||||||
line!() as usize,
|
|
||||||
attr_name.loc(),
|
|
||||||
namespace.name.to_string(),
|
|
||||||
obj.qual_name().as_deref().unwrap_or("?"),
|
|
||||||
obj.ref_t(),
|
|
||||||
attr_name.inspect(),
|
|
||||||
self.get_similar_attr_from_singular(obj, attr_name.inspect()),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
match self.get_attr_type_by_name(obj, attr_name, namespace) {
|
match self.get_attr_type_by_name(obj, attr_name, namespace) {
|
||||||
Triple::Ok(method) => {
|
Triple::Ok(method) => {
|
||||||
let def_t = self
|
let def_t = self
|
||||||
|
@ -1581,7 +1567,7 @@ impl Context {
|
||||||
);
|
);
|
||||||
return Ok(vi);
|
return Ok(vi);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
for patch in self.find_patches_of(obj.ref_t()) {
|
for patch in self.find_patches_of(obj.ref_t()) {
|
||||||
if let Some(vi) = patch.get_current_scope_callable(&attr_name.name) {
|
if let Some(vi) = patch.get_current_scope_callable(&attr_name.name) {
|
||||||
self.validate_visibility(attr_name, vi, input, namespace)?;
|
self.validate_visibility(attr_name, vi, input, namespace)?;
|
||||||
|
@ -1594,6 +1580,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
let coerced = self
|
let coerced = self
|
||||||
.coerce(obj.t(), &())
|
.coerce(obj.t(), &())
|
||||||
.map_err(|mut errs| errs.remove(0))?;
|
.map_err(|mut errs| errs.remove(0))?;
|
||||||
|
@ -2824,7 +2811,7 @@ impl Context {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_similar_attr_from_singular<'a>(
|
pub(crate) fn _get_similar_attr_from_singular<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
obj: &hir::Expr,
|
obj: &hir::Expr,
|
||||||
name: &str,
|
name: &str,
|
||||||
|
@ -3023,6 +3010,10 @@ impl Context {
|
||||||
opt_max
|
opt_max
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ```erg
|
||||||
|
/// get_nominal_super_type_ctx(Nat) == [<Nat>, <Int>, <Float>, ..., <Obj>, <Eq>, ...]
|
||||||
|
/// get_nominal_super_type_ctx({Nat}) == [<Type>, <Obj>, <Eq>, ...]
|
||||||
|
/// ```
|
||||||
pub fn get_nominal_super_type_ctxs<'a>(&'a self, t: &Type) -> Option<Vec<&'a TypeContext>> {
|
pub fn get_nominal_super_type_ctxs<'a>(&'a self, t: &Type) -> Option<Vec<&'a TypeContext>> {
|
||||||
match t {
|
match t {
|
||||||
Type::FreeVar(fv) if fv.is_linked() => self.get_nominal_super_type_ctxs(&fv.crack()),
|
Type::FreeVar(fv) if fv.is_linked() => self.get_nominal_super_type_ctxs(&fv.crack()),
|
||||||
|
|
|
@ -8,21 +8,21 @@
|
||||||
.TypeAlias: ClassType
|
.TypeAlias: ClassType
|
||||||
.Tuple: ClassType
|
.Tuple: ClassType
|
||||||
.Tuple.
|
.Tuple.
|
||||||
__getitem__: (*Type) -> Type
|
__getitem__: (HomogenousTuple Type) -> Type
|
||||||
.Union: ClassType
|
.Union: ClassType
|
||||||
.Union.
|
.Union.
|
||||||
__getitem__: (*Type) -> Type
|
__getitem__: (HomogenousTuple Type) -> Type
|
||||||
.Optional: ClassType
|
.Optional: ClassType
|
||||||
.Optional.
|
.Optional.
|
||||||
__getitem__: (Type) -> Type
|
__getitem__: (HomogenousTuple Type) -> Type
|
||||||
.Callable: ClassType
|
.Callable: ClassType
|
||||||
.Callable.
|
.Callable.
|
||||||
__getitem__: (params: [Type; _], Type) -> Type
|
__getitem__: (HomogenousTuple Type) -> Type
|
||||||
.Concatenate: (*Type) -> Type
|
.Concatenate: (*Type) -> Type
|
||||||
.Type: (Type) -> Type
|
.Type: (Type) -> Type
|
||||||
.Literal: ClassType
|
.Literal: ClassType
|
||||||
.Literal.
|
.Literal.
|
||||||
__getitem__: (*Obj) -> Type
|
__getitem__: (HomogenousTuple Obj) -> Type
|
||||||
.ClassVar: (Type) -> Type
|
.ClassVar: (Type) -> Type
|
||||||
.Final: (Type) -> Type
|
.Final: (Type) -> Type
|
||||||
.Required: (Type) -> Type
|
.Required: (Type) -> Type
|
||||||
|
@ -64,24 +64,42 @@
|
||||||
.AnyStr: ClassType
|
.AnyStr: ClassType
|
||||||
.Protocol: (Type := NoneType) -> Type
|
.Protocol: (Type := NoneType) -> Type
|
||||||
.NamedTuple: ClassType
|
.NamedTuple: ClassType
|
||||||
|
.NamedTuple.
|
||||||
|
__call__: (typename: Str, it := global::Iterable(Obj)) -> Type
|
||||||
.NewType: ClassType
|
.NewType: ClassType
|
||||||
.NewType.
|
.NewType.
|
||||||
__module__: Str
|
__module__: Str
|
||||||
__name__: Str
|
__name__: Str
|
||||||
__supertype__: Type
|
__supertype__: Type
|
||||||
__call__: (name: Str, tp: Type) -> NewType
|
__call__: (name: Str, tp: Type) -> NewType
|
||||||
.TypedDict: (Str, Type) -> Type
|
.TypedDict: (typename: Str, it := global::Iterable(Obj)) -> Type
|
||||||
.Dict: (Type, Type) -> Type
|
.Dict: (Type, Type) -> Type
|
||||||
.List: (Type) -> Type
|
.List: (Type) -> Type
|
||||||
.Set: (Type) -> Type
|
.Set: (Type) -> Type
|
||||||
.FrozenSet: (Type) -> Type
|
.FrozenSet: (Type) -> ClassType
|
||||||
.OrderedDict: (Type, Type) -> Type
|
.FrozenSet.
|
||||||
|
__getitem__: Type -> Type
|
||||||
|
.OrderedDict: (Type, Type) -> ClassType
|
||||||
|
.OrderedDict.
|
||||||
|
__getitem__: (kv: (Type, Type)) -> Type
|
||||||
.ChainMap: (Type, Type) -> Type
|
.ChainMap: (Type, Type) -> Type
|
||||||
.Counter: (Type, Int) -> Type
|
.Counter: (Type, Int) -> Type
|
||||||
.Deque: (Type) -> Type
|
.Deque: (T: Type) -> ClassType
|
||||||
.IO: ClassType
|
.Deque.
|
||||||
|
__call__: |T|(iter: global::Iterable(T)) -> Deque T
|
||||||
|
__getitem__: (Type) -> Type
|
||||||
|
.IO: Type -> ClassType
|
||||||
|
.IO.
|
||||||
|
__call__: () -> IO Obj
|
||||||
|
__getitem__: (Type) -> Type
|
||||||
.TextIO: ClassType
|
.TextIO: ClassType
|
||||||
|
.TextIO <: IO Str
|
||||||
|
.TextIO.
|
||||||
|
__call__: () -> TextIO
|
||||||
.BinaryIO: ClassType
|
.BinaryIO: ClassType
|
||||||
|
.BinaryIO <: IO Bytes
|
||||||
|
.BinaryIO.
|
||||||
|
__call__: () -> BinaryIO
|
||||||
.Pattern: ClassType
|
.Pattern: ClassType
|
||||||
.Match: ClassType
|
.Match: ClassType
|
||||||
.Text: ClassType
|
.Text: ClassType
|
||||||
|
@ -127,20 +145,40 @@
|
||||||
.KeysView: ClassType
|
.KeysView: ClassType
|
||||||
.Mapping: ClassType
|
.Mapping: ClassType
|
||||||
.Mapping.
|
.Mapping.
|
||||||
__getitem__: (Type, Type) -> Type
|
__getitem__: (kv: (Type, Type)) -> Type
|
||||||
.MappingView: ClassType
|
.MappingView: ClassType
|
||||||
|
.MappingView.
|
||||||
|
__getitem__: (Type) -> Type
|
||||||
.MutableMapping: ClassType
|
.MutableMapping: ClassType
|
||||||
|
.MutableMapping.
|
||||||
|
__getitem__: (kv: (Type, Type)) -> Type
|
||||||
.MutableSequence: ClassType
|
.MutableSequence: ClassType
|
||||||
|
.MutableSequence.
|
||||||
|
__getitem__: Type -> Type
|
||||||
.MutableSet: ClassType
|
.MutableSet: ClassType
|
||||||
|
.MutableSet.
|
||||||
|
__getitem__: Type -> Type
|
||||||
.Sized: ClassType
|
.Sized: ClassType
|
||||||
.ValuesView: ClassType
|
.ValuesView: ClassType
|
||||||
.Awaitable: ClassType
|
.Awaitable: ClassType
|
||||||
.AsyncIterator: ClassType
|
.AsyncIterator: ClassType
|
||||||
|
.AsyncIterator.
|
||||||
|
__getitem__: Type -> Type
|
||||||
.AsyncIterable: ClassType
|
.AsyncIterable: ClassType
|
||||||
|
.AsyncIterable.
|
||||||
|
__getitem__: Type -> Type
|
||||||
.Coroutine: ClassType
|
.Coroutine: ClassType
|
||||||
|
.Coroutine.
|
||||||
|
__getitem__: (t: (Type, Type, Type)) -> Type
|
||||||
.Collection: ClassType
|
.Collection: ClassType
|
||||||
|
.Collection.
|
||||||
|
__getitem__: Type -> Type
|
||||||
.AsyncGenerator: ClassType
|
.AsyncGenerator: ClassType
|
||||||
|
.AsyncGenerator.
|
||||||
|
__getitem__: (t: (Type, Type)) -> Type
|
||||||
.AsyncContextManager: ClassType
|
.AsyncContextManager: ClassType
|
||||||
|
.AsyncContextManager.
|
||||||
|
__getitem__: Type -> Type
|
||||||
.SupportsAbs: ClassType
|
.SupportsAbs: ClassType
|
||||||
.SupportsBytes: ClassType
|
.SupportsBytes: ClassType
|
||||||
.SupportsComplex: ClassType
|
.SupportsComplex: ClassType
|
||||||
|
@ -149,5 +187,9 @@
|
||||||
.SupportsInt: ClassType
|
.SupportsInt: ClassType
|
||||||
.SupportsRound: ClassType
|
.SupportsRound: ClassType
|
||||||
|
|
||||||
.Genertor: ClassType
|
.Generator: ClassType
|
||||||
|
.Generator.
|
||||||
|
__getitem__: (t: (Type, Type, Type)) -> Type
|
||||||
.Reversible: ClassType
|
.Reversible: ClassType
|
||||||
|
.Reversible.
|
||||||
|
__getitem__: Type -> Type
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
.urlparse: (urlstring: Str, scheme := Str, allow_fragments := Bool) -> NamedTuple {
|
||||||
|
.scheme = Str;
|
||||||
|
.netloc = Str;
|
||||||
|
.path = Str;
|
||||||
|
.params = Str;
|
||||||
|
.query = Str;
|
||||||
|
.fragment = Str;
|
||||||
|
.username = Str or NoneType;
|
||||||
|
.password = Str or NoneType;
|
||||||
|
.hostname = Str or NoneType;
|
||||||
|
.port = Int or NoneType;
|
||||||
|
}
|
||||||
|
.parse_qs: (
|
||||||
|
qs: Str,
|
||||||
|
keep_blank_values := Bool,
|
||||||
|
strict_parsing := Bool,
|
||||||
|
encoding := Str,
|
||||||
|
errors := Str,
|
||||||
|
max_num_fields := Nat or NoneType,
|
||||||
|
separator := Str,
|
||||||
|
) -> {Str: [Str; _]}
|
Loading…
Add table
Add a link
Reference in a new issue