Mercurial > p > roundup > code
comparison roundup/anypy/strings.py @ 7766:c65e0a725c88
fix: replace eval with ast.literal_eval; ruff linting
strings.py:
When reading csv export files, use the safer literal_eval to
evaluate the fields. Issue pointed out by ruff linter.
Other Cleanup:
sort imports
replace if, else, if, else with if, elif, else
use isinstance with tuples rather than 'isinstance() or
isinstance()'
test_anypy.py:
Added tests for tuples, and booleans. Also added exception handling
for malformed strings, booleans, tuples.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Sat, 02 Mar 2024 04:01:22 -0500 |
| parents | 417c8ddc98ac |
| children | 4261449081be |
comparison
equal
deleted
inserted
replaced
| 7765:dec7de56f253 | 7766:c65e0a725c88 |
|---|---|
| 2 # In Python 3, these are Unicode strings. In Python 2, these are | 2 # In Python 3, these are Unicode strings. In Python 2, these are |
| 3 # encoded using UTF-8, and the Python 2 unicode type is only used in a | 3 # encoded using UTF-8, and the Python 2 unicode type is only used in a |
| 4 # few places, generally for interacting with external modules | 4 # few places, generally for interacting with external modules |
| 5 # requiring that type to be used. | 5 # requiring that type to be used. |
| 6 | 6 |
| 7 import ast | |
| 8 import io | |
| 7 import sys | 9 import sys |
| 8 import io | |
| 9 | 10 |
| 10 _py3 = sys.version_info[0] > 2 | 11 _py3 = sys.version_info[0] > 2 |
| 11 | 12 |
| 12 if _py3: | 13 if _py3: |
| 13 StringIO = io.StringIO | 14 StringIO = io.StringIO |
| 61 | 62 |
| 62 def us2u(s, errors='strict'): | 63 def us2u(s, errors='strict'): |
| 63 """Convert a string or Unicode string to a Unicode string.""" | 64 """Convert a string or Unicode string to a Unicode string.""" |
| 64 if _py3: | 65 if _py3: |
| 65 return s | 66 return s |
| 67 elif isinstance(s, unicode): # noqa: F821 | |
| 68 return s | |
| 66 else: | 69 else: |
| 67 if isinstance(s, unicode): # noqa: F821 | 70 return unicode(s, 'utf-8', errors) # noqa: F821 |
| 68 return s | |
| 69 else: | |
| 70 return unicode(s, 'utf-8', errors) # noqa: F821 | |
| 71 | 71 |
| 72 | 72 |
| 73 def us2s(u): | 73 def us2s(u): |
| 74 """Convert a string or Unicode string to the internal string format.""" | 74 """Convert a string or Unicode string to the internal string format.""" |
| 75 if _py3: | 75 if _py3: |
| 76 return u | 76 return u |
| 77 elif isinstance(u, unicode): # noqa: F821 | |
| 78 return u.encode('utf-8') | |
| 77 else: | 79 else: |
| 78 if isinstance(u, unicode): # noqa: F821 | 80 return u |
| 79 return u.encode('utf-8') | |
| 80 else: | |
| 81 return u | |
| 82 | 81 |
| 83 | 82 |
| 84 def uany2s(u): | 83 def uany2s(u): |
| 85 """Convert a Unicode string or other object to the internal string format. | 84 """Convert a Unicode string or other object to the internal string format. |
| 86 | 85 |
| 87 Objects that are not Unicode strings are passed to str().""" | 86 Objects that are not Unicode strings are passed to str().""" |
| 88 if _py3: | 87 if _py3: |
| 89 return str(u) | 88 return str(u) |
| 89 elif isinstance(u, unicode): # noqa: F821 | |
| 90 return u.encode('utf-8') | |
| 90 else: | 91 else: |
| 91 if isinstance(u, unicode): # noqa: F821 | 92 return str(u) |
| 92 return u.encode('utf-8') | |
| 93 else: | |
| 94 return str(u) | |
| 95 | 93 |
| 96 | 94 |
| 97 def is_us(s): | 95 def is_us(s): |
| 98 """Return whether an object is a string or Unicode string.""" | 96 """Return whether an object is a string or Unicode string.""" |
| 99 if _py3: | 97 if _py3: |
| 100 return isinstance(s, str) | 98 return isinstance(s, str) |
| 101 else: | 99 else: |
| 102 return isinstance(s, str) or isinstance(s, unicode) # noqa: F821 | 100 return isinstance(s, (str, unicode)) # noqa: F821 |
| 103 | 101 |
| 104 | 102 |
| 105 def uchr(c): | 103 def uchr(c): |
| 106 """Return the Unicode string containing the given character.""" | 104 """Return the Unicode string containing the given character.""" |
| 107 if _py3: | 105 if _py3: |
| 139 return repr(v) | 137 return repr(v) |
| 140 | 138 |
| 141 | 139 |
| 142 def eval_import(s): | 140 def eval_import(s): |
| 143 """Evaluate a Python-2-style value imported from a CSV file.""" | 141 """Evaluate a Python-2-style value imported from a CSV file.""" |
| 144 if _py3: | 142 try: |
| 145 try: | 143 if _py3: |
| 146 v = eval(s) | 144 try: |
| 147 except SyntaxError: | 145 v = ast.literal_eval(s) |
| 148 # handle case where link operation reports id a long int | 146 except SyntaxError: |
| 149 # ('issue', 5002L, "status") rather than as a string. | 147 # handle case where link operation reports id a long |
| 150 # This was a bug that existed and was fixed before or with v1.2.0 | 148 # int ('issue', 5002L, "status") rather than as a |
| 151 import re | 149 # string. This was a bug that existed and was fixed |
| 152 v = eval(re.sub(r', ([0-9]+)L,', r', \1,', s)) | 150 # before or with v1.2.0 |
| 151 import re | |
| 152 v = ast.literal_eval(re.sub(r', ([0-9]+)L,', r', \1,', s)) | |
| 153 | 153 |
| 154 if isinstance(v, str): | 154 if isinstance(v, str): |
| 155 return v.encode('iso-8859-1').decode('utf-8') | 155 return v.encode('iso-8859-1').decode('utf-8') |
| 156 elif isinstance(v, dict): | 156 elif isinstance(v, dict): |
| 157 v_mod = {} | 157 v_mod = {} |
| 158 for key, value in v.items(): | 158 # ruff: noqa: PLW2901 |
| 159 if isinstance(key, str): | 159 for key, value in v.items(): |
| 160 key = key.encode('iso-8859-1').decode('utf-8') | 160 if isinstance(key, str): |
| 161 if isinstance(value, str): | 161 key = key.encode('iso-8859-1').decode('utf-8') |
| 162 value = value.encode('iso-8859-1').decode('utf-8') | 162 if isinstance(value, str): |
| 163 v_mod[key] = value | 163 value = value.encode('iso-8859-1').decode('utf-8') |
| 164 return v_mod | 164 v_mod[key] = value |
| 165 return v_mod | |
| 166 else: | |
| 167 return v | |
| 165 else: | 168 else: |
| 166 return v | 169 return ast.literal_eval(s) |
| 167 else: | 170 |
| 168 return eval(s) | 171 except (ValueError, SyntaxError) as e: |
| 172 raise ValueError( | |
| 173 ("Error %(exception)s trying to parse value '%(value)s'") % | |
| 174 { 'exception': e, 'value': s}) | |
| 175 |
