Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bpo-33671: Add support.MS_WINDOWS and support.MACOS #7800

Merged
merged 4 commits into from
Jun 22, 2018
Merged

bpo-33671: Add support.MS_WINDOWS and support.MACOS #7800

merged 4 commits into from
Jun 22, 2018

Conversation

vstinner
Copy link
Member

@vstinner vstinner commented Jun 19, 2018

  • MS_WINDOWS: True if Python is running on Microsoft Windows.
  • MACOS: True if Python is running on Apple macOS.
  • Rename support.is_android to support.ANDROID
  • Rename support.is_jython to support.JYTHON

https://bugs.python.org/issue33671

* MS_WINDOWS: True if Python is running on Microsoft Windows.
* MACOS: True if Python is running on Apple macOS.
@vstinner
Copy link
Member Author

This change is not related to fast file copies, it just that I found the idea when reading commits of https://bugs.python.org/issue33671 :-)

@vstinner
Copy link
Member Author

I tried to write the smallest change. There are much more tests testing the platform, but I don't think that it's worth it to update all existing code.

@vstinner
Copy link
Member Author

cc @serhiy-storchaka @giampaolo

@giampaolo
Copy link
Contributor

Nice! Why not cover all platforms?

$ grep -r "sys.platform" Lib/test/ | grep bsd | wc -l
19
$ grep -r "sys.platform" Lib/test/ | grep solaris | wc -l
2
$ grep -r "sys.platform" Lib/test/ | grep aix | wc -l
18
$ grep -r "os.name" Lib/test/  | grep posix | wc -l
41

You can use psutil as an example:
https://github.com/giampaolo/psutil/blob/abbe589de7e6109849924bf6172bd40132fdfc5c/psutil/_common.py#L70-L84

Also, (personal taste), I would use "WINDOWS" instead of "MS_WINDOWS". It would be nice to have a test case in Lib\test\test_support.py which makes sure that only 1 of such constants is true and all others are False.

Copy link
Contributor

@ngnpope ngnpope left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @giampaolo - ditch the MS prefix.

Also these should either be is_windowsand is_macos - to match the existing is_android and is_jython - or the latter should be changed to ANDROID and JYTHON.

@@ -108,6 +108,18 @@
"run_with_tz", "PGO", "missing_compiler_executable", "fd_count",
]


# True if Python is running on Microsoft Windows.
MS_WINDOWS = (sys.platform == 'win32')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we happy this is suitable for replacing all of the following without changing behaviour?

mswindows = (sys.platform == "win32")
MS_WINDOWS = (sys.platform == 'win32')
MS_WINDOWS = (os.name == 'nt')
WIN32 = (sys.platform == "win32")
sys.platform[:3] == 'win'

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sys.platform[:3] == 'win'

On "win64", Python uses "win32" as well.

MS_WINDOWS = (os.name == 'nt')

I'm not sure about Cygwin which is a strange beast.

MS_WINDOWS = (sys.platform == 'win32')

# True if Python is running on Apple macOS.
MACOS = (sys.platform == 'darwin')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise here:

MACOS = sys.platform.startswith("darwin")
sys.platform == 'darwin'

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MACOS = sys.platform.startswith("darwin")

I don't see the purpose of this test. sys.platform is always the "darwin" string on macOS, no?

@ngnpope
Copy link
Contributor

ngnpope commented Jun 20, 2018

It would be nice to have a test case in Lib\test\test_support.py which makes sure that only 1 of such constants is true and all others are False.

A test that ensures Windows, macOS, Linux, etc. are exclusive would make sense, but note that Linux and POSIX, for example, can both be true.

@vstinner
Copy link
Member Author

Nice! Why not cover all platforms?

See my previous comment: #7800 (comment)

I don't want to write a giant "coding style change". It would make backports painful for everyone, especially for downstream patches. But maybe I will backport this small change to all stable branches.

is_android = hasattr(sys, 'getandroidapilevel')

if sys.platform != 'win32':
if not MS_WINDOWS:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if MS_WINDOWS:
    ...
elif is_androif:
    ...
else:
    ...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum, this change is unrelated, but ok, let's do that :-)

