-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Initial Prototype for Cygwin support module (take 2) #1483
Conversation
…string conversions to use them where appopriate
psutil/tests/__init__.py
Outdated
@@ -904,6 +905,29 @@ def bind_socket(family=AF_INET, type=SOCK_STREAM, addr=None): | |||
raise | |||
|
|||
|
|||
if CYGWIN: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't mean to commit this bit yet. Going to remove it and rebase.
Good job @embray. I added some initial comments. On top of that, I still don't like the separate _linux_common.py file. Please keep the main logic in _pslinux.py and do this instead:
# _pslinux.py
if not CYGWIN:
...
# _pscygwin.py
pids = _pslinux.pids # same as Linux
def virtual_memory(): # not the same
...
# _pscygwin.py
class Process(_pslinux.Process):
@memoize_when_activated
def _parse_stat_file(self):
... Also, generally speaking instead of merging a partial implementation I'm aiming at implementing everything, unless it's really difficult or not possible (in which case we'll document it). For the functionality which need to use MSDN APIs in C we can figure out how to refactor _psutil_windows.c. I have no idea how things are on that front yet but it seems we have two choices:
...but let's get to that later. Also I noticed something interesting. I'd have further comments, like trying to reuse tests from Extra: I notices something weird. While playing with this on Windows 10 + VirtualBox the VM suddenly crashed a couple of times. Scary... =) |
That's going to require significant refactoring, which I do intend to do, but it's going to have to be done separately. The complexity will grow significantly à la #998, it will become difficult to keep up with changes in master, and just generally become an unmaintainable mess again. Better to start with something small, note in the documentation (as I have started to do) that it is partial and/or experimental, and then add on functionality as able. All the core functionality is already there. |
My original implementation in #998 does have this, and I agree it's useful. I plan to add it back in later, as you say. |
In fact a better way would be to just go ahead and duplicate the common parts; it's unfortunate but also clear. I don't know how many other ways to explain that Cygwin is not Linux. It just takes inspiration from Linux in more areas than most other platforms being that it's the dominant UNIX-like OS. This is for practical reasons in porting software primarily written on Linux, it's necessary to copy some Linux-like functionality, in particular in the procfs implementation. Other areas hew more closely to plain POSIX. There is no |
sigh @giampaolo I owe you an apology. I went ahead and tried it your way just to see how bad it actually was, and this is all it took to at least make I tried to keep the changes from even being Cygwin-specific and this is all it took: diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py
index a1eaa3cd..f303ed53 100644
--- a/psutil/_pslinux.py
+++ b/psutil/_pslinux.py
@@ -23,7 +23,12 @@ from collections import namedtuple
from . import _common
from . import _psposix
from . import _pslinux_common
-from . import _psutil_linux as cext
+
+try:
+ from . import _psutil_linux as cext
+except ImportError:
+ cext = object()
+
from . import _psutil_posix as cext_posix
from ._common import isfile_strict
from ._common import memoize
@@ -102,11 +107,16 @@ LITTLE_ENDIAN = sys.byteorder == 'little'
# * https://lkml.org/lkml/2015/8/17/234
DISK_SECTOR_SIZE = 512
+if hasattr(socket, 'AF_PACKET'):
+ AF_PACKET = socket.AF_PACKET
+else:
+ AF_PACKET = -1
+
if enum is None:
- AF_LINK = socket.AF_PACKET
+ AF_LINK = AF_PACKET
else:
AddressFamily = enum.IntEnum('AddressFamily',
- {'AF_LINK': int(socket.AF_PACKET)})
+ {'AF_LINK': int(AF_PACKET)})
AF_LINK = AddressFamily.AF_LINK
# ioprio_* constants http://linux.die.net/man/2/ioprio_get On principle I still don't like it, per my comment that Cygwin as not Linux. But we can try things your way for now, given that at least practically speaking it took very little to at least make the |
functionality. Many tests are set to skip on Cygwin for now, but can be re-enabled as more functionality is added back in. The C extension module is just a stub for now and might end up being removed altogether, especially if we can add [PyCygwin](https://pycygwin.readthedocs.io/en/latest/) as a dependency.
How's this as a middle ground? I did away with the However, it does not make Instead, |
_pslinux.NoSuchProcess = NoSuchProcess | ||
_pslinux.ZombieProcess = ZombieProcess | ||
_pslinux.AccessDenied = AccessDenied | ||
_pslinux.TimeoutExpired = TimeoutExpired |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like this. Didn't there used to be a psutil._exceptions
module? Why did that go away? Having something like that would seem a bit less crazy than stuff like this...
Look @embray, I'm not willing to debate over design decisions anymore. I've basically been saying the same thing over the course of 2 years already:
There must be some communication issue at play here because the same goes for the str/unicode/bytes utilities which I rejected in the other PR some time ago already, but that you decided to include into this one anyway (they could have made some sense if Also, comments like these ones:
...are not constructive and keep the both of us in this never ending loop in which we just disagree with each other and nothing happens. I believe we can easily move this forward. This is even a relatively easy task since most of the stuff is in psutil already, the differences re. the parsing of /proc on Linux vs. Cygwin are minimal, and for the rest we'll just reuse or adjust the existing |
I'm a little confused by your last comment. I think you might have missed something since I initially replied: I even went ahead and reworked things I think closer to your way and I'm not sure if you actually looked at the code because I did almost exactly as you asked.
Like I said, I'm not sure what you mean here. Are you referring to the Relatedly, you keep saying you disagree without giving any sort of justification. I've at least explained my reasoning and I'm not satisfied often that you have.
I don't understand the second link. The logic there is nothing specifically to do with Cygwin, and is just reworked a bit to be a bit clearer and easier to extend if needed.
I'm not sure what you mean by this. The comment you're mentioning here is exactly related to this PR, it's on code I added. As for the bytes / str stuff as I explained last time we discussed it I wasn't satisfied with your reasoning behind rejecting the PR as-is because I foresaw future usage that you didn't. That's fair enough though, so I also explained that I would make a new PR explicitly incorporating it to make clearer the use I had in mind. So while you're still free to disagree with it, when you write
You make it sound like I'm trying to make an end run around this, when in fact I'm doing exactly what I (think) I previously communicated was my plan in the first place.
Maybe but having done the actual work I don't think it's as easy as you think. You're welcome to either do it yourself or show some willingness to compromise as I have. |
BTW I'm sorry again for being cranky about this. I think it's mostly not your fault. But I do wish you'd explain your rationale behind things better, as then it'd be easier to find understanding and compromises. Instead I just get absolutisms like
|
Actually that last comment leaves me especially confused because there are many features in this package that are platform-dependent and some that are available on some platforms if not others, so I really don't see what the problem is, especially if it's documented as provisional and or an initial version. Furthermore, I had just assumed you would be happier with a smaller, more minimal PR that would be easier to review. Again, I communicated clearly that that was my plan and you approved it. If you didn't like that idea I wish you had said so. Of course, I'm happy to build further on top of this one, though I figured it would be best to merge the initial work first (hence the care I took in stubbing out those tests that don't work yet; all other tests pass on my system). This way it can start being used and tested immediately in the development version while continuing the work of adding additional functionality. Adding more will take some time in refactoring the Windows code. I'm particularly wary of using Windows API at all because Cygwin is not Windows. Regardless it's possible in some cases as a workaround to missing Cygwin features. Just not always without danger. It will take some additional care and I fear tast stalling for too long will once again prevent getting anything at all done. Why let something that works mostly be the enemy of something that works 100%? I don't think this is an unreasonable question. |
My last comment was about the (not so nice) message you deleted, in which you kept insisting to use
You're right, my bad.
The reason this is the way it is is because of #1402, which is unrelated with Cygwin.
I'm happy to compromise when I agree with your proposal and think it's reasonable, not because I necessarily have to.
You misunderstood me. I proposed to proceed step by step, which is different than committing a draft PR. Compared to #998 this PR is surely a step in the right direction, but it's still a draft, useful to discuss how to proceed (together) and add functionality as we go. Crucial things (because interconnected with other functionality) like Process There is no point in committing this as-is and it is inappropriate of you to tell me what should be part of a new release so insistently. My aim at delivering a close-to-complete implementation is because I believe it can be achieved. And even in case we decide to do otherwise (minimal functionality) as we go, it would at the very least pass the quality standards, meaning engaging in a code review first and progressively go from "draft" to "minimal" (but stable).
The question is not unreasonable but if I already expressed my view on this twice in this very thread, why do you keep insisting?
I explained why I didn't foresee future usage: #1342 (comment)
In the 10 years I've received contributions to this project for which I gave most of my spare time for free (including to you) it's the first time I've read something like this. I don't think you can delete these 2 PRs so if you can please do me a favor and do a "blank" push-force similarly to what you did above in order to remove your changes. I will eventually implement this myself from scratch sometime over the course of this year. |
This is an easier to digest alternative to #998 .
Rather than try to implement the kitchen sink, this provides a barely-more-than bare-minimum implementation for a Cygwin support module. Most top-level functions and
Process
methods either work, at least with the default arguments, or raise aNotImplementedError
for now.You can get a sense for what works and what doesn't work by looking at what tests are skipped.
The major bit of refactoring needed for this to work is the introduction of a
psutil._pslinux_common
module. It implements aProcess
base class and several functions that work on Linux and Cygwin, but mostly avoids very specialized Linux-specific functionality. In principle this could also be useful for implementing support on other platforms (if they exist?) that aim for partial Linux-compatibility without being fully Linux.I think some version of this would be good to start with and is much better than nothing (it still does quite a bit!) and I will reintroduce additional features a bit at a time, making any additional prerequisite refactoring in the process.
TODO: