Mutable default arguments are recreated on each function call instead of shared between calls

Đang mở
#909 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
52/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Ít trao đổi
Công nghệ
javascript, python
Lĩnh vực
compilers

Hướng nghiên cứu

Start with the minimal Python example in the issue and compare its Transcrypt-generated JavaScript with CPython's output. Trace how omitted default arguments are emitted, then verify that repeated calls share the mutable default and that the identity check reports True.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

IS: bug?
Description

Mutable default arguments appear to behave differently in Transcrypt compared with CPython.

In Python, default argument expressions are evaluated when the function definition is executed. Therefore, when a mutable object such as [] is used as a default argument, calls that omit the argument use the same object.

In Transcrypt 3.9.5, the default list appears to be recreated for every function call instead.

Minimal example

Tested with Python 3.9 and Transcrypt 3.9.5:

def append_list1(new_item, lst=[]):
    lst.append(new_item)
    return lst

print(append_list1(1), append_list1(2))


def append_list2(new_item, lst=[]):
    lst.append(new_item)
    return lst

lst1 = append_list2(1)
lst2 = append_list2(2)

print(lst1 is lst2)
CPython output
[1, 2] [1, 2]
True
Output when running the Transcrypt-generated JavaScript
[1] [2]
False
Expected behaviour

The default value of lst should be created once when the function is defined. Therefore, calls to append_list2() without explicitly supplying lst should receive the same list object, and lst1 is lst2 should be True.

Generated JavaScript

The generated JavaScript appears to initialise the default argument inside the function when the argument is omitted, conceptually equivalent to:

var append_list2 = function (new_item, lst) {
    if (typeof lst == 'undefined') {
        var lst = [];
    }

    lst.append(new_item);
    return lst;
};

This causes a new list to be created each time the function is called without lst, rather than once when the function is defined.

Environment

Python: 3.9.0
Transcrypt: 3.9.5
Node.js: v24.19.0
OS: Windows 11

Ngôn ngữ chính
Python
Star
2.9k
Fork
218
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của TranscryptOrg/Transcrypt

Tất cả issue của TranscryptOrg/Transcrypt

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.