Skip to content

Commit 9677f77

Browse files
committed
Merge branch 'master' of https://github.com/RustPython/RustPython into extend-socket
2 parents a8c2959 + 5b555ae commit 9677f77

23 files changed

+6989
-80
lines changed

Lib/datetime.py

Lines changed: 2472 additions & 0 deletions
Large diffs are not rendered by default.

bytecode/src/bytecode.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,19 @@ bitflags! {
5959
pub type Label = usize;
6060

6161
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
62+
/// An indication where the name must be accessed.
6263
pub enum NameScope {
64+
/// The name will be in the local scope.
6365
Local,
66+
67+
/// The name will be located in scope surrounding the current scope.
6468
NonLocal,
69+
70+
/// The name will be in global scope.
6571
Global,
72+
73+
/// The name will be located in any scope between the current scope and the top scope.
74+
Free,
6675
}
6776

6877
/// Transforms a value prior to formatting it.

compiler/src/compile.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -282,8 +282,8 @@ impl<O: OutputStream> Compiler<O> {
282282
match symbol.scope {
283283
SymbolScope::Global => bytecode::NameScope::Global,
284284
SymbolScope::Nonlocal => bytecode::NameScope::NonLocal,
285-
SymbolScope::Unknown => bytecode::NameScope::Local,
286-
SymbolScope::Local => bytecode::NameScope::Local,
285+
SymbolScope::Unknown => bytecode::NameScope::Free,
286+
SymbolScope::Local => bytecode::NameScope::Free,
287287
}
288288
}
289289

@@ -500,7 +500,7 @@ impl<O: OutputStream> Compiler<O> {
500500
self.compile_jump_if(test, true, end_label)?;
501501
self.emit(Instruction::LoadName {
502502
name: String::from("AssertionError"),
503-
scope: bytecode::NameScope::Local,
503+
scope: bytecode::NameScope::Global,
504504
});
505505
match msg {
506506
Some(e) => {
@@ -736,7 +736,7 @@ impl<O: OutputStream> Compiler<O> {
736736
// Check exception type:
737737
self.emit(Instruction::LoadName {
738738
name: String::from("isinstance"),
739-
scope: bytecode::NameScope::Local,
739+
scope: bytecode::NameScope::Global,
740740
});
741741
self.emit(Instruction::Rotate { amount: 2 });
742742
self.compile_expression(exc_type)?;
@@ -931,11 +931,11 @@ impl<O: OutputStream> Compiler<O> {
931931

932932
self.emit(Instruction::LoadName {
933933
name: "__name__".to_string(),
934-
scope: bytecode::NameScope::Local,
934+
scope: bytecode::NameScope::Free,
935935
});
936936
self.emit(Instruction::StoreName {
937937
name: "__module__".to_string(),
938-
scope: bytecode::NameScope::Local,
938+
scope: bytecode::NameScope::Free,
939939
});
940940
self.compile_statements(new_body)?;
941941
self.emit(Instruction::LoadConst {

compiler/src/symboltable.rs

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ pub fn statements_to_symbol_table(
3131
/// Captures all symbols in the current scope, and has a list of subscopes in this scope.
3232
#[derive(Clone, Default)]
3333
pub struct SymbolTable {
34+
/// The name of this symbol table. Often the name of the class or function.
35+
pub name: String,
36+
3437
/// A set of symbols present on this scope level.
3538
pub symbols: IndexMap<String, Symbol>,
3639

@@ -40,8 +43,9 @@ pub struct SymbolTable {
4043
}
4144

4245
impl SymbolTable {
43-
fn new() -> Self {
46+
fn new(name: String) -> Self {
4447
SymbolTable {
48+
name,
4549
symbols: Default::default(),
4650
sub_tables: vec![],
4751
}
@@ -209,20 +213,22 @@ impl SymbolTableAnalyzer {
209213
if symbol.is_assigned || symbol.is_parameter {
210214
symbol.scope = SymbolScope::Local;
211215
} else {
212-
// TODO: comment this out and make it work properly:
213-
/*
214-
let found_in_outer_scope = self
215-
.tables
216-
.iter()
217-
.any(|t| t.symbols.contains_key(&symbol.name));
216+
// Interesting stuff about the __class__ variable:
217+
// https://docs.python.org/3/reference/datamodel.html?highlight=__class__#creating-the-class-object
218+
let found_in_outer_scope = (symbol.name == "__class__")
219+
|| self
220+
.tables
221+
.iter()
222+
.skip(1)
223+
.any(|t| t.symbols.contains_key(&symbol.name));
224+
218225
if found_in_outer_scope {
219226
// Symbol is in some outer scope.
220-
227+
symbol.is_free = true;
221228
} else {
222229
// Well, it must be a global then :)
223-
// symbol.scope = SymbolScope::Global;
230+
symbol.scope = SymbolScope::Global;
224231
}
225-
*/
226232
}
227233
}
228234
}
@@ -257,8 +263,7 @@ enum ExpressionContext {
257263

258264
impl SymbolTableBuilder {
259265
fn prepare(&mut self) {
260-
let table = SymbolTable::new();
261-
self.tables.push(table);
266+
self.enter_block("top")
262267
}
263268

264269
fn finish(&mut self) -> Result<SymbolTable, SymbolTableError> {
@@ -268,9 +273,9 @@ impl SymbolTableBuilder {
268273
Ok(symbol_table)
269274
}
270275

271-
fn enter_block(&mut self) {
276+
fn enter_block(&mut self, name: &str) {
272277
// let parent = Some(self.tables.last().unwrap().clone());
273-
let table = SymbolTable::new();
278+
let table = SymbolTable::new(name.to_string());
274279
self.tables.push(table);
275280
}
276281

@@ -343,7 +348,7 @@ impl SymbolTableBuilder {
343348
if let Some(expression) = returns {
344349
self.scan_expression(expression, &ExpressionContext::Load)?;
345350
}
346-
self.enter_function(args)?;
351+
self.enter_function(name, args)?;
347352
self.scan_statements(body)?;
348353
self.leave_block();
349354
}
@@ -355,7 +360,7 @@ impl SymbolTableBuilder {
355360
decorator_list,
356361
} => {
357362
self.register_name(name, SymbolUsage::Assigned)?;
358-
self.enter_block();
363+
self.enter_block(name);
359364
self.scan_statements(body)?;
360365
self.leave_block();
361366
self.scan_expressions(bases, &ExpressionContext::Load)?;
@@ -607,7 +612,7 @@ impl SymbolTableBuilder {
607612
}
608613
}
609614
Lambda { args, body } => {
610-
self.enter_function(args)?;
615+
self.enter_function("lambda", args)?;
611616
self.scan_expression(body, &ExpressionContext::Load)?;
612617
self.leave_block();
613618
}
@@ -620,7 +625,7 @@ impl SymbolTableBuilder {
620625
Ok(())
621626
}
622627

623-
fn enter_function(&mut self, args: &ast::Parameters) -> SymbolTableResult {
628+
fn enter_function(&mut self, name: &str, args: &ast::Parameters) -> SymbolTableResult {
624629
// Evaluate eventual default parameters:
625630
self.scan_expressions(&args.defaults, &ExpressionContext::Load)?;
626631
for kw_default in &args.kw_defaults {
@@ -639,7 +644,7 @@ impl SymbolTableBuilder {
639644
self.scan_parameter_annotation(name)?;
640645
}
641646

642-
self.enter_block();
647+
self.enter_block(name);
643648

644649
// Fill scope with parameter names:
645650
self.scan_parameters(&args.args)?;

crawl_sourcecode.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,4 @@ def print_table(table, indent=0):
7373
print('======== dis.dis ========')
7474
print()
7575
co = compile(source, filename, 'exec')
76-
print(dis.dis(co))
76+
dis.dis(co)

tests/snippets/arraymodule.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from array import array
2+
3+
a1 = array("b", [0, 1, 2, 3])
4+
5+
assert a1.tobytes() == b"\x00\x01\x02\x03"
6+
assert a1[2] == 2
7+
8+
assert list(a1) == [0, 1, 2, 3]
9+
10+
a1.reverse()
11+
assert a1 == array("B", [3, 2, 1, 0])
12+
13+
a1.extend([4, 5, 6, 7])
14+
15+
assert a1 == array("h", [3, 2, 1, 0, 4, 5, 6, 7])

tests/snippets/ints.py

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,57 @@
9797
assert -10 // -4 == 2
9898

9999
assert int() == 0
100+
assert int(1) == 1
100101
assert int("101", 2) == 5
101102
assert int("101", base=2) == 5
102-
assert int(1) == 1
103+
104+
# implied base
105+
assert int('1', base=0) == 1
106+
assert int('123', base=0) == 123
107+
assert int('0b101', base=0) == 5
108+
assert int('0B101', base=0) == 5
109+
assert int('0o100', base=0) == 64
110+
assert int('0O100', base=0) == 64
111+
assert int('0xFF', base=0) == 255
112+
assert int('0XFF', base=0) == 255
113+
with assertRaises(ValueError):
114+
int('0xFF', base=10)
115+
with assertRaises(ValueError):
116+
int('0oFF', base=10)
117+
with assertRaises(ValueError):
118+
int('0bFF', base=10)
119+
with assertRaises(ValueError):
120+
int('0bFF', base=10)
121+
with assertRaises(ValueError):
122+
int(b"F\xc3\xb8\xc3\xb6\xbbB\xc3\xa5r")
123+
with assertRaises(ValueError):
124+
int(b"F\xc3\xb8\xc3\xb6\xbbB\xc3\xa5r")
125+
126+
# underscore
127+
assert int('0xFF_FF_FF', base=16) == 16_777_215
128+
with assertRaises(ValueError):
129+
int("_123_")
130+
with assertRaises(ValueError):
131+
int("123_")
132+
with assertRaises(ValueError):
133+
int("_123")
134+
with assertRaises(ValueError):
135+
int("1__23")
136+
137+
# signed
138+
assert int('-123') == -123
139+
assert int('+0b101', base=2) == +5
140+
141+
# trailing spaces
103142
assert int(' 1') == 1
104143
assert int('1 ') == 1
105144
assert int(' 1 ') == 1
106145
assert int('10', base=0) == 10
107146

147+
# type byte, signed, implied base
148+
assert int(b' -0XFF ', base=0) == -255
149+
150+
108151
assert int.from_bytes(b'\x00\x10', 'big') == 16
109152
assert int.from_bytes(b'\x00\x10', 'little') == 4096
110153
assert int.from_bytes(b'\xfc\x00', 'big', signed=True) == -1024
@@ -179,4 +222,4 @@ def __int__(self):
179222
assert_raises(TypeError, lambda: (0).__round__(None))
180223
assert_raises(TypeError, lambda: (1).__round__(None))
181224
assert_raises(TypeError, lambda: (0).__round__(0.0))
182-
assert_raises(TypeError, lambda: (1).__round__(0.0))
225+
assert_raises(TypeError, lambda: (1).__round__(0.0))

0 commit comments

Comments
 (0)