Skip to content

Commit dda6f86

Browse files
authored
Fix global behavior on class (RustPython#4234)
1 parent 2868e87 commit dda6f86

File tree

5 files changed

+12
-25
lines changed

5 files changed

+12
-25
lines changed

Lib/test/test_dataclasses.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1925,8 +1925,6 @@ class Parent(Generic[T]):
19251925
# Check MRO resolution.
19261926
self.assertEqual(Child.__mro__, (Child, Parent, Generic, object))
19271927

1928-
# TODO: RUSTPYTHON
1929-
@unittest.expectedFailure
19301928
def test_dataclasses_pickleable(self):
19311929
global P, Q, R
19321930
@dataclass

Lib/test/test_pickle.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,6 @@ def test_complex_newobj_ex(self): # TODO: RUSTPYTHON, remove when this passes
110110
def test_in_band_buffers(self): # TODO: RUSTPYTHON, remove when this passes
111111
super().test_in_band_buffers() # TODO: RUSTPYTHON, remove when this passes
112112

113-
# TODO: RUSTPYTHON, pickle.PicklingError
114-
@unittest.expectedFailure
115-
def test_nested_names(self): # TODO: RUSTPYTHON, remove when this passes
116-
super().test_nested_names() # TODO: RUSTPYTHON, remove when this passes
117-
118113
# TODO: RUSTPYTHON, AttributeError: module 'pickle' has no attribute 'PickleBuffer'
119114
@unittest.expectedFailure
120115
def test_oob_buffers(self): # TODO: RUSTPYTHON, remove when this passes
@@ -201,11 +196,6 @@ def test_in_band_buffers(self): # TODO: RUSTPYTHON, remove when this passes
201196
def test_load_python2_str_as_bytes(self): # TODO: RUSTPYTHON, remove when this passes
202197
super().test_load_python2_str_as_bytes() # TODO: RUSTPYTHON, remove when this passes
203198

204-
# TODO: RUSTPYTHON, pickle.PicklingError
205-
@unittest.expectedFailure
206-
def test_nested_names(self): # TODO: RUSTPYTHON, remove when this passes
207-
super().test_nested_names() # TODO: RUSTPYTHON, remove when this passes
208-
209199
# TODO: RUSTPYTHON, AttributeError: module 'pickle' has no attribute 'PickleBuffer'
210200
@unittest.expectedFailure
211201
def test_oob_buffers(self): # TODO: RUSTPYTHON, remove when this passes

Lib/test/test_pickletools.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,6 @@ def test_complex_newobj_ex(self): # TODO: RUSTPYTHON, remove when this passes
3535
def test_in_band_buffers(self): # TODO: RUSTPYTHON, remove when this passes
3636
super().test_in_band_buffers()
3737

38-
# TODO: RUSTPYTHON, pickle.PicklingError
39-
@unittest.expectedFailure
40-
def test_nested_names(self): # TODO: RUSTPYTHON, remove when this passes
41-
super().test_nested_names()
42-
4338
def test_notimplemented(self): # TODO: RUSTPYTHON, remove when this passes
4439
super().test_notimplemented()
4540

Lib/test/test_typing.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,8 +1581,6 @@ class P(Protocol):
15811581
Alias2 = typing.Union[P, typing.Iterable]
15821582
self.assertEqual(Alias, Alias2)
15831583

1584-
# TODO: RUSTPYTHON
1585-
@unittest.expectedFailure
15861584
def test_protocols_pickleable(self):
15871585
global P, CP # pickle wants to reference the class by name
15881586
T = TypeVar('T')
@@ -2186,8 +2184,6 @@ def test_all_repr_eq_any(self):
21862184
self.assertNotEqual(repr(base), '')
21872185
self.assertEqual(base, base)
21882186

2189-
# TODO: RUSTPYTHON
2190-
@unittest.expectedFailure
21912187
def test_pickle(self):
21922188
global C # pickle wants to reference the class by name
21932189
T = TypeVar('T')
@@ -4802,8 +4798,6 @@ def test_too_few_type_args(self):
48024798
with self.assertRaisesRegex(TypeError, 'at least two arguments'):
48034799
Annotated[int]
48044800

4805-
# TODO: RUSTPYTHON
4806-
@unittest.expectedFailure
48074801
def test_pickle(self):
48084802
samples = [typing.Any, typing.Union[int, str],
48094803
typing.Optional[str], Tuple[int, ...],

compiler/codegen/src/compile.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,6 +1275,15 @@ impl Compiler {
12751275

12761276
let prev_class_name = std::mem::replace(&mut self.class_name, Some(name.to_owned()));
12771277

1278+
// Check if the class is declared global
1279+
let symbol_table = self.symbol_table_stack.last().unwrap();
1280+
let symbol = symbol_table.lookup(name.as_ref()).expect(
1281+
"The symbol must be present in the symbol table, even when it is undefined in python.",
1282+
);
1283+
let mut global_path_prefix = Vec::new();
1284+
if symbol.scope == SymbolScope::GlobalExplicit {
1285+
global_path_prefix.append(&mut self.qualified_path);
1286+
}
12781287
self.push_qualified_path(name);
12791288
let qualified_name = self.qualified_path.join(".");
12801289

@@ -1287,7 +1296,7 @@ impl Compiler {
12871296
let dunder_module = self.name("__module__");
12881297
self.emit(Instruction::StoreLocal(dunder_module));
12891298
self.emit_constant(ConstantData::Str {
1290-
value: qualified_name.clone(),
1299+
value: qualified_name,
12911300
});
12921301
let qualname = self.name("__qualname__");
12931302
self.emit(Instruction::StoreLocal(qualname));
@@ -1323,6 +1332,7 @@ impl Compiler {
13231332

13241333
self.class_name = prev_class_name;
13251334
self.qualified_path.pop();
1335+
self.qualified_path.append(global_path_prefix.as_mut());
13261336
self.ctx = prev_ctx;
13271337

13281338
let mut funcflags = bytecode::MakeFunctionFlags::empty();
@@ -1342,7 +1352,7 @@ impl Compiler {
13421352
self.emit(Instruction::MakeFunction(funcflags));
13431353

13441354
self.emit_constant(ConstantData::Str {
1345-
value: qualified_name,
1355+
value: name.to_owned(),
13461356
});
13471357

13481358
let call = self.compile_call_inner(2, bases, keywords)?;

0 commit comments

Comments
 (0)