diff --git a/Cargo.lock b/Cargo.lock index 57f775b..3a98a99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -145,9 +145,9 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "els" -version = "0.1.57-nightly.0" +version = "0.1.57-nightly.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98756af66882a065224c97f2fdc5194488743202edd74dd237b16702f826d1de" +checksum = "ae46d42c34d43c4cb9b50c67fbd79403821735ac628e52c558dfc8ce07e04510" dependencies = [ "erg_common", "erg_compiler", @@ -159,9 +159,9 @@ dependencies = [ [[package]] name = "erg_common" -version = "0.6.45-nightly.0" +version = "0.6.45-nightly.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219046e2b30f4e0b74089d95acfb49c4b5591ccc2d4d0a7e60c3616d0ed59fcb" +checksum = "246a0322e068e652ad568ad53d86f320dd2d057d9b0f6393b9e265e47c48fd19" dependencies = [ "backtrace-on-stack-overflow", "erg_proc_macros", @@ -172,9 +172,9 @@ dependencies = [ [[package]] name = "erg_compiler" -version = "0.6.45-nightly.0" +version = "0.6.45-nightly.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e58d1703e885cbf39337d087eb864f93aee1b8d327a222a6b7dd3cc5a26e6e4" +checksum = "db35fd108cbbce8fa039f08480884e76503c96f1a396d61abccc87e8df95d3b4" dependencies = [ "erg_common", "erg_parser", @@ -182,9 +182,9 @@ dependencies = [ [[package]] name = "erg_parser" -version = "0.6.45-nightly.0" +version = "0.6.45-nightly.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3103c4b8049db34a0ef3598c9603d3113d072f258d44d33715d3ba8d98ae2328" +checksum = "6d661080b205b781562ef5f63102cf3fed9dbb5be8854e44fcb7acde76b0afab" dependencies = [ "erg_common", "erg_proc_macros", @@ -193,9 +193,9 @@ dependencies = [ [[package]] name = "erg_proc_macros" -version = "0.6.45-nightly.0" +version = "0.6.45-nightly.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afe652e09673d3abbfc272472d9f6f89fdace58238bcaf21f6f6abd397bd8583" +checksum = "fda0516eecbd227bdc1962a0aa5e3ea093551f01413fd7cd4f5c9d45a1a58574" dependencies = [ "quote", "syn 1.0.109", @@ -938,15 +938,15 @@ dependencies = [ [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-xid" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "unicode_names2" diff --git a/Cargo.toml b/Cargo.toml index da16814..4107178 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,9 +24,9 @@ edition = "2021" repository = "https://github.com/mtshiba/pylyzer" [workspace.dependencies] -erg_common = { version = "0.6.45-nightly.0", features = ["py_compat", "els"] } -erg_compiler = { version = "0.6.45-nightly.0", features = ["py_compat", "els"] } -els = { version = "0.1.57-nightly.0", features = ["py_compat"] } +erg_common = { version = "0.6.45-nightly.2", features = ["py_compat", "els"] } +erg_compiler = { version = "0.6.45-nightly.2", features = ["py_compat", "els"] } +els = { version = "0.1.57-nightly.2", features = ["py_compat"] } # rustpython-parser = { version = "0.3.0", features = ["all-nodes-with-ranges", "location"] } # rustpython-ast = { version = "0.3.0", features = ["all-nodes-with-ranges", "location"] } rustpython-parser = { git = "https://github.com/RustPython/Parser", version = "0.4.0", features = ["all-nodes-with-ranges", "location"] } diff --git a/README.md b/README.md index da0e830..6502ed6 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,7 @@ pylyzer converts Python ASTs to Erg ASTs and passes them to Erg's type checker. * [x] `Callable` * [ ] `TypedDict` * [x] `TypeVar` + * [ ] `ClassVar` * [ ] `Generic` * [ ] `Protocol` * [ ] `Final` diff --git a/crates/py2erg/convert.rs b/crates/py2erg/convert.rs index 46b7804..141b75b 100644 --- a/crates/py2erg/convert.rs +++ b/crates/py2erg/convert.rs @@ -409,7 +409,7 @@ impl ASTConverter { name_info.defined_in = DefinedPlace::Known(cur_namespace); name_info.defined_times += 1; // 0 -> 1 } - if name_info.defined_block_id == cur_block_id { + if name_info.defined_block_id == cur_block_id || name_info.defined_times == 0 { CanShadow::Yes } else { CanShadow::No @@ -1388,6 +1388,10 @@ impl ASTConverter { ); method.call1(self.convert_expr(*subs.slice)) } + // [start:] == [slice(start, None)] + // [:stop] == [slice(stop)] + // [start:stop] == [slice(start, stop)] + // [start:stop:step] == [slice(start, stop, step)] py_ast::Expr::Slice(slice) => { let loc = slice.location(); let start = slice.lower.map(|ex| self.convert_expr(*ex)); diff --git a/tests/collection.py b/tests/collection.py index 122e64d..66ec660 100644 --- a/tests/collection.py +++ b/tests/collection.py @@ -31,3 +31,4 @@ def f(s: Str): return None assert 1 in {1, 2} assert 1 in {1: "a"} assert 1 in (1, 2) +assert 1 in map(lambda x: x + 1, [0, 1, 2]) diff --git a/tests/decl.py b/tests/decl.py new file mode 100644 index 0000000..e086214 --- /dev/null +++ b/tests/decl.py @@ -0,0 +1,11 @@ +i: int +if True: + i = 1 +else: + i = 2 + +j: int +if True: + j = "1" # ERR +else: + j = "2" diff --git a/tests/test.rs b/tests/test.rs index 8a9e5c8..71a0458 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -9,6 +9,8 @@ use pylyzer_core::PythonAnalyzer; pub fn exec_analyzer(file_path: &'static str) -> Result { let cfg = ErgConfig { input: Input::file(PathBuf::from(file_path)), + effect_check: false, + ownership_check: false, ..Default::default() }; let mut analyzer = PythonAnalyzer::new(cfg); @@ -21,6 +23,7 @@ fn _expect(file_path: &'static str, warns: usize, errors: usize) -> Result<(), S match exec_analyzer(file_path) { Ok(artifact) => { if artifact.warns.len() != warns { + eprintln!("warns: {}", artifact.warns); return Err(format!( "Expected {warns} warnings, found {}", artifact.warns.len() @@ -33,12 +36,14 @@ fn _expect(file_path: &'static str, warns: usize, errors: usize) -> Result<(), S } Err(artifact) => { if artifact.warns.len() != warns { + eprintln!("warns: {}", artifact.warns); return Err(format!( "Expected {warns} warnings, found {}", artifact.warns.len() )); } if artifact.errors.len() != errors { + eprintln!("errors: {}", artifact.errors); return Err(format!( "Expected {errors} errors, found {}", artifact.errors.len() @@ -137,6 +142,11 @@ fn exec_call() -> Result<(), String> { expect("tests/call.py", 0, 6) } +#[test] +fn exec_decl() -> Result<(), String> { + expect("tests/decl.py", 0, 1) +} + #[test] fn exec_shadowing() -> Result<(), String> { expect("tests/shadowing.py", 0, 3) diff --git a/tests/union.py b/tests/union.py index 5635ab4..c942226 100644 --- a/tests/union.py +++ b/tests/union.py @@ -7,3 +7,7 @@ def f(x: str | bytes): return x.isalnum() + +def check(s: str | bytes | bytearray): + if isinstance(s, (bytes, bytearray)): + pass