Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into DisplayException
Browse files Browse the repository at this point in the history
  • Loading branch information
iritkatriel committed Mar 16, 2023
2 parents 2c4f399 + 0f17576 commit ab84a68
Show file tree
Hide file tree
Showing 22 changed files with 552 additions and 175 deletions.
88 changes: 65 additions & 23 deletions Doc/library/os.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2858,6 +2858,12 @@ features:
Added support for the :class:`~os.PathLike` interface. Added support
for :class:`bytes` paths on Windows.

.. versionchanged:: 3.12
The ``st_ctime`` attribute of a stat result is deprecated on Windows.
The file creation time is properly available as ``st_birthtime``, and
in the future ``st_ctime`` may be changed to return zero or the
metadata change time, if available.


.. function:: stat(path, *, dir_fd=None, follow_symlinks=True)

Expand Down Expand Up @@ -2973,10 +2979,12 @@ features:

.. attribute:: st_ctime

Platform dependent:
Time of most recent metadata change expressed in seconds.

* the time of most recent metadata change on Unix,
* the time of creation on Windows, expressed in seconds.
.. versionchanged:: 3.12
``st_ctime`` is deprecated on Windows. Use ``st_birthtime`` for
the file creation time. In the future, ``st_ctime`` will contain
the time of the most recent metadata change, as for other platforms.

.. attribute:: st_atime_ns

Expand All @@ -2989,29 +2997,48 @@ features:

.. attribute:: st_ctime_ns

Platform dependent:
Time of most recent metadata change expressed in nanoseconds as an
integer.

.. versionchanged:: 3.12
``st_ctime_ns`` is deprecated on Windows. Use ``st_birthtime_ns``
for the file creation time. In the future, ``st_ctime`` will contain
the time of the most recent metadata change, as for other platforms.

.. attribute:: st_birthtime

Time of file creation expressed in seconds. This attribute is not
always available, and may raise :exc:`AttributeError`.

.. versionchanged:: 3.12
``st_birthtime`` is now available on Windows.

.. attribute:: st_birthtime_ns

* the time of most recent metadata change on Unix,
* the time of creation on Windows, expressed in nanoseconds as an
integer.
Time of file creation expressed in nanoseconds as an integer.
This attribute is not always available, and may raise
:exc:`AttributeError`.

.. versionadded:: 3.12

.. note::

The exact meaning and resolution of the :attr:`st_atime`,
:attr:`st_mtime`, and :attr:`st_ctime` attributes depend on the operating
system and the file system. For example, on Windows systems using the FAT
or FAT32 file systems, :attr:`st_mtime` has 2-second resolution, and
:attr:`st_atime` has only 1-day resolution. See your operating system
documentation for details.
:attr:`st_mtime`, :attr:`st_ctime` and :attr:`st_birthtime` attributes
depend on the operating system and the file system. For example, on
Windows systems using the FAT32 file systems, :attr:`st_mtime` has
2-second resolution, and :attr:`st_atime` has only 1-day resolution.
See your operating system documentation for details.

Similarly, although :attr:`st_atime_ns`, :attr:`st_mtime_ns`,
and :attr:`st_ctime_ns` are always expressed in nanoseconds, many
systems do not provide nanosecond precision. On systems that do
provide nanosecond precision, the floating-point object used to
store :attr:`st_atime`, :attr:`st_mtime`, and :attr:`st_ctime`
cannot preserve all of it, and as such will be slightly inexact.
If you need the exact timestamps you should always use
:attr:`st_atime_ns`, :attr:`st_mtime_ns`, and :attr:`st_ctime_ns`.
:attr:`st_ctime_ns` and :attr:`st_birthtime_ns` are always expressed in
nanoseconds, many systems do not provide nanosecond precision. On
systems that do provide nanosecond precision, the floating-point object
used to store :attr:`st_atime`, :attr:`st_mtime`, :attr:`st_ctime` and
:attr:`st_birthtime` cannot preserve all of it, and as such will be
slightly inexact. If you need the exact timestamps you should always use
:attr:`st_atime_ns`, :attr:`st_mtime_ns`, :attr:`st_ctime_ns` and
:attr:`st_birthtime_ns`.

On some Unix systems (such as Linux), the following attributes may also be
available:
Expand Down Expand Up @@ -3041,10 +3068,6 @@ features:

File generation number.

.. attribute:: st_birthtime

Time of file creation.

On Solaris and derivatives, the following attributes may also be
available:

Expand Down Expand Up @@ -3117,6 +3140,25 @@ features:
files as :const:`S_IFCHR`, :const:`S_IFIFO` or :const:`S_IFBLK`
as appropriate.

.. versionchanged:: 3.12
On Windows, :attr:`st_ctime` is deprecated. Eventually, it will
contain the last metadata change time, for consistency with other
platforms, but for now still contains creation time.
Use :attr:`st_birthtime` for the creation time.

