Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions Doc/c-api/long.rst
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
on failure.


.. c:function:: PyObject* PyLong_FromUnsignedLongLong(unsigned long long v)

Return a new :c:type:`PyLongObject` object from a C :c:expr:`unsigned long long`,
or ``NULL`` on failure.


.. c:function:: PyObject* PyLong_FromInt32(int32_t value)
PyObject* PyLong_FromInt64(int64_t value)

Expand All @@ -81,12 +87,6 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
.. versionadded:: 3.14


.. c:function:: PyObject* PyLong_FromUnsignedLongLong(unsigned long long v)

Return a new :c:type:`PyLongObject` object from a C :c:expr:`unsigned long long`,
or ``NULL`` on failure.


.. c:function:: PyObject* PyLong_FromUInt32(uint32_t value)
PyObject* PyLong_FromUInt64(uint64_t value)

Expand Down
1 change: 0 additions & 1 deletion Doc/library/importlib.resources.rst
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,6 @@ For all the following functions:

.. versionchanged:: 3.13
Multiple *path_names* are accepted.
*encoding* and *errors* must be given as keyword arguments.


.. function:: is_resource(anchor, *path_names)
Expand Down
27 changes: 27 additions & 0 deletions Lib/idlelib/iomenu.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def set_filename_change_hook(self, hook):
self.filename_change_hook = hook

filename = None
file_timestamp = None
dirname = None

def set_filename(self, filename):
Expand Down Expand Up @@ -127,6 +128,7 @@ def loadfile(self, filename):
chars = f.read()
fileencoding = f.encoding
eol_convention = f.newlines
file_timestamp = self.getmtime(filename)
converted = False
except (UnicodeDecodeError, SyntaxError):
# Wait for the editor window to appear
Expand All @@ -142,6 +144,7 @@ def loadfile(self, filename):
chars = f.read()
fileencoding = f.encoding
eol_convention = f.newlines
file_timestamp = self.getmtime(filename)
converted = True
except OSError as err:
messagebox.showerror("I/O Error", str(err), parent=self.text)
Expand Down Expand Up @@ -170,6 +173,7 @@ def loadfile(self, filename):
self.text.insert("1.0", chars)
self.reset_undo()
self.set_filename(filename)
self.file_timestamp = file_timestamp
if converted:
# We need to save the conversion results first
# before being able to execute the code
Expand Down Expand Up @@ -206,7 +210,26 @@ def save(self, event):
if not self.filename:
self.save_as(event)
else:
# Check the time of most recent content modification so the
# user doesn't accidentally overwrite a newer version of the file.
try:
file_timestamp = self.getmtime(self.filename)
except OSError:
pass
else:
if self.file_timestamp != file_timestamp:
confirm = messagebox.askokcancel(
title="File has changed",
message=(
"The file has changed on disk since reading it!\n\n"
"Do you really want to overwrite it?"),
default=messagebox.CANCEL,
parent=self.text)
if not confirm:
return "break"

if self.writefile(self.filename):
self.file_timestamp = self.getmtime(self.filename)
self.set_saved(True)
try:
self.editwin.store_file_breaks()
Expand All @@ -219,6 +242,7 @@ def save_as(self, event):
filename = self.asksavefile()
if filename:
if self.writefile(filename):
self.file_timestamp = self.getmtime(filename)
self.set_filename(filename)
self.set_saved(1)
try:
Expand Down Expand Up @@ -251,6 +275,9 @@ def writefile(self, filename):
parent=self.text)
return False

def getmtime(self, filename):
return os.stat(filename).st_mtime

def fixnewlines(self):
"""Return text with os eols.

Expand Down
29 changes: 29 additions & 0 deletions Lib/test/test_free_threading/test_gc.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,35 @@ def setter():
finally:
gc.set_threshold(*current_threshold)

def test_get_count(self):
class CyclicReference:
def __init__(self):
self.ref = self

NUM_ALLOCATORS = 7
NUM_READERS = 1
NUM_THREADS = NUM_ALLOCATORS + NUM_READERS
NUM_ITERS = 1000

barrier = threading.Barrier(NUM_THREADS)

def allocator():
barrier.wait()
for _ in range(NUM_ITERS):
CyclicReference()


def reader():
barrier.wait()
for _ in range(NUM_ITERS):
gc.get_count()

threads = [Thread(target=allocator) for _ in range(NUM_ALLOCATORS)]
threads.extend(Thread(target=reader) for _ in range(NUM_READERS))

with threading_helper.start_threads(threads):
pass


if __name__ == "__main__":
unittest.main()
2 changes: 1 addition & 1 deletion Lib/urllib/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ def _hostinfo(self):
return hostname, port


_UNSPECIFIED = ['not specified']
_UNSPECIFIED = sentinel("_UNSPECIFIED", repr="<not specified>")
_MISSING_AS_NONE_DEFAULT = False

class _ResultBase:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix a data race in the free-threaded build when :func:`gc.get_count` reads
the young generation allocation count while another thread updates it.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Warn the user if a file will be overwritten when saving.
2 changes: 1 addition & 1 deletion Modules/gcmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ gc_get_count_impl(PyObject *module)
gcstate->generations[2].count);
#else
return Py_BuildValue("(iii)",
gcstate->young.count,
_Py_atomic_load_int_relaxed(&gcstate->young.count),
gcstate->old[0].count,
gcstate->old[1].count);
#endif
Expand Down
Loading