aboutsummaryrefslogtreecommitdiffhomepage
path: root/libs/guessit
diff options
context:
space:
mode:
authormorpheus65535 <[email protected]>2021-03-22 10:26:26 -0400
committermorpheus65535 <[email protected]>2021-03-22 10:26:26 -0400
commit24c075051d7299190595437a5a733235b89ac739 (patch)
treeda87f82f004acbfc672bed1f41732dad7e5e8042 /libs/guessit
parent762cd61b215e9f6aa8f0dfee9855f80bc7753f04 (diff)
downloadbazarr-24c075051d7299190595437a5a733235b89ac739.tar.gz
bazarr-24c075051d7299190595437a5a733235b89ac739.zip
Updated guessit and rebulk to latest version
Diffstat (limited to 'libs/guessit')
-rw-r--r--libs/guessit/__main__.py35
-rw-r--r--libs/guessit/__version__.py2
-rw-r--r--libs/guessit/api.py86
-rw-r--r--libs/guessit/backports.py27
-rw-r--r--libs/guessit/config/options.json11
-rw-r--r--libs/guessit/data/tlds-alpha-by-domain.txt (renamed from libs/guessit/tlds-alpha-by-domain.txt)0
-rw-r--r--libs/guessit/monkeypatch.py5
-rw-r--r--libs/guessit/options.py16
-rw-r--r--libs/guessit/rules/common/__init__.py2
-rw-r--r--libs/guessit/rules/common/comparators.py14
-rw-r--r--libs/guessit/rules/common/expected.py2
-rw-r--r--libs/guessit/rules/common/quantity.py5
-rw-r--r--libs/guessit/rules/markers/groups.py6
-rw-r--r--libs/guessit/rules/processors.py8
-rw-r--r--libs/guessit/rules/properties/audio_codec.py10
-rw-r--r--libs/guessit/rules/properties/bit_rate.py2
-rw-r--r--libs/guessit/rules/properties/episode_title.py10
-rw-r--r--libs/guessit/rules/properties/episodes.py10
-rw-r--r--libs/guessit/rules/properties/language.py6
-rw-r--r--libs/guessit/rules/properties/other.py2
-rw-r--r--libs/guessit/rules/properties/release_group.py5
-rw-r--r--libs/guessit/rules/properties/screen_size.py2
-rw-r--r--libs/guessit/rules/properties/size.py2
-rw-r--r--libs/guessit/rules/properties/streaming_service.py17
-rw-r--r--libs/guessit/rules/properties/title.py4
-rw-r--r--libs/guessit/rules/properties/website.py2
-rw-r--r--libs/guessit/test/movies.yml1
-rw-r--r--libs/guessit/test/rules/other.yml3
-rw-r--r--libs/guessit/test/streaming_services.yaml31
-rw-r--r--libs/guessit/test/test_api.py33
-rw-r--r--libs/guessit/test/test_api_unicode_literals.py29
-rw-r--r--libs/guessit/test/test_main.py32
-rw-r--r--libs/guessit/test/test_yml.py33
-rw-r--r--libs/guessit/yamlutils.py9
34 files changed, 201 insertions, 261 deletions
diff --git a/libs/guessit/__main__.py b/libs/guessit/__main__.py
index fad196d6b..1adf078a7 100644
--- a/libs/guessit/__main__.py
+++ b/libs/guessit/__main__.py
@@ -4,14 +4,12 @@
Entry point module
"""
# pragma: no cover
-from __future__ import print_function
-
import json
import logging
-import os
import sys
-import six
+from collections import OrderedDict
+
from rebulk.__version__ import __version__ as __rebulk_version__
from guessit import api
@@ -20,12 +18,6 @@ from guessit.jsonutils import GuessitEncoder
from guessit.options import argument_parser, parse_options, load_config, merge_options
-try:
- from collections import OrderedDict
-except ImportError: # pragma: no-cover
- from ordereddict import OrderedDict # pylint:disable=import-error
-
-
def guess_filename(filename, options):
"""
Guess a single filename using given options
@@ -48,6 +40,7 @@ def guess_filename(filename, options):
if options.get('json'):
print(json.dumps(guess, cls=GuessitEncoder, ensure_ascii=False))
elif options.get('yaml'):
+ # pylint:disable=import-outside-toplevel
import yaml
from guessit import yamlutils
@@ -78,6 +71,7 @@ def display_properties(options):
else:
print(json.dumps(list(properties.keys()), cls=GuessitEncoder, ensure_ascii=False))
elif options.get('yaml'):
+ # pylint:disable=import-outside-toplevel
import yaml
from guessit import yamlutils
if options.get('values'):
@@ -97,24 +91,10 @@ def display_properties(options):
print(4 * ' ' + '[!] %s' % (property_value,))
-def fix_argv_encoding():
- """
- Fix encoding of sys.argv on windows Python 2
- """
- if six.PY2 and os.name == 'nt': # pragma: no cover
- # see http://bugs.python.org/issue2128
- import locale
-
- for i, j in enumerate(sys.argv):
- sys.argv[i] = j.decode(locale.getpreferredencoding())
-
-
def main(args=None): # pylint:disable=too-many-branches
"""
Main function for entry point
"""
- fix_argv_encoding()
-
if args is None: # pragma: no cover
options = parse_options()
else:
@@ -142,7 +122,7 @@ def main(args=None): # pylint:disable=too-many-branches
if options.get('yaml'):
try:
- import yaml # pylint:disable=unused-variable,unused-import
+ import yaml # pylint:disable=unused-variable,unused-import,import-outside-toplevel
except ImportError: # pragma: no cover
del options['yaml']
print('PyYAML is not installed. \'--yaml\' option will be ignored ...', file=sys.stderr)
@@ -156,10 +136,7 @@ def main(args=None): # pylint:disable=too-many-branches
for filename in options.get('filename'):
filenames.append(filename)
if options.get('input_file'):
- if six.PY2:
- input_file = open(options.get('input_file'), 'r')
- else:
- input_file = open(options.get('input_file'), 'r', encoding='utf-8')
+ input_file = open(options.get('input_file'), 'r', encoding='utf-8')
try:
filenames.extend([line.strip() for line in input_file.readlines()])
finally:
diff --git a/libs/guessit/__version__.py b/libs/guessit/__version__.py
index e505897bb..357f94c75 100644
--- a/libs/guessit/__version__.py
+++ b/libs/guessit/__version__.py
@@ -4,4 +4,4 @@
Version module
"""
# pragma: no cover
-__version__ = '3.1.1'
+__version__ = '3.3.1'
diff --git a/libs/guessit/api.py b/libs/guessit/api.py
index 8e306340b..eeb8def1c 100644
--- a/libs/guessit/api.py
+++ b/libs/guessit/api.py
@@ -4,15 +4,12 @@
API functions that can be used by external software
"""
-try:
- from collections import OrderedDict
-except ImportError: # pragma: no-cover
- from ordereddict import OrderedDict # pylint:disable=import-error
+from collections import OrderedDict
+from pathlib import Path
import os
import traceback
-import six
from rebulk.introspector import introspect
from .__version__ import __version__
@@ -26,18 +23,18 @@ class GuessitException(Exception):
"""
def __init__(self, string, options):
- super(GuessitException, self).__init__("An internal error has occured in guessit.\n"
- "===================== Guessit Exception Report =====================\n"
- "version=%s\n"
- "string=%s\n"
- "options=%s\n"
- "--------------------------------------------------------------------\n"
- "%s"
- "--------------------------------------------------------------------\n"
- "Please report at "
- "https://github.com/guessit-io/guessit/issues.\n"
- "====================================================================" %
- (__version__, str(string), str(options), traceback.format_exc()))
+ super().__init__("An internal error has occured in guessit.\n"
+ "===================== Guessit Exception Report =====================\n"
+ "version=%s\n"
+ "string=%s\n"
+ "options=%s\n"
+ "--------------------------------------------------------------------\n"
+ "%s"
+ "--------------------------------------------------------------------\n"
+ "Please report at "
+ "https://github.com/guessit-io/guessit/issues.\n"
+ "====================================================================" %
+ (__version__, str(string), str(options), traceback.format_exc()))
self.string = string
self.options = options
@@ -113,9 +110,7 @@ class GuessItApi(object):
return [cls._fix_encoding(item) for item in value]
if isinstance(value, dict):
return {cls._fix_encoding(k): cls._fix_encoding(v) for k, v in value.items()}
- if six.PY2 and isinstance(value, six.text_type):
- return value.encode('utf-8')
- if six.PY3 and isinstance(value, six.binary_type):
+ if isinstance(value, bytes):
return value.decode('ascii')
return value
@@ -175,16 +170,12 @@ class GuessItApi(object):
:return:
:rtype:
"""
- try:
- from pathlib import Path
- if isinstance(string, Path):
- try:
- # Handle path-like object
- string = os.fspath(string)
- except AttributeError:
- string = str(string)
- except ImportError:
- pass
+ if isinstance(string, Path):
+ try:
+ # Handle path-like object
+ string = os.fspath(string)
+ except AttributeError:
+ string = str(string)
try:
options = parse_options(options, True)
@@ -194,32 +185,27 @@ class GuessItApi(object):
result_decode = False
result_encode = False
- if six.PY2:
- if isinstance(string, six.text_type):
- string = string.encode("utf-8")
- result_decode = True
- elif isinstance(string, six.binary_type):
- string = six.binary_type(string)
- if six.PY3:
- if isinstance(string, six.binary_type):
- string = string.decode('ascii')
- result_encode = True
- elif isinstance(string, six.text_type):
- string = six.text_type(string)
+ if isinstance(string, bytes):
+ string = string.decode('ascii')
+ result_encode = True
matches = self.rebulk.matches(string, options)
if result_decode:
for match in matches:
- if isinstance(match.value, six.binary_type):
+ if isinstance(match.value, bytes):
match.value = match.value.decode("utf-8")
if result_encode:
for match in matches:
- if isinstance(match.value, six.text_type):
+ if isinstance(match.value, str):
match.value = match.value.encode("ascii")
- return matches.to_dict(options.get('advanced', False), options.get('single_value', False),
- options.get('enforce_list', False))
- except:
- raise GuessitException(string, options)
+ matches_dict = matches.to_dict(options.get('advanced', False), options.get('single_value', False),
+ options.get('enforce_list', False))
+ output_input_string = options.get('output_input_string', False)
+ if output_input_string:
+ matches_dict['input_string'] = matches.input_string
+ return matches_dict
+ except Exception as err:
+ raise GuessitException(string, options) from err
def properties(self, options=None):
"""
@@ -235,8 +221,8 @@ class GuessItApi(object):
options = merge_options(config, options)
unordered = introspect(self.rebulk, options).properties
ordered = OrderedDict()
- for k in sorted(unordered.keys(), key=six.text_type):
- ordered[k] = list(sorted(unordered[k], key=six.text_type))
+ for k in sorted(unordered.keys(), key=str):
+ ordered[k] = list(sorted(unordered[k], key=str))
if hasattr(self.rebulk, 'customize_properties'):
ordered = self.rebulk.customize_properties(ordered)
return ordered
diff --git a/libs/guessit/backports.py b/libs/guessit/backports.py
deleted file mode 100644
index c149a6b5d..000000000
--- a/libs/guessit/backports.py
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-"""
-Backports
-"""
-# pragma: no-cover
-# pylint: skip-file
-
-def cmp_to_key(mycmp):
- """functools.cmp_to_key backport"""
- class KeyClass(object):
- """Key class"""
- def __init__(self, obj, *args): # pylint: disable=unused-argument
- self.obj = obj
- def __lt__(self, other):
- return mycmp(self.obj, other.obj) < 0
- def __gt__(self, other):
- return mycmp(self.obj, other.obj) > 0
- def __eq__(self, other):
- return mycmp(self.obj, other.obj) == 0
- def __le__(self, other):
- return mycmp(self.obj, other.obj) <= 0
- def __ge__(self, other):
- return mycmp(self.obj, other.obj) >= 0
- def __ne__(self, other):
- return mycmp(self.obj, other.obj) != 0
- return KeyClass
diff --git a/libs/guessit/config/options.json b/libs/guessit/config/options.json
index da7c70306..5a343bcb4 100644
--- a/libs/guessit/config/options.json
+++ b/libs/guessit/config/options.json
@@ -416,6 +416,10 @@
"Animal Planet": "ANPL",
"AnimeLab": "ANLB",
"AOL": "AOL",
+ "AppleTV": [
+ "ATVP",
+ "ATV+"
+ ],
"ARD": "ARD",
"BBC iPlayer": [
"iP",
@@ -482,6 +486,7 @@
"HBO",
"re:HBO-?Go"
],
+ "HBO Max": "HMAX",
"HGTV": "HGTV",
"History": [
"HIST",
@@ -490,7 +495,10 @@
"Hulu": "HULU",
"Investigation Discovery": "ID",
"IFC": "IFC",
- "iTunes": "iTunes",
+ "iTunes": [
+ "iTunes",
+ {"pattern": "iT", "ignore_case": false}
+ ],
"ITV": "ITV",
"Knowledge Network": "KNOW",
"Lifetime": "LIFE",
@@ -537,6 +545,7 @@
"SeeSo"
],
"Shomi": "SHMI",
+ "Showtime": "SHO",
"Spike": "SPIK",
"Spike TV": [
"SPKE",
diff --git a/libs/guessit/tlds-alpha-by-domain.txt b/libs/guessit/data/tlds-alpha-by-domain.txt
index 280c794c5..280c794c5 100644
--- a/libs/guessit/tlds-alpha-by-domain.txt
+++ b/libs/guessit/data/tlds-alpha-by-domain.txt
diff --git a/libs/guessit/monkeypatch.py b/libs/guessit/monkeypatch.py
index 33e7c46ee..14ddf6e89 100644
--- a/libs/guessit/monkeypatch.py
+++ b/libs/guessit/monkeypatch.py
@@ -4,10 +4,7 @@
Monkeypatch initialisation functions
"""
-try:
- from collections import OrderedDict
-except ImportError: # pragma: no-cover
- from ordereddict import OrderedDict # pylint:disable=import-error
+from collections import OrderedDict
from rebulk.match import Match
diff --git a/libs/guessit/options.py b/libs/guessit/options.py
index 8fa6825cc..d1a76b037 100644
--- a/libs/guessit/options.py
+++ b/libs/guessit/options.py
@@ -11,8 +11,6 @@ import shlex
from argparse import ArgumentParser
-import six
-
def build_argument_parser():
"""
@@ -68,6 +66,8 @@ def build_argument_parser():
help='Display information for filename guesses as json output')
output_opts.add_argument('-y', '--yaml', dest='yaml', action='store_true', default=None,
help='Display information for filename guesses as yaml output')
+ output_opts.add_argument('-i', '--output-input-string', dest='output_input_string', action='store_true',
+ default=False, help='Add input_string property in the output')
conf_opts = opts.add_argument_group("Configuration")
conf_opts.add_argument('-c', '--config', dest='config', action='append', default=None,
@@ -108,7 +108,7 @@ def parse_options(options=None, api=False):
:return:
:rtype:
"""
- if isinstance(options, six.string_types):
+ if isinstance(options, str):
args = shlex.split(options)
options = vars(argument_parser.parse_args(args))
elif options is None:
@@ -153,7 +153,7 @@ def load_config(options):
cwd = os.getcwd()
yaml_supported = False
try:
- import yaml # pylint:disable=unused-variable,unused-import
+ import yaml # pylint:disable=unused-variable,unused-import,import-outside-toplevel
yaml_supported = True
except ImportError:
pass
@@ -225,7 +225,7 @@ def merge_option_value(option, value, merged):
if value is not None and option != 'pristine':
if option in merged.keys() and isinstance(merged[option], list):
for val in value:
- if val not in merged[option]:
+ if val not in merged[option] and val is not None:
merged[option].append(val)
elif option in merged.keys() and isinstance(merged[option], dict):
merged[option] = merge_options(merged[option], value)
@@ -250,13 +250,13 @@ def load_config_file(filepath):
return json.load(config_file_data)
if filepath.endswith('.yaml') or filepath.endswith('.yml'):
try:
- import yaml
+ import yaml # pylint:disable=import-outside-toplevel
with open(filepath) as config_file_data:
return yaml.load(config_file_data, yaml.SafeLoader)
- except ImportError: # pragma: no cover
+ except ImportError as err: # pragma: no cover
raise ConfigurationException('Configuration file extension is not supported. '
'PyYAML should be installed to support "%s" file' % (
- filepath,))
+ filepath,)) from err
try:
# Try to load input as JSON
diff --git a/libs/guessit/rules/common/__init__.py b/libs/guessit/rules/common/__init__.py
index 444dc72a9..24f9433dd 100644
--- a/libs/guessit/rules/common/__init__.py
+++ b/libs/guessit/rules/common/__init__.py
@@ -3,7 +3,7 @@
"""
Common module
"""
-import re
+from rebulk.remodule import re
seps = r' [](){}+*|=-_~#/\\.,;:' # list of tags/words separators
seps_no_groups = seps.replace('[](){}', '')
diff --git a/libs/guessit/rules/common/comparators.py b/libs/guessit/rules/common/comparators.py
index f46f0c119..277493144 100644
--- a/libs/guessit/rules/common/comparators.py
+++ b/libs/guessit/rules/common/comparators.py
@@ -3,10 +3,8 @@
"""
Comparators
"""
-try:
- from functools import cmp_to_key
-except ImportError:
- from ...backports import cmp_to_key
+
+from functools import cmp_to_key
def marker_comparator_predicate(match):
@@ -14,10 +12,10 @@ def marker_comparator_predicate(match):
Match predicate used in comparator
"""
return (
- not match.private
- and match.name not in ('proper_count', 'title')
- and not (match.name == 'container' and 'extension' in match.tags)
- and not (match.name == 'other' and match.value == 'Rip')
+ not match.private
+ and match.name not in ('proper_count', 'title')
+ and not (match.name == 'container' and 'extension' in match.tags)
+ and not (match.name == 'other' and match.value == 'Rip')
)
diff --git a/libs/guessit/rules/common/expected.py b/libs/guessit/rules/common/expected.py
index eae562a2d..19f2f8874 100644
--- a/libs/guessit/rules/common/expected.py
+++ b/libs/guessit/rules/common/expected.py
@@ -3,7 +3,7 @@
"""
Expected property factory
"""
-import re
+from rebulk.remodule import re
from rebulk import Rebulk
from rebulk.utils import find_all
diff --git a/libs/guessit/rules/common/quantity.py b/libs/guessit/rules/common/quantity.py
index bbd41fbb9..8d3f21d4a 100644
--- a/libs/guessit/rules/common/quantity.py
+++ b/libs/guessit/rules/common/quantity.py
@@ -3,10 +3,9 @@
"""
Quantities: Size
"""
-import re
from abc import abstractmethod
-import six
+from rebulk.remodule import re
from ..common import seps
@@ -50,7 +49,7 @@ class Quantity(object):
return hash(str(self))
def __eq__(self, other):
- if isinstance(other, six.string_types):
+ if isinstance(other, str):
return str(self) == other
if not isinstance(other, self.__class__):
return NotImplemented
diff --git a/libs/guessit/rules/markers/groups.py b/libs/guessit/rules/markers/groups.py
index 4716d15d7..ac66f0443 100644
--- a/libs/guessit/rules/markers/groups.py
+++ b/libs/guessit/rules/markers/groups.py
@@ -5,6 +5,7 @@ Groups markers (...), [...] and {...}
"""
from rebulk import Rebulk
+from ...options import ConfigurationException
def groups(config):
"""
@@ -21,6 +22,9 @@ def groups(config):
starting = config['starting']
ending = config['ending']
+ if len(starting) != len(ending):
+ raise ConfigurationException("Starting and ending groups must have the same length")
+
def mark_groups(input_string):
"""
Functional pattern to mark groups (...), [...] and {...}.
@@ -28,7 +32,7 @@ def groups(config):
:param input_string:
:return:
"""
- openings = ([], [], [])
+ openings = ([], ) * len(starting)
i = 0
ret = []
diff --git a/libs/guessit/rules/processors.py b/libs/guessit/rules/processors.py
index 5b018140c..069e75d2d 100644
--- a/libs/guessit/rules/processors.py
+++ b/libs/guessit/rules/processors.py
@@ -6,8 +6,6 @@ Processors
from collections import defaultdict
import copy
-import six
-
from rebulk import Rebulk, Rule, CustomRule, POST_PROCESS, PRE_PROCESS, AppendMatch, RemoveMatch
from .common import seps_no_groups
@@ -68,7 +66,7 @@ class EquivalentHoles(Rule):
for name in matches.names:
for hole in list(holes):
for current_match in matches.named(name):
- if isinstance(current_match.value, six.string_types) and \
+ if isinstance(current_match.value, str) and \
hole.value.lower() == current_match.value.lower():
if 'equivalent-ignore' in current_match.tags:
continue
@@ -96,7 +94,7 @@ class RemoveAmbiguous(Rule):
consequence = RemoveMatch
def __init__(self, sort_function=marker_sorted, predicate=None):
- super(RemoveAmbiguous, self).__init__()
+ super().__init__()
self.sort_function = sort_function
self.predicate = predicate
@@ -131,7 +129,7 @@ class RemoveLessSpecificSeasonEpisode(RemoveAmbiguous):
keep the one tagged as 'SxxExx' or in the rightmost filepart.
"""
def __init__(self, name):
- super(RemoveLessSpecificSeasonEpisode, self).__init__(
+ super().__init__(
sort_function=(lambda markers, matches:
marker_sorted(list(reversed(markers)), matches,
lambda match: match.name == name and 'SxxExx' in match.tags)),
diff --git a/libs/guessit/rules/properties/audio_codec.py b/libs/guessit/rules/properties/audio_codec.py
index 815caff99..0aa7d31bc 100644
--- a/libs/guessit/rules/properties/audio_codec.py
+++ b/libs/guessit/rules/properties/audio_codec.py
@@ -130,7 +130,7 @@ class AudioProfileRule(Rule):
consequence = RemoveMatch
def __init__(self, codec):
- super(AudioProfileRule, self).__init__()
+ super().__init__()
self.codec = codec
def enabled(self, context):
@@ -166,7 +166,7 @@ class DtsHDRule(AudioProfileRule):
"""
def __init__(self):
- super(DtsHDRule, self).__init__('DTS-HD')
+ super().__init__('DTS-HD')
class DtsRule(AudioProfileRule):
@@ -175,7 +175,7 @@ class DtsRule(AudioProfileRule):
"""
def __init__(self):
- super(DtsRule, self).__init__('DTS')
+ super().__init__('DTS')
class AacRule(AudioProfileRule):
@@ -184,7 +184,7 @@ class AacRule(AudioProfileRule):
"""
def __init__(self):
- super(AacRule, self).__init__('AAC')
+ super().__init__('AAC')
class DolbyDigitalRule(AudioProfileRule):
@@ -193,7 +193,7 @@ class DolbyDigitalRule(AudioProfileRule):
"""
def __init__(self):
- super(DolbyDigitalRule, self).__init__('Dolby Digital')
+ super().__init__('Dolby Digital')
class HqConflictRule(Rule):
diff --git a/libs/guessit/rules/properties/bit_rate.py b/libs/guessit/rules/properties/bit_rate.py
index d279c9f1c..640a6a2e4 100644
--- a/libs/guessit/rules/properties/bit_rate.py
+++ b/libs/guessit/rules/properties/bit_rate.py
@@ -3,7 +3,7 @@
"""
video_bit_rate and audio_bit_rate properties
"""
-import re
+from rebulk.remodule import re
from rebulk import Rebulk
from rebulk.rules import Rule, RemoveMatch, RenameMatch
diff --git a/libs/guessit/rules/properties/episode_title.py b/libs/guessit/rules/properties/episode_title.py
index ece8921d2..2c4fab669 100644
--- a/libs/guessit/rules/properties/episode_title.py
+++ b/libs/guessit/rules/properties/episode_title.py
@@ -47,7 +47,7 @@ class RemoveConflictsWithEpisodeTitle(Rule):
consequence = RemoveMatch
def __init__(self, previous_names):
- super(RemoveConflictsWithEpisodeTitle, self).__init__()
+ super().__init__()
self.previous_names = previous_names
self.next_names = ('streaming_service', 'screen_size', 'source',
'video_codec', 'audio_codec', 'other', 'container')
@@ -129,7 +129,7 @@ class EpisodeTitleFromPosition(TitleBaseRule):
dependency = TitleToEpisodeTitle
def __init__(self, previous_names):
- super(EpisodeTitleFromPosition, self).__init__('episode_title', ['title'])
+ super().__init__('episode_title', ['title'])
self.previous_names = previous_names
def hole_filter(self, hole, matches):
@@ -150,12 +150,12 @@ class EpisodeTitleFromPosition(TitleBaseRule):
def should_remove(self, match, matches, filepart, hole, context):
if match.name == 'episode_details':
return False
- return super(EpisodeTitleFromPosition, self).should_remove(match, matches, filepart, hole, context)
+ return super().should_remove(match, matches, filepart, hole, context)
def when(self, matches, context): # pylint:disable=inconsistent-return-statements
if matches.named('episode_title'):
return
- return super(EpisodeTitleFromPosition, self).when(matches, context)
+ return super().when(matches, context)
class AlternativeTitleReplace(Rule):
@@ -166,7 +166,7 @@ class AlternativeTitleReplace(Rule):
consequence = RenameMatch
def __init__(self, previous_names):
- super(AlternativeTitleReplace, self).__init__()
+ super().__init__()
self.previous_names = previous_names
def when(self, matches, context): # pylint:disable=inconsistent-return-statements
diff --git a/libs/guessit/rules/properties/episodes.py b/libs/guessit/rules/properties/episodes.py
index 345c785de..7aa2245ae 100644
--- a/libs/guessit/rules/properties/episodes.py
+++ b/libs/guessit/rules/properties/episodes.py
@@ -479,7 +479,7 @@ class SeePatternRange(Rule):
consequence = [RemoveMatch, AppendMatch]
def __init__(self, range_separators):
- super(SeePatternRange, self).__init__()
+ super().__init__()
self.range_separators = range_separators
def when(self, matches, context):
@@ -516,7 +516,7 @@ class AbstractSeparatorRange(Rule):
consequence = [RemoveMatch, AppendMatch]
def __init__(self, range_separators, property_name):
- super(AbstractSeparatorRange, self).__init__()
+ super().__init__()
self.range_separators = range_separators
self.property_name = property_name
@@ -608,7 +608,7 @@ class EpisodeNumberSeparatorRange(AbstractSeparatorRange):
"""
def __init__(self, range_separators):
- super(EpisodeNumberSeparatorRange, self).__init__(range_separators, "episode")
+ super().__init__(range_separators, "episode")
class SeasonSeparatorRange(AbstractSeparatorRange):
@@ -617,7 +617,7 @@ class SeasonSeparatorRange(AbstractSeparatorRange):
"""
def __init__(self, range_separators):
- super(SeasonSeparatorRange, self).__init__(range_separators, "season")
+ super().__init__(range_separators, "season")
class RemoveWeakIfMovie(Rule):
@@ -662,7 +662,7 @@ class RemoveWeak(Rule):
consequence = RemoveMatch, AppendMatch
def __init__(self, episode_words):
- super(RemoveWeak, self).__init__()
+ super().__init__()
self.episode_words = episode_words
def when(self, matches, context):
diff --git a/libs/guessit/rules/properties/language.py b/libs/guessit/rules/properties/language.py
index 3f83bc344..c1f9e6a17 100644
--- a/libs/guessit/rules/properties/language.py
+++ b/libs/guessit/rules/properties/language.py
@@ -396,7 +396,7 @@ class SubtitlePrefixLanguageRule(Rule):
def then(self, matches, when_response, context):
to_rename, to_remove = when_response
- super(SubtitlePrefixLanguageRule, self).then(matches, to_remove, context)
+ super().then(matches, to_remove, context)
for prefix, match in to_rename:
# Remove suffix equivalent of prefix.
suffix = copy.copy(prefix)
@@ -435,7 +435,7 @@ class SubtitleSuffixLanguageRule(Rule):
def then(self, matches, when_response, context):
to_rename, to_remove = when_response
- super(SubtitleSuffixLanguageRule, self).then(matches, to_remove, context)
+ super().then(matches, to_remove, context)
for match in to_rename:
matches.remove(match)
match.name = 'subtitle_language'
@@ -488,7 +488,7 @@ class RemoveInvalidLanguages(Rule):
def __init__(self, common_words):
"""Constructor."""
- super(RemoveInvalidLanguages, self).__init__()
+ super().__init__()
self.common_words = common_words
def when(self, matches, context):
diff --git a/libs/guessit/rules/properties/other.py b/libs/guessit/rules/properties/other.py
index c7dc9a88e..bfcbe680f 100644
--- a/libs/guessit/rules/properties/other.py
+++ b/libs/guessit/rules/properties/other.py
@@ -86,7 +86,7 @@ def other(config): # pylint:disable=unused-argument,too-many-statements
rebulk.regex('(HD)(?P<another>Rip)', value={'other': 'HD', 'another': 'Rip'},
private_parent=True, children=True, validator={'__parent__': seps_surround}, validate_all=True)
- for value in ('Screener', 'Remux', 'PAL', 'SECAM', 'NTSC', 'XXX'):
+ for value in ('Screener', 'Remux', 'Hybrid', 'PAL', 'SECAM', 'NTSC', 'XXX'):
rebulk.string(value, value=value)
rebulk.string('3D', value='3D', tags='has-neighbor')
diff --git a/libs/guessit/rules/properties/release_group.py b/libs/guessit/rules/properties/release_group.py
index ecff808b4..09e845f56 100644
--- a/libs/guessit/rules/properties/release_group.py
+++ b/libs/guessit/rules/properties/release_group.py
@@ -98,7 +98,7 @@ class DashSeparatedReleaseGroup(Rule):
def __init__(self, value_formatter):
"""Default constructor."""
- super(DashSeparatedReleaseGroup, self).__init__()
+ super().__init__()
self.value_formatter = value_formatter
@classmethod
@@ -212,7 +212,7 @@ class SceneReleaseGroup(Rule):
def __init__(self, value_formatter):
"""Default constructor."""
- super(SceneReleaseGroup, self).__init__()
+ super().__init__()
self.value_formatter = value_formatter
@staticmethod
@@ -321,7 +321,6 @@ class AnimeReleaseGroup(Rule):
for filepart in marker_sorted(matches.markers.named('path'), matches):
- # pylint:disable=bad-continuation
empty_group = matches.markers.range(filepart.start,
filepart.end,
lambda marker: (marker.name == 'group'
diff --git a/libs/guessit/rules/properties/screen_size.py b/libs/guessit/rules/properties/screen_size.py
index 77d5d0521..966fc3c1d 100644
--- a/libs/guessit/rules/properties/screen_size.py
+++ b/libs/guessit/rules/properties/screen_size.py
@@ -69,7 +69,7 @@ class PostProcessScreenSize(Rule):
consequence = AppendMatch
def __init__(self, standard_heights, min_ar, max_ar):
- super(PostProcessScreenSize, self).__init__()
+ super().__init__()
self.standard_heights = standard_heights
self.min_ar = min_ar
self.max_ar = max_ar
diff --git a/libs/guessit/rules/properties/size.py b/libs/guessit/rules/properties/size.py
index c61580c04..0a0970020 100644
--- a/libs/guessit/rules/properties/size.py
+++ b/libs/guessit/rules/properties/size.py
@@ -3,7 +3,7 @@
"""
size property
"""
-import re
+from rebulk.remodule import re
from rebulk import Rebulk
diff --git a/libs/guessit/rules/properties/streaming_service.py b/libs/guessit/rules/properties/streaming_service.py
index f467f20a6..b27fc4401 100644
--- a/libs/guessit/rules/properties/streaming_service.py
+++ b/libs/guessit/rules/properties/streaming_service.py
@@ -3,7 +3,7 @@
"""
streaming_service property
"""
-import re
+from rebulk.remodule import re
from rebulk import Rebulk
from rebulk.rules import Rule, RemoveMatch
@@ -25,13 +25,22 @@ def streaming_service(config): # pylint: disable=too-many-statements,unused-arg
rebulk = rebulk.string_defaults(ignore_case=True).regex_defaults(flags=re.IGNORECASE, abbreviations=[dash])
rebulk.defaults(name='streaming_service', tags=['source-prefix'])
+ regex_prefix = 're:'
+
for value, items in config.items():
patterns = items if isinstance(items, list) else [items]
for pattern in patterns:
- if pattern.startswith('re:'):
- rebulk.regex(pattern, value=value)
+ if isinstance(pattern, dict):
+ pattern_value = pattern.pop('pattern')
+ kwargs = pattern
+ pattern = pattern_value
+ else:
+ kwargs = {}
+ regex = kwargs.pop('regex', False)
+ if regex or pattern.startswith(regex_prefix):
+ rebulk.regex(pattern[len(regex_prefix):], value=value, **kwargs)
else:
- rebulk.string(pattern, value=value)
+ rebulk.string(pattern, value=value, **kwargs)
rebulk.rules(ValidateStreamingService)
diff --git a/libs/guessit/rules/properties/title.py b/libs/guessit/rules/properties/title.py
index 0d2630167..2a065cb04 100644
--- a/libs/guessit/rules/properties/title.py
+++ b/libs/guessit/rules/properties/title.py
@@ -53,7 +53,7 @@ class TitleBaseRule(Rule):
consequence = [AppendMatch, RemoveMatch]
def __init__(self, match_name, match_tags=None, alternative_match_name=None):
- super(TitleBaseRule, self).__init__()
+ super().__init__()
self.match_name = match_name
self.match_tags = match_tags
self.alternative_match_name = alternative_match_name
@@ -299,7 +299,7 @@ class TitleFromPosition(TitleBaseRule):
properties = {'title': [None], 'alternative_title': [None]}
def __init__(self):
- super(TitleFromPosition, self).__init__('title', ['title'], 'alternative_title')
+ super().__init__('title', ['title'], 'alternative_title')
def enabled(self, context):
return not is_disabled(context, 'alternative_title')
diff --git a/libs/guessit/rules/properties/website.py b/libs/guessit/rules/properties/website.py
index c19653117..96bed6400 100644
--- a/libs/guessit/rules/properties/website.py
+++ b/libs/guessit/rules/properties/website.py
@@ -27,7 +27,7 @@ def website(config):
rebulk = rebulk.regex_defaults(flags=re.IGNORECASE).string_defaults(ignore_case=True)
rebulk.defaults(name="website")
- with resource_stream('guessit', 'tlds-alpha-by-domain.txt') as tld_file:
+ with resource_stream('guessit', 'data/tlds-alpha-by-domain.txt') as tld_file:
tlds = [
tld.strip().decode('utf-8')
for tld in tld_file.readlines()
diff --git a/libs/guessit/test/movies.yml b/libs/guessit/test/movies.yml
index a534ca0f2..6b503d13a 100644
--- a/libs/guessit/test/movies.yml
+++ b/libs/guessit/test/movies.yml
@@ -1752,6 +1752,7 @@
year: 2018
other:
- 3D
+ - Hybrid
- Proper
- Remux
proper_count: 1
diff --git a/libs/guessit/test/rules/other.yml b/libs/guessit/test/rules/other.yml
index 447f1787d..0ae0c990f 100644
--- a/libs/guessit/test/rules/other.yml
+++ b/libs/guessit/test/rules/other.yml
@@ -80,6 +80,9 @@
? Remux
: other: Remux
+? Hybrid
+: other: Hybrid
+
? 3D.2019
: other: 3D
diff --git a/libs/guessit/test/streaming_services.yaml b/libs/guessit/test/streaming_services.yaml
index adf52e715..227d72d75 100644
--- a/libs/guessit/test/streaming_services.yaml
+++ b/libs/guessit/test/streaming_services.yaml
@@ -577,13 +577,13 @@
release_group: BTW
type: episode
-# Streaming service: RTÉ One
+# Streaming service: RTE One
? Show.Name.S10E01.576p.RTE.WEBRip.AAC2.0.H.264-RTN
: title: Show Name
season: 10
episode: 1
screen_size: 576p
- streaming_service: RTÉ One
+ streaming_service: RTE One
source: Web
other: Rip
audio_codec: AAC
@@ -818,7 +818,6 @@
episode: 0
episode_details: Pilot
episode_title: Pilot
- language: zh
other:
- Proper
- Rip
@@ -862,7 +861,6 @@
? What.The.Fuck.France.S01E01.Le.doublage.CNLP.WEBRip.AAC2.0.x264-TURTLE
: audio_channels: '2.0'
audio_codec: AAC
- country: FR
episode: 1
episode_title: Le doublage
other: Rip
@@ -870,7 +868,7 @@
season: 1
source: Web
streaming_service: Canal+
- title: What The Fuck
+ title: What The Fuck France
type: episode
video_codec: H.264
@@ -943,14 +941,13 @@
? The.Amazing.Race.Canada.S03.720p.CTV.WEBRip.AAC2.0.H.264-BTW
: audio_channels: '2.0'
audio_codec: AAC
- country: CA
other: Rip
release_group: BTW
screen_size: 720p
season: 3
source: Web
streaming_service: CTV
- title: The Amazing Race
+ title: The Amazing Race Canada
type: episode
video_codec: H.264
@@ -1240,13 +1237,12 @@
? Big.Brother.Canada.S05.GLBL.WEBRip.AAC2.0.H.264-RTN
: audio_channels: '2.0'
audio_codec: AAC
- country: CA
other: Rip
release_group: RTN
season: 5
source: Web
streaming_service: Global
- title: Big Brother
+ title: Big Brother Canada
type: episode
video_codec: H.264
@@ -1330,7 +1326,6 @@
? Handmade.in.Japan.S01E01.720p.iP.WEBRip.AAC2.0.H.264-SUP
: audio_channels: '2.0'
audio_codec: AAC
- country: JP
episode: 1
other: Rip
release_group: SUP
@@ -1338,7 +1333,7 @@
season: 1
source: Web
streaming_service: BBC iPlayer
- title: Handmade in
+ title: Handmade in Japan
type: episode
video_codec: H.264
@@ -1463,9 +1458,8 @@
? Bunsen.is.a.Beast.S01E23.Guinea.Some.Lovin.1080p.NICK.WEBRip.AAC2.0.x264-TVSmash
: audio_channels: '2.0'
audio_codec: AAC
- country: GN
episode: 23
- episode_title: Some Lovin
+ episode_title: Guinea Some Lovin
other: Rip
release_group: TVSmash
screen_size: 1080p
@@ -1538,13 +1532,14 @@
episode_title: The Masquerade
other: Rip
part: 2
- release_group: VP9-BTW
+ release_group: BTW
screen_size: 1080p
season: 2
source: Web
streaming_service: YouTube Red
title: Escape The Night
type: episode
+ video_codec: VP9
? Escape.The.Night.S02E02.The.Masquerade.Part.II.2160p.RED.WEBRip.AAC5.1.VP9-BTW
: audio_channels: '5.1'
@@ -1553,13 +1548,14 @@
episode_title: The Masquerade
other: Rip
part: 2
- release_group: VP9-BTW
+ release_group: BTW
screen_size: 2160p
season: 2
source: Web
streaming_service: YouTube Red
title: Escape The Night
type: episode
+ video_codec: VP9
? Escape.The.Night.S02E02.The.Masquerade.Part.II.720p.RED.WEBRip.AAC5.1.VP9-BTW
: audio_channels: '5.1'
@@ -1568,13 +1564,14 @@
episode_title: The Masquerade
other: Rip
part: 2
- release_group: VP9-BTW
+ release_group: BTW
screen_size: 720p
season: 2
source: Web
streaming_service: YouTube Red
title: Escape The Night
type: episode
+ video_codec: VP9
? The.Family.Law.S02E01.720p.SBS.WEB-DL.AAC2.0.H.264-BTN
: audio_channels: '2.0'
@@ -1892,7 +1889,7 @@
season: 1
source: Web
streaming_service: Vimeo
- title: '555'
+ # title: '555'
type: episode
video_codec: H.264
diff --git a/libs/guessit/test/test_api.py b/libs/guessit/test/test_api.py
index 391dbced8..542292580 100644
--- a/libs/guessit/test/test_api.py
+++ b/libs/guessit/test/test_api.py
@@ -3,10 +3,9 @@
# pylint: disable=no-self-use, pointless-statement, missing-docstring, invalid-name, pointless-string-statement
import json
import os
-import sys
+from pathlib import Path
import pytest
-import six
from ..api import guessit, properties, suggested_expected, GuessitException
@@ -19,25 +18,19 @@ def test_default():
def test_forced_unicode():
- ret = guessit(u'Fear.and.Loathing.in.Las.Vegas.FRENCH.ENGLISH.720p.HDDVD.DTS.x264-ESiR.mkv')
- assert ret and 'title' in ret and isinstance(ret['title'], six.text_type)
+ ret = guessit('Fear.and.Loathing.in.Las.Vegas.FRENCH.ENGLISH.720p.HDDVD.DTS.x264-ESiR.mkv')
+ assert ret and 'title' in ret and isinstance(ret['title'], str)
def test_forced_binary():
ret = guessit(b'Fear.and.Loathing.in.Las.Vegas.FRENCH.ENGLISH.720p.HDDVD.DTS.x264-ESiR.mkv')
- assert ret and 'title' in ret and isinstance(ret['title'], six.binary_type)
+ assert ret and 'title' in ret and isinstance(ret['title'], bytes)
[email protected](sys.version_info < (3, 4), reason="Path is not available")
def test_pathlike_object():
- try:
- from pathlib import Path
-
- path = Path('Fear.and.Loathing.in.Las.Vegas.FRENCH.ENGLISH.720p.HDDVD.DTS.x264-ESiR.mkv')
- ret = guessit(path)
- assert ret and 'title' in ret
- except ImportError: # pragma: no-cover
- pass
+ path = Path('Fear.and.Loathing.in.Las.Vegas.FRENCH.ENGLISH.720p.HDDVD.DTS.x264-ESiR.mkv')
+ ret = guessit(path)
+ assert ret and 'title' in ret
def test_unicode_japanese():
@@ -51,16 +44,8 @@ def test_unicode_japanese_options():
def test_forced_unicode_japanese_options():
- ret = guessit(u"[阿维达].Avida.2006.FRENCH.DVDRiP.XViD-PROD.avi", options={"expected_title": [u"阿维达"]})
- assert ret and 'title' in ret and ret['title'] == u"阿维达"
-
-# TODO: This doesn't compile on python 3, but should be tested on python 2.
-"""
-if six.PY2:
- def test_forced_binary_japanese_options():
- ret = guessit(b"[阿维达].Avida.2006.FRENCH.DVDRiP.XViD-PROD.avi", options={"expected_title": [b"阿维达"]})
- assert ret and 'title' in ret and ret['title'] == b"阿维达"
-"""
+ ret = guessit("[阿维达].Avida.2006.FRENCH.DVDRiP.XViD-PROD.avi", options={"expected_title": ["阿维达"]})
+ assert ret and 'title' in ret and ret['title'] == "阿维达"
def test_properties():
diff --git a/libs/guessit/test/test_api_unicode_literals.py b/libs/guessit/test/test_api_unicode_literals.py
index 826f7cd16..79bbbca15 100644
--- a/libs/guessit/test/test_api_unicode_literals.py
+++ b/libs/guessit/test/test_api_unicode_literals.py
@@ -3,12 +3,9 @@
# pylint: disable=no-self-use, pointless-statement, missing-docstring, invalid-name, pointless-string-statement
-from __future__ import unicode_literals
-
import os
import pytest
-import six
from ..api import guessit, properties, GuessitException
@@ -21,13 +18,13 @@ def test_default():
def test_forced_unicode():
- ret = guessit(u'Fear.and.Loathing.in.Las.Vegas.FRENCH.ENGLISH.720p.HDDVD.DTS.x264-ESiR.mkv')
- assert ret and 'title' in ret and isinstance(ret['title'], six.text_type)
+ ret = guessit('Fear.and.Loathing.in.Las.Vegas.FRENCH.ENGLISH.720p.HDDVD.DTS.x264-ESiR.mkv')
+ assert ret and 'title' in ret and isinstance(ret['title'], str)
def test_forced_binary():
ret = guessit(b'Fear.and.Loathing.in.Las.Vegas.FRENCH.ENGLISH.720p.HDDVD.DTS.x264-ESiR.mkv')
- assert ret and 'title' in ret and isinstance(ret['title'], six.binary_type)
+ assert ret and 'title' in ret and isinstance(ret['title'], bytes)
def test_unicode_japanese():
@@ -41,24 +38,18 @@ def test_unicode_japanese_options():
def test_forced_unicode_japanese_options():
- ret = guessit(u"[阿维达].Avida.2006.FRENCH.DVDRiP.XViD-PROD.avi", options={"expected_title": [u"阿维达"]})
- assert ret and 'title' in ret and ret['title'] == u"阿维达"
-
-# TODO: This doesn't compile on python 3, but should be tested on python 2.
-"""
-if six.PY2:
- def test_forced_binary_japanese_options():
- ret = guessit(b"[阿维达].Avida.2006.FRENCH.DVDRiP.XViD-PROD.avi", options={"expected_title": [b"阿维达"]})
- assert ret and 'title' in ret and ret['title'] == b"阿维达"
-"""
+ ret = guessit("[阿维达].Avida.2006.FRENCH.DVDRiP.XViD-PROD.avi", options={"expected_title": ["阿维达"]})
+ assert ret and 'title' in ret and ret['title'] == "阿维达"
-def test_ensure_standard_string_class():
+def test_ensure_custom_string_class():
class CustomStr(str):
pass
- ret = guessit(CustomStr('1080p'), options={'advanced': True})
- assert ret and 'screen_size' in ret and not isinstance(ret['screen_size'].input_string, CustomStr)
+ ret = guessit(CustomStr('some.title.1080p.mkv'), options={'advanced': True})
+ assert ret and 'screen_size' in ret and isinstance(ret['screen_size'].input_string, CustomStr)
+ assert ret and 'title' in ret and isinstance(ret['title'].input_string, CustomStr)
+ assert ret and 'container' in ret and isinstance(ret['container'].input_string, CustomStr)
def test_properties():
diff --git a/libs/guessit/test/test_main.py b/libs/guessit/test/test_main.py
index cbdba7aa4..30de4ccae 100644
--- a/libs/guessit/test/test_main.py
+++ b/libs/guessit/test/test_main.py
@@ -1,16 +1,25 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# pylint: disable=no-self-use, pointless-statement, missing-docstring, invalid-name
-
+import json
import os
+import sys
import pytest
+from _pytest.capture import CaptureFixture
from ..__main__ import main
__location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
+# Prevent output from spamming the console
[email protected](scope="function", autouse=True)
+def no_stdout(monkeypatch):
+ with open(os.devnull, "w") as f:
+ monkeypatch.setattr(sys, "stdout", f)
+ yield
+
def test_main_no_args():
main([])
@@ -24,7 +33,7 @@ def test_main_unicode():
def test_main_forced_unicode():
- main([u'Fear.and.Loathing.in.Las.Vegas.FRENCH.ENGLISH.720p.HDDVD.DTS.x264-ESiR.mkv'])
+ main(['Fear.and.Loathing.in.Las.Vegas.FRENCH.ENGLISH.720p.HDDVD.DTS.x264-ESiR.mkv'])
def test_main_verbose():
@@ -70,3 +79,22 @@ def test_main_help():
def test_main_version():
main(['--version'])
+
+
+def test_json_output_input_string(capsys: CaptureFixture):
+ main(['--json', '--output-input-string', 'test.avi'])
+
+ outerr = capsys.readouterr()
+ data = json.loads(outerr.out)
+
+ assert 'input_string' in data
+ assert data['input_string'] == 'test.avi'
+
+
+def test_json_no_output_input_string(capsys: CaptureFixture):
+ main(['--json', 'test.avi'])
+
+ outerr = capsys.readouterr()
+ data = json.loads(outerr.out)
+
+ assert 'input_string' not in data
diff --git a/libs/guessit/test/test_yml.py b/libs/guessit/test/test_yml.py
index 040796dea..d7cb4b5e0 100644
--- a/libs/guessit/test/test_yml.py
+++ b/libs/guessit/test/test_yml.py
@@ -7,7 +7,6 @@ import os
from io import open # pylint: disable=redefined-builtin
import babelfish
-import six # pylint:disable=wrong-import-order
import yaml # pylint:disable=wrong-import-order
from rebulk.remodule import re
from rebulk.utils import is_iterable
@@ -53,16 +52,16 @@ class EntryResult(object):
if self.ok:
return self.string + ': OK!'
if self.warning:
- return '%s%s: WARNING! (valid=%i, extra=%i)' % ('-' if self.negates else '', self.string, len(self.valid),
- len(self.extra))
+ return '%s%s: WARNING! (valid=%i, extra=%s)' % ('-' if self.negates else '', self.string, len(self.valid),
+ self.extra)
if self.error:
- return '%s%s: ERROR! (valid=%i, missing=%i, different=%i, extra=%i, others=%i)' % \
- ('-' if self.negates else '', self.string, len(self.valid), len(self.missing), len(self.different),
- len(self.extra), len(self.others))
+ return '%s%s: ERROR! (valid=%i, extra=%s, missing=%s, different=%s, others=%s)' % \
+ ('-' if self.negates else '', self.string, len(self.valid), self.extra, self.missing,
+ self.different, self.others)
- return '%s%s: UNKOWN! (valid=%i, missing=%i, different=%i, extra=%i, others=%i)' % \
- ('-' if self.negates else '', self.string, len(self.valid), len(self.missing), len(self.different),
- len(self.extra), len(self.others))
+ return '%s%s: UNKOWN! (valid=%i, extra=%s, missing=%s, different=%s, others=%s)' % \
+ ('-' if self.negates else '', self.string, len(self.valid), self.extra, self.missing, self.different,
+ self.others)
@property
def details(self):
@@ -110,7 +109,7 @@ def files_and_ids(predicate=None):
for filename in filenames:
name, ext = os.path.splitext(filename)
filepath = os.path.join(dirpath_rel, filename)
- if ext == '.yml' and (not predicate or predicate(filepath)):
+ if ext in ['.yml', '.yaml'] and (not predicate or predicate(filepath)):
files.append(filepath)
ids.append(os.path.join(dirpath_rel, name))
@@ -161,7 +160,7 @@ class TestYml(object):
for string, expected in data.items():
TestYml.set_default(expected, default)
- string = TestYml.fix_encoding(string, expected)
+ string = TestYml.fix_encoding(string)
entries.append((filename, string, expected))
unique_id = self._get_unique_id(entry_set, '[' + filename + '] ' + str(string))
@@ -178,17 +177,7 @@ class TestYml(object):
expected[k] = v
@classmethod
- def fix_encoding(cls, string, expected):
- if six.PY2:
- if isinstance(string, six.text_type):
- string = string.encode('utf-8')
- converts = []
- for k, v in expected.items():
- if isinstance(v, six.text_type):
- v = v.encode('utf-8')
- converts.append((k, v))
- for k, v in converts:
- expected[k] = v
+ def fix_encoding(cls, string):
if not isinstance(string, str):
string = str(string)
return string
diff --git a/libs/guessit/yamlutils.py b/libs/guessit/yamlutils.py
index d04be641b..f038a99bc 100644
--- a/libs/guessit/yamlutils.py
+++ b/libs/guessit/yamlutils.py
@@ -4,10 +4,7 @@
Options
"""
-try:
- from collections import OrderedDict
-except ImportError: # pragma: no-cover
- from ordereddict import OrderedDict # pylint:disable=import-error
+from collections import OrderedDict
import babelfish
import yaml # pylint:disable=wrong-import-order
@@ -24,8 +21,8 @@ class OrderedDictYAMLLoader(yaml.SafeLoader):
def __init__(self, *args, **kwargs):
yaml.SafeLoader.__init__(self, *args, **kwargs)
- self.add_constructor(u'tag:yaml.org,2002:map', type(self).construct_yaml_map)
- self.add_constructor(u'tag:yaml.org,2002:omap', type(self).construct_yaml_map)
+ self.add_constructor('tag:yaml.org,2002:map', type(self).construct_yaml_map)
+ self.add_constructor('tag:yaml.org,2002:omap', type(self).construct_yaml_map)
def construct_yaml_map(self, node):
data = OrderedDict()