@@ -108,6 +108,18 @@
"run_with_tz", "PGO", "missing_compiler_executable", "fd_count",
]


# True if Python is running on Microsoft Windows.
MS_WINDOWS = (sys.platform == 'win32')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't be better to use is_windows and is_macos for uniformity with is_jython and is_android?

Or rename the latter two?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I replied here: #7800 (comment)

If we do something, I would prefer to rename is_android and is_jython to ANDROID and JYTHON to be more consistent with PEP 8 and existing code (rather than adding support.is_windows and support.is_macos).

@serhiy-storchaka
Copy link
Member

What is the benefit from this change?

@vstinner
Copy link
Member Author

Also, (personal taste), I would use "WINDOWS" instead of "MS_WINDOWS". It would be nice to have a test case in Lib\test\test_support.py which makes sure that only 1 of such constants is true and all others are False.

MS_WINDOWS or mswindows is already used in the code base. I guess that it avoids confusion with a physical window. Think about GUI tests like IDLE or Tkinter. Moreover, the C code uses "#ifdef MS_WINDOWS": so it's also about consistency.

@vstinner
Copy link
Member Author

Also these should either be is_windowsand is_macos - to match the existing is_android and is_jython - or the latter should be changed to ANDROID and JYTHON.

I hesitate to rename lowercase is_android to ANDROID, but I have no strong opinion about that one. Maybe it's fine to keep inconstency here? Again, uppercase MS_WINDOWS is also used in C: "#ifdef MS_WINDOWS".

@vstinner
Copy link
Member Author

What is the benefit from this change?

I always hesitate between (os.name == 'nt') and (sys.platform == 'win32'): sys.platform == 'win32' looks suspicious on 64-bit Windows, and NT is the legacy name of Windows... I prefer an obvious MS_WINDOWS constant: it's no needed to guess what is the correct way to detect Windows, and the name is more explicit and less surprising.

Same for macOS: "darwin" is not well known, at least, less known than "macOS". Darwin is the name of the macOS kernel.

More generally, there are already MACOS and MS_WINDOWS constants. Another goal is to factorize the code.

@giampaolo
Copy link
Contributor

What is the benefit from this change?

Put all OS-recognizing logic in one place.

@vstinner
Copy link
Member Author

You can use psutil as an example:
https://github.com/giampaolo/psutil/blob/abbe589de7e6109849924bf6172bd40132fdfc5c/psutil/_common.py#L70-L84

In Python 3, testing for Linux is just sys.platform == 'linux'. IMHO the test is obvious enough, no need for an additional constant.

For FreeBSD, in tests usually we want to skip tests on old versions of FreeBSD, and we already have @requires_freebsd_version decorator for that.

POSIX = os.name == "posix"

Again, IMHO this test is explicit enough, no need for an additonal constant.

BSD = FREEBSD or OPENBSD or NETBSD

I don't recall that any unit test uses/needs that.

I prefer to limit my PR to Windows and macOS for these reasons:
#7800 (comment)

@giampaolo
Copy link
Contributor

I don't want to write a giant "coding style change". It would make backports painful for everyone, especially for downstream patches. But maybe I will backport this small change to all stable branches.

+1 for backporting this. That's probably the best as it would allow to expose all the necessary constants instead of just a few.

@krytarowski
Copy link

BSD = FREEBSD or OPENBSD or NETBSD

Please don't pretend that there is a shared BSD target. And even if 3 of them do something in the same way, there are other unrelated BSD systems including dead ones. The main ones BSDs diverged in 1995! And there were even decade older forks like 386BSD.

It's almost like pretending that MINIX and LINUX should share a common check.

@giampaolo
Copy link
Contributor

I prefer to limit my PR to Windows and macOS for these reasons: #7800 (comment)

I see. I guess it makes sense. For the record, this argument is valid also for Solaris which can be detected in 2 ways:

SUNOS = sys.platform.startswith(("sunos", "solaris"))

There are 8 occurrences for that in Lib/test.

@vstinner
Copy link
Member Author

"For the record, this argument is valid also for Solaris which can be detected in 2 ways: (...) There are 8 occurrences for that in Lib/test."

Well, it's uncommon and Solaris is dying... :-)

