From 32fafd9c92fab359b85bf3460c8af8347cad4ed5 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 4 Nov 2022 18:45:10 -0400 Subject: [PATCH 01/12] Removed unused imports --- Xlib/ext/composite.py | 1 - Xlib/ext/damage.py | 1 - Xlib/ext/dpms.py | 1 - Xlib/ext/randr.py | 2 +- Xlib/ext/record.py | 1 - Xlib/ext/xfixes.py | 3 +-- 6 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Xlib/ext/composite.py b/Xlib/ext/composite.py index 0e10b635..5909b31e 100644 --- a/Xlib/ext/composite.py +++ b/Xlib/ext/composite.py @@ -33,7 +33,6 @@ graphics. """ -from Xlib import X from Xlib.protocol import rq from Xlib.xobject import drawable diff --git a/Xlib/ext/damage.py b/Xlib/ext/damage.py index 60c56606..126d8507 100644 --- a/Xlib/ext/damage.py +++ b/Xlib/ext/damage.py @@ -22,7 +22,6 @@ from Xlib import X from Xlib.protocol import rq, structs -from Xlib.xobject import resource from Xlib.error import XError extname = 'DAMAGE' diff --git a/Xlib/ext/dpms.py b/Xlib/ext/dpms.py index 3ff9a246..20b570bc 100644 --- a/Xlib/ext/dpms.py +++ b/Xlib/ext/dpms.py @@ -27,7 +27,6 @@ Documentation: https://www.x.org/releases/X11R7.7/doc/xextproto/dpms.html ''' -from Xlib import X from Xlib.protocol import rq extname = 'DPMS' diff --git a/Xlib/ext/randr.py b/Xlib/ext/randr.py index 256e3dee..61ce727d 100644 --- a/Xlib/ext/randr.py +++ b/Xlib/ext/randr.py @@ -34,7 +34,7 @@ """ -from tkinter import W +W = "w" from Xlib import X from Xlib.protocol import rq, structs diff --git a/Xlib/ext/record.py b/Xlib/ext/record.py index bb53ec19..638a5b38 100644 --- a/Xlib/ext/record.py +++ b/Xlib/ext/record.py @@ -19,7 +19,6 @@ # Suite 330, # Boston, MA 02111-1307 USA -from Xlib import X from Xlib.protocol import rq extname = 'RECORD' diff --git a/Xlib/ext/xfixes.py b/Xlib/ext/xfixes.py index 59f9277b..8b3c35fe 100644 --- a/Xlib/ext/xfixes.py +++ b/Xlib/ext/xfixes.py @@ -25,8 +25,7 @@ ShowCursor requests and SelectionNotify events are provided. ''' -from Xlib import X -from Xlib.protocol import rq, structs +from Xlib.protocol import rq extname = 'XFIXES' From 1791c97c3470c19e0645de2d32bfbeb0212b9b4e Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 16 Nov 2022 13:45:42 -0500 Subject: [PATCH 02/12] Update Xlib/ext/randr.py --- Xlib/ext/randr.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Xlib/ext/randr.py b/Xlib/ext/randr.py index 61ce727d..4003c8af 100644 --- a/Xlib/ext/randr.py +++ b/Xlib/ext/randr.py @@ -34,7 +34,6 @@ """ -W = "w" from Xlib import X from Xlib.protocol import rq, structs From dd01cee066fa1fd37a146b29bc3686abbd85877d Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 16 Nov 2022 18:22:25 -0500 Subject: [PATCH 03/12] Update Xlib/ext/randr.py --- Xlib/ext/randr.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Xlib/ext/randr.py b/Xlib/ext/randr.py index 4003c8af..9cbfe2da 100644 --- a/Xlib/ext/randr.py +++ b/Xlib/ext/randr.py @@ -35,7 +35,7 @@ from Xlib import X -from Xlib.protocol import rq, structs +from Xlib.protocol import rq extname = 'RANDR' From a9890197d9c65753462f3e2f505b5e3750bf8842 Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 16 Nov 2022 18:24:42 -0500 Subject: [PATCH 04/12] Update xinerama.py --- Xlib/ext/xinerama.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Xlib/ext/xinerama.py b/Xlib/ext/xinerama.py index f0546707..dcb78b89 100644 --- a/Xlib/ext/xinerama.py +++ b/Xlib/ext/xinerama.py @@ -35,7 +35,6 @@ returns the state information - because that's what libXinerama does.""" -from Xlib import X from Xlib.protocol import rq, structs extname = 'XINERAMA' From cf11374a42c656f0bb691f2f49f9e4d0fe32bb5e Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 16 Nov 2022 18:29:12 -0500 Subject: [PATCH 05/12] Update rq.py --- Xlib/protocol/rq.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Xlib/protocol/rq.py b/Xlib/protocol/rq.py index 86cb2def..c1eba34b 100644 --- a/Xlib/protocol/rq.py +++ b/Xlib/protocol/rq.py @@ -24,7 +24,6 @@ import traceback import struct from array import array -import types # Python 2/3 compatibility. from six import PY3, binary_type, byte2int, indexbytes, iterbytes From b091980a349fb32a2d96824f144d7131732c8158 Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 16 Nov 2022 18:32:05 -0500 Subject: [PATCH 06/12] Update drawable.py --- Xlib/xobject/drawable.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Xlib/xobject/drawable.py b/Xlib/xobject/drawable.py index c36a9738..3a56f532 100644 --- a/Xlib/xobject/drawable.py +++ b/Xlib/xobject/drawable.py @@ -19,7 +19,7 @@ # Suite 330, # Boston, MA 02111-1307 USA -from Xlib import X, Xatom, Xutil +from Xlib import X, Xatom from Xlib.protocol import request, rq # Other X resource objects From 06cd8219872d422baa5a926d2dea11579d2bc8ad Mon Sep 17 00:00:00 2001 From: Yasushi Itoh Date: Sun, 2 Jan 2022 10:04:33 +0900 Subject: [PATCH 07/12] Avoid to use fcntl module on some environments --- Xlib/support/unix_connect.py | 47 ++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/Xlib/support/unix_connect.py b/Xlib/support/unix_connect.py index c2261dae..bd690c18 100644 --- a/Xlib/support/unix_connect.py +++ b/Xlib/support/unix_connect.py @@ -23,23 +23,6 @@ import os import platform import socket - -# FCNTL is deprecated from Python 2.2, so only import it if we doesn't -# get the names we need. Furthermore, FD_CLOEXEC seems to be missing -# in Python 2.2. - -import fcntl - -if hasattr(fcntl, 'F_SETFD'): - F_SETFD = fcntl.F_SETFD - if hasattr(fcntl, 'FD_CLOEXEC'): - FD_CLOEXEC = fcntl.FD_CLOEXEC - else: - FD_CLOEXEC = 1 -else: - from FCNTL import F_SETFD, FD_CLOEXEC - - from Xlib import error, xauth @@ -93,11 +76,13 @@ def _get_tcp_socket(host, dno): s.connect((host, 6000 + dno)) return s + def _get_unix_socket(address): s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) s.connect(address) return s + def get_socket(dname, protocol, host, dno): assert protocol in SUPPORTED_PROTOCOLS try: @@ -127,11 +112,37 @@ def get_socket(dname, protocol, host, dno): raise error.DisplayConnectionError(dname, str(val)) # Make sure that the connection isn't inherited in child processes. - fcntl.fcntl(s.fileno(), F_SETFD, FD_CLOEXEC) + _ensure_not_inheritable(s) return s +def _ensure_not_inheritable(sock): + # According to PEP446, in Python 3.4 and above, + # it is not inherited in child processes by default. + # However, just in case, we explicitly make it non-inheritable. + # Also, we don't use the code like the following, + # because there would be no possibility of backporting to past versions. + # if sys.version_info.major == 3 and sys.version_info.minor >= 4: + # sock.set_inheritable(False) + # return + # We just check if the socket has `set_inheritable`. + if hasattr(sock, 'set_inheritable'): + sock.set_inheritable(False) + return + + # On Windows, + # Python doesn't support fcntl module because Windows doesn't have fcntl API. + # At least by not importing fcntl, we will be able to import python-xlib on Windows. + if platform.system() == 'Windows': + # so.. unfortunately, for Python 3.3 and below, on Windows, + # we can't make sure that the connection isn't inherited in child processes for now. + return + + import fcntl + fcntl.fcntl(sock.fileno(), fcntl.F_SETFD, fcntl.FD_CLOEXEC) + + def new_get_auth(sock, dname, protocol, host, dno): assert protocol in SUPPORTED_PROTOCOLS # Translate socket address into the xauth domain From 1127b311b3dce054eebc2deabc6f96b41310b92e Mon Sep 17 00:00:00 2001 From: Yasushi Itoh Date: Sun, 2 Jan 2022 17:40:10 +0900 Subject: [PATCH 08/12] Change a test behavior for unix_connect.get_socket --- test/test_unix_connect.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/test/test_unix_connect.py b/test/test_unix_connect.py index 7680ba5b..3199fa5f 100644 --- a/test/test_unix_connect.py +++ b/test/test_unix_connect.py @@ -72,8 +72,8 @@ def _get_socket(socket_type, raises, *params): def path_exists(returns, path): calls.append(('os.path.exists', path)) return returns - def fcntl(*args): - calls.append(('fcntl',) + args) + def ensure_not_inheritable(*args): + calls.append(('ensure_not_inheritable',) + args) for params, allow_unix, unix_addr_exists, allow_tcp, expect_connection_error, expected_calls in ( # Successful explicit TCP socket connection. (('tcp/host:6', None, 'host', 6), False, False, True, False, [ @@ -141,7 +141,7 @@ def fcntl(*args): partial(_get_socket, 'tcp', not allow_tcp)), \ patch('os.path.exists', partial(path_exists, unix_addr_exists)), \ - patch('fcntl.fcntl', fcntl): + patch('Xlib.support.unix_connect._ensure_not_inheritable', ensure_not_inheritable): del calls[:] if expect_connection_error: with self.assertRaises(DisplayConnectionError): @@ -149,9 +149,7 @@ def fcntl(*args): else: s = unix_connect.get_socket(*params) self.assertIsInstance(s, FakeSocket) - expected_calls.append(('fcntl', 42, - unix_connect.F_SETFD, - unix_connect.FD_CLOEXEC)) + expected_calls.append(('ensure_not_inheritable', s)) self.assertEqual(calls, expected_calls) From 9f406d4e50a4b947915739ea4e1068b78fd5910d Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 16 Nov 2022 19:22:09 -0500 Subject: [PATCH 09/12] Prefer `bool` over `Literal[0, 1, None]` --- Xlib/display.py | 8 ++++---- Xlib/error.py | 2 +- Xlib/protocol/display.py | 28 ++++++++++++++-------------- Xlib/protocol/rq.py | 20 ++++++++++---------- Xlib/xobject/drawable.py | 6 +++--- 5 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Xlib/display.py b/Xlib/display.py index e0f7b5c8..87b9aa61 100644 --- a/Xlib/display.py +++ b/Xlib/display.py @@ -71,7 +71,7 @@ def __init__(self, *args, **keys): protocol_display.Display.__init__(self, *args, **keys) self._atom_cache = {} - def get_atom(self, atomname, only_if_exists=0): + def get_atom(self, atomname, only_if_exists=False): if atomname in self._atom_cache: return self._atom_cache[atomname] @@ -473,7 +473,7 @@ def rebind_string(self, keysym, newstring): ### X requests ### - def intern_atom(self, name, only_if_exists = 0): + def intern_atom(self, name, only_if_exists = False): """Intern the string name, returning its atom number. If only_if_exists is true and the atom does not already exist, it will not be created and X.NONE is returned.""" @@ -482,7 +482,7 @@ def intern_atom(self, name, only_if_exists = 0): only_if_exists = only_if_exists) return r.atom - def get_atom(self, atom, only_if_exists = 0): + def get_atom(self, atom, only_if_exists = False): """Alias for intern_atom, using internal cache""" return self.display.get_atom(atom, only_if_exists) @@ -501,7 +501,7 @@ def get_selection_owner(self, selection): selection = selection) return r.owner - def send_event(self, destination, event, event_mask = 0, propagate = 0, + def send_event(self, destination, event, event_mask = 0, propagate = False, onerror = None): """Send a synthetic event to the window destination which can be a window object, or X.PointerWindow or X.InputFocus. event is the diff --git a/Xlib/error.py b/Xlib/error.py index cb6d0d07..3b6e13f8 100644 --- a/Xlib/error.py +++ b/Xlib/error.py @@ -70,7 +70,7 @@ class XError(rq.GetAttrData, Exception): ) def __init__(self, display, data): - self._data, data = self._fields.parse_binary(data, display, rawdict = 1) + self._data, _ = self._fields.parse_binary(data, display, rawdict = True) def __str__(self): s = [] diff --git a/Xlib/protocol/display.py b/Xlib/protocol/display.py index 56623c35..4bd939e9 100644 --- a/Xlib/protocol/display.py +++ b/Xlib/protocol/display.py @@ -214,7 +214,7 @@ def next_event(self): # Call send_and_recv, which will return when # something has occured - self.send_and_recv(event = 1) + self.send_and_recv(event = True) # Before looping around, lock the event queue against # modifications. @@ -240,7 +240,7 @@ def pending_events(self): # Make a send_and_recv pass, receiving any events self.send_recv_lock.acquire() - self.send_and_recv(recv = 1) + self.send_and_recv(recv = True) # Lock the queue, get the event count, and unlock again. self.event_queue_write_lock.acquire() @@ -252,7 +252,7 @@ def pending_events(self): def flush(self): self.check_for_error() self.send_recv_lock.acquire() - self.send_and_recv(flush = 1) + self.send_and_recv(flush = True) def close(self): self.flush() @@ -384,7 +384,7 @@ def close_internal(self, whom): self.socket_error_lock.release() - def send_and_recv(self, flush = None, event = None, request = None, recv = None): + def send_and_recv(self, flush = False, event = False, request = None, recv = False): """send_and_recv(flush = None, event = None, request = None, recv = None) Perform I/O, or wait for some other thread to do it for us. @@ -689,8 +689,8 @@ def parse_response(self, request): return self.parse_connection_setup() # Parse ordinary server response - gotreq = 0 - while 1: + gotreq = False + while True: if self.data_recv: # Check the first byte to find out what kind of response it is rtype = byte2int(self.data_recv) @@ -772,7 +772,7 @@ def parse_error_response(self, request): else: self.default_error_handler(e) - return 0 + return False def default_error_handler(self, err): @@ -937,7 +937,7 @@ def parse_connection_setup(self): # Only the ConnectionSetupRequest has been sent so far r = self.sent_requests[0] - while 1: + while True: # print 'data_send:', repr(self.data_send) # print 'data_recv:', repr(self.data_recv) @@ -946,7 +946,7 @@ def parse_connection_setup(self): # The full response haven't arrived yet if len(self.data_recv) < alen: - return 0 + return False # Connection failed or further authentication is needed. # Set reason to the reason string @@ -956,22 +956,22 @@ def parse_connection_setup(self): # Else connection succeeded, parse the reply else: x, d = r._success_reply.parse_binary(self.data_recv[:alen], - self, rawdict = 1) + self, rawdict = True) r._data.update(x) del self.sent_requests[0] self.data_recv = self.data_recv[alen:] - return 1 + return True else: # The base reply is 8 bytes long if len(self.data_recv) < 8: - return 0 + return False r._data, d = r._reply.parse_binary(self.data_recv[:8], - self, rawdict = 1) + self, rawdict = True) self.data_recv = self.data_recv[8:] # Loop around to see if we have got the additional data @@ -1066,7 +1066,7 @@ def __init__(self, display, *args, **keys): # Don't bother about locking, since no other threads have # access to the display yet - display.request_queue.append((self, 1)) + display.request_queue.append((self, True)) # However, we must lock send_and_recv, but we don't have # to loop. diff --git a/Xlib/protocol/rq.py b/Xlib/protocol/rq.py index c1eba34b..5fff5e77 100644 --- a/Xlib/protocol/rq.py +++ b/Xlib/protocol/rq.py @@ -118,7 +118,7 @@ class Field(object): check_value = None parse_value = None - keyword_args = 0 + keyword_args = False def __init__(self): pass @@ -723,7 +723,7 @@ def pack_value(self, value): class ValueList(Field): structcode = None - keyword_args = 1 + keyword_args = True default = 'usekeywords' def __init__(self, name, mask, pad, *fields): @@ -1088,7 +1088,7 @@ def pack_value(self, value): raise BadDataError('%s is not a tuple or a list' % (value)) - def parse_value(self, val, display, rawdict = 0): + def parse_value(self, val, display, rawdict = False): """This function is used by List and Object fields to convert Struct objects with no var_fields into Python values. @@ -1131,9 +1131,9 @@ def parse_value(self, val, display, rawdict = 0): return DictWrapper(ret) return ret - def parse_binary(self, data, display, rawdict = 0): + def parse_binary(self, data, display, rawdict = False): - """values, remdata = s.parse_binary(data, display, rawdict = 0) + """values, remdata = s.parse_binary(data, display, rawdict = False) Convert a binary representation of the structure into Python values. @@ -1354,16 +1354,16 @@ def _set_error(self, error): return 0 class ReplyRequest(GetAttrData): - def __init__(self, display, defer = 0, *args, **keys): + def __init__(self, display, defer = False, *args, **keys): self._display = display self._binary = self._request.to_binary(*args, **keys) self._serial = None - self._data = None + self._data = {} self._error = None self._response_lock = lock.allocate_lock() - self._display.send_request(self, 1) + self._display.send_request(self, True) if not defer: self.reply() @@ -1389,7 +1389,7 @@ def reply(self): def _parse_response(self, data): self._response_lock.acquire() - self._data, d = self._reply.parse_binary(data, self._display, rawdict = 1) + self._data, d = self._reply.parse_binary(data, self._display, rawdict = True) self._response_lock.release() def _set_error(self, error): @@ -1408,7 +1408,7 @@ def __init__(self, binarydata = None, display = None, if binarydata: self._binary = binarydata self._data, data = self._fields.parse_binary(binarydata, display, - rawdict = 1) + rawdict = True) # split event type into type and send_event bit self._data['send_event'] = not not self._data['type'] & 0x80 self._data['type'] = self._data['type'] & 0x7f diff --git a/Xlib/xobject/drawable.py b/Xlib/xobject/drawable.py index 3a56f532..f8e625f6 100644 --- a/Xlib/xobject/drawable.py +++ b/Xlib/xobject/drawable.py @@ -451,7 +451,7 @@ def delete_property(self, property, onerror = None): window = self.id, property = property) - def get_property(self, property, property_type, offset, length, delete = 0): + def get_property(self, property, property_type, offset, length, delete = False): r = request.GetProperty(display = self.display, delete = delete, window = self.id, @@ -516,7 +516,7 @@ def convert_selection(self, selection, target, property, time, onerror = None): property = property, time = time) - def send_event(self, event, event_mask = 0, propagate = 0, onerror = None): + def send_event(self, event, event_mask = 0, propagate = False, onerror = None): request.SendEvent(display = self.display, onerror = onerror, propagate = propagate, @@ -629,7 +629,7 @@ def set_input_focus(self, revert_to, time, onerror = None): focus = self.id, time = time) - def clear_area(self, x = 0, y = 0, width = 0, height = 0, exposures = 0, onerror = None): + def clear_area(self, x = 0, y = 0, width = 0, height = 0, exposures = False, onerror = None): request.ClearArea(display = self.display, onerror = onerror, exposures = exposures, From fdf873908ed300d4af685fe889079df0f5b7845f Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 18 Nov 2022 15:42:54 -0500 Subject: [PATCH 10/12] fix accidental data change --- Xlib/protocol/display.py | 2 +- Xlib/protocol/rq.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Xlib/protocol/display.py b/Xlib/protocol/display.py index 4bd939e9..0d910dab 100644 --- a/Xlib/protocol/display.py +++ b/Xlib/protocol/display.py @@ -402,7 +402,7 @@ def send_and_recv(self, flush = False, event = False, request = None, recv = Fal To wait for an event to be received, event should be true. To wait for a response to a certain request (either an error - or a response), request should be set the that request's + or a response), request should be set to that request's serial number. To just read any pending data from the server, recv should be true. diff --git a/Xlib/protocol/rq.py b/Xlib/protocol/rq.py index 5fff5e77..8bc82059 100644 --- a/Xlib/protocol/rq.py +++ b/Xlib/protocol/rq.py @@ -1358,7 +1358,7 @@ def __init__(self, display, defer = False, *args, **keys): self._display = display self._binary = self._request.to_binary(*args, **keys) self._serial = None - self._data = {} + self._data = None self._error = None self._response_lock = lock.allocate_lock() From b04e96a39b8ae0b82c52d0385d1edc1d8f96cb6a Mon Sep 17 00:00:00 2001 From: Marcel Telka Date: Thu, 15 Dec 2022 22:07:31 +0100 Subject: [PATCH 11/12] Change parentheses to brackets in LICENSE --- LICENSE | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE b/LICENSE index 19e30718..d762d815 100644 --- a/LICENSE +++ b/LICENSE @@ -6,9 +6,9 @@ Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. -(This is the first released version of the Lesser GPL. It also counts +[This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.) + the version number 2.1.] Preamble From 4e8bbf8fc4941e5da301a8b3db8d27e98de68666 Mon Sep 17 00:00:00 2001 From: Vasily Ryabov Date: Sun, 25 Dec 2022 21:49:10 +0300 Subject: [PATCH 12/12] Update CHANGELOG, bump version to 0.33 --- CHANGELOG.md | 14 ++++++++++++++ Xlib/__init__.py | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cac28024..74eb66b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ NEWS for Python X Library +Version 0.33 +============ + +Bug Fixes +--------- + +- Removed unused imports (thanks @Avasam). +- Avoid to use fcntl module on some environments (thanks @i2y). +- Change a test behavior for `unix_connect.get_socket` (thanks @i2y). +- Fix accidental data change (thanks @Avasam). +- Prefer `bool` over `Literal[0, 1, None]` (thanks @Avasam). +- Change parentheses to brackets in LICENSE (thanks @mtelka). + +--- Version 0.32 ============ diff --git a/Xlib/__init__.py b/Xlib/__init__.py index 9db8beec..28a0e017 100644 --- a/Xlib/__init__.py +++ b/Xlib/__init__.py @@ -19,7 +19,7 @@ # Suite 330, # Boston, MA 02111-1307 USA -__version__ = (0, 32) +__version__ = (0, 33) __version_extra__ = ''