Skip to content

Commit c6858d1

Browse files
authoredMar 9, 2023
pythongh-102255: Improve build support for Windows API partitions (pythonGH-102256)
Add `MS_WINDOWS_DESKTOP`, `MS_WINDOWS_APPS`, `MS_WINDOWS_SYSTEM` and `MS_WINDOWS_GAMES` preprocessor definitions to allow switching off functionality missing from particular API partitions ("partitions" are used in Windows to identify overlapping subsets of APIs). CPython only officially supports `MS_WINDOWS_DESKTOP` and `MS_WINDOWS_SYSTEM` (APPS is included by normal desktop builds, but APPS without DESKTOP is not covered). Other configurations are a convenience for people building their own runtimes. `MS_WINDOWS_GAMES` is for the Xbox subset of the Windows API, which is also available on client OS, but is restricted compared to `MS_WINDOWS_DESKTOP`. These restrictions may change over time, as they relate to the build headers rather than the OS support, and so we assume that Xbox builds will use the latest available version of the GDK.
1 parent ca066bd commit c6858d1

36 files changed

+633
-100
lines changed
 

‎Include/internal/pycore_fileutils.h

+8
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,14 @@ extern int _Py_add_relfile(wchar_t *dirname,
251251
extern size_t _Py_find_basename(const wchar_t *filename);
252252
PyAPI_FUNC(wchar_t *) _Py_normpath(wchar_t *path, Py_ssize_t size);
253253

254+
// The Windows Games API family does not provide these functions
255+
// so provide our own implementations. Remove them in case they get added
256+
// to the Games API family
257+
#if defined(MS_WINDOWS_GAMES) && !defined(MS_WINDOWS_DESKTOP)
258+
#include <winerror.h>
259+
260+
extern HRESULT PathCchSkipRoot(const wchar_t *pszPath, const wchar_t **ppszRootEnd);
261+
#endif /* defined(MS_WINDOWS_GAMES) && !defined(MS_WINDOWS_DESKTOP) */
254262

255263
// Macros to protect CRT calls against instant termination when passed an
256264
// invalid parameter (bpo-23524). IPH stands for Invalid Parameter Handler.

‎Lib/test/test_os.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -3084,11 +3084,13 @@ def test_device_encoding(self):
30843084
class PidTests(unittest.TestCase):
30853085
@unittest.skipUnless(hasattr(os, 'getppid'), "test needs os.getppid")
30863086
def test_getppid(self):
3087-
p = subprocess.Popen([sys.executable, '-c',
3087+
p = subprocess.Popen([sys._base_executable, '-c',
30883088
'import os; print(os.getppid())'],
3089-
stdout=subprocess.PIPE)
3090-
stdout, _ = p.communicate()
3089+
stdout=subprocess.PIPE,
3090+
stderr=subprocess.PIPE)
3091+
stdout, error = p.communicate()
30913092
# We are the parent of our subprocess
3093+
self.assertEqual(error, b'')
30923094
self.assertEqual(int(stdout), os.getpid())
30933095

30943096
def check_waitpid(self, code, exitcode, callback=None):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve build support for the Xbox. Patch by Max Bachmann.

‎Modules/_io/_iomodule.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode,
317317
_PyIO_State *state = get_io_state(module);
318318
{
319319
PyObject *RawIO_class = (PyObject *)state->PyFileIO_Type;
320-
#ifdef MS_WINDOWS
320+
#ifdef HAVE_WINDOWS_CONSOLE_IO
321321
const PyConfig *config = _Py_GetConfig();
322322
if (!config->legacy_windows_stdio && _PyIO_get_console_type(path_or_fd) != '\0') {
323323
RawIO_class = (PyObject *)&PyWindowsConsoleIO_Type;
@@ -660,7 +660,7 @@ static PyTypeObject* static_types[] = {
660660

661661
// PyRawIOBase_Type(PyIOBase_Type) subclasses
662662
&_PyBytesIOBuffer_Type,
663-
#ifdef MS_WINDOWS
663+
#ifdef HAVE_WINDOWS_CONSOLE_IO
664664
&PyWindowsConsoleIO_Type,
665665
#endif
666666
};
@@ -718,7 +718,7 @@ PyInit__io(void)
718718
}
719719

720720
// Set type base classes
721-
#ifdef MS_WINDOWS
721+
#ifdef HAVE_WINDOWS_CONSOLE_IO
722722
PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type;
723723
#endif
724724

‎Modules/_io/_iomodule.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ extern PyType_Spec fileio_spec;
2626
extern PyType_Spec stringio_spec;
2727
extern PyType_Spec textiowrapper_spec;
2828

29-
#ifdef MS_WINDOWS
29+
#ifdef HAVE_WINDOWS_CONSOLE_IO
3030
extern PyTypeObject PyWindowsConsoleIO_Type;
31-
#endif /* MS_WINDOWS */
31+
#endif /* HAVE_WINDOWS_CONSOLE_IO */
3232

3333
/* These functions are used as METH_NOARGS methods, are normally called
3434
* with args=NULL, and return a new reference.
@@ -178,7 +178,7 @@ find_io_state_by_def(PyTypeObject *type)
178178

179179
extern _PyIO_State *_PyIO_get_module_state(void);
180180

181-
#ifdef MS_WINDOWS
181+
#ifdef HAVE_WINDOWS_CONSOLE_IO
182182
extern char _PyIO_get_console_type(PyObject *);
183183
#endif
184184

‎Modules/_io/clinic/winconsoleio.c.h

+21-21
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Modules/_io/fileio.c

+2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@
3737
#ifdef MS_WINDOWS
3838
/* can simulate truncate with Win32 API functions; see file_truncate */
3939
#define HAVE_FTRUNCATE
40+
#ifndef WIN32_LEAN_AND_MEAN
4041
#define WIN32_LEAN_AND_MEAN
42+
#endif
4143
#include <windows.h>
4244
#endif
4345

‎Modules/_io/winconsoleio.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include "pycore_fileutils.h" // _Py_BEGIN_SUPPRESS_IPH
1212
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
1313

14-
#ifdef MS_WINDOWS
14+
#ifdef HAVE_WINDOWS_CONSOLE_IO
1515

1616
#include "structmember.h" // PyMemberDef
1717
#ifdef HAVE_SYS_TYPES_H
@@ -22,7 +22,9 @@
2222
#endif
2323
#include <stddef.h> /* For offsetof */
2424

25+
#ifndef WIN32_LEAN_AND_MEAN
2526
#define WIN32_LEAN_AND_MEAN
27+
#endif
2628
#include <windows.h>
2729
#include <fcntl.h>
2830

@@ -1177,4 +1179,4 @@ PyTypeObject PyWindowsConsoleIO_Type = {
11771179
0, /* tp_finalize */
11781180
};
11791181

1180-
#endif /* MS_WINDOWS */
1182+
#endif /* HAVE_WINDOWS_CONSOLE_IO */

‎Modules/_localemodule.c

+5-3
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ This software comes with no warranty. Use at your own risk.
3535
#endif
3636

3737
#if defined(MS_WINDOWS)
38+
#ifndef WIN32_LEAN_AND_MEAN
3839
#define WIN32_LEAN_AND_MEAN
40+
#endif
3941
#include <windows.h>
4042
#endif
4143

@@ -457,12 +459,12 @@ _locale__getdefaultlocale_impl(PyObject *module)
457459

458460
PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP());
459461

460-
if (GetLocaleInfo(LOCALE_USER_DEFAULT,
462+
if (GetLocaleInfoA(LOCALE_USER_DEFAULT,
461463
LOCALE_SISO639LANGNAME,
462464
locale, sizeof(locale))) {
463465
Py_ssize_t i = strlen(locale);
464466
locale[i++] = '_';
465-
if (GetLocaleInfo(LOCALE_USER_DEFAULT,
467+
if (GetLocaleInfoA(LOCALE_USER_DEFAULT,
466468
LOCALE_SISO3166CTRYNAME,
467469
locale+i, (int)(sizeof(locale)-i)))
468470
return Py_BuildValue("ss", locale, encoding);
@@ -474,7 +476,7 @@ _locale__getdefaultlocale_impl(PyObject *module)
474476

475477
locale[0] = '0';
476478
locale[1] = 'x';
477-
if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
479+
if (GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE,
478480
locale+2, sizeof(locale)-2)) {
479481
return Py_BuildValue("ss", locale, encoding);
480482
}

‎Modules/_multiprocessing/multiprocessing.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
*/
1313

1414
#ifdef MS_WINDOWS
15-
# define WIN32_LEAN_AND_MEAN
15+
# ifndef WIN32_LEAN_AND_MEAN
16+
# define WIN32_LEAN_AND_MEAN
17+
# endif
1618
# include <windows.h>
1719
# include <winsock2.h>
1820
# include <process.h> /* getpid() */

‎Modules/_pickle.c

+6
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ enum {
4242
#define FLOAT FLOAT_
4343
#define INT INT_
4444
#define LONG LONG_
45+
46+
/* This can already be defined on Windows to set the character set
47+
the Windows header files treat as default */
48+
#ifdef UNICODE
49+
#undef UNICODE
50+
#endif
4551
#endif
4652

4753
/* Pickle opcodes. These must be kept updated with pickle.py.

‎Modules/_randommodule.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@
7777
# include <process.h> // getpid()
7878
#endif
7979

80+
#ifdef MS_WINDOWS
81+
# include <windows.h>
82+
#endif
83+
8084
/* Period parameters -- These are all magic. Don't change. */
8185
#define N 624
8286
#define M 397
@@ -259,7 +263,7 @@ random_seed_time_pid(RandomObject *self)
259263
key[0] = (uint32_t)(now & 0xffffffffU);
260264
key[1] = (uint32_t)(now >> 32);
261265

262-
#ifdef MS_WINDOWS_NON_DESKTOP
266+
#if defined(MS_WINDOWS) && !defined(MS_WINDOWS_DESKTOP) && !defined(MS_WINDOWS_SYSTEM)
263267
key[2] = (uint32_t)GetCurrentProcessId();
264268
#elif defined(HAVE_GETPID)
265269
key[2] = (uint32_t)getpid();

‎Modules/_ssl.c

+4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
/* Include symbols from _socket module */
2929
#include "socketmodule.h"
3030

31+
#ifdef MS_WINDOWS
32+
# include <wincrypt.h>
33+
#endif
34+
3135
#include "_ssl.h"
3236

3337
/* Redefined below for Windows debug builds after important #includes */

‎Modules/_winapi.c

+13
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,11 @@
3939
#include "structmember.h" // PyMemberDef
4040

4141

42+
#ifndef WINDOWS_LEAN_AND_MEAN
4243
#define WINDOWS_LEAN_AND_MEAN
44+
#endif
4345
#include "windows.h"
46+
#include <winioctl.h>
4447
#include <crtdbg.h>
4548
#include "winreparse.h"
4649

@@ -63,6 +66,14 @@
6366

6467
#define T_HANDLE T_POINTER
6568

69+
// winbase.h limits the STARTF_* flags to the desktop API as of 10.0.19041.
70+
#ifndef STARTF_USESHOWWINDOW
71+
#define STARTF_USESHOWWINDOW 0x00000001
72+
#endif
73+
#ifndef STARTF_USESTDHANDLES
74+
#define STARTF_USESTDHANDLES 0x00000100
75+
#endif
76+
6677
typedef struct {
6778
PyTypeObject *overlapped_type;
6879
} WinApiState;
@@ -1201,8 +1212,10 @@ _winapi_ExitProcess_impl(PyObject *module, UINT ExitCode)
12011212
/*[clinic end generated code: output=a387deb651175301 input=4f05466a9406c558]*/
12021213
{
12031214
#if defined(Py_DEBUG)
1215+
#ifdef MS_WINDOWS_DESKTOP
12041216
SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOALIGNMENTFAULTEXCEPT|
12051217
SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX);
1218+
#endif
12061219
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
12071220
#endif
12081221

0 commit comments

Comments
 (0)
Please sign in to comment.