@krytarowski
Copy link

Solaris has set EOL dates and the Illumos community.. isn't growing.

@vstinner
Copy link
Member Author

I added two additional changes to make my PR and test.support more consistent:

  • Rename support.is_android to support.ANDROID
  • Rename support.is_jython to support.JYTHON

@vstinner
Copy link
Member Author

If someone wants to add a new constant for a different OS (BSD, Solaris, whatever), please open a different issue. This PR is more about moving existing constants to test.support than adding new constants.

Copy link
Contributor

@giampaolo giampaolo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I didn't grep for all occurrences of Windows/OSX/Android/Jython but I trust you did.

@vstinner vstinner deleted the support_ms_windows branch June 22, 2018 17:25
@vstinner
Copy link
Member Author

Thank you for the review and advices @serhiy-storchaka, @giampaolo, @pope1ni and others!

@miss-islington
Copy link
Contributor

Thanks @vstinner for the PR 🌮🎉.. I'm working now to backport this PR to: 3.6.
🐍🍒⛏🤖 I'm not a witch! I'm not a witch!

@miss-islington
Copy link
Contributor

Thanks @vstinner for the PR 🌮🎉.. I'm working now to backport this PR to: 2.7.
🐍🍒⛏🤖 I'm not a witch! I'm not a witch!

@miss-islington
Copy link
Contributor

Thanks @vstinner for the PR 🌮🎉.. I'm working now to backport this PR to: 3.7.
🐍🍒⛏🤖

@miss-islington
Copy link
Contributor

Sorry, @vstinner, I could not cleanly backport this to 3.6 due to a conflict.
Please backport using cherry_picker on command line.
cherry_picker 8fbbdf0c3107c3052659e166f73990b466eacbb0 3.6

@miss-islington
Copy link
Contributor

Sorry, @vstinner, I could not cleanly backport this to 3.7 due to a conflict.
Please backport using cherry_picker on command line.
cherry_picker 8fbbdf0c3107c3052659e166f73990b466eacbb0 3.7

@miss-islington
Copy link
Contributor

Sorry, @vstinner, I could not cleanly backport this to 2.7 due to a conflict.
Please backport using cherry_picker on command line.
cherry_picker 8fbbdf0c3107c3052659e166f73990b466eacbb0 2.7

@ned-deily
Copy link
Member

Argh! Why would you make such a major change as part of a totally unrelated issue? It's major enough to warrant its own issue and discussion first. I'm really not keen on seeing all this questionable churn backported to the existing branches but without backporting that's going to make ongoing maintenance (i.e. automatic backporting) problematic. And people submitting changes are still going to need to be familiar with spellings like sys.platform == "darwin" and nt because those spellings are used throughout the non-test parts of the standard library; please don't try to change the non-test usages in maintenance branches as that may have impact on downstream users.

@ned-deily
Copy link
Member

Also, this change proposes a change in coding style for the tests, at least, that contributors to cpython, both core developers and non-committers, need to be aware of or else, over time, the existing spellings will start to reappear in the tests like they appear in the standard library.

@vstinner
Copy link
Member Author

Argh! Why would you make such a major change as part of a totally unrelated issue?

#7800 (comment)

@ned-deily: I'm not sure if you think about this change? Should it be reverted? I understand that you are are ok to backport it to other branches.

Are you suggesting to replace all sys.platform/os.name tests with the new constants? I propose to not modify everything to reduce the risk of conflicts on upstream and downstream patches.

Also, this change proposes a change in coding style for the tests, at least, that contributors to cpython, both core developers and non-committers, need to be aware of or else, over time, the existing spellings will start to reappear in the tests like they appear in the standard library.

It's ok :-)

@ned-deily
Copy link
Member

ned-deily commented Jun 23, 2018

