Skip to content

Commit

Permalink
Merge branch 'master' into function_infos
Browse files Browse the repository at this point in the history
# Conflicts:
#	www/src/brython.js
#	www/src/brython_stdlib.js
#	www/src/version_info.js
  • Loading branch information
PierreQuentel committed Dec 29, 2024
2 parents cf1ccfd + 8e0a20a commit 8386dd9
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 24 deletions.
2 changes: 1 addition & 1 deletion scripts/make_skeleton.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import types


stdlib_name = '_typing'
stdlib_name = '_socket'

include_doc = False
include_base_classes = False
Expand Down
29 changes: 25 additions & 4 deletions www/src/Lib/_socket.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,10 +250,10 @@ def dup(*args,**kw):
sockets; on some platforms os.dup() won't work for socket file descriptors."""
pass

class error:
class error(BaseException):
pass

class gaierror:
class gaierror(BaseException):
pass

def getaddrinfo(*args,**kw):
Expand Down Expand Up @@ -360,12 +360,33 @@ def setdefaulttimeout(*args,**kw):
pass

class socket:
def __init__(self,*args,**kw):
pass
def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None):
self._family = family
self._type = type
self.proto = proto
self._fileno = fileno

@property
def family(self):
return self._family

@property
def type(self):
return self._type

def fileno(self):
return self._fileno or -1

def bind(self,*args,**kw):
pass
def close(self):
pass

def getsockname(self):
raise error()

def getpeername(self):
raise error()

class timeout:
pass
3 changes: 2 additions & 1 deletion www/src/Lib/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,8 @@ def handle_line(self, event=None):
code = compile(currentLine, '<stdin>', 'exec')
exec(code, self.globals, self.locals)
except SyntaxError as exc:
if exc.args[0].startswith('expected an indented block'):
if exc.args and \
exc.args[0].startswith('expected an indented block'):
self.insert_continuation()
self._status = "block"
else:
Expand Down
11 changes: 8 additions & 3 deletions www/src/Lib/tb.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def show_line():
handle_repeats(filename, lineno, count_repeats)

if isinstance(exc, SyntaxError):
trace.write(syntax_error(exc.args))
trace.write(syntax_error(exc))
else:
message = exc_msg
if isinstance(exc, AttributeError):
Expand All @@ -96,8 +96,13 @@ def print_exc(file=None):
file = sys.stderr
file.write(format_exc())

def syntax_error(args):
def syntax_error(exc):
trace = Trace()
args = exc.args
name = exc.__class__.__name__
if not args:
trace.write(f"{name}:", '<no detail available>')
return trace.format()
info, [filename, lineno, offset, line, *extra] = args
trace.write(f' File "{filename}", line {lineno}')
indent = len(line) - len(line.lstrip())
Expand All @@ -111,5 +116,5 @@ def syntax_error(args):
nb_marks = end_offset - offset
nb_marks = max(nb_marks, 1)
trace.write(" " + (offset - 1) * " " + "^" * nb_marks)
trace.write("SyntaxError:", info)
trace.write(f"{name}:", info)
return trace.format()
48 changes: 46 additions & 2 deletions www/src/ast_to_js.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,10 @@ function bind(name, scopes){
}
}
scope.locals.add(name)
if(up_scope.type == 'class'){
up_scope.maybe_locals = up_scope.maybe_locals ?? new Set()
up_scope.maybe_locals.add(name)
}
return scope
}

