| |
@@ -42,10 +42,15 @@
|
| |
file.
|
| |
|
| |
"""
|
| |
+ from __future__ import annotations
|
| |
|
| |
from distutils.sysconfig import get_python_lib
|
| |
from enum import IntEnum
|
| |
from functools import partial
|
| |
+ from typing import (
|
| |
+ Any, AnyStr, Callable, Dict, Iterator, List, Match, NoReturn, Optional,
|
| |
+ Pattern, Protocol, Set, Tuple, Union
|
| |
+ )
|
| |
import os
|
| |
import platform
|
| |
import re
|
| |
@@ -145,6 +150,7 @@
|
| |
return token_type == TokenType.EQ \
|
| |
or TokenType.PLUSEQ <= token_type <= TokenType.EQPLUSEQ
|
| |
|
| |
+
|
| |
class OpamString(pp.Token):
|
| |
"""Token for matching strings that are delimited by quoting characters.
|
| |
The opam file format allows for a small set of escape sequences.
|
| |
@@ -152,8 +158,9 @@
|
| |
This code was largely borrowed from pyparsing.QuotedString.
|
| |
|
| |
"""
|
| |
+ strRepr: Optional[str]
|
| |
|
| |
- def __init__(self, quote_char):
|
| |
+ def __init__(self, quote_char: str) -> None:
|
| |
"""
|
| |
Initialize an opam string.
|
| |
|
| |
@@ -169,9 +176,9 @@
|
| |
SyntaxWarning, stacklevel=2)
|
| |
raise SyntaxError()
|
| |
|
| |
- self.quote_char = quote_char
|
| |
- self.quote_char_len = len(quote_char)
|
| |
- self.first_quote_char = quote_char[0]
|
| |
+ self.quote_char: str = quote_char
|
| |
+ self.quote_char_len: int = len(quote_char)
|
| |
+ self.first_quote_char: str = quote_char[0]
|
| |
self.flags = re.MULTILINE | re.DOTALL
|
| |
self.pattern = r'%s(?:[^%s]' \
|
| |
% (re.escape(self.quote_char),
|
| |
@@ -188,19 +195,20 @@
|
| |
self.pattern += (r')*%s' % re.escape(self.quote_char))
|
| |
|
| |
try:
|
| |
- self.re = re.compile(self.pattern, self.flags)
|
| |
- self.re_match = self.re.match
|
| |
+ self.re: Pattern = re.compile(self.pattern, self.flags)
|
| |
+ self.re_match: Callable[[AnyStr, int], Optional[Match]] \
|
| |
+ = self.re.match
|
| |
except re.error:
|
| |
- warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern,
|
| |
+ warnings.warn(f"invalid pattern ({self.pattern}) passed to Regex",
|
| |
SyntaxWarning, stacklevel=2)
|
| |
raise
|
| |
|
| |
- self.name = str(self)
|
| |
- self.errmsg = "Expected " + self.name
|
| |
+ self.name: str = str(self)
|
| |
+ self.errmsg: str = "Expected " + self.name
|
| |
self.mayIndexError = False
|
| |
self.mayReturnEmpty = True
|
| |
|
| |
- def parseImpl(self, instring, loc, doActions=True):
|
| |
+ def parseImpl(self, instring, loc, doActions=True) -> Tuple[int, str]:
|
| |
"""Parse an opam string."""
|
| |
result = self.re_match(instring, loc) \
|
| |
if instring[loc] == self.first_quote_char else None
|
| |
@@ -232,7 +240,7 @@
|
| |
idx = ret.find('\\x')
|
| |
while idx >= 0:
|
| |
digits = ret[(idx + 2):(idx + 4)]
|
| |
- ret = ret[:idx] + int(digits, 16) + ret[idx+4:]
|
| |
+ ret = ret[:idx] + chr(int(digits, 16)) + ret[idx+4:]
|
| |
idx = ret.find('\\x', idx + 1)
|
| |
|
| |
# replace decimal character literals
|
| |
@@ -243,12 +251,12 @@
|
| |
char = int(digits)
|
| |
if char < 0 or char > 255:
|
| |
raise ValueError('illegal escape sequence')
|
| |
- ret = ret[:idx] + char + ret[idx+4:]
|
| |
+ ret = ret[:idx] + chr(char) + ret[idx+4:]
|
| |
idx = ret.find('\\', idx + 1)
|
| |
|
| |
return loc, ret
|
| |
|
| |
- def __str__(self):
|
| |
+ def __str__(self) -> str:
|
| |
try:
|
| |
return super(OpamString, self).__str__()
|
| |
except Exception:
|
| |
I have added type hints and tests to the OpamString type and while doing that realized that decoding of escape strings does not work properly. I have therefore changed lines 80 & 89 in opamparser.py to properly handle escape sequences.
However, I am not entirely sure whether that is the correct result. Please take a look at the unit tests, whether the results are what you expect.