fix: Python 3.7~3.8 bugs

This commit is contained in:
Shunsuke Shibayama 2023-09-13 11:09:30 +09:00
parent 75c1ac733c
commit aacdca31b8
6 changed files with 35 additions and 4 deletions

View file

@ -35,7 +35,7 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
os: [windows-latest, ubuntu-latest, macos-latest] os: [windows-latest, ubuntu-latest, macos-latest]
python-version: ['3.9', '3.10', '3.11.3'] python-version: ['3.7', '3.8', '3.9', '3.10', '3.11.3']
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
env: env:
RUST_BACKTRACE: full RUST_BACKTRACE: full

View file

@ -187,6 +187,7 @@ pub struct PyCodeGenerator {
union_loaded: bool, union_loaded: bool,
fake_generic_loaded: bool, fake_generic_loaded: bool,
abc_loaded: bool, abc_loaded: bool,
builtins_loaded: bool,
unit_size: usize, unit_size: usize,
units: PyCodeGenStack, units: PyCodeGenStack,
fresh_gen: SharedFreshNameGenerator, fresh_gen: SharedFreshNameGenerator,
@ -209,6 +210,7 @@ impl PyCodeGenerator {
union_loaded: false, union_loaded: false,
fake_generic_loaded: false, fake_generic_loaded: false,
abc_loaded: false, abc_loaded: false,
builtins_loaded: false,
unit_size: 0, unit_size: 0,
units: PyCodeGenStack::empty(), units: PyCodeGenStack::empty(),
fresh_gen: SharedFreshNameGenerator::new("codegen"), fresh_gen: SharedFreshNameGenerator::new("codegen"),
@ -231,6 +233,7 @@ impl PyCodeGenerator {
union_loaded: false, union_loaded: false,
fake_generic_loaded: false, fake_generic_loaded: false,
abc_loaded: false, abc_loaded: false,
builtins_loaded: false,
unit_size: 0, unit_size: 0,
units: PyCodeGenStack::empty(), units: PyCodeGenStack::empty(),
fresh_gen: self.fresh_gen.clone(), fresh_gen: self.fresh_gen.clone(),
@ -253,6 +256,7 @@ impl PyCodeGenerator {
self.union_loaded = false; self.union_loaded = false;
self.fake_generic_loaded = false; self.fake_generic_loaded = false;
self.abc_loaded = false; self.abc_loaded = false;
self.builtins_loaded = false;
} }
#[inline] #[inline]
@ -2456,13 +2460,18 @@ impl PyCodeGenerator {
Some(7) => self.emit_with_instr_307(args), Some(7) => self.emit_with_instr_307(args),
_ => todo!("not supported Python version"), _ => todo!("not supported Python version"),
}, },
"sum" if self.py_version.minor <= Some(7) && args.get_kw("start").is_some() => {
self.load_builtins();
self.emit_load_name_instr(Identifier::private("#sum"));
self.emit_args_311(args, Name, true);
}
other if local.ref_t().is_poly_type_meta() && other != "classof" => { other if local.ref_t().is_poly_type_meta() && other != "classof" => {
if self.py_version.minor <= Some(9) { if self.py_version.minor <= Some(9) {
self.load_fake_generic(); self.load_fake_generic();
self.emit_load_name_instr(Identifier::private("#FakeGenericAlias")); self.emit_load_name_instr(Identifier::private("#FakeGenericAlias"));
let mut args = args; let mut args = args;
args.insert_pos(0, PosArg::new(Expr::Accessor(Accessor::Ident(local)))); args.insert_pos(0, PosArg::new(Expr::Accessor(Accessor::Ident(local))));
self.emit_args_311(args, Name, false); self.emit_args_311(args, Name, true);
} else { } else {
self.emit_load_name_instr(local); self.emit_load_name_instr(local);
self.emit_index_args(args); self.emit_index_args(args);
@ -3573,6 +3582,13 @@ impl PyCodeGenerator {
); );
} }
fn load_builtins(&mut self) {
self.emit_global_import_items(
Identifier::public("_erg_builtins"),
vec![(Identifier::public("sum"), Some(Identifier::private("#sum")))],
);
}
pub fn emit(&mut self, hir: HIR) -> CodeObj { pub fn emit(&mut self, hir: HIR) -> CodeObj {
log!(info "the code-generating process has started.{RESET}"); log!(info "the code-generating process has started.{RESET}");
self.unit_size += 1; self.unit_size += 1;

View file

@ -139,7 +139,7 @@ impl Context {
let t_isinstance = nd_func( let t_isinstance = nd_func(
vec![ vec![
kw(KW_OBJECT, Obj), kw(KW_OBJECT, Obj),
kw(KW_CLASSINFO, ClassType), // TODO: => ClassInfo kw(KW_CLASSINFO, ClassType | unknown_len_array_t(ClassType)), // TODO: => ClassInfo
], ],
None, None,
Bool, Bool,
@ -147,7 +147,7 @@ impl Context {
let t_issubclass = nd_func( let t_issubclass = nd_func(
vec![ vec![
kw(KW_SUBCLASS, ClassType), kw(KW_SUBCLASS, ClassType),
kw(KW_CLASSINFO, ClassType), // TODO: => ClassInfo kw(KW_CLASSINFO, ClassType | unknown_len_array_t(ClassType)), // TODO: => ClassInfo
], ],
None, None,
Bool, Bool,

View file

@ -385,6 +385,13 @@ impl Args {
pub fn insert_pos(&mut self, idx: usize, pos: PosArg) { pub fn insert_pos(&mut self, idx: usize, pos: PosArg) {
self.pos_args.insert(idx, pos); self.pos_args.insert(idx, pos);
} }
pub fn get_kw(&self, keyword: &str) -> Option<&Expr> {
self.kw_args
.iter()
.find(|kw| kw.keyword.inspect() == keyword)
.map(|kw| &kw.expr)
}
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]

View file

@ -0,0 +1,6 @@
# in Python 3.7, `sum` takes no keyword arguments
def sum(iterable, start=0):
s = start
for i in iterable:
s += i
return s

View file

@ -14,6 +14,8 @@ def contains_operator(y, elem) -> bool:
return True return True
elif hasattr(y, "try_new") and is_ok(y.try_new(elem)): elif hasattr(y, "try_new") and is_ok(y.try_new(elem)):
return True return True
elif hasattr(y, "__origin__") and hasattr(y.__origin__, "type_check"):
return y.__origin__.type_check(elem, y)
# TODO: trait check # TODO: trait check
return False return False
# [1] in [Int] # [1] in [Int]