Expand Down Expand Up @@ -360,7 +364,7 @@ function local_scope(name, scope){

function name_scope(name, scopes){
// return the scope where name is bound, or undefined
var test = false //name == 'x' // && scopes[scopes.length - 1].name == "g"
var test = false // name == 'xw' // && scopes[scopes.length - 1].name == "g"
if(test){
console.log('name scope', name, scopes.slice())
alert()
Expand Down Expand Up @@ -420,11 +424,17 @@ function name_scope(name, scopes){
// name is local (symtable) but may not have yet been bound in scope
// If scope is a "subscope", look in its parents
var l_scope = local_scope(name, scope)
if(test){
console.log('l_scope', l_scope)
}
if(! l_scope.found){
if(block.type == SF.TYPE_CLASS){
// In class definition, unbound local variables are looked up
// in the global namespace (Language Reference 4.2.2)
scope.needs_frames = true
if(scope.maybe_locals && scope.maybe_locals.has(name)){
return {found: false, resolve: 'local'}
}
return {found: false, resolve: 'global'}
}else if(block.type == SF.TYPE_MODULE){
scope.needs_frames = true
Expand Down Expand Up @@ -778,9 +788,25 @@ function init_genexpr(comp, scopes){
prefix + `var _frame_obj = $B.frame_obj\n`
}

function comp_bindings(comp, bindings){
if(comp.target instanceof $B.ast.Name){
bindings.add(comp.target.id)
}else if(comp.target.elts){
for(var elt of comp.target.elts){
comp_bindings({target: elt}, bindings)
}
}
return bindings
}

function make_comp(scopes){
// Code common to list / set / dict comprehensions
// List all names bound inside the comprehension generators
var bindings = new Set()
for(var gen of this.generators){
comp_bindings(gen, bindings)
}
var save_locals = new Set()
var plen = prefix.length
var comp_prefix = prefix
var id = make_id(),
Expand All @@ -790,10 +816,22 @@ function make_comp(scopes){
comp_iter,
comp_scope = $B.last(scopes),
upper_comp_scope = comp_scope

// Check the names bound in the comprehension that would shadow names
// in the comprehension scope
for(var name of comp_scope.locals){
if(bindings.has(name)){
save_locals.add(name)
}
}
while(upper_comp_scope.parent){
upper_comp_scope = upper_comp_scope.parent
for(var name of upper_comp_scope.locals){
if(bindings.has(name)){
save_locals.add(name)
}
}
}

var comp_scope_block = scopes.symtable.table.blocks.get(
fast_id(upper_comp_scope.ast)),
comp_scope_symbols = comp_scope_block.symbols
Expand Down Expand Up @@ -826,6 +864,9 @@ function make_comp(scopes){
if(comp_iter_scope.found){
js += prefix + `var save_comp_iter = ${name_reference(comp_iter, scopes)}\n`
}
for(var name of save_locals){
js += prefix + `var save_${name} = ${name_reference(name, scopes)}\n`
}
if(this instanceof $B.ast.ListComp){
js += prefix + `var result_${id} = $B.$list([])\n`
}else if(this instanceof $B.ast.SetComp){
Expand Down Expand Up @@ -916,6 +957,9 @@ function make_comp(scopes){
js += prefix + `}\n` +
(has_await ? prefix + `\n$B.restore_frame_obj(save_frame_obj, ${comp.locals_name});` : '')

for(var name of save_locals){
js += prefix + `${name_reference(name, scopes)} = save_${name}\n`
}
if(comp_iter_scope.found){
js += prefix + `${name_reference(comp_iter, scopes)} = save_comp_iter\n`
}
Expand Down
4 changes: 2 additions & 2 deletions www/src/builtin_modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -1311,9 +1311,9 @@
for(var name in _b_){
var builtin = _b_[name]
if(_b_[name].__class__ === _b_.type){
_b_[name].__qualname__ = name
_b_[name].__qualname__ = _b_[name].__qualname__ ?? name
_b_[name].__module__ = 'builtins'
_b_[name].__name__ = name
_b_[name].__name__ = _b_[name].__name__ ?? name
_b_[name].$is_builtin_class = true
$B.builtin_classes.push(_b_[name]) // defined in brython_builtins.js
for(var key in _b_[name]){
Expand Down
24 changes: 14 additions & 10 deletions www/src/py_exceptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -590,8 +590,9 @@ make_builtin_exception(["DeprecationWarning", "PendingDeprecationWarning",
"ImportWarning", "UnicodeWarning", "BytesWarning", "ResourceWarning",
"EncodingWarning"], _b_.Warning)

make_builtin_exception(["EnvironmentError", "IOError", "VMSError",
"WindowsError"], _b_.OSError)
_b_.EnvironmentError = _b_.OSError
_b_.WindowsError = _b_.OSError
_b_.IOError = _b_.OSError

// AttributeError supports keyword-only "name" and "obj" parameters
_b_.AttributeError = $B.make_class('AttributeError',
Expand Down Expand Up @@ -859,7 +860,7 @@ $B.offer_suggestions_for_unexpected_keyword_error = function(arg_names, key){
}

// PEP 654
_b_.BaseExceptionGroup = $B.make_class("BaseExceptionGFroup",
_b_.BaseExceptionGroup = $B.make_class("BaseExceptionGroup",
function(){
var missing = {},
$ = $B.args("BaseExceptionGroup", 2,
Expand Down Expand Up @@ -962,7 +963,7 @@ $B.set_func_names(_b_.BaseExceptionGroup, "builtins")
_b_.BaseExceptionGroup.__class_getitem__ =
_b_.classmethod.$factory(_b_.BaseExceptionGroup.__class_getitem__)

_b_.ExceptionGroup = $B.make_class("ExceptionGFroup",
_b_.ExceptionGroup = $B.make_class("ExceptionGroup",
function(){
var missing = {},
$ = $B.args("ExceptionGroup", 2, {message: null, exceptions: null},
Expand Down Expand Up @@ -1132,11 +1133,13 @@ $B.error_trace = function(err){
err.__class__ === _b_.IndentationError){
err.$frame_obj = err.$frame_obj === null ? null : err.$frame_obj.prev
trace += trace_from_stack(err)
var filename = err.filename,
line = err.text,
indent = line.length - line.trimLeft().length
trace += ` File "${filename}", line ${err.args[1][1]}\n` +
` ${line.trim()}\n`
if(err.args.length > 0){
var filename = err.filename,
line = err.text,
indent = line.length - line.trimLeft().length
trace += ` File "${filename}", line ${err.args[1][1]}\n` +
` ${line.trim()}\n`
}
if(err.__class__ !== _b_.IndentationError &&
err.text){
// add ^ under the line
Expand Down Expand Up @@ -1164,7 +1167,8 @@ $B.error_trace = function(err){
marks += '^'.repeat(nb_marks) + '\n'
trace += marks
}
trace += `${err.__class__.__name__}: ${err.args[0]}`

trace += `${err.__class__.__name__}: ${err.args[0] ?? '<no detail available>'}`
}else if(err.__class__ !== undefined){
var name = $B.class_name(err)
trace += trace_from_stack(err)
Expand Down
4 changes: 3 additions & 1 deletion www/tests/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ def show_line(filename, lineno, src):

handle_repeats(save_filename, save_lineno, count_repeats)

if isinstance(exc_value, SyntaxError):
if isinstance(exc_value, SyntaxError) and exc_value.args:
filename = exc_value.args[1][0]
lineno = exc_value.args[1][1]
result_lines.append(f' File {filename}, line {lineno}')
Expand All @@ -202,6 +202,8 @@ def show_line(filename, lineno, src):
result_lines.append(' ' + (col_offset - indent - 1) * ' ' + '^')

message = str(exc_value) + suggestion(exc_value)
if isinstance(exc_value, SyntaxError) and not exc_value.args:
message = '<no detail available>'
result_lines.append(f'{exc_type.__name__}: {message}')
return '\n'.join(result_lines)

Expand Down
8 changes: 8 additions & 0 deletions www/tests/test_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,4 +207,12 @@ def f(src):
message = out.getvalue()
assert f'line {lineno + 2}' in message

# issue 2530
assert IOError is OSError
assert WindowsError is OSError
assert EnvironmentError is OSError

ioerror = IOError()
assert type(ioerror) is OSError

print('all tests passed...')

0 comments on commit 8386dd9

Please sign in to comment.