summaryrefslogtreecommitdiff
path: root/src/pip/_vendor/chardet/sbcharsetprober.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/pip/_vendor/chardet/sbcharsetprober.py')
-rw-r--r--src/pip/_vendor/chardet/sbcharsetprober.py73
1 files changed, 44 insertions, 29 deletions
diff --git a/src/pip/_vendor/chardet/sbcharsetprober.py b/src/pip/_vendor/chardet/sbcharsetprober.py
index 46ba835c6..31d70e154 100644
--- a/src/pip/_vendor/chardet/sbcharsetprober.py
+++ b/src/pip/_vendor/chardet/sbcharsetprober.py
@@ -31,44 +31,49 @@ from collections import namedtuple
from .charsetprober import CharSetProber
from .enums import CharacterCategory, ProbingState, SequenceLikelihood
-
-SingleByteCharSetModel = namedtuple('SingleByteCharSetModel',
- ['charset_name',
- 'language',
- 'char_to_order_map',
- 'language_model',
- 'typical_positive_ratio',
- 'keep_ascii_letters',
- 'alphabet'])
+SingleByteCharSetModel = namedtuple(
+ "SingleByteCharSetModel",
+ [
+ "charset_name",
+ "language",
+ "char_to_order_map",
+ "language_model",
+ "typical_positive_ratio",
+ "keep_ascii_letters",
+ "alphabet",
+ ],
+)
class SingleByteCharSetProber(CharSetProber):
SAMPLE_SIZE = 64
- SB_ENOUGH_REL_THRESHOLD = 1024 # 0.25 * SAMPLE_SIZE^2
+ SB_ENOUGH_REL_THRESHOLD = 1024 # 0.25 * SAMPLE_SIZE^2
POSITIVE_SHORTCUT_THRESHOLD = 0.95
NEGATIVE_SHORTCUT_THRESHOLD = 0.05
- def __init__(self, model, reversed=False, name_prober=None):
- super(SingleByteCharSetProber, self).__init__()
+ def __init__(self, model, is_reversed=False, name_prober=None):
+ super().__init__()
self._model = model
# TRUE if we need to reverse every pair in the model lookup
- self._reversed = reversed
+ self._reversed = is_reversed
# Optional auxiliary prober for name decision
self._name_prober = name_prober
self._last_order = None
self._seq_counters = None
self._total_seqs = None
self._total_char = None
+ self._control_char = None
self._freq_char = None
self.reset()
def reset(self):
- super(SingleByteCharSetProber, self).reset()
+ super().reset()
# char order of last character
self._last_order = 255
self._seq_counters = [0] * SequenceLikelihood.get_num_categories()
self._total_seqs = 0
self._total_char = 0
+ self._control_char = 0
# characters that fall in our sampling range
self._freq_char = 0
@@ -76,20 +81,20 @@ class SingleByteCharSetProber(CharSetProber):
def charset_name(self):
if self._name_prober:
return self._name_prober.charset_name
- else:
- return self._model.charset_name
+ return self._model.charset_name
@property
def language(self):
if self._name_prober:
return self._name_prober.language
- else:
- return self._model.language
+ return self._model.language
def feed(self, byte_str):
# TODO: Make filter_international_words keep things in self.alphabet
if not self._model.keep_ascii_letters:
byte_str = self.filter_international_words(byte_str)
+ else:
+ byte_str = self.remove_xml_tags(byte_str)
if not byte_str:
return self.state
char_to_order_map = self._model.char_to_order_map
@@ -103,9 +108,6 @@ class SingleByteCharSetProber(CharSetProber):
# _total_char purposes.
if order < CharacterCategory.CONTROL:
self._total_char += 1
- # TODO: Follow uchardet's lead and discount confidence for frequent
- # control characters.
- # See https://github.com/BYVoid/uchardet/commit/55b4f23971db61
if order < self.SAMPLE_SIZE:
self._freq_char += 1
if self._last_order < self.SAMPLE_SIZE:
@@ -122,14 +124,17 @@ class SingleByteCharSetProber(CharSetProber):
if self._total_seqs > self.SB_ENOUGH_REL_THRESHOLD:
confidence = self.get_confidence()
if confidence > self.POSITIVE_SHORTCUT_THRESHOLD:
- self.logger.debug('%s confidence = %s, we have a winner',
- charset_name, confidence)
+ self.logger.debug(
+ "%s confidence = %s, we have a winner", charset_name, confidence
+ )
self._state = ProbingState.FOUND_IT
elif confidence < self.NEGATIVE_SHORTCUT_THRESHOLD:
- self.logger.debug('%s confidence = %s, below negative '
- 'shortcut threshhold %s', charset_name,
- confidence,
- self.NEGATIVE_SHORTCUT_THRESHOLD)
+ self.logger.debug(
+ "%s confidence = %s, below negative shortcut threshold %s",
+ charset_name,
+ confidence,
+ self.NEGATIVE_SHORTCUT_THRESHOLD,
+ )
self._state = ProbingState.NOT_ME
return self.state
@@ -137,8 +142,18 @@ class SingleByteCharSetProber(CharSetProber):
def get_confidence(self):
r = 0.01
if self._total_seqs > 0:
- r = ((1.0 * self._seq_counters[SequenceLikelihood.POSITIVE]) /
- self._total_seqs / self._model.typical_positive_ratio)
+ r = (
+ (
+ self._seq_counters[SequenceLikelihood.POSITIVE]
+ + 0.25 * self._seq_counters[SequenceLikelihood.LIKELY]
+ )
+ / self._total_seqs
+ / self._model.typical_positive_ratio
+ )
+ # The more control characters (proportionnaly to the size
+ # of the text), the less confident we become in the current
+ # charset.
+ r = r * (self._total_char - self._control_char) / self._total_char
r = r * self._freq_char / self._total_char
if r >= 1.0:
r = 0.99