.. versionchanged:: 3.12
On Windows, :attr:`st_ino` may now be up to 128 bits, depending
on the file system. Previously it would not be above 64 bits, and
larger file identifiers would be arbitrarily packed.

.. versionchanged:: 3.12
On Windows, :attr:`st_rdev` no longer returns a value. Previously
it would contain the same as :attr:`st_dev`, which was incorrect.

.. versionadded:: 3.12
Added the :attr:`st_birthtime` member on Windows.


.. function:: statvfs(path)

Perform a :c:func:`statvfs` system call on the given path. The return value is
Expand Down
3 changes: 2 additions & 1 deletion Doc/library/random.rst
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,8 @@ from the combinatoric iterators in the :mod:`itertools` module:
return tuple(pool[i] for i in indices)

def random_combination_with_replacement(iterable, r):
"Random selection from itertools.combinations_with_replacement(iterable, r)"
"Choose r elements with replacement. Order the result to match the iterable."
# Result will be in set(itertools.combinations_with_replacement(iterable, r)).
pool = tuple(iterable)
n = len(pool)
indices = sorted(random.choices(range(n), k=r))
Expand Down
20 changes: 20 additions & 0 deletions Doc/whatsnew/3.12.rst
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,10 @@ asyncio
* Add C implementation of :func:`asyncio.current_task` for 4x-6x speedup.
(Contributed by Itamar Ostricher and Pranav Thulasiram Bhat in :gh:`100344`.)

* :func:`asyncio.iscoroutine` now returns ``False`` for generators as
:mod:`asyncio` does not support legacy generator-based coroutines.
(Contributed by Kumar Aditya in :gh:`102748`.)

inspect
-------

Expand Down Expand Up @@ -302,6 +306,16 @@ os
functions on Windows for enumerating drives, volumes and mount points.
(Contributed by Steve Dower in :gh:`102519`.)

* :func:`os.stat` and :func:`os.lstat` are now more accurate on Windows.
The ``st_birthtime`` field will now be filled with the creation time
of the file, and ``st_ctime`` is deprecated but still contains the
creation time (but in the future will return the last metadata change,
for consistency with other platforms). ``st_dev`` may be up to 64 bits
and ``st_ino`` up to 128 bits depending on your file system, and
``st_rdev`` is always set to zero rather than incorrect values.
Both functions may be significantly faster on newer releases of
Windows. (Contributed by Steve Dower in :gh:`99726`.)

os.path
-------

Expand Down Expand Up @@ -465,6 +479,12 @@ Deprecated
warning at compile time. This field will be removed in Python 3.14.
(Contributed by Ramvikrams and Kumar Aditya in :gh:`101193`. PEP by Ken Jin.)

* The ``st_ctime`` fields return by :func:`os.stat` and :func:`os.lstat` on
Windows are deprecated. In a future release, they will contain the last
metadata change time, consistent with other platforms. For now, they still
contain the creation time, which is also available in the new ``st_birthtime``
field. (Contributed by Steve Dower in :gh:`99726`.)

Pending Removal in Python 3.13
------------------------------

Expand Down
5 changes: 4 additions & 1 deletion Include/internal/pycore_fileutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ PyAPI_FUNC(PyObject *) _Py_device_encoding(int);

