Skip to content

Commit

Permalink
Merge pull request #4 from minrk/warn-unsafe
Browse files Browse the repository at this point in the history
Warn when escape character is in safe character set
  • Loading branch information
minrk committed Apr 30, 2020
2 parents 35f4c19 + 9001a34 commit 29e4604
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 7 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ python:
- 2.7
- 3.4
- 3.6
- 3.7
- 3.8
cache:
- pip
install:
Expand Down
15 changes: 11 additions & 4 deletions escapism.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
import re
import string
import sys
import warnings

__version__ = '1.0.0'
__version__ = "1.0.1"

SAFE = set(string.ascii_letters + string.digits)
ESCAPE_CHAR = '_'
Expand Down Expand Up @@ -67,7 +68,13 @@ def escape(to_escape, safe=SAFE, escape_char=ESCAPE_CHAR, allow_collisions=False
if allow_collisions:
safe.add(escape_char)
elif escape_char in safe:
# escape char can't be in safe list
warnings.warn(
"Escape character %r cannot be a safe character."
" Set allow_collisions=True if you want to allow ambiguous escaped strings."
% escape_char,
RuntimeWarning,
stacklevel=2,
)
safe.remove(escape_char)

chars = []
Expand All @@ -81,7 +88,7 @@ def escape(to_escape, safe=SAFE, escape_char=ESCAPE_CHAR, allow_collisions=False

def _unescape_char(m):
"""Unescape a single byte
Used as a callback in pattern.subn. `m.group(1)` must be a single byte in hex,
e.g. `a4` or `ff`.
"""
Expand All @@ -90,7 +97,7 @@ def _unescape_char(m):

def unescape(escaped, escape_char=ESCAPE_CHAR):
"""Unescape a string escaped with `escape`
escape_char must be the same as that used in the call to escape.
"""
if isinstance(escaped, bytes):
Expand Down
17 changes: 14 additions & 3 deletions tests/test_escapism.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# coding: utf-8

import warnings

import pytest

from escapism import escape, unescape, SAFE

text = type(u'')
Expand All @@ -11,6 +16,7 @@
u'_\\-+',
]


def test_escape_default():
for s in test_strings:
e = escape(s)
Expand All @@ -19,6 +25,7 @@ def test_escape_default():
assert isinstance(u, text)
assert u == s


def test_escape_custom_char():
for escape_char in r'\-%+_':
for s in test_strings:
Expand All @@ -28,6 +35,7 @@ def test_escape_custom_char():
assert isinstance(u, text)
assert u == s


def test_escape_custom_safe():
safe = 'ABCDEFabcdef0123456789'
escape_char = '\\'
Expand All @@ -38,14 +46,17 @@ def test_escape_custom_safe():
u = unescape(e, escape_char=escape_char)
assert u == s


def test_safe_escape_char():
escape_char = '-'
escape_char = "-"
safe = SAFE.union({escape_char})
e = escape(escape_char, safe=safe, escape_char=escape_char)
assert e == '{}{:02X}'.format(escape_char, ord(escape_char))
with pytest.warns(RuntimeWarning):
e = escape(escape_char, safe=safe, escape_char=escape_char)
assert e == "{}{:02X}".format(escape_char, ord(escape_char))
u = unescape(e, escape_char=escape_char)
assert u == escape_char


def test_allow_collisions():
escaped = escape('foo-bar ', escape_char='-', allow_collisions=True)
assert escaped == 'foo-bar-20'

0 comments on commit 29e4604

Please sign in to comment.