Canonicalize paths before using them further

Convert/normalize path types before further usage
and attempt to translate non-string objects so that
they can be used correctly in further interprocess
locking code.

Fixes issue #16
This commit is contained in:
Joshua Harlow
2015-12-06 16:47:04 -08:00
parent 0417e414a4
commit 25541c89bf
2 changed files with 31 additions and 1 deletions

View File

@@ -17,8 +17,25 @@
# under the License.
import logging
import sys
import time
try:
from os import fsencode as _fsencode
except (ImportError, AttributeError):
def _fsencode(path):
# Replicate similar logic to what py3.2+ fsencode does.
# See: https://bugs.python.org/issue8514
encoding = sys.getfilesystemencoding()
if encoding == 'mbcs':
errors = 'strict'
else:
errors = 'surrogateescape'
return path.encode(encoding, errors)
import six
from monotonic import monotonic as now # noqa
# log level for low-level debugging
@@ -27,6 +44,19 @@ BLATHER = 5
LOG = logging.getLogger(__name__)
def canonicalize_path(path):
"""Canonicalizes a potential path.
Returns a binary string encoded into filesystem encoding.
"""
if isinstance(path, six.binary_type):
return path
if isinstance(path, six.text_type):
return _fsencode(path)
else:
return canonicalize_path(str(path))
def pick_first_not_none(*values):
"""Returns first of values that is *not* None (or None if all are/were)."""
for val in values:

View File

@@ -84,7 +84,7 @@ class _InterProcessLock(object):
def __init__(self, path, sleep_func=time.sleep, logger=None):
self.lockfile = None
self.path = path
self.path = _utils.canonicalize_path(path)
self.acquired = False
self.sleep_func = sleep_func
self.logger = _utils.pick_first_not_none(logger, LOG)