@@ -560,20 +560,15 @@ def __init__(self):
560
560
self .errors = list ()
561
561
562
562
563
- class _LineParser :
563
+ class _Line (str ):
564
+ __slots__ = 'clean' , 'has_comments'
564
565
565
- def __init__ ( self , comments ):
566
- self . comments = comments
566
+ def __new__ ( cls , val , * args , ** kwargs ):
567
+ return super (). __new__ ( cls , val )
567
568
568
- @property
569
- def value (self ):
570
- return self ._value
571
-
572
- @value .setter
573
- def value (self , text ):
574
- self ._value = text
575
- trimmed = text .strip ()
576
- self .clean = self .comments .strip (trimmed )
569
+ def __init__ (self , val , comments ):
570
+ trimmed = val .strip ()
571
+ self .clean = comments .strip (trimmed )
577
572
self .has_comments = trimmed != self .clean
578
573
579
574
@@ -594,6 +589,9 @@ def __init__(self, full_prefixes, inline_prefixes):
594
589
def strip (self , text ):
595
590
return self .pattern .sub ('' , text ).rstrip ()
596
591
592
+ def load (self , text ):
593
+ return _Line (text , self )
594
+
597
595
598
596
class RawConfigParser (MutableMapping ):
599
597
"""ConfigParser that does not do interpolation."""
@@ -1063,9 +1061,8 @@ def _read(self, fp, fpname):
1063
1061
1064
1062
def _read_inner (self , fp , fpname ):
1065
1063
st = _ReadState ()
1066
- line = _LineParser (self ._comments )
1067
1064
1068
- for st .lineno , line . value in enumerate (fp , start = 1 ):
1065
+ for st .lineno , line in enumerate (map ( self . _comments . load , fp ) , start = 1 ):
1069
1066
if not line .clean :
1070
1067
if self ._empty_lines_in_values :
1071
1068
# add empty line to the value, but only if there was no
@@ -1080,7 +1077,7 @@ def _read_inner(self, fp, fpname):
1080
1077
st .indent_level = sys .maxsize
1081
1078
continue
1082
1079
1083
- first_nonspace = self .NONSPACECRE .search (line . value )
1080
+ first_nonspace = self .NONSPACECRE .search (line )
1084
1081
st .cur_indent_level = first_nonspace .start () if first_nonspace else 0
1085
1082
1086
1083
if self ._handle_continuation_line (st , line , fpname ):
@@ -1096,7 +1093,7 @@ def _handle_continuation_line(self, st, line, fpname):
1096
1093
st .cur_indent_level > st .indent_level )
1097
1094
if is_continue :
1098
1095
if st .cursect [st .optname ] is None :
1099
- raise MultilineContinuationError (fpname , st .lineno , line . value )
1096
+ raise MultilineContinuationError (fpname , st .lineno , line )
1100
1097
st .cursect [st .optname ].append (line .clean )
1101
1098
return is_continue
1102
1099
@@ -1110,7 +1107,7 @@ def _handle_rest(self, st, line, fpname):
1110
1107
mo = self .SECTCRE .match (line .clean )
1111
1108
1112
1109
if not mo and st .cursect is None :
1113
- raise MissingSectionHeaderError (fpname , st .lineno , line . value )
1110
+ raise MissingSectionHeaderError (fpname , st .lineno , line )
1114
1111
1115
1112
self ._handle_header (st , mo .group ('header' ), fpname ) if mo else self ._handle_option (st , line , fpname )
1116
1113
@@ -1142,12 +1139,12 @@ def _handle_option(self, st, line, fpname):
1142
1139
# exception but keep going. the exception will be
1143
1140
# raised at the end of the file and will contain a
1144
1141
# list of all bogus lines
1145
- st .errors .append (ParsingError (fpname , st .lineno , line . value ))
1142
+ st .errors .append (ParsingError (fpname , st .lineno , line ))
1146
1143
return
1147
1144
1148
1145
st .optname , vi , optval = mo .group ('option' , 'vi' , 'value' )
1149
1146
if not st .optname :
1150
- st .errors .append (ParsingError (fpname , st .lineno , line . value ))
1147
+ st .errors .append (ParsingError (fpname , st .lineno , line ))
1151
1148
st .optname = self .optionxform (st .optname .rstrip ())
1152
1149
if (self ._strict and
1153
1150
(st .sectname , st .optname ) in st .elements_added ):
0 commit comments