#ifdef MS_WINDOWS
struct _Py_stat_struct {
unsigned long st_dev;
uint64_t st_dev;
uint64_t st_ino;
unsigned short st_mode;
int st_nlink;
Expand All @@ -80,8 +80,11 @@ struct _Py_stat_struct {
int st_mtime_nsec;
time_t st_ctime;
int st_ctime_nsec;
time_t st_birthtime;
int st_birthtime_nsec;
unsigned long st_file_attributes;
unsigned long st_reparse_tag;
uint64_t st_ino_high;
};
#else
# define _Py_stat_struct stat
Expand Down
80 changes: 80 additions & 0 deletions Include/internal/pycore_fileutils_windows.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#ifndef Py_INTERNAL_FILEUTILS_WINDOWS_H
#define Py_INTERNAL_FILEUTILS_WINDOWS_H
#ifdef __cplusplus
extern "C" {
#endif

#ifndef Py_BUILD_CORE
# error "Py_BUILD_CORE must be defined to include this header"
#endif

#ifdef MS_WINDOWS

#if !defined(NTDDI_WIN10_NI) || !(NTDDI_VERSION >= NTDDI_WIN10_NI)
typedef struct _FILE_STAT_BASIC_INFORMATION {
LARGE_INTEGER FileId;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER AllocationSize;
LARGE_INTEGER EndOfFile;
ULONG FileAttributes;
ULONG ReparseTag;
ULONG NumberOfLinks;
ULONG DeviceType;
ULONG DeviceCharacteristics;
ULONG Reserved;
FILE_ID_128 FileId128;
LARGE_INTEGER VolumeSerialNumber;
} FILE_STAT_BASIC_INFORMATION;

typedef enum _FILE_INFO_BY_NAME_CLASS {
FileStatByNameInfo,
FileStatLxByNameInfo,
FileCaseSensitiveByNameInfo,
FileStatBasicByNameInfo,
MaximumFileInfoByNameClass
} FILE_INFO_BY_NAME_CLASS;
#endif

typedef BOOL (WINAPI *PGetFileInformationByName)(
PCWSTR FileName,
FILE_INFO_BY_NAME_CLASS FileInformationClass,
PVOID FileInfoBuffer,
ULONG FileInfoBufferSize
);

static inline BOOL _Py_GetFileInformationByName(
PCWSTR FileName,
FILE_INFO_BY_NAME_CLASS FileInformationClass,
PVOID FileInfoBuffer,
ULONG FileInfoBufferSize
) {
static PGetFileInformationByName GetFileInformationByName = NULL;
static int GetFileInformationByName_init = -1;

if (GetFileInformationByName_init < 0) {
HMODULE hMod = LoadLibraryW(L"api-ms-win-core-file-l2-1-4");
GetFileInformationByName_init = 0;
if (hMod) {
GetFileInformationByName = (PGetFileInformationByName)GetProcAddress(
hMod, "GetFileInformationByName");
if (GetFileInformationByName) {
GetFileInformationByName_init = 1;
} else {
FreeLibrary(hMod);
}
}
}

if (GetFileInformationByName_init <= 0) {
SetLastError(ERROR_NOT_SUPPORTED);
return FALSE;
}
return GetFileInformationByName(FileName, FileInformationClass, FileInfoBuffer, FileInfoBufferSize);
}

#endif

#endif
10 changes: 1 addition & 9 deletions Lib/_collections_abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,15 +481,8 @@ def __getitem__(self, item):
# rather than the default types.GenericAlias object. Most of the
# code is copied from typing's _GenericAlias and the builtin
# types.GenericAlias.

if not isinstance(item, tuple):
item = (item,)
# A special case in PEP 612 where if X = Callable[P, int],
# then X[int, str] == X[[int, str]].
if (len(self.__parameters__) == 1
and _is_param_expr(self.__parameters__[0])
and item and not _is_param_expr(item[0])):
item = (item,)

new_args = super().__getitem__(item).__args__

Expand Down Expand Up @@ -517,9 +510,8 @@ def _type_repr(obj):
Copied from :mod:`typing` since collections.abc
shouldn't depend on that module.
(Keep this roughly in sync with the typing version.)
"""
if isinstance(obj, GenericAlias):
return repr(obj)
if isinstance(obj, type):
if obj.__module__ == 'builtins':
return obj.__qualname__
Expand Down
3 changes: 1 addition & 2 deletions Lib/asyncio/coroutines.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ def iscoroutinefunction(func):

# Prioritize native coroutine check to speed-up
# asyncio.iscoroutine.
_COROUTINE_TYPES = (types.CoroutineType, types.GeneratorType,
collections.abc.Coroutine)
_COROUTINE_TYPES = (types.CoroutineType, collections.abc.Coroutine)
_iscoroutine_typecache = set()


Expand Down
6 changes: 6 additions & 0 deletions Lib/test/test_asyncio/test_pep492.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ async def foo(): pass

self.assertTrue(asyncio.iscoroutine(FakeCoro()))

def test_iscoroutine_generator(self):
def foo(): yield

self.assertFalse(asyncio.iscoroutine(foo()))


def test_iscoroutinefunction(self):
async def foo(): pass
self.assertTrue(asyncio.iscoroutinefunction(foo))
Expand Down
12 changes: 11 additions & 1 deletion Lib/test/test_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,15 @@ def trunc(x): return x
nanosecondy = getattr(result, name + "_ns") // 10000
self.assertAlmostEqual(floaty, nanosecondy, delta=2)

# Ensure both birthtime and birthtime_ns roughly agree, if present
try:
floaty = int(result.st_birthtime * 100000)
nanosecondy = result.st_birthtime_ns // 10000
except AttributeError:
pass
else:
self.assertAlmostEqual(floaty, nanosecondy, delta=2)

try:
result[200]
self.fail("No exception raised")
Expand Down Expand Up @@ -4234,7 +4243,8 @@ def assert_stat_equal(self, stat1, stat2, skip_fields):
for attr in dir(stat1):
if not attr.startswith("st_"):
continue
if attr in ("st_dev", "st_ino", "st_nlink"):
if attr in ("st_dev", "st_ino", "st_nlink", "st_ctime",
"st_ctime_ns"):
continue
self.assertEqual(getattr(stat1, attr),
getattr(stat2, attr),
Expand Down
Loading

0 comments on commit ab84a68

Please sign in to comment.