...
 
Commits (4)
......@@ -24,8 +24,6 @@ before_deploy:
# Note: only do this with Python 3.5 because the contents
# of the distribution are the same for all versions.
- case "$TRAVIS_PYTHON_VERSION" in 3.5) python setup.py sdist --formats=bztar;; esac
# Generate egg distribution.
- python setup.py bdist_egg
# Generate wheel distribution.
# Note: only do this once, since we create a universal wheel.
- case "$TRAVIS_PYTHON_VERSION" in 3.5) python setup.py bdist_wheel;; esac
......@@ -37,7 +35,6 @@ deploy:
file_glob: true
file:
- dist/*.tar.*
- dist/*.egg
- dist/*.whl
on:
tags: true
......
This diff is collapsed.
Metadata-Version: 1.1
Name: python-xlib
Version: 0.20
Version: 0.23
Summary: Python X Library
Home-page: https://github.com/python-xlib/python-xlib
Author: Peter Liljenberg
Author-email: petli@ctrl-c.liu.se
License: LGPLv2+
Download-URL: https://github.com/python-xlib/python-xlib/releases
Description: UNKNOWN
Keywords: xlib x11 x windows
Description-Content-Type: UNKNOWN
Description: The Python X Library
====================
|Build Status| |codecov.io| |Code Health|
`Homepage`_ | `Releases`_ | `Changelog`_
Copyright
~~~~~~~~~
The main part of the code is
::
Copyright (C) 2000-2002 Peter Liljenberg
Some contributed code is copyrighted by `the contributors <Contributors_>`_,
in these cases that is indicated in the source files in question.
The Python X Library is released under LGPL v2.1 or later (since 2016),
see the file LICENSE for details. 0.15rc1 and before were released under
GPL v2.
Requirements
~~~~~~~~~~~~
The Python X Library requires Python 2.7 or newer. It has been tested to
various extents with Python 2.7 and 3.3 through 3.6.
Installation
~~~~~~~~~~~~
The Python Xlib uses the standard setuptools package, to install run
this command:
::
python setup.py install
See the command help for details: ``python setup.py install -h``.
Alternatively, you can run programs from the distribution directory, or
change the module path in programs.
There's a simple example program, implemented twice using both the
high-level interface and the low-level protocol.
Introduction
~~~~~~~~~~~~
The Python X Library is intended to be a fully functional X client
library for Python programs. It is written entirely in Python, in
contrast to earlier X libraries for Python (the ancient X extension and
the newer plxlib) which were interfaces to the C Xlib.
This is possible to do since X client programs communicate with the X
server via the X protocol. The communication takes place over TCP/IP,
Unix sockets, DECnet or any other streaming network protocol. The C Xlib
is merely an interface to this protocol, providing functions suitable
for a C environment.
There are three advantages of implementing a pure Python library:
- Integration: The library can make use of the wonderful object system
in Python, providing an easy-to-use class hierarchy.
- Portability: The library will be usable on (almost) any computer
which have Python installed. A C interface could be problematic to
port to non-Unix systems, such as MS Windows or OpenVMS.
- Maintainability: It is much easier to develop and debug native Python
modules than modules written in C.
Documentation
~~~~~~~~~~~~~
The reference manual is not finished by far, but is probably still useful. It
can be `browsed online <http://python-xlib.sourceforge.net/doc/html/index.html>`__.
There are also some `example programs <Examples_>`_ and, of course,
`the standard X11 documentation <http://tronche.com/gui/x/xlib/>`__ applies.
Project status
~~~~~~~~~~~~~~
The low-level protocol is complete, implementing client-side X11R6. The
high-level object oriented interface is also fully functional. It is
possible to write client applications with the library. Currently, the
only real application using Python Xlib is the window manager PLWM,
starting with version 2.0.
There is a resource database implementation, ICCCM support and a
framework for adding X extension code. Several extensions have been
implemented; (RECORD, SHAPE, Xinerama, Composite, RANDR, and XTEST)
patches for additions are very welcome.
There are most likely still bugs, but the library is at least stable
enough to run PLWM. A continuously bigger part of the library is covered
by regression tests, improving stability.
The documentation is still quite rudimentary, but should be of some help
for people programming with the Xlib. X beginners should first find some
general texts on X. A very good starting point is
http://www.rahul.net/kenton/xsites.html
See the file TODO for a detailed list of what is missing, approximately
ordered by importance.
.. _Homepage: https://github.com/python-xlib/python-xlib
.. _Releases: https://github.com/python-xlib/python-xlib/releases
.. _Changelog: https://github.com/python-xlib/python-xlib/tree/master/CHANGELOG.md
.. _Contributors: https://github.com/python-xlib/python-xlib/graphs/contributors
.. _Examples: https://github.com/python-xlib/python-xlib/tree/master/examples
.. |Build Status| image:: https://travis-ci.org/python-xlib/python-xlib.svg?branch=master
:target: https://travis-ci.org/python-xlib/python-xlib
.. |codecov.io| image:: https://codecov.io/github/python-xlib/python-xlib/coverage.svg?branch=master
:target: https://codecov.io/github/python-xlib/python-xlib?branch=master
.. |Code Health| image:: https://landscape.io/github/python-xlib/python-xlib/master/landscape.svg?style=flat
:target: https://landscape.io/github/python-xlib/python-xlib/master
Keywords: windows,x,x11,xlib
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: X11 Applications
......@@ -20,6 +142,8 @@ Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Libraries
......
|Build Status| |codecov.io| |Code Health|
The Python X Library
====================
|Build Status| |codecov.io| |Code Health|
`Homepage`_ | `Releases`_ | `Changelog`_
Copyright
~~~~~~~~~
......@@ -12,8 +14,7 @@ The main part of the code is
Copyright (C) 2000-2002 Peter Liljenberg
Some contributed code is copyrighted by `the
contributors <https://github.com/python-xlib/python-xlib/graphs/contributors>`__,
Some contributed code is copyrighted by `the contributors <Contributors_>`_,
in these cases that is indicated in the source files in question.
The Python X Library is released under LGPL v2.1 or later (since 2016),
......@@ -24,7 +25,7 @@ Requirements
~~~~~~~~~~~~
The Python X Library requires Python 2.7 or newer. It has been tested to
various extents with Python 2.7 and 3.3 through 3.5.
various extents with Python 2.7 and 3.3 through 3.6.
Installation
~~~~~~~~~~~~
......@@ -73,9 +74,11 @@ There are three advantages of implementing a pure Python library:
Documentation
~~~~~~~~~~~~~
The reference manual is not finished by far, but is probably still useful. It can be `browsed online <http://python-xlib.sourceforge.net/doc/html/index.html>`__.
The reference manual is not finished by far, but is probably still useful. It
can be `browsed online <http://python-xlib.sourceforge.net/doc/html/index.html>`__.
There are also some `example programs <examples/>`__ and, of course, `the standard X11 documentation <http://tronche.com/gui/x/xlib/>`__ applies.
There are also some `example programs <Examples_>`_ and, of course,
`the standard X11 documentation <http://tronche.com/gui/x/xlib/>`__ applies.
Project status
......@@ -104,22 +107,11 @@ http://www.rahul.net/kenton/xsites.html
See the file TODO for a detailed list of what is missing, approximately
ordered by importance.
Contact information
~~~~~~~~~~~~~~~~~~~
Author email: Peter Liljenberg petli@ctrl-c.liu.se
Mailing list: http://sourceforge.net/mail/?group\_id=10350
The Python X Library is a SourceForged project (currently migrating to
GitHub). The project page is
http://sourceforge.net/projects/python-xlib/. Source is available from
that page as zip archive and from the `releases
list <https://github.com/python-xlib/python-xlib/releases>`__.
There isn't any real web page yet, only a derivative of this file. It is
located at http://python-xlib.sourceforge.net/. It now also features the
documentation for downloading or browsing.
.. _Homepage: https://github.com/python-xlib/python-xlib
.. _Releases: https://github.com/python-xlib/python-xlib/releases
.. _Changelog: https://github.com/python-xlib/python-xlib/tree/master/CHANGELOG.md
.. _Contributors: https://github.com/python-xlib/python-xlib/graphs/contributors
.. _Examples: https://github.com/python-xlib/python-xlib/tree/master/examples
.. |Build Status| image:: https://travis-ci.org/python-xlib/python-xlib.svg?branch=master
:target: https://travis-ci.org/python-xlib/python-xlib
......
......@@ -19,7 +19,7 @@
# Suite 330,
# Boston, MA 02111-1307 USA
__version__ = (0, 20)
__version__ = (0, 23)
__version_extra__ = ''
......
......@@ -814,7 +814,7 @@ class Display(object):
request.ChangePointerControl(display = self.display,
onerror = onerror,
do_accel = do_accel,
do_thres = do_threshold,
do_thresh = do_threshold,
accel_num = accel_num,
accel_denum = accel_denum,
threshold = threshold)
......
......@@ -82,12 +82,12 @@ class Display(object):
event_classes = event.event_class.copy()
def __init__(self, display = None):
name, host, displayno, screenno = connect.get_display(display)
name, protocol, host, displayno, screenno = connect.get_display(display)
self.display_name = name
self.default_screen = screenno
self.socket = connect.get_socket(name, host, displayno)
self.socket = connect.get_socket(name, protocol, host, displayno)
auth_name, auth_data = connect.get_auth(self.socket,
name, host, displayno)
......
......@@ -35,7 +35,7 @@ from ..support import lock
def decode_string(bs):
return bs.decode('ascii')
return bs.decode('latin1')
if PY3:
def encode_array(a):
......
......@@ -56,15 +56,16 @@ def _relative_import(modname):
def get_display(display):
"""dname, host, dno, screen = get_display(display)
"""dname, protocol, host, dno, screen = get_display(display)
Parse DISPLAY into its components. If DISPLAY is None, use
the default display. The return values are:
DNAME -- the full display name (string)
HOST -- the host name (string, possibly empty)
DNO -- display number (integer)
SCREEN -- default screen number (integer)
DNAME -- the full display name (string)
PROTOCOL -- the protocol to use (None if automatic)
HOST -- the host name (string, possibly empty)
DNO -- display number (integer)
SCREEN -- default screen number (integer)
"""
modname = _display_mods.get(platform, _default_display_mod)
......@@ -72,10 +73,10 @@ def get_display(display):
return mod.get_display(display)
def get_socket(dname, host, dno):
"""socket = get_socket(dname, host, dno)
def get_socket(dname, protocol, host, dno):
"""socket = get_socket(dname, protocol, host, dno)
Connect to the display specified by DNAME, HOST and DNO, which
Connect to the display specified by DNAME, PROTOCOL, HOST and DNO, which
are the corresponding values from a previous call to get_display().
Return SOCKET, a new socket object connected to the X server.
......@@ -83,7 +84,7 @@ def get_socket(dname, host, dno):
modname = _socket_mods.get(platform, _default_socket_mod)
mod = _relative_import(modname)
return mod.get_socket(dname, host, dno)
return mod.get_socket(dname, protocol, host, dno)
def get_auth(sock, dname, host, dno):
......
......@@ -62,50 +62,57 @@ def get_display(display):
name = display
protocol, host, dno, screen = m.group('proto', 'host', 'dno', 'screen')
if protocol == 'tcp':
if protocol == 'tcp' and not host:
# Host is mandatory when protocol is TCP.
if not host:
raise error.DisplayNameError(display)
elif protocol == 'unix':
# Clear host to force Unix socket connection.
host = ''
else:
# Special case: `unix:0.0` is equivalent to `:0.0`.
if host == 'unix':
host = ''
raise error.DisplayNameError(display)
dno = int(dno)
if screen:
screen = int(screen)
else:
screen = 0
return name, host, dno, screen
return name, protocol, host, dno, screen
def _get_tcp_socket(host, dno):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
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, host, dno):
def get_socket(dname, protocol, host, dno):
assert protocol in (None, 'tcp', 'unix')
try:
# Darwin funky socket
if (uname[0] == 'Darwin') and host and host.startswith('/private/tmp/'):
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(dname)
# Darwin funky socket.
if uname[0] == 'Darwin' and host and host.startswith('/private/tmp/'):
s = _get_unix_socket(dname)
# If hostname (or IP) is provided, use TCP socket
elif host:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, 6000 + dno))
# TCP socket, note the special case: `unix:0.0` is equivalent to `:0.0`.
elif (not protocol or protocol != 'unix') and host and host != 'unix':
s = _get_tcp_socket(host, dno)
# Else use Unix socket
# Unix socket.
else:
address = '/tmp/.X11-unix/X%d' % dno
if not os.path.exists(address):
# Use abstract address.
address = '\0' + address
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(address)
try:
s = _get_unix_socket(address)
except socket.error:
if not protocol and not host:
# If no protocol/host was specified, fallback to TCP.
s = _get_tcp_socket(host, dno)
else:
raise
except socket.error as val:
raise error.DisplayConnectionError(dname, str(val))
# Make sure that the connection isn't inherited in child processes
# Make sure that the connection isn't inherited in child processes.
fcntl.fcntl(s.fileno(), F_SETFD, FD_CLOEXEC)
return s
......
......@@ -32,7 +32,7 @@ def get_display(display):
# check DECW$DISPLAY instead, but that has to wait
if display is None:
return ':0.0', 'localhost', 0, 0
return ':0.0', None, 'localhost', 0, 0
m = display_re.match(display)
if not m:
......@@ -52,10 +52,10 @@ def get_display(display):
else:
screen = 0
return name, host, dno, screen
return name, None, host, dno, screen
def get_socket(dname, host, dno):
def get_socket(dname, protocol, host, dno):
try:
# Always use TCP/IP sockets. Later it would be nice to
# be able to use DECNET och LOCAL connections.
......
......@@ -249,7 +249,7 @@ class Drawable(resource.Resource):
else:
subimage = image
w, h = subimage.size
data = subimage.tostring("raw", rawmode, stride, 0)
data = subimage.tobytes("raw", rawmode, stride, 0)
self.put_image(gc, x, y, w, h, format, depth, 0, data)
y1 = y1 + h
y = y + h
......
python-xlib (0.23-1) unstable; urgency=medium
[ Ondřej Nový ]
* d/control: Set Vcs-* to salsa.debian.org
[ Andrej Shadura ]
* New upstream release.
* Refresh patches.
-- Andrej Shadura <andrewsh@debian.org> Sat, 21 Jul 2018 13:30:51 +0200
python-xlib (0.20-3) unstable; urgency=medium
[ Jeremy Bicha ]
......
......@@ -7,8 +7,8 @@ Subject: use makeinfo instead of texi2html
include ../src/defs
python-xlib_toc.html: $(SRCS)
- ./texi2html -splitnode -menu $(TOPSRC)
+ makeinfo --html --split=node $(TOPSRC)
- texi2html --output=. --split=node --menu $(TOPSRC)
+ makeinfo --output=. --html --split=node $(TOPSRC)
ln -sf python-xlib_toc.html index.html
clean:
......@@ -3,7 +3,7 @@
include ../src/defs
python-xlib_toc.html: $(SRCS)
./texi2html -splitnode -menu $(TOPSRC)
texi2html --output=. --split=node --menu $(TOPSRC)
ln -sf python-xlib_toc.html index.html
clean:
......
This diff is collapsed.
Metadata-Version: 1.1
Name: python-xlib
Version: 0.20
Version: 0.23
Summary: Python X Library
Home-page: https://github.com/python-xlib/python-xlib
Author: Peter Liljenberg
Author-email: petli@ctrl-c.liu.se
License: LGPLv2+
Download-URL: https://github.com/python-xlib/python-xlib/releases
Description: UNKNOWN
Keywords: xlib x11 x windows
Description-Content-Type: UNKNOWN
Description: The Python X Library
====================
|Build Status| |codecov.io| |Code Health|
`Homepage`_ | `Releases`_ | `Changelog`_
Copyright
~~~~~~~~~
The main part of the code is
::
Copyright (C) 2000-2002 Peter Liljenberg
Some contributed code is copyrighted by `the contributors <Contributors_>`_,
in these cases that is indicated in the source files in question.
The Python X Library is released under LGPL v2.1 or later (since 2016),
see the file LICENSE for details. 0.15rc1 and before were released under
GPL v2.
Requirements
~~~~~~~~~~~~
The Python X Library requires Python 2.7 or newer. It has been tested to
various extents with Python 2.7 and 3.3 through 3.6.
Installation
~~~~~~~~~~~~
The Python Xlib uses the standard setuptools package, to install run
this command:
::
python setup.py install
See the command help for details: ``python setup.py install -h``.
Alternatively, you can run programs from the distribution directory, or
change the module path in programs.
There's a simple example program, implemented twice using both the
high-level interface and the low-level protocol.
Introduction
~~~~~~~~~~~~
The Python X Library is intended to be a fully functional X client
library for Python programs. It is written entirely in Python, in
contrast to earlier X libraries for Python (the ancient X extension and
the newer plxlib) which were interfaces to the C Xlib.
This is possible to do since X client programs communicate with the X
server via the X protocol. The communication takes place over TCP/IP,
Unix sockets, DECnet or any other streaming network protocol. The C Xlib
is merely an interface to this protocol, providing functions suitable
for a C environment.
There are three advantages of implementing a pure Python library:
- Integration: The library can make use of the wonderful object system
in Python, providing an easy-to-use class hierarchy.
- Portability: The library will be usable on (almost) any computer
which have Python installed. A C interface could be problematic to
port to non-Unix systems, such as MS Windows or OpenVMS.
- Maintainability: It is much easier to develop and debug native Python
modules than modules written in C.
Documentation
~~~~~~~~~~~~~
The reference manual is not finished by far, but is probably still useful. It
can be `browsed online <http://python-xlib.sourceforge.net/doc/html/index.html>`__.
There are also some `example programs <Examples_>`_ and, of course,
`the standard X11 documentation <http://tronche.com/gui/x/xlib/>`__ applies.
Project status
~~~~~~~~~~~~~~
The low-level protocol is complete, implementing client-side X11R6. The
high-level object oriented interface is also fully functional. It is
possible to write client applications with the library. Currently, the
only real application using Python Xlib is the window manager PLWM,
starting with version 2.0.
There is a resource database implementation, ICCCM support and a
framework for adding X extension code. Several extensions have been
implemented; (RECORD, SHAPE, Xinerama, Composite, RANDR, and XTEST)
patches for additions are very welcome.
There are most likely still bugs, but the library is at least stable
enough to run PLWM. A continuously bigger part of the library is covered
by regression tests, improving stability.
The documentation is still quite rudimentary, but should be of some help
for people programming with the Xlib. X beginners should first find some
general texts on X. A very good starting point is
http://www.rahul.net/kenton/xsites.html
See the file TODO for a detailed list of what is missing, approximately
ordered by importance.
.. _Homepage: https://github.com/python-xlib/python-xlib
.. _Releases: https://github.com/python-xlib/python-xlib/releases
.. _Changelog: https://github.com/python-xlib/python-xlib/tree/master/CHANGELOG.md
.. _Contributors: https://github.com/python-xlib/python-xlib/graphs/contributors
.. _Examples: https://github.com/python-xlib/python-xlib/tree/master/examples
.. |Build Status| image:: https://travis-ci.org/python-xlib/python-xlib.svg?branch=master
:target: https://travis-ci.org/python-xlib/python-xlib
.. |codecov.io| image:: https://codecov.io/github/python-xlib/python-xlib/coverage.svg?branch=master
:target: https://codecov.io/github/python-xlib/python-xlib?branch=master
.. |Code Health| image:: https://landscape.io/github/python-xlib/python-xlib/master/landscape.svg?style=flat
:target: https://landscape.io/github/python-xlib/python-xlib/master
Keywords: windows,x,x11,xlib
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: X11 Applications
......@@ -20,6 +142,8 @@ Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Libraries
......
.gitignore
.landscape.yml
.travis.yml
CHANGELOG.md
LICENSE
NEWS
README.rst
TODO
codecov.yml
......@@ -84,7 +84,6 @@ debian/prerm
debian/rules
doc/Makefile
doc/html/Makefile
doc/html/texi2html
doc/info/Makefile
doc/ps/Makefile
doc/src/Makefile
......
[metadata]
name = python-xlib
version = attr: Xlib.__version_string__
description = Python X Library
long_description = file: README.rst
download_url = https://github.com/python-xlib/python-xlib/releases
url = https://github.com/python-xlib/python-xlib
license = LGPLv2+
author = Peter Liljenberg
author_email = petli@ctrl-c.liu.se
keywords =
windows
x
x11
xlib
classifiers =
Development Status :: 5 - Production/Stable
Environment :: X11 Applications
Intended Audience :: Developers
License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)
Operating System :: OS Independent
Programming Language :: Python :: 2.7
Programming Language :: Python :: 3
Programming Language :: Python :: 3.3
Programming Language :: Python :: 3.4
Programming Language :: Python :: 3.5
Programming Language :: Python :: 3.5
Programming Language :: Python :: 3.6
Programming Language :: Python :: Implementation :: CPython
Topic :: Software Development :: Libraries :: Python Modules
Topic :: Software Development :: Libraries
Topic :: Software Development :: User Interfaces
[bdist_wheel]
universal = 1
......
# Distutils script for python-xlib
from setuptools import setup
from pkg_resources import parse_requirements
from setuptools import (__version__ as setuptools_version, setup)
import Xlib
# Check setuptools is recent enough to support `setup.cfg`.
setuptools_require = next(parse_requirements('setuptools>=30.3.0'))
assert setuptools_version in setuptools_require, '{} is required'.format(setuptools_require)
setup(
name='python-xlib',
version=Xlib.__version_string__,
description='Python X Library',
download_url='https://github.com/python-xlib/python-xlib/releases',
url='https://github.com/python-xlib/python-xlib',
license='LGPLv2+',
author='Peter Liljenberg',
author_email='petli@ctrl-c.liu.se',
setup(
install_requires=['six>=1.10.0'],
setup_requires=['setuptools-scm'],
packages=[
'Xlib',
'Xlib.ext',
......@@ -28,22 +20,4 @@ setup(
'Xlib.support',
'Xlib.xobject'
],
keywords='xlib x11 x windows',
classifiers=[
'Development Status :: 5 - Production/Stable',
'Environment :: X11 Applications',
'Intended Audience :: Developers',
'License :: OSI Approved :: GNU Lesser General Public License v2 or later (LGPLv2+)',
'Operating System :: OS Independent',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: Implementation :: CPython',
'Topic :: Software Development :: Libraries :: Python Modules',
'Topic :: Software Development :: Libraries',
'Topic :: Software Development :: User Interfaces',
],
)
#!/usr/bin/env python
# -*- coding: utf-8 -*
from functools import partial
import socket
import sys
import unittest
from mock import patch
from Xlib.support import unix_connect
from Xlib.error import DisplayNameError
from Xlib.error import DisplayConnectionError, DisplayNameError
@unittest.skipUnless(sys.platform.startswith('linux'), 'Linux specific tests')
class TestUnixConnect(unittest.TestCase):
def test_get_display(self):
# Valid cases.
for display, expected in (
# Implicit Unix socket connections.
(':0.1', ('', 0, 1)),
(':4', ('', 4, 0)),
# Implicit TCP connections.
('foo:1.2', ('foo', 1, 2)),
('bar:5', ('bar', 5, 0)),
# Explicit Unix socket connections.
('unix/foo:4.3', ('', 4, 3)),
('unix/:66', ('', 66, 0)),
# Explicit TCP connections.
('tcp/foo:11.1', ('foo', 11, 1)),
('tcp/bar:66.6', ('bar', 66, 6)),
('tcp/unix:54.3', ('unix', 54, 3)),
# Special case: `unix:0.0` is equivalent to `:0.0`.
('unix:99.5', ('', 99, 5)),
('unix:42', ('', 42, 0)),
):
result = unix_connect.get_display(display)
self.assertEqual(result, (display,) + expected)
# Invalid cases.
for display in (
# No display number.
'',
':',
'foo',
'bar:',
# Bad screen number.
':48.',
':47.f',
# Bad hostname.
u'fòó:0',
u'tcp/bàr:1',
u'unix/fòóbàr:2',
# Bad protocol.
'udp/foo:0'
# With explicit TCP connections, hostname must be set.
'tcp/:0',
):
with self.assertRaises(DisplayNameError):
unix_connect.get_display(display)
def test_get_display(self):
# Valid cases.
for display, expected in (
# Implicit Unix socket connections.
(':0.1', (None, '', 0, 1)),
(':4', (None, '', 4, 0)),
# Implicit TCP connections.
('foo:1.2', (None, 'foo', 1, 2)),
('bar:5', (None, 'bar', 5, 0)),
# Explicit Unix socket connections.
('unix/foo:4.3', ('unix', 'foo', 4, 3)),
('unix/:66', ('unix', '', 66, 0)),
# Explicit TCP connections.
('tcp/foo:11.1', ('tcp', 'foo', 11, 1)),
('tcp/bar:66.6', ('tcp', 'bar', 66, 6)),
('tcp/unix:54.3', ('tcp', 'unix', 54, 3)),
# Special case: `unix:0.0` is equivalent to `:0.0`.
('unix:99.5', (None, 'unix', 99, 5)),
('unix:42', (None, 'unix', 42, 0)),
):
result = unix_connect.get_display(display)
self.assertEqual(result, (display,) + expected)
# Invalid cases.
for display in (
# No display number.
'',
':',
'foo',
'bar:',
# Bad screen number.
':48.',
':47.f',
# Bad hostname.
u'fòó:0',
u'tcp/bàr:1',
u'unix/fòóbàr:2',
# Bad protocol.
'udp/foo:0'
# With explicit TCP connections, hostname must be set.
'tcp/:0',
):
with self.assertRaises(DisplayNameError):
unix_connect.get_display(display)
def test_get_socket(self):
class FakeSocket(object):
def fileno(self):
return 42
calls = []
def _get_socket(socket_type, raises, *params):
calls.append(('_get_%s_socket' % socket_type,) + params)
if raises:
raise socket.error()
return FakeSocket()
def path_exists(returns, path):
calls.append(('os.path.exists', path))
return returns
def fcntl(*args):
calls.append(('fcntl',) + 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, [
('_get_tcp_socket', 'host', 6),
]),
# Failed explicit TCP socket connection.
(('tcp/host:6', None, 'host', 6), False, False, False, True, [
('_get_tcp_socket', 'host', 6),
]),
# Successful implicit TCP socket connection.
(('host:5', None, 'host', 5), False, False, True, False, [
('_get_tcp_socket', 'host', 5),
]),
# Failed implicit TCP socket connection.
(('host:5', None, 'host', 5), False, False, False, True, [
('_get_tcp_socket', 'host', 5),
]),
# Successful explicit Unix socket connection.
(('unix/name:0', 'unix', 'name', 0), True, True, False, False, [
('os.path.exists', '/tmp/.X11-unix/X0'),
('_get_unix_socket', '/tmp/.X11-unix/X0'),
]),
# Failed explicit Unix socket connection.
(('unix/name:0', 'unix', 'name', 0), False, True, False, True, [
('os.path.exists', '/tmp/.X11-unix/X0'),
('_get_unix_socket', '/tmp/.X11-unix/X0'),
]),
# Successful explicit Unix socket connection, variant.
(('unix:0', None, 'unix', 0), True, True, False, False, [
('os.path.exists', '/tmp/.X11-unix/X0'),
('_get_unix_socket', '/tmp/.X11-unix/X0'),
]),
# Failed explicit Unix socket connection, variant.
(('unix:0', None, 'unix', 0), False, True, False, True, [
('os.path.exists', '/tmp/.X11-unix/X0'),
('_get_unix_socket', '/tmp/.X11-unix/X0'),
]),
# Successful implicit Unix socket connection.
((':4', None, '', 4), True, True, False, False, [
('os.path.exists', '/tmp/.X11-unix/X4'),
('_get_unix_socket', '/tmp/.X11-unix/X4'),
]),
# Successful implicit Unix socket connection, abstract address.
((':3', None, '', 3), True, False, False, False, [
('os.path.exists', '/tmp/.X11-unix/X3'),
('_get_unix_socket', '\0/tmp/.X11-unix/X3'),
]),
# Failed implicit Unix socket connection, successful fallback on TCP.
((':2', None, '', 2), False, False, True, False, [
('os.path.exists', '/tmp/.X11-unix/X2'),
('_get_unix_socket', '\0/tmp/.X11-unix/X2'),
('_get_tcp_socket', '', 2),
]),
# Failed implicit Unix socket connection, failed fallback on TCP.
((':1', None, '', 1), False, False, False, True, [
('os.path.exists', '/tmp/.X11-unix/X1'),
('_get_unix_socket', '\0/tmp/.X11-unix/X1'),
('_get_tcp_socket', '', 1),
]),
):
with \
patch('Xlib.support.unix_connect._get_unix_socket',
partial(_get_socket, 'unix', not allow_unix)), \
patch('Xlib.support.unix_connect._get_tcp_socket',
partial(_get_socket, 'tcp', not allow_tcp)), \
patch('os.path.exists',
partial(path_exists, unix_addr_exists)), \
patch('fcntl.fcntl', fcntl):
del calls[:]
if expect_connection_error:
with self.assertRaises(DisplayConnectionError):
unix_connect.get_socket(*params)
else:
s = unix_connect.get_socket(*params)
self.assertIsInstance(s, FakeSocket)
expected_calls.append(('fcntl', 42,
unix_connect.F_SETFD,
unix_connect.FD_CLOEXEC))
self.assertEqual(calls, expected_calls)
if __name__ == '__main__':
......