@vstinner It seems to me there are a number of issues here. Let me see if I can articulate them.

  1. Independent of what we do for master, I really don't think a change like this should be backported to maintenance branches (3.7, 3.6, much less 2.7 - although that's not my call). As the devguide puts it: "The only changes allowed to occur in a maintenance branch without debate are bug fixes." I would add "documentation fixes". "Also, a general rule for maintenance branches is that compatibility must not be broken at any point between sibling minor releases (3.5.1, 3.5.2, etc.). For both rules, only rare exceptions are accepted and must be discussed first." So we clearly make exceptions for security fixes and possibly platform changes (new OS releases, etc) usually with discussions. And we are perhaps a little bit looser with the tests part of the branches, so, for example, accepting without a lot of discussion small changes to regrtest that bring meaningful improvements to running tests with a very small risk of introducing a downstream user incompatibility and without requiring a change in developer workflow. But I don't think this proposed change fits into any of those categories. At best, it doesn't introduce any new errors. But ...

  2. it does force unnecessary changes on all maintainers and inspectors of the code base. Something as simple as grepping the code base for sections relevant to a particular platform now has to change and people now have to know to do that, for example, grepping for 'darwin', something I do a lot, isn't sufficient anymore. And they would need to know to use these new spellings when adding or changing tests, ...

  3. something they would hardly know about unless they stumble across it by accident (like I did) or examine the changed code base and start wondering what the difference is between the old spellings and the new. At the moment, as far as I know, there is no mention of this major change on the bug tracker at all so you can't search there for it; the only discussion is here on a merged PR that is attached to a totally unrelated 3.8-only feature. That doesn't seem right.

  4. So if the changes remain in master and are not backported, it seems like we have added an unnecessary maintenance burden by now preventing future automatic backports in dozens of files simply because of the changes in spellings that add no new functionality nor solve any existing bugs, simply adding another way to express something that might have been slightly more readable if we had used it from day one but in the end comes down to a matter of taste.

  5. (Although I would question whether:

 -        if sys.platform in ('linux', 'darwin'):
 +        if support.MACOS or sys.platform == 'linux': 

a change being proposed in a follow-on PR is more readable, or even, were it available:

 +        if support.MACOS or support.LINUX:

)

So, I honestly don't know what the right thing to do for master is. It's not my call for 3.8 as I'm not wearing the release manager hat for it. But as a fellow core developer I think such a change deserves more exposure and possibly discussion before we follow it to its logical conclusion and people start proposing to make more wholesale changes throughout the code base (as they already are). And as a core developer, I would not be unhappy if it were reverted from master.

With my 3.7 and 3.6 release manager hat on, I'm a strong -1 on backporting unless someone can come up with a really compelling case to do so.

@serhiy-storchaka
Copy link
Member

I think it is better for us (CPython core developers) to backport this PR. Otherwise the difference between master and maintained branches will make harder backporting other changes.

On other side, backporting it will make the life harder for external developers: maintainers of Linux distributives which backport bug fixes to unmaintained versions, core developers of PyPy and other implementations which synchronize tests with CPython, etc.

@vstinner
Copy link
Member Author

Oh wow, I didn't expect so much discussions around just twice simple constants... I didn't know that two constants in tests was a major change. I'm not interested to spend more time on this change and so I just reverted it (PR #7919), sorry for the noise.

vstinner added a commit that referenced this pull request Jun 26, 2018
@ned-deily
Copy link
Member

Thanks, @vstinner!

@gpshead
Copy link
Member

gpshead commented Jun 26, 2018

FYI - We do state that test.support is not a public API and may change without concern for backwards compatibility between releases in https://docs.python.org/3/library/test.html#module-test.support

I have no opinion on the constant names other than as this PR points out they are inconsistent and messy today.

In distant past workflows we'd sometimes not bother to add nicer cleaned up code because it'd make forward porting more annoying. Now we're not adding nicer more consistent code because it makes backporting more difficult? There is no winning long term when optimizing for merging ease as opposed to making the master branch better and living with the manual merge fixups on the backports.

@ned-deily
Copy link
Member

@gpshead I agree that test.support is not a public API and I agree that, in general, it is better to make the master branch better rather than optimizing for merges. But, as I tried to point out, I don't think this particular change makes the master branch better in that it would have added yet another set of ways to spell various conditions without completely removing the old spellings. Also note that the now reverted PR was just the start: there were many more tests that would have been needed to change but the old spellings would still remain in the standard library outside of the tests. To me, it made things more confusing, not less. But it's a moot point now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants