I made a patch making the python-daemon package (version 1.5.5) suitable 
for both python3 and to (tested with python3.2.3 and python2.7.3). It 
does also some other changes that are lsited below:

It replaces the pidlockfile.py. Instead the file contains a simple 
PIDLockFile context. So the package doesn't require the lockfile module. 
It's still possible to use every pidfile context with the deamon.

Note that the tests are left unchanged and aren't expected to work. 
Instead i wrote my own, simple test script, which worked with both 
python3 and python2. But i think some more testing may be appreciated.

The patch is attached to this E-Mail. If you have any questions just 
answer to this E-Mail.
diff -Naur python-daemon-1.5.5/daemon/daemon.py python-daemon-1.5.5-python3.2/daemon/daemon.py
--- python-daemon-1.5.5/daemon/daemon.py	2010-02-26 04:09:27.000000000 +0100
+++ python-daemon-1.5.5-python3.2/daemon/daemon.py	2013-08-09 19:21:48.333834083 +0200
@@ -439,9 +439,13 @@
             itself.
 
             """
+        if sys.version_info.major == 3:
+            string = str
+        else:
+            string = basestring
         if target is None:
             result = signal.SIG_IGN
-        elif isinstance(target, basestring):
+        elif isinstance(target, string):
             name = target
             result = getattr(self, name)
         else:
@@ -468,7 +472,7 @@
         """
     try:
         os.chdir(directory)
-    except Exception, exc:
+    except Exception as exc:
         error = DaemonOSEnvironmentError(
             "Unable to change working directory (%(exc)s)"
             % vars())
@@ -486,7 +490,7 @@
     try:
         os.chdir(directory)
         os.chroot(directory)
-    except Exception, exc:
+    except Exception as exc:
         error = DaemonOSEnvironmentError(
             "Unable to change root directory (%(exc)s)"
             % vars())
@@ -498,7 +502,7 @@
         """
     try:
         os.umask(mask)
-    except Exception, exc:
+    except Exception as exc:
         error = DaemonOSEnvironmentError(
             "Unable to change file creation mask (%(exc)s)"
             % vars())
@@ -516,7 +520,7 @@
     try:
         os.setgid(gid)
         os.setuid(uid)
-    except Exception, exc:
+    except Exception as exc:
         error = DaemonOSEnvironmentError(
             "Unable to change file creation mask (%(exc)s)"
             % vars())
@@ -537,7 +541,7 @@
         # Ensure the resource limit exists on this platform, by requesting
         # its current value
         core_limit_prev = resource.getrlimit(core_resource)
-    except ValueError, exc:
+    except ValueError as exc:
         error = DaemonOSEnvironmentError(
             "System does not support RLIMIT_CORE resource limit (%(exc)s)"
             % vars())
@@ -571,7 +575,7 @@
             pid = os.fork()
             if pid > 0:
                 os._exit(0)
-        except OSError, exc:
+        except OSError as exc:
             exc_errno = exc.errno
             exc_strerror = exc.strerror
             error = DaemonProcessDetachError(
@@ -613,7 +617,7 @@
     try:
         socket_type = file_socket.getsockopt(
             socket.SOL_SOCKET, socket.SO_TYPE)
-    except socket.error, exc:
+    except socket.error as exc:
         exc_errno = exc.args[0]
         if exc_errno == errno.ENOTSOCK:
             # Socket operation on non-socket
@@ -673,7 +677,7 @@
         """
     try:
         os.close(fd)
-    except OSError, exc:
+    except OSError as exc:
         if exc.errno == errno.EBADF:
             # File descriptor was not open
             pass
diff -Naur python-daemon-1.5.5/daemon/__init__.py python-daemon-1.5.5-python3.2/daemon/__init__.py
--- python-daemon-1.5.5/daemon/__init__.py	2010-01-20 12:33:10.000000000 +0100
+++ python-daemon-1.5.5-python3.2/daemon/__init__.py	2013-08-09 15:53:13.673754274 +0200
@@ -37,8 +37,8 @@
 
     """
 
-import version
-from daemon import DaemonContext
+from . import version
+from .daemon import DaemonContext
 
 
 _version = version.version
diff -Naur python-daemon-1.5.5/daemon/pidlockfile.py python-daemon-1.5.5-python3.2/daemon/pidlockfile.py
--- python-daemon-1.5.5/daemon/pidlockfile.py	2010-01-20 12:33:10.000000000 +0100
+++ python-daemon-1.5.5-python3.2/daemon/pidlockfile.py	2013-08-09 22:37:35.349869343 +0200
@@ -1,194 +1,34 @@
 # -*- coding: utf-8 -*-
 
-# daemon/pidlockfile.py
+# daemon/daemon.py
 # Part of python-daemon, an implementation of PEP 3143.
 #
 # Copyright © 2008–2010 Ben Finney <[email protected]>
+# Copyright © 2007–2008 Robert Niederreiter, Jens Klein
+# Copyright © 2004–2005 Chad J. Schroeder
+# Copyright © 2003 Clark Evans
+# Copyright © 2002 Noah Spurrier
+# Copyright © 2001 Jürgen Hermann
 #
 # This is free software: you may copy, modify, and/or distribute this work
 # under the terms of the Python Software Foundation License, version 2 or
 # later as published by the Python Software Foundation.
 # No warranty expressed or implied. See the file LICENSE.PSF-2 for details.
 
-""" Lockfile behaviour implemented via Unix PID files.
-    """
-
 import os
-import errno
-
-from lockfile import (
-    LinkFileLock,
-    AlreadyLocked, LockFailed,
-    NotLocked, NotMyLock,
-    )
-
-
-class PIDFileError(Exception):
-    """ Abstract base class for errors specific to PID files. """
-
-class PIDFileParseError(ValueError, PIDFileError):
-    """ Raised when parsing contents of PID file fails. """
-
-
-class PIDLockFile(LinkFileLock, object):
-    """ Lockfile implemented as a Unix PID file.
-
-        The PID file is named by the attribute `path`. When locked,
-        the file will be created with a single line of text,
-        containing the process ID (PID) of the process that acquired
-        the lock.
-
-        The lock is acquired and maintained as per `LinkFileLock`.
-
-        """
-
-    def read_pid(self):
-        """ Get the PID from the lock file.
-            """
-        result = read_pid_from_pidfile(self.path)
-        return result
-
-    def acquire(self, *args, **kwargs):
-        """ Acquire the lock.
-
-            Locks the PID file then creates the PID file for this
-            lock. The `timeout` parameter is used as for the
-            `LinkFileLock` class.
-
-            """
-        super(PIDLockFile, self).acquire(*args, **kwargs)
-        try:
-            write_pid_to_pidfile(self.path)
-        except OSError, exc:
-            error = LockFailed("%(exc)s" % vars())
-            raise error
-
-    def release(self):
-        """ Release the lock.
-
-            Removes the PID file then releases the lock, or raises an
-            error if the current process does not hold the lock.
-
-            """
-        if self.i_am_locking():
-            remove_existing_pidfile(self.path)
-        super(PIDLockFile, self).release()
-
-    def break_lock(self):
-        """ Break an existing lock.
-
-            If the lock is held, breaks the lock and removes the PID
-            file.
-
-            """
-        super(PIDLockFile, self).break_lock()
-        remove_existing_pidfile(self.path)
-
-
-class TimeoutPIDLockFile(PIDLockFile):
-    """ Lockfile with default timeout, implemented as a Unix PID file.
-
-        This uses the ``PIDLockFile`` implementation, with the
-        following changes:
-
-        * The `acquire_timeout` parameter to the initialiser will be
-          used as the default `timeout` parameter for the `acquire`
-          method.
-
-        """
-
-    def __init__(self, path, acquire_timeout=None, *args, **kwargs):
-        """ Set up the parameters of a DaemonRunnerLock. """
-        self.acquire_timeout = acquire_timeout
-        super(TimeoutPIDLockFile, self).__init__(path, *args, **kwargs)
-
-    def acquire(self, timeout=None, *args, **kwargs):
-        """ Acquire the lock. """
-        if timeout is None:
-            timeout = self.acquire_timeout
-        super(TimeoutPIDLockFile, self).acquire(timeout, *args, **kwargs)
-
-
-def read_pid_from_pidfile(pidfile_path):
-    """ Read the PID recorded in the named PID file.
-
-        Read and return the numeric PID recorded as text in the named
-        PID file. If the PID file does not exist, return ``None``. If
-        the content is not a valid PID, raise ``PIDFileParseError``.
-
-        """
-    pid = None
-    pidfile = None
-    try:
-        pidfile = open(pidfile_path, 'r')
-    except IOError, exc:
-        if exc.errno == errno.ENOENT:
-            pass
-        else:
-            raise
-
-    if pidfile:
-        # According to the FHS 2.3 section on PID files in ‘/var/run’:
-        #
-        #   The file must consist of the process identifier in
-        #   ASCII-encoded decimal, followed by a newline character. …
-        #
-        #   Programs that read PID files should be somewhat flexible
-        #   in what they accept; i.e., they should ignore extra
-        #   whitespace, leading zeroes, absence of the trailing
-        #   newline, or additional lines in the PID file.
-
-        line = pidfile.readline().strip()
-        try:
-            pid = int(line)
-        except ValueError:
-            raise PIDFileParseError(
-                "PID file %(pidfile_path)r contents invalid" % vars())
-        pidfile.close()
-
-    return pid
-
-
-def write_pid_to_pidfile(pidfile_path):
-    """ Write the PID in the named PID file.
-
-        Get the numeric process ID (“PID”) of the current process
-        and write it to the named file as a line of text.
-
-        """
-    open_flags = (os.O_CREAT | os.O_EXCL | os.O_WRONLY)
-    open_mode = (
-        ((os.R_OK | os.W_OK) << 6) |
-        ((os.R_OK) << 3) |
-        ((os.R_OK)))
-    pidfile_fd = os.open(pidfile_path, open_flags, open_mode)
-    pidfile = os.fdopen(pidfile_fd, 'w')
-
-    # According to the FHS 2.3 section on PID files in ‘/var/run’:
-    #
-    #   The file must consist of the process identifier in
-    #   ASCII-encoded decimal, followed by a newline character. For
-    #   example, if crond was process number 25, /var/run/crond.pid
-    #   would contain three characters: two, five, and newline.
-
-    pid = os.getpid()
-    line = "%(pid)d\n" % vars()
-    pidfile.write(line)
-    pidfile.close()
-
-
-def remove_existing_pidfile(pidfile_path):
-    """ Remove the named PID file if it exists.
 
-        Remove the named PID file. Ignore the condition if the file
-        does not exist, since that only means we are already in the
-        desired state.
+class LockError(OSError):
+    pass
 
-        """
-    try:
-        os.remove(pidfile_path)
-    except OSError, exc:
-        if exc.errno == errno.ENOENT:
-            pass
-        else:
-            raise
+class PIDLockFile(object):
+    def __init__(self, path):
+        self.path = path
+    """context which creates a PID file and deletes it when exits.
+NOTE: Works ONLY as context"""
+    def __enter__(self):
+        if os.path.exists(self.path):
+            raise LockError("PIDFile {0} already exists!".format(self.path))
+        with open(self.path, 'w') as file:
+            file.write(str(os.getpid()))
+    def __exit__(self, *args): #For some reason the server gives three Nones
+        os.unlink(self.path)
diff -Naur python-daemon-1.5.5/daemon/pidlockfile.py~ python-daemon-1.5.5-python3.2/daemon/pidlockfile.py~
--- python-daemon-1.5.5/daemon/pidlockfile.py~	1970-01-01 01:00:00.000000000 +0100
+++ python-daemon-1.5.5-python3.2/daemon/pidlockfile.py~	2013-08-09 19:48:09.189838829 +0200
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+
+# daemon/daemon.py
+# Part of python-daemon, an implementation of PEP 3143.
+#
+# Copyright © 2008–2010 Ben Finney <[email protected]>
+# Copyright © 2007–2008 Robert Niederreiter, Jens Klein
+# Copyright © 2004–2005 Chad J. Schroeder
+# Copyright © 2003 Clark Evans
+# Copyright © 2002 Noah Spurrier
+# Copyright © 2001 Jürgen Hermann
+#
+# This is free software: you may copy, modify, and/or distribute this work
+# under the terms of the Python Software Foundation License, version 2 or
+# later as published by the Python Software Foundation.
+# No warranty expressed or implied. See the file LICENSE.PSF-2 for details.
+
+import os
+
+class LockError(OSError):
+    pass
+
+class PIDLockFile(object):
+    def __init__(self, path):
+        self.path = path
+    """context which creates a PID file and deletes it when exits.
+NOTE: Works ONLY as context"""
+    def __enter__(self):
+        if os.path.exists(self.path):
+            raise LockError("PIDFile {0} already exists!".format(self.path))
+        with open(self.path, 'w') as file:
+            file.write(str(os.getpid()))
+    def __exit__(self):
+        os.unlink(self.path)
diff -Naur python-daemon-1.5.5/daemon/runner.py python-daemon-1.5.5-python3.2/daemon/runner.py
--- python-daemon-1.5.5/daemon/runner.py	2010-01-20 12:33:10.000000000 +0100
+++ python-daemon-1.5.5-python3.2/daemon/runner.py	2013-08-09 15:58:41.441755260 +0200
@@ -136,7 +136,7 @@
         pid = self.pidfile.read_pid()
         try:
             os.kill(pid, signal.SIGTERM)
-        except OSError, exc:
+        except OSError as exc:
             raise DaemonRunnerStopFailureError(
                 "Failed to terminate %(pid)d: %(exc)s" % vars())
 
@@ -221,7 +221,7 @@
     if pidfile_pid is not None:
         try:
             os.kill(pidfile_pid, signal.SIG_DFL)
-        except OSError, exc:
+        except OSError as exc:
             if exc.errno == errno.ESRCH:
                 # The specified PID does not exist
                 result = True
diff -Naur python-daemon-1.5.5/daemon/version/__init__.py python-daemon-1.5.5-python3.2/daemon/version/__init__.py
--- python-daemon-1.5.5/daemon/version/__init__.py	2010-03-02 10:20:42.000000000 +0100
+++ python-daemon-1.5.5-python3.2/daemon/version/__init__.py	2013-08-09 15:44:06.701752632 +0200
@@ -11,26 +11,26 @@
 
 """ Version information for the python-daemon distribution. """
 
-from version_info import version_info
+from .version_info import version_info
 
-version_info['version_string'] = u"1.5.5"
+version_info['version_string'] = "1.5.5"
 
-version_short = u"%(version_string)s" % version_info
-version_full = u"%(version_string)s.r%(revno)s" % version_info
+version_short = "%(version_string)s" % version_info
+version_full = "%(version_string)s.r%(revno)s" % version_info
 version = version_short
 
-author_name = u"Ben Finney"
-author_email = u"[email protected]"
-author = u"%(author_name)s <%(author_email)s>" % vars()
+author_name = "Ben Finney"
+author_email = "[email protected]"
+author = "%(author_name)s <%(author_email)s>" % vars()
 
-copyright_year_begin = u"2001"
+copyright_year_begin = "2001"
 date = version_info['date'].split(' ', 1)[0]
 copyright_year = date.split('-')[0]
 copyright_year_range = copyright_year_begin
 if copyright_year > copyright_year_begin:
-    copyright_year_range += u"–%(copyright_year)s" % vars()
+    copyright_year_range += "–%(copyright_year)s" % vars()
 
 copyright = (
-    u"Copyright © %(copyright_year_range)s %(author)s and others"
+    "Copyright © %(copyright_year_range)s %(author)s and others"
     ) % vars()
-license = u"PSF-2+"
+license = "PSF-2+"
diff -Naur python-daemon-1.5.5/daemon/version/version_info.py python-daemon-1.5.5-python3.2/daemon/version/version_info.py
--- python-daemon-1.5.5/daemon/version/version_info.py	2009-05-22 11:50:21.000000000 +0200
+++ python-daemon-1.5.5-python3.2/daemon/version/version_info.py	2013-08-09 15:52:26.477754132 +0200
@@ -3,8 +3,9 @@
 It uses the current working tree to determine the revision.
 So don't edit it. :)
 """
+from __future__ import print_function
 
-version_info = {'branch_nick': u'python-daemon.devel',
+version_info = {'branch_nick': 'python-daemon.devel',
  'build_date': '2009-05-22 19:50:06 +1000',
  'clean': None,
  'date': '2009-05-22 19:47:30 +1000',
@@ -18,6 +19,6 @@
 
 
 if __name__ == '__main__':
-    print 'revision: %(revno)d' % version_info
-    print 'nick: %(branch_nick)s' % version_info
-    print 'revision id: %(revision_id)s' % version_info
+    print('revision: %(revno)d' % version_info)
+    print('nick: %(branch_nick)s' % version_info)
+    print('revision id: %(revision_id)s' % version_info)
diff -Naur python-daemon-1.5.5/python_daemon.egg-info/PKG-INFO python-daemon-1.5.5-python3.2/python_daemon.egg-info/PKG-INFO
--- python-daemon-1.5.5/python_daemon.egg-info/PKG-INFO	2010-03-02 10:35:54.000000000 +0100
+++ python-daemon-1.5.5-python3.2/python_daemon.egg-info/PKG-INFO	2013-08-09 22:41:44.953870092 +0200
@@ -1,4 +1,4 @@
-Metadata-Version: 1.0
+Metadata-Version: 1.1
 Name: python-daemon
 Version: 1.5.5
 Summary: Library to implement a well-behaved Unix daemon process.
@@ -17,12 +17,12 @@
         
         Simple example of usage::
         
-        import daemon
+            import daemon
         
-        from spam import do_main_program
+            from spam import do_main_program
         
-        with daemon.DaemonContext():
-        do_main_program()
+            with daemon.DaemonContext():
+                do_main_program()
         
         Customisation of the steps to become a daemon is available by
         setting options on the `DaemonContext` instance; see the
diff -Naur python-daemon-1.5.5/python_daemon.egg-info/requires.txt python-daemon-1.5.5-python3.2/python_daemon.egg-info/requires.txt
--- python-daemon-1.5.5/python_daemon.egg-info/requires.txt	2010-03-02 10:35:54.000000000 +0100
+++ python-daemon-1.5.5-python3.2/python_daemon.egg-info/requires.txt	2013-08-09 22:41:44.949870093 +0200
@@ -1,2 +1 @@
-setuptools
-lockfile >=0.7
\ Kein Zeilenumbruch am Dateiende.
+setuptools
\ Kein Zeilenumbruch am Dateiende.
diff -Naur python-daemon-1.5.5/python_daemon.egg-info/SOURCES.txt python-daemon-1.5.5-python3.2/python_daemon.egg-info/SOURCES.txt
--- python-daemon-1.5.5/python_daemon.egg-info/SOURCES.txt	2010-03-02 10:35:54.000000000 +0100
+++ python-daemon-1.5.5-python3.2/python_daemon.egg-info/SOURCES.txt	2013-08-09 22:41:44.957870091 +0200
@@ -2,6 +2,7 @@
 LICENSE.GPL-2
 LICENSE.PSF-2
 MANIFEST.in
+setup.cfg
 setup.py
 daemon/__init__.py
 daemon/daemon.py
diff -Naur python-daemon-1.5.5/setup.py python-daemon-1.5.5-python3.2/setup.py
--- python-daemon-1.5.5/setup.py	2010-03-02 10:16:34.000000000 +0100
+++ python-daemon-1.5.5-python3.2/setup.py	2013-08-09 19:38:34.401837103 +0200
@@ -24,7 +24,7 @@
 
 short_description, long_description = (
     textwrap.dedent(d).strip()
-    for d in main_module.__doc__.split(u'\n\n', 1)
+    for d in main_module.__doc__.split('\n\n', 1)
     )
 
 
@@ -41,7 +41,6 @@
         ],
     install_requires=[
         "setuptools",
-        "lockfile >=0.7",
         ],
 
     # PyPI metadata
@@ -49,7 +48,7 @@
     author_email=version.author_email,
     description=short_description,
     license=version.license,
-    keywords=u"daemon fork unix".split(),
+    keywords="daemon fork unix".split(),
     url=main_module._url,
     long_description=long_description,
     classifiers=[
diff -Naur python-daemon-1.5.5/test/test_daemon.py python-daemon-1.5.5-python3.2/test/test_daemon.py
--- python-daemon-1.5.5/test/test_daemon.py	2010-02-26 04:09:27.000000000 +0100
+++ python-daemon-1.5.5-python3.2/test/test_daemon.py	2013-08-09 19:59:35.077840888 +0200
@@ -735,7 +735,7 @@
         expect_exception = SystemExit
         try:
             instance.terminate(*args)
-        except expect_exception, exc:
+        except expect_exception as exc:
             pass
         self.failUnlessIn(str(exc), str(signal_number))
 
@@ -945,7 +945,7 @@
         expect_error = daemon.daemon.DaemonOSEnvironmentError
         try:
             daemon.daemon.change_working_directory(**args)
-        except expect_error, exc:
+        except expect_error as exc:
             pass
         self.failUnlessIn(str(exc), str(test_error))
 
@@ -1023,7 +1023,7 @@
         expect_error = daemon.daemon.DaemonOSEnvironmentError
         try:
             daemon.daemon.change_root_directory(**args)
-        except expect_error, exc:
+        except expect_error as exc:
             pass
         self.failUnlessIn(str(exc), str(test_error))
 
@@ -1076,7 +1076,7 @@
         expect_error = daemon.daemon.DaemonOSEnvironmentError
         try:
             daemon.daemon.change_file_creation_mask(**args)
-        except expect_error, exc:
+        except expect_error as exc:
             pass
         self.failUnlessIn(str(exc), str(test_error))
 
@@ -1172,7 +1172,7 @@
         expect_error = daemon.daemon.DaemonOSEnvironmentError
         try:
             daemon.daemon.change_process_owner(**args)
-        except expect_error, exc:
+        except expect_error as exc:
             pass
         self.failUnlessIn(str(exc), str(test_error))
 

Attachment: signature.asc
Description: This is a digitally signed message part.

_______________________________________________
python-daemon-devel mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/python-daemon-devel

Reply via email to