summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/platform.rst15
-rw-r--r--Lib/distutils/_msvccompiler.py16
-rw-r--r--Lib/distutils/spawn.py2
-rw-r--r--Lib/distutils/sysconfig.py1
-rw-r--r--Lib/distutils/util.py16
-rwxr-xr-xLib/platform.py21
-rw-r--r--Lib/sysconfig.py2
-rw-r--r--Lib/test/test_codecs.py32
-rw-r--r--Lib/test/test_mimetypes.py3
-rw-r--r--Lib/test/test_os.py3
-rw-r--r--Lib/test/test_startfile.py2
-rw-r--r--Lib/test/test_sundry.py3
-rw-r--r--Lib/test/test_winreg.py3
-rw-r--r--Misc/NEWS.d/next/Windows/2019-04-22-16-59-20.bpo-35920.VSfGOI.rst3
-rw-r--r--PC/bdist_wininst/bdist_wininst.vcxproj16
-rw-r--r--PCbuild/build.bat2
-rw-r--r--PCbuild/pcbuild.sln9
17 files changed, 134 insertions, 15 deletions
diff --git a/Doc/library/platform.rst b/Doc/library/platform.rst
index 60c6089..e07f9d6 100644
--- a/Doc/library/platform.rst
+++ b/Doc/library/platform.rst
@@ -216,6 +216,21 @@ Windows Platform
later (support for this was added in Python 2.6). It obviously
only runs on Win32 compatible platforms.
+.. function:: win32_edition()
+
+ Returns a string representing the current Windows edition. Possible
+ values include but are not limited to ``'Enterprise'``, ``'IoTUAP'``,
+ ``'ServerStandard'``, and ``'nanoserver'``.
+
+ .. versionadded:: 3.8
+
+.. function:: win32_is_iot()
+
+ Returns True if the windows edition returned by win32_edition is recognized
+ as an IoT edition.
+
+ .. versionadded:: 3.8
+
Mac OS Platform
---------------
diff --git a/Lib/distutils/_msvccompiler.py b/Lib/distutils/_msvccompiler.py
index 58b20a2..c7ac3f0 100644
--- a/Lib/distutils/_msvccompiler.py
+++ b/Lib/distutils/_msvccompiler.py
@@ -89,13 +89,24 @@ def _find_vc2017():
return None, None
+PLAT_SPEC_TO_RUNTIME = {
+ 'x86' : 'x86',
+ 'x86_amd64' : 'x64',
+ 'x86_arm' : 'arm',
+}
+
def _find_vcvarsall(plat_spec):
_, best_dir = _find_vc2017()
vcruntime = None
- vcruntime_plat = 'x64' if 'amd64' in plat_spec else 'x86'
+
+ if plat_spec in PLAT_SPEC_TO_RUNTIME:
+ vcruntime_plat = PLAT_SPEC_TO_RUNTIME[plat_spec]
+ else:
+ vcruntime_plat = 'x64' if 'amd64' in plat_spec else 'x86'
+
if best_dir:
vcredist = os.path.join(best_dir, "..", "..", "redist", "MSVC", "**",
- "Microsoft.VC141.CRT", "vcruntime140.dll")
+ vcruntime_plat, "Microsoft.VC141.CRT", "vcruntime140.dll")
try:
import glob
vcruntime = glob.glob(vcredist, recursive=True)[-1]
@@ -178,6 +189,7 @@ def _find_exe(exe, paths=None):
PLAT_TO_VCVARS = {
'win32' : 'x86',
'win-amd64' : 'x86_amd64',
+ 'win-arm32' : 'x86_arm',
}
# A set containing the DLLs that are guaranteed to be available for
diff --git a/Lib/distutils/spawn.py b/Lib/distutils/spawn.py
index d3a12c2..ceb9494 100644
--- a/Lib/distutils/spawn.py
+++ b/Lib/distutils/spawn.py
@@ -81,7 +81,6 @@ def _spawn_nt(cmd, search_path=1, verbose=0, dry_run=0):
"command %r failed with exit status %d" % (cmd, rc))
if sys.platform == 'darwin':
- from distutils import sysconfig
_cfg_target = None
_cfg_target_split = None
@@ -95,6 +94,7 @@ def _spawn_posix(cmd, search_path=1, verbose=0, dry_run=0):
if sys.platform == 'darwin':
global _cfg_target, _cfg_target_split
if _cfg_target is None:
+ from distutils import sysconfig
_cfg_target = sysconfig.get_config_var(
'MACOSX_DEPLOYMENT_TARGET') or ''
if _cfg_target:
diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py
index 570a612..b51629e 100644
--- a/Lib/distutils/sysconfig.py
+++ b/Lib/distutils/sysconfig.py
@@ -15,6 +15,7 @@ import re
import sys
from .errors import DistutilsPlatformError
+from .util import get_platform, get_host_platform
# These are needed in a couple of spots, so just compute them once.
PREFIX = os.path.normpath(sys.prefix)
diff --git a/Lib/distutils/util.py b/Lib/distutils/util.py
index 15cd2ad..50550e1 100644
--- a/Lib/distutils/util.py
+++ b/Lib/distutils/util.py
@@ -15,7 +15,7 @@ from distutils.spawn import spawn
from distutils import log
from distutils.errors import DistutilsByteCompileError
-def get_platform ():
+def get_host_platform():
"""Return a string that identifies the current platform. This is used mainly to
distinguish platform-specific build directories and platform-specific built
distributions. Typically includes the OS name and version and the
@@ -38,6 +38,8 @@ def get_platform ():
if os.name == 'nt':
if 'amd64' in sys.version.lower():
return 'win-amd64'
+ if '(arm)' in sys.version.lower():
+ return 'win-arm32'
return sys.platform
# Set for cross builds explicitly
@@ -90,8 +92,16 @@ def get_platform ():
return "%s-%s-%s" % (osname, release, machine)
-# get_platform ()
-
+def get_platform():
+ if os.name == 'nt':
+ TARGET_TO_PLAT = {
+ 'x86' : 'win32',
+ 'x64' : 'win-amd64',
+ 'arm' : 'win-arm32',
+ }
+ return TARGET_TO_PLAT.get(os.environ.get('VSCMD_ARG_TGT_ARCH')) or get_host_platform()
+ else:
+ return get_host_platform()
def convert_path (pathname):
"""Return 'pathname' as a name that will work on the native filesystem,
diff --git a/Lib/platform.py b/Lib/platform.py
index 21defd1..9f7bd95 100755
--- a/Lib/platform.py
+++ b/Lib/platform.py
@@ -334,6 +334,27 @@ _WIN32_SERVER_RELEASES = {
(6, None): "post2012ServerR2",
}
+def win32_is_iot():
+ return win32_edition() in ('IoTUAP', 'NanoServer', 'WindowsCoreHeadless', 'IoTEdgeOS')
+
+def win32_edition():
+ try:
+ try:
+ import winreg
+ except ImportError:
+ import _winreg as winreg
+ except ImportError:
+ pass
+ else:
+ try:
+ cvkey = r'SOFTWARE\Microsoft\Windows NT\CurrentVersion'
+ with winreg.OpenKeyEx(winreg.HKEY_LOCAL_MACHINE, cvkey) as key:
+ return winreg.QueryValueEx(key, 'EditionId')[0]
+ except OSError:
+ pass
+
+ return None
+
def win32_ver(release='', version='', csd='', ptype=''):
try:
from sys import getwindowsversion
diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py
index cc8c796..8446c8d 100644
--- a/Lib/sysconfig.py
+++ b/Lib/sysconfig.py
@@ -626,6 +626,8 @@ def get_platform():
if os.name == 'nt':
if 'amd64' in sys.version.lower():
return 'win-amd64'
+ if '(arm)' in sys.version.lower():
+ return 'win-arm32'
return sys.platform
if os.name != "posix" or not hasattr(os, 'uname'):
diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py
index 05843c5..027a84e 100644
--- a/Lib/test/test_codecs.py
+++ b/Lib/test/test_codecs.py
@@ -27,6 +27,26 @@ def coding_checker(self, coder):
self.assertEqual(coder(input), (expect, len(input)))
return check
+# On small versions of Windows like Windows IoT or Windows Nano Server not all codepages are present
+def is_code_page_present(cp):
+ from ctypes import POINTER, WINFUNCTYPE, windll, WinError, Structure, WinDLL
+ from ctypes.wintypes import BOOL, UINT, BYTE, WCHAR, UINT, DWORD
+
+ MAX_LEADBYTES = 12 # 5 ranges, 2 bytes ea., 0 term.
+ MAX_DEFAULTCHAR = 2 # single or double byte
+ MAX_PATH = 260
+ class CPINFOEXW(ctypes.Structure):
+ _fields_ = [("MaxCharSize", UINT),
+ ("DefaultChar", BYTE*MAX_DEFAULTCHAR),
+ ("LeadByte", BYTE*MAX_LEADBYTES),
+ ("UnicodeDefaultChar", WCHAR),
+ ("CodePage", UINT),
+ ("CodePageName", WCHAR*MAX_PATH)]
+
+ prototype = WINFUNCTYPE(BOOL, UINT, DWORD, POINTER(CPINFOEXW))
+ GetCPInfoEx = prototype(("GetCPInfoExW", WinDLL("kernel32")))
+ info = CPINFOEXW()
+ return GetCPInfoEx(cp, 0, info)
class Queue(object):
"""
@@ -3078,9 +3098,19 @@ class CodePageTest(unittest.TestCase):
def test_code_page_decode_flags(self):
# Issue #36312: For some code pages (e.g. UTF-7) flags for
# MultiByteToWideChar() must be set to 0.
+ if support.verbose:
+ sys.stdout.write('\n')
for cp in (50220, 50221, 50222, 50225, 50227, 50229,
*range(57002, 57011+1), 65000):
- self.assertEqual(codecs.code_page_decode(cp, b'abc'), ('abc', 3))
+ # On small versions of Windows like Windows IoT
+ # not all codepages are present.
+ # A missing codepage causes an OSError exception
+ # so check for the codepage before decoding
+ if is_code_page_present(cp):
+ self.assertEqual(codecs.code_page_decode(cp, b'abc'), ('abc', 3), f'cp{cp}')
+ else:
+ if support.verbose:
+ print(f" skipping cp={cp}")
self.assertEqual(codecs.code_page_decode(42, b'abc'),
('\uf061\uf062\uf063', 3))
diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py
index 554d3d5..c4b2fe2 100644
--- a/Lib/test/test_mimetypes.py
+++ b/Lib/test/test_mimetypes.py
@@ -6,6 +6,7 @@ import sys
import unittest
from test import support
+from platform import win32_edition
# Tell it we don't know about external files:
mimetypes.knownfiles = []
@@ -116,6 +117,8 @@ class Win32MimeTypesTestCase(unittest.TestCase):
mimetypes.types_map.clear()
mimetypes.types_map.update(self.original_types_map)
+ @unittest.skipIf(win32_edition() in ('NanoServer', 'WindowsCoreHeadless', 'IoTEdgeOS'),
+ "MIME types registry keys unavailable")
def test_registry_parsing(self):
# the original, minimum contents of the MIME database in the
# Windows registry is undocumented AFAIK.
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index bbadb81..a2021b1 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -28,6 +28,7 @@ import unittest
import uuid
import warnings
from test import support
+from platform import win32_is_iot
try:
import resource
@@ -2439,7 +2440,7 @@ class DeviceEncodingTests(unittest.TestCase):
# Return None when an fd doesn't actually exist.
self.assertIsNone(os.device_encoding(123456))
- @unittest.skipUnless(os.isatty(0) and (sys.platform.startswith('win') or
+ @unittest.skipUnless(os.isatty(0) and not win32_is_iot() and (sys.platform.startswith('win') or
(hasattr(locale, 'nl_langinfo') and hasattr(locale, 'CODESET'))),
'test requires a tty and either Windows or nl_langinfo(CODESET)')
def test_device_encoding(self):
diff --git a/Lib/test/test_startfile.py b/Lib/test/test_startfile.py
index f59252e..1a26a80 100644
--- a/Lib/test/test_startfile.py
+++ b/Lib/test/test_startfile.py
@@ -10,6 +10,7 @@
import unittest
from test import support
import os
+import platform
import sys
from os import path
@@ -20,6 +21,7 @@ class TestCase(unittest.TestCase):
def test_nonexisting(self):
self.assertRaises(OSError, startfile, "nonexisting.vbs")
+ @unittest.skipIf(platform.win32_is_iot(), "starting files is not supported on Windows IoT Core or nanoserver")
def test_empty(self):
# We need to make sure the child process starts in a directory
# we're not about to delete. If we're running under -j, that
diff --git a/Lib/test/test_sundry.py b/Lib/test/test_sundry.py
index 6e36a61..2accad1 100644
--- a/Lib/test/test_sundry.py
+++ b/Lib/test/test_sundry.py
@@ -1,5 +1,6 @@
"""Do a minimal test of all the modules that aren't otherwise tested."""
import importlib
+import platform
import sys
from test import support
import unittest
@@ -25,7 +26,7 @@ class TestUntestedModules(unittest.TestCase):
import distutils.unixccompiler
import distutils.command.bdist_dumb
- if sys.platform.startswith('win'):
+ if sys.platform.startswith('win') and not platform.win32_is_iot():
import distutils.command.bdist_msi
import distutils.command.bdist
import distutils.command.bdist_rpm
diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py
index 11d054e..dc2b46e 100644
--- a/Lib/test/test_winreg.py
+++ b/Lib/test/test_winreg.py
@@ -5,7 +5,7 @@ import os, sys, errno
import unittest
from test import support
import threading
-from platform import machine
+from platform import machine, win32_edition
# Do this first so test will be skipped if module doesn't exist
support.import_module('winreg', required_on=['win'])
@@ -399,6 +399,7 @@ class Win64WinregTests(BaseWinregTests):
DeleteKeyEx(key=HKEY_CURRENT_USER, sub_key=test_key_name,
access=KEY_ALL_ACCESS, reserved=0)
+ @unittest.skipIf(win32_edition() in ('WindowsCoreHeadless', 'IoTEdgeOS'), "APIs not available on WindowsCoreHeadless")
def test_reflection_functions(self):
# Test that we can call the query, enable, and disable functions
# on a key which isn't on the reflection list with no consequences.
diff --git a/Misc/NEWS.d/next/Windows/2019-04-22-16-59-20.bpo-35920.VSfGOI.rst b/Misc/NEWS.d/next/Windows/2019-04-22-16-59-20.bpo-35920.VSfGOI.rst
new file mode 100644
index 0000000..455e824
--- /dev/null
+++ b/Misc/NEWS.d/next/Windows/2019-04-22-16-59-20.bpo-35920.VSfGOI.rst
@@ -0,0 +1,3 @@
+Added platform.win32_edition() and platform.win32_is_iot(). Added support
+for cross-compiling packages for Windows ARM32. Skip tests that are not
+expected to work on Windows IoT Core ARM32.
diff --git a/PC/bdist_wininst/bdist_wininst.vcxproj b/PC/bdist_wininst/bdist_wininst.vcxproj
index 70bfb9c..d2f1bb7 100644
--- a/PC/bdist_wininst/bdist_wininst.vcxproj
+++ b/PC/bdist_wininst/bdist_wininst.vcxproj
@@ -1,6 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|ARM">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
@@ -9,6 +13,10 @@
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
+ <ProjectConfiguration Include="PGInstrument|ARM">
+ <Configuration>PGInstrument</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
<ProjectConfiguration Include="PGInstrument|Win32">
<Configuration>PGInstrument</Configuration>
<Platform>Win32</Platform>
@@ -17,6 +25,10 @@
<Configuration>PGInstrument</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
+ <ProjectConfiguration Include="PGUpdate|ARM">
+ <Configuration>PGUpdate</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
<ProjectConfiguration Include="PGUpdate|Win32">
<Configuration>PGUpdate</Configuration>
<Platform>Win32</Platform>
@@ -25,6 +37,10 @@
<Configuration>PGUpdate</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM">
+ <Configuration>Release</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
diff --git a/PCbuild/build.bat b/PCbuild/build.bat
index 759aa52..cd0c07a 100644
--- a/PCbuild/build.bat
+++ b/PCbuild/build.bat
@@ -41,7 +41,7 @@ echo.
echo.Available arguments:
echo. -c Release ^| Debug ^| PGInstrument ^| PGUpdate
echo. Set the configuration (default: Release)
-echo. -p x64 ^| Win32
+echo. -p x64 ^| Win32 ^| ARM
echo. Set the platform (default: Win32)
echo. -t Build ^| Rebuild ^| Clean ^| CleanAll
echo. Set the target manually
diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln
index 951dc93..66be9ac 100644
--- a/PCbuild/pcbuild.sln
+++ b/PCbuild/pcbuild.sln
@@ -597,16 +597,16 @@ Global
{D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|Win32.Build.0 = Release|Win32
{D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.ActiveCfg = Release|x64
{D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.Build.0 = Release|x64
- {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|ARM.ActiveCfg = Debug|Win32
+ {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|ARM.ActiveCfg = Debug|ARM
{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|Win32.ActiveCfg = Debug|Win32
{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|x64.ActiveCfg = Release|x64
- {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|ARM.ActiveCfg = PGInstrument|Win32
+ {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM
{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|Win32.ActiveCfg = Release|Win32
{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|x64.ActiveCfg = Release|x64
- {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|ARM.ActiveCfg = PGUpdate|Win32
+ {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM
{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|Win32.ActiveCfg = Release|Win32
{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|x64.ActiveCfg = Release|x64
- {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|ARM.ActiveCfg = Release|Win32
+ {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|ARM.ActiveCfg = Release|ARM
{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|Win32.ActiveCfg = Release|Win32
{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|x64.ActiveCfg = Release|x64
{447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|ARM.ActiveCfg = Debug|ARM
@@ -896,6 +896,7 @@ Global
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|x64.ActiveCfg = PGUpdate|x64
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|x64.Build.0 = PGUpdate|x64
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|ARM.ActiveCfg = Release|ARM
+ {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|ARM.Build.0 = Release|ARM
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|Win32.ActiveCfg = Release|Win32
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|Win32.Build.0 = Release|Win32
{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|x64.ActiveCfg = Release|x64