From 35544e2fc6eed0ce4a27ec7285aac71ff0ddc473 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Sat, 29 Feb 2020 15:45:08 +0100 Subject: [PATCH] Remove Python 2 compatibility (#1348) * Remove Python 2 compatibility * remove 2/3 shims in pygments.util * update setup.py metadata * Remove unneeded object inheritance. * Remove unneeded future imports. --- .github/workflows/build.yaml | 2 +- CHANGES | 3 ++ pygments/__init__.py | 3 +- pygments/cmdline.py | 29 +++-------- pygments/filter.py | 2 +- pygments/filters/__init__.py | 9 ++-- pygments/formatter.py | 6 +-- pygments/formatters/__init__.py | 8 +-- pygments/formatters/_mapping.py | 2 - pygments/formatters/html.py | 12 ++--- pygments/formatters/img.py | 6 +-- pygments/formatters/latex.py | 9 ++-- pygments/formatters/terminal.py | 6 --- pygments/formatters/terminal256.py | 6 --- pygments/lexer.py | 26 +++++----- pygments/lexers/__init__.py | 18 +++---- pygments/lexers/_cocoa_builtins.py | 2 - pygments/lexers/_lua_builtins.py | 4 +- pygments/lexers/_mapping.py | 2 - pygments/lexers/_php_builtins.py | 2 - pygments/lexers/_scilab_builtins.py | 2 +- pygments/lexers/_sourcemod_builtins.py | 2 - pygments/lexers/css.py | 5 +- pygments/lexers/dotnet.py | 6 +-- pygments/lexers/javascript.py | 6 +-- pygments/lexers/php.py | 5 +- pygments/lexers/robotframework.py | 15 +++--- pygments/lexers/scripting.py | 4 +- pygments/lexers/special.py | 5 +- pygments/lexers/sql.py | 9 ++-- pygments/scanner.py | 2 +- pygments/sphinxext.py | 2 - pygments/style.py | 4 +- pygments/unistring.py | 4 -- pygments/util.py | 67 ++++++-------------------- scripts/check_sources.py | 2 - scripts/debug_lexer.py | 2 - scripts/detect_missing_analyse_text.py | 1 - scripts/get_vimkw.py | 2 - scripts/vim2pygments.py | 4 +- setup.py | 4 +- tests/test_basic_api.py | 17 +++---- tests/test_cmdline.py | 21 +++----- tests/test_crystal.py | 2 - tests/test_examplefiles.py | 2 - tests/test_html_formatter.py | 4 +- tests/test_irc_formatter.py | 3 +- tests/test_latex_formatter.py | 2 - tests/test_modeline.py | 2 - tests/test_rtf_formatter.py | 3 +- tests/test_terminal_formatter.py | 4 +- tests/test_unistring.py | 3 +- tests/test_util.py | 15 +----- 53 files changed, 128 insertions(+), 260 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index a4c90115ca..f95482c770 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -9,7 +9,7 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: [2.7, 3.5, 3.6, 3.7, 3.8, pypy2, pypy3] + python-version: [3.5, 3.6, 3.7, 3.8, pypy3] steps: - uses: actions/checkout@v1 diff --git a/CHANGES b/CHANGES index 4128c2c8d8..c463d212b9 100644 --- a/CHANGES +++ b/CHANGES @@ -11,6 +11,9 @@ Version 2.6 ----------- (not released yet) +- Running Pygments on Python 2.x is no longer supported. + (The Python 2 lexer still exists.) + - Added lexers: * Linux kernel logs (PR#1310) diff --git a/pygments/__init__.py b/pygments/__init__.py index 89efc350ee..e253503e90 100644 --- a/pygments/__init__.py +++ b/pygments/__init__.py @@ -26,8 +26,7 @@ :license: BSD, see LICENSE for details. """ import sys - -from pygments.util import StringIO, BytesIO +from io import StringIO, BytesIO __version__ = '2.5.2' __docformat__ = 'restructuredtext' diff --git a/pygments/cmdline.py b/pygments/cmdline.py index 34752d66b2..d5af5f5430 100644 --- a/pygments/cmdline.py +++ b/pygments/cmdline.py @@ -9,8 +9,6 @@ :license: BSD, see LICENSE for details. """ -from __future__ import print_function - import os import sys import getopt @@ -18,7 +16,8 @@ from pygments import __version__, highlight from pygments.util import ClassNotFound, OptionError, docstring_headline, \ - guess_decode, guess_decode_from_terminal, terminal_encoding + guess_decode, guess_decode_from_terminal, terminal_encoding, \ + UnclosingTextIOWrapper from pygments.lexers import get_all_lexers, get_lexer_by_name, guess_lexer, \ load_lexer_from_file, get_lexer_for_filename, find_lexer_class_for_filename from pygments.lexers.special import TextLexer @@ -397,11 +396,7 @@ def main_inner(popts, args, usage): elif '-s' not in opts: # treat stdin as full file (-s support is later) # read code from terminal, always in binary mode since we want to # decode ourselves and be tolerant with it - if sys.version_info > (3,): - # Python 3: we have to use .buffer to get a binary stream - code = sys.stdin.buffer.read() - else: - code = sys.stdin.read() + code = sys.stdin.buffer.read() # use .buffer to get a binary stream if not inencoding: code, inencoding = guess_decode_from_terminal(code, sys.stdin) # else the lexer will do the decoding @@ -466,11 +461,7 @@ def main_inner(popts, args, usage): fmter = Terminal256Formatter(**parsed_opts) else: fmter = TerminalFormatter(**parsed_opts) - if sys.version_info > (3,): - # Python 3: we have to use .buffer to get a binary stream - outfile = sys.stdout.buffer - else: - outfile = sys.stdout + outfile = sys.stdout.buffer # determine output encoding if not explicitly selected if not outencoding: @@ -485,10 +476,8 @@ def main_inner(popts, args, usage): if not outfn and sys.platform in ('win32', 'cygwin') and \ fmter.name in ('Terminal', 'Terminal256'): # pragma: no cover # unfortunately colorama doesn't support binary streams on Py3 - if sys.version_info > (3,): - from pygments.util import UnclosingTextIOWrapper - outfile = UnclosingTextIOWrapper(outfile, encoding=fmter.encoding) - fmter.encoding = None + outfile = UnclosingTextIOWrapper(outfile, encoding=fmter.encoding) + fmter.encoding = None try: import colorama.initialise except ImportError: @@ -515,11 +504,7 @@ def main_inner(popts, args, usage): # line by line processing of stdin (eg: for 'tail -f')... try: while 1: - if sys.version_info > (3,): - # Python 3: we have to use .buffer to get a binary stream - line = sys.stdin.buffer.readline() - else: - line = sys.stdin.readline() + line = sys.stdin.buffer.readline() if not line: break if not inencoding: diff --git a/pygments/filter.py b/pygments/filter.py index 7f81920bc9..faa18bfc18 100644 --- a/pygments/filter.py +++ b/pygments/filter.py @@ -40,7 +40,7 @@ def lowercase(self, lexer, stream, options): }) -class Filter(object): +class Filter: """ Default filter. Subclass this class or use the `simplefilter` decorator to create own filters. diff --git a/pygments/filters/__init__.py b/pygments/filters/__init__.py index 3fe6caa7d2..3fd2fee052 100644 --- a/pygments/filters/__init__.py +++ b/pygments/filters/__init__.py @@ -16,7 +16,7 @@ string_to_tokentype from pygments.filter import Filter from pygments.util import get_list_opt, get_int_opt, get_bool_opt, \ - get_choice_opt, ClassNotFound, OptionError, text_type, string_types + get_choice_opt, ClassNotFound, OptionError from pygments.plugin import find_plugin_filters @@ -113,7 +113,7 @@ def __init__(self, **options): Filter.__init__(self, **options) case = get_choice_opt(options, 'case', ['lower', 'upper', 'capitalize'], 'lower') - self.convert = getattr(text_type, case) + self.convert = getattr(str, case) def filter(self, lexer, stream): for ttype, value in stream: @@ -233,7 +233,7 @@ def __init__(self, **options): ('tabs', u'»'), ('newlines', u'¶')]: opt = options.get(name, False) - if isinstance(opt, string_types) and len(opt) == 1: + if isinstance(opt, str) and len(opt) == 1: setattr(self, name, opt) else: setattr(self, name, (opt and default or '')) @@ -250,6 +250,7 @@ def filter(self, lexer, stream): tabs = self.tabs or u'\t' newlines = self.newlines or u'\n' regex = re.compile(r'\s') + def replacefunc(wschar): if wschar == ' ': return spaces @@ -302,7 +303,7 @@ def gobble(self, value, left): def filter(self, lexer, stream): n = self.n - left = n # How many characters left to gobble. + left = n # How many characters left to gobble. for ttype, value in stream: # Remove ``left`` tokens from first line, ``n`` from all others. parts = value.split('\n') diff --git a/pygments/formatter.py b/pygments/formatter.py index f09f6e3cb8..60531523c7 100644 --- a/pygments/formatter.py +++ b/pygments/formatter.py @@ -11,19 +11,19 @@ import codecs -from pygments.util import get_bool_opt, string_types +from pygments.util import get_bool_opt from pygments.styles import get_style_by_name __all__ = ['Formatter'] def _lookup_style(style): - if isinstance(style, string_types): + if isinstance(style, str): return get_style_by_name(style) return style -class Formatter(object): +class Formatter: """ Converts a token stream to text. diff --git a/pygments/formatters/__init__.py b/pygments/formatters/__init__.py index 6f1130a801..9ff30643b4 100644 --- a/pygments/formatters/__init__.py +++ b/pygments/formatters/__init__.py @@ -17,7 +17,7 @@ from pygments.formatters._mapping import FORMATTERS from pygments.plugin import find_plugin_formatters -from pygments.util import ClassNotFound, itervalues +from pygments.util import ClassNotFound __all__ = ['get_formatter_by_name', 'get_formatter_for_filename', 'get_all_formatters', 'load_formatter_from_file'] + list(FORMATTERS) @@ -45,7 +45,7 @@ def _load_formatters(module_name): def get_all_formatters(): """Return a generator for all formatter classes.""" # NB: this returns formatter classes, not info like get_all_lexers(). - for info in itervalues(FORMATTERS): + for info in FORMATTERS.values(): if info[1] not in _formatter_cache: _load_formatters(info[0]) yield _formatter_cache[info[1]] @@ -58,7 +58,7 @@ def find_formatter_class(alias): Returns None if not found. """ - for module_name, name, aliases, _, _ in itervalues(FORMATTERS): + for module_name, name, aliases, _, _ in FORMATTERS.values(): if alias in aliases: if name not in _formatter_cache: _load_formatters(module_name) @@ -121,7 +121,7 @@ def get_formatter_for_filename(fn, **options): Raises ClassNotFound if not found. """ fn = basename(fn) - for modname, name, _, filenames, _ in itervalues(FORMATTERS): + for modname, name, _, filenames, _ in FORMATTERS.values(): for filename in filenames: if _fn_matches(fn, filename): if name not in _formatter_cache: diff --git a/pygments/formatters/_mapping.py b/pygments/formatters/_mapping.py index 5086e51970..487036941a 100755 --- a/pygments/formatters/_mapping.py +++ b/pygments/formatters/_mapping.py @@ -13,8 +13,6 @@ :license: BSD, see LICENSE for details. """ -from __future__ import print_function - FORMATTERS = { 'BBCodeFormatter': ('pygments.formatters.bbcode', 'BBCode', ('bbcode', 'bb'), (), 'Format tokens with BBcodes. These formatting codes are used by many bulletin boards, so you can highlight your sourcecode with pygments before posting it there.'), 'BmpImageFormatter': ('pygments.formatters.img', 'img_bmp', ('bmp', 'bitmap'), ('*.bmp',), 'Create a bitmap image from source code. This uses the Python Imaging Library to generate a pixmap from the source code.'), diff --git a/pygments/formatters/html.py b/pygments/formatters/html.py index be9d85342c..c5ae774df5 100644 --- a/pygments/formatters/html.py +++ b/pygments/formatters/html.py @@ -9,16 +9,14 @@ :license: BSD, see LICENSE for details. """ -from __future__ import print_function - import os import sys import os.path +from io import StringIO from pygments.formatter import Formatter from pygments.token import Token, Text, STANDARD_TYPES -from pygments.util import get_bool_opt, get_int_opt, get_list_opt, \ - StringIO, string_types, iteritems +from pygments.util import get_bool_opt, get_int_opt, get_list_opt try: import ctags @@ -41,12 +39,14 @@ def escape_html(text, table=_escape_html_table): """Escape &, <, > as well as single and double quotes for HTML.""" return text.translate(table) + def webify(color): if color.startswith('calc') or color.startswith('var'): return color else: return '#' + color + def _get_ttype_class(ttype): fname = STANDARD_TYPES.get(ttype) if fname: @@ -497,7 +497,7 @@ def get_style_defs(self, arg=None): """ if arg is None: arg = ('cssclass' in self.options and '.'+self.cssclass or '') - if isinstance(arg, string_types): + if isinstance(arg, str): args = [arg] else: args = list(arg) @@ -511,7 +511,7 @@ def prefix(cls): return ', '.join(tmp) styles = [(level, ttype, cls, style) - for cls, (style, ttype, level) in iteritems(self.class2style) + for cls, (style, ttype, level) in self.class2style.items() if cls and style] styles.sort() lines = ['%s { %s } /* %s */' % (prefix(cls), style, repr(ttype)[6:]) diff --git a/pygments/formatters/img.py b/pygments/formatters/img.py index 6bb3364458..57a37a7bd2 100644 --- a/pygments/formatters/img.py +++ b/pygments/formatters/img.py @@ -14,7 +14,7 @@ from pygments.formatter import Formatter from pygments.util import get_bool_opt, get_int_opt, get_list_opt, \ - get_choice_opt, xrange + get_choice_opt import subprocess @@ -59,7 +59,7 @@ class FontNotFound(Exception): """When there are no usable fonts specified""" -class FontManager(object): +class FontManager: """ Manages a set of fonts: normal, italic, bold, etc... """ @@ -504,7 +504,7 @@ def _draw_line_numbers(self): """ if not self.line_numbers: return - for p in xrange(self.maxlineno): + for p in range(self.maxlineno): n = p + self.line_number_start if (n % self.line_number_step) == 0: self._draw_linenumber(p, n) diff --git a/pygments/formatters/latex.py b/pygments/formatters/latex.py index 7f6aa9e307..d5f80ef833 100644 --- a/pygments/formatters/latex.py +++ b/pygments/formatters/latex.py @@ -9,13 +9,12 @@ :license: BSD, see LICENSE for details. """ -from __future__ import division +from io import StringIO from pygments.formatter import Formatter from pygments.lexer import Lexer from pygments.token import Token, STANDARD_TYPES -from pygments.util import get_bool_opt, get_int_opt, StringIO, xrange, \ - iteritems +from pygments.util import get_bool_opt, get_int_opt __all__ = ['LatexFormatter'] @@ -322,7 +321,7 @@ def get_style_defs(self, arg=''): """ cp = self.commandprefix styles = [] - for name, definition in iteritems(self.cmd2def): + for name, definition in self.cmd2def.items(): styles.append(r'\expandafter\def\csname %s@tok@%s\endcsname{%s}' % (cp, name, definition)) return STYLE_TEMPLATE % {'cp': self.commandprefix, @@ -354,7 +353,7 @@ def format_unencoded(self, tokensource, outfile): if self.texcomments: # Try to guess comment starting lexeme and escape it ... start = value[0:1] - for i in xrange(1, len(value)): + for i in range(1, len(value)): if start[0] != value[i]: break start += value[i] diff --git a/pygments/formatters/terminal.py b/pygments/formatters/terminal.py index e60bde912f..f0f3d7ae04 100644 --- a/pygments/formatters/terminal.py +++ b/pygments/formatters/terminal.py @@ -92,12 +92,6 @@ def __init__(self, **options): self._lineno = 0 def format(self, tokensource, outfile): - # hack: if the output is a terminal and has an encoding set, - # use that to avoid unicode encode problems - if not self.encoding and hasattr(outfile, "encoding") and \ - hasattr(outfile, "isatty") and outfile.isatty() and \ - sys.version_info < (3,): - self.encoding = outfile.encoding return Formatter.format(self, tokensource, outfile) def _write_lineno(self, outfile): diff --git a/pygments/formatters/terminal256.py b/pygments/formatters/terminal256.py index b6bf9376b8..30e6e1e2a0 100644 --- a/pygments/formatters/terminal256.py +++ b/pygments/formatters/terminal256.py @@ -239,12 +239,6 @@ def _setup_styles(self): escape.reset_string()) def format(self, tokensource, outfile): - # hack: if the output is a terminal and has an encoding set, - # use that to avoid unicode encode problems - if not self.encoding and hasattr(outfile, "encoding") and \ - hasattr(outfile, "isatty") and outfile.isatty() and \ - sys.version_info < (3,): - self.encoding = outfile.encoding return Formatter.format(self, tokensource, outfile) def format_unencoded(self, tokensource, outfile): diff --git a/pygments/lexer.py b/pygments/lexer.py index 56a7e1e8e3..b7aef6ec15 100644 --- a/pygments/lexer.py +++ b/pygments/lexer.py @@ -9,8 +9,6 @@ :license: BSD, see LICENSE for details. """ -from __future__ import print_function - import re import sys import time @@ -19,7 +17,7 @@ from pygments.filters import get_filter_by_name from pygments.token import Error, Text, Other, _TokenType from pygments.util import get_bool_opt, get_int_opt, get_list_opt, \ - make_analysator, text_type, add_metaclass, iteritems, Future, guess_decode + make_analysator, Future, guess_decode from pygments.regexopt import regex_opt __all__ = ['Lexer', 'RegexLexer', 'ExtendedRegexLexer', 'DelegatingLexer', @@ -48,8 +46,7 @@ def __new__(mcs, name, bases, d): return type.__new__(mcs, name, bases, d) -@add_metaclass(LexerMeta) -class Lexer(object): +class Lexer(metaclass=LexerMeta): """ Lexer for a specific language. @@ -145,7 +142,7 @@ def get_tokens(self, text, unfiltered=False): Also preprocess the text, i.e. expand tabs and strip it if wanted and applies registered filters. """ - if not isinstance(text, text_type): + if not isinstance(text, str): if self.encoding == 'guess': text, _ = guess_decode(text) elif self.encoding == 'chardet': @@ -252,7 +249,7 @@ class include(str): # pylint: disable=invalid-name pass -class _inherit(object): +class _inherit: """ Indicates the a state should inherit from its superclass. """ @@ -275,7 +272,7 @@ def __init__(self, *args): pass -class _PseudoMatch(object): +class _PseudoMatch: """ A pseudo match object constructed from a string. """ @@ -328,11 +325,12 @@ def callback(lexer, match, ctx=None): return callback -class _This(object): +class _This: """ Special singleton used for indicating the caller class. Used by ``using``. """ + this = _This() @@ -536,7 +534,7 @@ def get_tokendefs(cls): for c in cls.__mro__: toks = c.__dict__.get('tokens', {}) - for state, items in iteritems(toks): + for state, items in toks.items(): curitems = tokens.get(state) if curitems is None: # N.b. because this is assigned by reference, sufficiently @@ -582,8 +580,7 @@ def __call__(cls, *args, **kwds): return type.__call__(cls, *args, **kwds) -@add_metaclass(RegexLexerMeta) -class RegexLexer(Lexer): +class RegexLexer(Lexer, metaclass=RegexLexerMeta): """ Base for simple stateful regular expression-based lexers. Simplifies the lexing process so that you need only @@ -676,7 +673,7 @@ def get_tokens_unprocessed(self, text, stack=('root',)): break -class LexerContext(object): +class LexerContext: """ A helper object that holds lexer position data. """ @@ -850,8 +847,7 @@ def match_func(text, pos, endpos=sys.maxsize): return match_func -@add_metaclass(ProfilingRegexLexerMeta) -class ProfilingRegexLexer(RegexLexer): +class ProfilingRegexLexer(RegexLexer, metaclass=ProfilingRegexLexerMeta): """Drop-in replacement for RegexLexer that does profiling of its regexes.""" _prof_data = [] diff --git a/pygments/lexers/__init__.py b/pygments/lexers/__init__.py index 100d807660..a56911716b 100644 --- a/pygments/lexers/__init__.py +++ b/pygments/lexers/__init__.py @@ -18,7 +18,7 @@ from pygments.lexers._mapping import LEXERS from pygments.modeline import get_filetype_from_buffer from pygments.plugin import find_plugin_lexers -from pygments.util import ClassNotFound, itervalues, guess_decode, text_type +from pygments.util import ClassNotFound, guess_decode COMPAT = { 'Python3Lexer': 'PythonLexer', @@ -52,7 +52,7 @@ def get_all_lexers(): """Return a generator of tuples in the form ``(name, aliases, filenames, mimetypes)`` of all know lexers. """ - for item in itervalues(LEXERS): + for item in LEXERS.values(): yield item[1:] for lexer in find_plugin_lexers(): yield lexer.name, lexer.aliases, lexer.filenames, lexer.mimetypes @@ -66,7 +66,7 @@ def find_lexer_class(name): if name in _lexer_cache: return _lexer_cache[name] # lookup builtin lexers - for module_name, lname, aliases, _, _ in itervalues(LEXERS): + for module_name, lname, aliases, _, _ in LEXERS.values(): if name == lname: _load_lexers(module_name) return _lexer_cache[name] @@ -86,7 +86,7 @@ def find_lexer_class_by_name(_alias): if not _alias: raise ClassNotFound('no lexer for alias %r found' % _alias) # lookup builtin lexers - for module_name, name, aliases, _, _ in itervalues(LEXERS): + for module_name, name, aliases, _, _ in LEXERS.values(): if _alias.lower() in aliases: if name not in _lexer_cache: _load_lexers(module_name) @@ -107,7 +107,7 @@ def get_lexer_by_name(_alias, **options): raise ClassNotFound('no lexer for alias %r found' % _alias) # lookup builtin lexers - for module_name, name, aliases, _, _ in itervalues(LEXERS): + for module_name, name, aliases, _, _ in LEXERS.values(): if _alias.lower() in aliases: if name not in _lexer_cache: _load_lexers(module_name) @@ -164,7 +164,7 @@ def find_lexer_class_for_filename(_fn, code=None): """ matches = [] fn = basename(_fn) - for modname, name, _, filenames, _ in itervalues(LEXERS): + for modname, name, _, filenames, _ in LEXERS.values(): for filename in filenames: if _fn_matches(fn, filename): if name not in _lexer_cache: @@ -175,7 +175,7 @@ def find_lexer_class_for_filename(_fn, code=None): if _fn_matches(fn, filename): matches.append((cls, filename)) - if sys.version_info > (3,) and isinstance(code, bytes): + if isinstance(code, bytes): # decode it, since all analyse_text functions expect unicode code = guess_decode(code) @@ -216,7 +216,7 @@ def get_lexer_for_mimetype(_mime, **options): Raises ClassNotFound if not found. """ - for modname, name, _, _, mimetypes in itervalues(LEXERS): + for modname, name, _, _, mimetypes in LEXERS.values(): if _mime in mimetypes: if name not in _lexer_cache: _load_lexers(modname) @@ -293,7 +293,7 @@ def type_sort(t): def guess_lexer(_text, **options): """Guess a lexer by strong distinctions in the text (eg, shebang).""" - if not isinstance(_text, text_type): + if not isinstance(_text, str): inencoding = options.get('inencoding', options.get('encoding')) if inencoding: _text = _text.decode(inencoding or 'utf8') diff --git a/pygments/lexers/_cocoa_builtins.py b/pygments/lexers/_cocoa_builtins.py index 2cf4443851..d5e7680c72 100644 --- a/pygments/lexers/_cocoa_builtins.py +++ b/pygments/lexers/_cocoa_builtins.py @@ -12,8 +12,6 @@ :license: BSD, see LICENSE for details. """ -from __future__ import print_function - COCOA_INTERFACES = {'UITableViewCell', 'HKCorrelationQuery', 'NSURLSessionDataTask', 'PHFetchOptions', 'NSLinguisticTagger', 'NSStream', 'AVAudioUnitDelay', 'GCMotion', 'SKPhysicsWorld', 'NSString', 'CMAttitude', 'AVAudioEnvironmentDistanceAttenuationParameters', 'HKStatisticsCollection', 'SCNPlane', 'CBPeer', 'JSContext', 'SCNTransaction', 'SCNTorus', 'AVAudioUnitEffect', 'UICollectionReusableView', 'MTLSamplerDescriptor', 'AVAssetReaderSampleReferenceOutput', 'AVMutableCompositionTrack', 'GKLeaderboard', 'NSFetchedResultsController', 'SKRange', 'MKTileOverlayRenderer', 'MIDINetworkSession', 'UIVisualEffectView', 'CIWarpKernel', 'PKObject', 'MKRoute', 'MPVolumeView', 'UIPrintInfo', 'SCNText', 'ADClient', 'PKPayment', 'AVMutableAudioMix', 'GLKEffectPropertyLight', 'WKScriptMessage', 'AVMIDIPlayer', 'PHCollectionListChangeRequest', 'UICollectionViewLayout', 'NSMutableCharacterSet', 'SKPaymentTransaction', 'NEOnDemandRuleConnect', 'NSShadow', 'SCNView', 'NSURLSessionConfiguration', 'MTLVertexAttributeDescriptor', 'CBCharacteristic', 'HKQuantityType', 'CKLocationSortDescriptor', 'NEVPNIKEv2SecurityAssociationParameters', 'CMStepCounter', 'NSNetService', 'AVAssetWriterInputMetadataAdaptor', 'UICollectionView', 'UIViewPrintFormatter', 'SCNLevelOfDetail', 'CAShapeLayer', 'MCPeerID', 'MPRatingCommand', 'WKNavigation', 'NSDictionary', 'NSFileVersion', 'CMGyroData', 'AVAudioUnitDistortion', 'CKFetchRecordsOperation', 'SKPhysicsJointSpring', 'SCNHitTestResult', 'AVAudioTime', 'CIFilter', 'UIView', 'SCNConstraint', 'CAPropertyAnimation', 'MKMapItem', 'MPRemoteCommandCenter', 'PKPaymentSummaryItem', 'UICollectionViewFlowLayoutInvalidationContext', 'UIInputViewController', 'PKPass', 'SCNPhysicsBehavior', 'MTLRenderPassColorAttachmentDescriptor', 'MKPolygonRenderer', 'CKNotification', 'JSValue', 'PHCollectionList', 'CLGeocoder', 'NSByteCountFormatter', 'AVCaptureScreenInput', 'MPFeedbackCommand', 'CAAnimation', 'MKOverlayPathView', 'UIActionSheet', 'UIMotionEffectGroup', 'NSLengthFormatter', 'UIBarItem', 'SKProduct', 'AVAssetExportSession', 'NSKeyedUnarchiver', 'NSMutableSet', 'SCNPyramid', 'PHAssetCollection', 'MKMapView', 'HMHomeManager', 'CATransition', 'MTLCompileOptions', 'UIVibrancyEffect', 'CLCircularRegion', 'MKTileOverlay', 'SCNShape', 'ACAccountCredential', 'SKPhysicsJointLimit', 'MKMapSnapshotter', 'AVMediaSelectionGroup', 'NSIndexSet', 'CBPeripheralManager', 'CKRecordZone', 'AVAudioRecorder', 'NSURL', 'CBCentral', 'NSNumber', 'AVAudioOutputNode', 'MTLVertexAttributeDescriptorArray', 'MKETAResponse', 'SKTransition', 'SSReadingList', 'HKSourceQuery', 'UITableViewRowAction', 'UITableView', 'SCNParticlePropertyController', 'AVCaptureStillImageOutput', 'GCController', 'AVAudioPlayerNode', 'AVAudioSessionPortDescription', 'NSHTTPURLResponse', 'NEOnDemandRuleEvaluateConnection', 'SKEffectNode', 'HKQuantity', 'GCControllerElement', 'AVPlayerItemAccessLogEvent', 'SCNBox', 'NSExtensionContext', 'MKOverlayRenderer', 'SCNPhysicsVehicle', 'NSDecimalNumber', 'EKReminder', 'MKPolylineView', 'CKQuery', 'AVAudioMixerNode', 'GKAchievementDescription', 'EKParticipant', 'NSBlockOperation', 'UIActivityItemProvider', 'CLLocation', 'NSBatchUpdateRequest', 'PHContentEditingOutput', 'PHObjectChangeDetails', 'HKWorkoutType', 'MPMoviePlayerController', 'AVAudioFormat', 'HMTrigger', 'MTLRenderPassDepthAttachmentDescriptor', 'SCNRenderer', 'GKScore', 'UISplitViewController', 'HKSource', 'NSURLConnection', 'ABUnknownPersonViewController', 'SCNTechnique', 'UIMenuController', 'NSEvent', 'SKTextureAtlas', 'NSKeyedArchiver', 'GKLeaderboardSet', 'NSSimpleCString', 'AVAudioPCMBuffer', 'CBATTRequest', 'GKMatchRequest', 'AVMetadataObject', 'SKProductsRequest', 'UIAlertView', 'NSIncrementalStore', 'MFMailComposeViewController', 'SCNFloor', 'NSSortDescriptor', 'CKFetchNotificationChangesOperation', 'MPMovieAccessLog', 'NSManagedObjectContext', 'AVAudioUnitGenerator', 'WKBackForwardList', 'SKMutableTexture', 'AVCaptureAudioDataOutput', 'ACAccount', 'AVMetadataItem', 'MPRatingCommandEvent', 'AVCaptureDeviceInputSource', 'CLLocationManager', 'MPRemoteCommand', 'AVCaptureSession', 'UIStepper', 'UIRefreshControl', 'NEEvaluateConnectionRule', 'CKModifyRecordsOperation', 'UICollectionViewTransitionLayout', 'CBCentralManager', 'NSPurgeableData', 'PKShippingMethod', 'SLComposeViewController', 'NSHashTable', 'MKUserTrackingBarButtonItem', 'UILexiconEntry', 'CMMotionActivity', 'SKAction', 'SKShader', 'AVPlayerItemOutput', 'MTLRenderPassAttachmentDescriptor', 'UIDocumentInteractionController', 'UIDynamicItemBehavior', 'NSMutableDictionary', 'UILabel', 'AVCaptureInputPort', 'NSExpression', 'CAInterAppAudioTransportView', 'SKMutablePayment', 'UIImage', 'PHCachingImageManager', 'SCNTransformConstraint', 'HKCorrelationType', 'UIColor', 'SCNGeometrySource', 'AVCaptureAutoExposureBracketedStillImageSettings', 'UIPopoverBackgroundView', 'UIToolbar', 'NSNotificationCenter', 'UICollectionViewLayoutAttributes', 'AVAssetReaderOutputMetadataAdaptor', 'NSEntityMigrationPolicy', 'HMUser', 'NSLocale', 'NSURLSession', 'SCNCamera', 'NSTimeZone', 'UIManagedDocument', 'AVMutableVideoCompositionLayerInstruction', 'AVAssetTrackGroup', 'NSInvocationOperation', 'ALAssetRepresentation', 'AVQueuePlayer', 'HMServiceGroup', 'UIPasteboard', 'PHContentEditingInput', 'NSLayoutManager', 'EKCalendarChooser', 'EKObject', 'CATiledLayer', 'GLKReflectionMapEffect', 'NSManagedObjectID', 'NSEnergyFormatter', 'SLRequest', 'HMCharacteristic', 'AVPlayerLayer', 'MTLRenderPassDescriptor', 'SKPayment', 'NSPointerArray', 'AVAudioMix', 'SCNLight', 'MCAdvertiserAssistant', 'MKMapSnapshotOptions', 'HKCategorySample', 'AVAudioEnvironmentReverbParameters', 'SCNMorpher', 'AVTimedMetadataGroup', 'CBMutableCharacteristic', 'NSFetchRequest', 'UIDevice', 'NSManagedObject', 'NKAssetDownload', 'AVOutputSettingsAssistant', 'SKPhysicsJointPin', 'UITabBar', 'UITextInputMode', 'NSFetchRequestExpression', 'HMActionSet', 'CTSubscriber', 'PHAssetChangeRequest', 'NSPersistentStoreRequest', 'UITabBarController', 'HKQuantitySample', 'AVPlayerItem', 'AVSynchronizedLayer', 'MKDirectionsRequest', 'NSMetadataItem', 'UIPresentationController', 'UINavigationItem', 'PHFetchResultChangeDetails', 'PHImageManager', 'AVCaptureManualExposureBracketedStillImageSettings', 'UIStoryboardPopoverSegue', 'SCNLookAtConstraint', 'UIGravityBehavior', 'UIWindow', 'CBMutableDescriptor', 'NEOnDemandRuleDisconnect', 'UIBezierPath', 'UINavigationController', 'ABPeoplePickerNavigationController', 'EKSource', 'AVAssetWriterInput', 'AVPlayerItemTrack', 'GLKEffectPropertyTexture', 'NSHTTPCookie', 'NSURLResponse', 'SKPaymentQueue', 'NSAssertionHandler', 'MKReverseGeocoder', 'GCControllerAxisInput', 'NSArray', 'NSOrthography', 'NSURLSessionUploadTask', 'NSCharacterSet', 'AVMutableVideoCompositionInstruction', 'AVAssetReaderOutput', 'EAGLContext', 'WKFrameInfo', 'CMPedometer', 'MyClass', 'CKModifyBadgeOperation', 'AVCaptureAudioFileOutput', 'SKEmitterNode', 'NSMachPort', 'AVVideoCompositionCoreAnimationTool', 'PHCollection', 'SCNPhysicsWorld', 'NSURLRequest', 'CMAccelerometerData', 'NSNetServiceBrowser', 'CLFloor', 'AVAsynchronousVideoCompositionRequest', 'SCNGeometry', 'SCNIKConstraint', 'CIKernel', 'CAGradientLayer', 'HKCharacteristicType', 'NSFormatter', 'SCNAction', 'CATransaction', 'CBUUID', 'UIStoryboard', 'MPMediaLibrary', 'UITapGestureRecognizer', 'MPMediaItemArtwork', 'NSURLSessionTask', 'AVAudioUnit', 'MCBrowserViewController', 'UIFontDescriptor', 'NSRelationshipDescription', 'HKSample', 'WKWebView', 'NSMutableAttributedString', 'NSPersistentStoreAsynchronousResult', 'MPNowPlayingInfoCenter', 'MKLocalSearch', 'EAAccessory', 'HKCorrelation', 'CATextLayer', 'NSNotificationQueue', 'UINib', 'GLKTextureLoader', 'HKObjectType', 'NSValue', 'NSMutableIndexSet', 'SKPhysicsContact', 'NSProgress', 'AVPlayerViewController', 'CAScrollLayer', 'GKSavedGame', 'NSTextCheckingResult', 'PHObjectPlaceholder', 'SKConstraint', 'EKEventEditViewController', 'NSEntityDescription', 'NSURLCredentialStorage', 'UIApplication', 'SKDownload', 'SCNNode', 'MKLocalSearchRequest', 'SKScene', 'UISearchDisplayController', 'NEOnDemandRule', 'MTLRenderPassStencilAttachmentDescriptor', 'CAReplicatorLayer', 'UIPrintPageRenderer', 'EKCalendarItem', 'NSUUID', 'EAAccessoryManager', 'NEOnDemandRuleIgnore', 'SKRegion', 'AVAssetResourceLoader', 'EAWiFiUnconfiguredAccessoryBrowser', 'NSUserActivity', 'CTCall', 'UIPrinterPickerController', 'CIVector', 'UINavigationBar', 'UIPanGestureRecognizer', 'MPMediaQuery', 'ABNewPersonViewController', 'CKRecordZoneID', 'HKAnchoredObjectQuery', 'CKFetchRecordZonesOperation', 'UIStoryboardSegue', 'ACAccountType', 'GKSession', 'SKVideoNode', 'PHChange', 'SKReceiptRefreshRequest', 'GCExtendedGamepadSnapshot', 'MPSeekCommandEvent', 'GCExtendedGamepad', 'CAValueFunction', 'SCNCylinder', 'NSNotification', 'NSBatchUpdateResult', 'PKPushCredentials', 'SCNPhysicsSliderJoint', 'AVCaptureDeviceFormat', 'AVPlayerItemErrorLog', 'NSMapTable', 'NSSet', 'CMMotionManager', 'GKVoiceChatService', 'UIPageControl', 'UILexicon', 'MTLArrayType', 'AVAudioUnitReverb', 'MKGeodesicPolyline', 'AVMutableComposition', 'NSLayoutConstraint', 'UIPrinter', 'NSOrderedSet', 'CBAttribute', 'PKPushPayload', 'NSIncrementalStoreNode', 'EKEventStore', 'MPRemoteCommandEvent', 'UISlider', 'UIBlurEffect', 'CKAsset', 'AVCaptureInput', 'AVAudioEngine', 'MTLVertexDescriptor', 'SKPhysicsBody', 'NSOperation', 'PKPaymentPass', 'UIImageAsset', 'MKMapCamera', 'SKProductsResponse', 'GLKEffectPropertyMaterial', 'AVCaptureDevice', 'CTCallCenter', 'CABTMIDILocalPeripheralViewController', 'NEVPNManager', 'HKQuery', 'SCNPhysicsContact', 'CBMutableService', 'AVSampleBufferDisplayLayer', 'SCNSceneSource', 'SKLightNode', 'CKDiscoveredUserInfo', 'NSMutableArray', 'MTLDepthStencilDescriptor', 'MTLArgument', 'NSMassFormatter', 'CIRectangleFeature', 'PKPushRegistry', 'NEVPNConnection', 'MCNearbyServiceBrowser', 'NSOperationQueue', 'MKPolylineRenderer', 'HKWorkout', 'NSValueTransformer', 'UICollectionViewFlowLayout', 'MPChangePlaybackRateCommandEvent', 'NSEntityMapping', 'SKTexture', 'NSMergePolicy', 'UITextInputStringTokenizer', 'NSRecursiveLock', 'AVAsset', 'NSUndoManager', 'AVAudioUnitSampler', 'NSItemProvider', 'SKUniform', 'MPMediaPickerController', 'CKOperation', 'MTLRenderPipelineDescriptor', 'EAWiFiUnconfiguredAccessory', 'NSFileCoordinator', 'SKRequest', 'NSFileHandle', 'NSConditionLock', 'UISegmentedControl', 'NSManagedObjectModel', 'UITabBarItem', 'SCNCone', 'MPMediaItem', 'SCNMaterial', 'EKRecurrenceRule', 'UIEvent', 'UITouch', 'UIPrintInteractionController', 'CMDeviceMotion', 'NEVPNProtocol', 'NSCompoundPredicate', 'HKHealthStore', 'MKMultiPoint', 'HKSampleType', 'UIPrintFormatter', 'AVAudioUnitEQFilterParameters', 'SKView', 'NSConstantString', 'UIPopoverController', 'CKDatabase', 'AVMetadataFaceObject', 'UIAccelerometer', 'EKEventViewController', 'CMAltitudeData', 'MTLStencilDescriptor', 'UISwipeGestureRecognizer', 'NSPort', 'MKCircleRenderer', 'AVCompositionTrack', 'NSAsynchronousFetchRequest', 'NSUbiquitousKeyValueStore', 'NSMetadataQueryResultGroup', 'AVAssetResourceLoadingDataRequest', 'UITableViewHeaderFooterView', 'CKNotificationID', 'AVAudioSession', 'HKUnit', 'NSNull', 'NSPersistentStoreResult', 'MKCircleView', 'AVAudioChannelLayout', 'NEVPNProtocolIKEv2', 'WKProcessPool', 'UIAttachmentBehavior', 'CLBeacon', 'NSInputStream', 'NSURLCache', 'GKPlayer', 'NSMappingModel', 'CIQRCodeFeature', 'AVMutableVideoComposition', 'PHFetchResult', 'NSAttributeDescription', 'AVPlayer', 'MKAnnotationView', 'PKPaymentRequest', 'NSTimer', 'CBDescriptor', 'MKOverlayView', 'AVAudioUnitTimePitch', 'NSSaveChangesRequest', 'UIReferenceLibraryViewController', 'SKPhysicsJointFixed', 'UILocalizedIndexedCollation', 'UIInterpolatingMotionEffect', 'UIDocumentPickerViewController', 'AVAssetWriter', 'NSBundle', 'SKStoreProductViewController', 'GLKViewController', 'NSMetadataQueryAttributeValueTuple', 'GKTurnBasedMatch', 'AVAudioFile', 'UIActivity', 'NSPipe', 'MKShape', 'NSMergeConflict', 'CIImage', 'HKObject', 'UIRotationGestureRecognizer', 'AVPlayerItemLegibleOutput', 'AVAssetImageGenerator', 'GCControllerButtonInput', 'CKMarkNotificationsReadOperation', 'CKSubscription', 'MPTimedMetadata', 'NKIssue', 'UIScreenMode', 'HMAccessoryBrowser', 'GKTurnBasedEventHandler', 'UIWebView', 'MKPolyline', 'JSVirtualMachine', 'AVAssetReader', 'NSAttributedString', 'GKMatchmakerViewController', 'NSCountedSet', 'UIButton', 'WKNavigationResponse', 'GKLocalPlayer', 'MPMovieErrorLog', 'AVSpeechUtterance', 'HKStatistics', 'UILocalNotification', 'HKBiologicalSexObject', 'AVURLAsset', 'CBPeripheral', 'NSDateComponentsFormatter', 'SKSpriteNode', 'UIAccessibilityElement', 'AVAssetWriterInputGroup', 'HMZone', 'AVAssetReaderAudioMixOutput', 'NSEnumerator', 'UIDocument', 'MKLocalSearchResponse', 'UISimpleTextPrintFormatter', 'PHPhotoLibrary', 'CBService', 'UIDocumentMenuViewController', 'MCSession', 'QLPreviewController', 'CAMediaTimingFunction', 'UITextPosition', 'ASIdentifierManager', 'AVAssetResourceLoadingRequest', 'SLComposeServiceViewController', 'UIPinchGestureRecognizer', 'PHObject', 'NSExtensionItem', 'HKSampleQuery', 'MTLRenderPipelineColorAttachmentDescriptorArray', 'MKRouteStep', 'SCNCapsule', 'NSMetadataQuery', 'AVAssetResourceLoadingContentInformationRequest', 'UITraitCollection', 'CTCarrier', 'NSFileSecurity', 'UIAcceleration', 'UIMotionEffect', 'MTLRenderPipelineReflection', 'CLHeading', 'CLVisit', 'MKDirectionsResponse', 'HMAccessory', 'MTLStructType', 'UITextView', 'CMMagnetometerData', 'UICollisionBehavior', 'UIProgressView', 'CKServerChangeToken', 'UISearchBar', 'MKPlacemark', 'AVCaptureConnection', 'NSPropertyMapping', 'ALAssetsFilter', 'SK3DNode', 'AVPlayerItemErrorLogEvent', 'NSJSONSerialization', 'AVAssetReaderVideoCompositionOutput', 'ABPersonViewController', 'CIDetector', 'GKTurnBasedMatchmakerViewController', 'MPMediaItemCollection', 'SCNSphere', 'NSCondition', 'NSURLCredential', 'MIDINetworkConnection', 'NSFileProviderExtension', 'NSDecimalNumberHandler', 'NSAtomicStoreCacheNode', 'NSAtomicStore', 'EKAlarm', 'CKNotificationInfo', 'AVAudioUnitEQ', 'UIPercentDrivenInteractiveTransition', 'MKPolygon', 'AVAssetTrackSegment', 'MTLVertexAttribute', 'NSExpressionDescription', 'HKStatisticsCollectionQuery', 'NSURLAuthenticationChallenge', 'NSDirectoryEnumerator', 'MKDistanceFormatter', 'UIAlertAction', 'NSPropertyListSerialization', 'GKPeerPickerController', 'UIUserNotificationSettings', 'UITableViewController', 'GKNotificationBanner', 'MKPointAnnotation', 'MTLRenderPassColorAttachmentDescriptorArray', 'NSCache', 'SKPhysicsJoint', 'NSXMLParser', 'UIViewController', 'PKPaymentToken', 'MFMessageComposeViewController', 'AVAudioInputNode', 'NSDataDetector', 'CABTMIDICentralViewController', 'AVAudioUnitMIDIInstrument', 'AVCaptureVideoPreviewLayer', 'AVAssetWriterInputPassDescription', 'MPChangePlaybackRateCommand', 'NSURLComponents', 'CAMetalLayer', 'UISnapBehavior', 'AVMetadataMachineReadableCodeObject', 'CKDiscoverUserInfosOperation', 'NSTextAttachment', 'NSException', 'UIMenuItem', 'CMMotionActivityManager', 'SCNGeometryElement', 'NCWidgetController', 'CAEmitterLayer', 'MKUserLocation', 'UIImagePickerController', 'CIFeature', 'AVCaptureDeviceInput', 'ALAsset', 'NSURLSessionDownloadTask', 'SCNPhysicsHingeJoint', 'MPMoviePlayerViewController', 'NSMutableOrderedSet', 'SCNMaterialProperty', 'UIFont', 'AVCaptureVideoDataOutput', 'NSCachedURLResponse', 'ALAssetsLibrary', 'NSInvocation', 'UILongPressGestureRecognizer', 'NSTextStorage', 'WKWebViewConfiguration', 'CIFaceFeature', 'MKMapSnapshot', 'GLKEffectPropertyFog', 'AVComposition', 'CKDiscoverAllContactsOperation', 'AVAudioMixInputParameters', 'CAEmitterBehavior', 'PKPassLibrary', 'UIMutableUserNotificationCategory', 'NSLock', 'NEVPNProtocolIPSec', 'ADBannerView', 'UIDocumentPickerExtensionViewController', 'UIActivityIndicatorView', 'AVPlayerMediaSelectionCriteria', 'CALayer', 'UIAccessibilityCustomAction', 'UIBarButtonItem', 'AVAudioSessionRouteDescription', 'CLBeaconRegion', 'HKBloodTypeObject', 'MTLVertexBufferLayoutDescriptorArray', 'CABasicAnimation', 'AVVideoCompositionInstruction', 'AVMutableTimedMetadataGroup', 'EKRecurrenceEnd', 'NSTextContainer', 'TWTweetComposeViewController', 'PKPaymentAuthorizationViewController', 'UIScrollView', 'WKNavigationAction', 'AVPlayerItemMetadataOutput', 'EKRecurrenceDayOfWeek', 'NSNumberFormatter', 'MTLComputePipelineReflection', 'UIScreen', 'CLRegion', 'NSProcessInfo', 'GLKTextureInfo', 'SCNSkinner', 'AVCaptureMetadataOutput', 'SCNAnimationEvent', 'NSTextTab', 'JSManagedValue', 'NSDate', 'UITextChecker', 'WKBackForwardListItem', 'NSData', 'NSParagraphStyle', 'AVMutableMetadataItem', 'EKCalendar', 'HKWorkoutEvent', 'NSMutableURLRequest', 'UIVideoEditorController', 'HMTimerTrigger', 'AVAudioUnitVarispeed', 'UIDynamicAnimator', 'AVCompositionTrackSegment', 'GCGamepadSnapshot', 'MPMediaEntity', 'GLKSkyboxEffect', 'UISwitch', 'EKStructuredLocation', 'UIGestureRecognizer', 'NSProxy', 'GLKBaseEffect', 'UIPushBehavior', 'GKScoreChallenge', 'NSCoder', 'MPMediaPlaylist', 'NSDateComponents', 'WKUserScript', 'EKEvent', 'NSDateFormatter', 'NSAsynchronousFetchResult', 'AVAssetWriterInputPixelBufferAdaptor', 'UIVisualEffect', 'UICollectionViewCell', 'UITextField', 'CLPlacemark', 'MPPlayableContentManager', 'AVCaptureOutput', 'HMCharacteristicWriteAction', 'CKModifySubscriptionsOperation', 'NSPropertyDescription', 'GCGamepad', 'UIMarkupTextPrintFormatter', 'SCNTube', 'NSPersistentStoreCoordinator', 'AVAudioEnvironmentNode', 'GKMatchmaker', 'CIContext', 'NSThread', 'SLComposeSheetConfigurationItem', 'SKPhysicsJointSliding', 'NSPredicate', 'GKVoiceChat', 'SKCropNode', 'AVCaptureAudioPreviewOutput', 'NSStringDrawingContext', 'GKGameCenterViewController', 'UIPrintPaper', 'SCNPhysicsBallSocketJoint', 'UICollectionViewLayoutInvalidationContext', 'GLKEffectPropertyTransform', 'AVAudioIONode', 'UIDatePicker', 'MKDirections', 'ALAssetsGroup', 'CKRecordZoneNotification', 'SCNScene', 'MPMovieAccessLogEvent', 'CKFetchSubscriptionsOperation', 'CAEmitterCell', 'AVAudioUnitTimeEffect', 'HMCharacteristicMetadata', 'MKPinAnnotationView', 'UIPickerView', 'UIImageView', 'UIUserNotificationCategory', 'SCNPhysicsVehicleWheel', 'HKCategoryType', 'MPMediaQuerySection', 'GKFriendRequestComposeViewController', 'NSError', 'MTLRenderPipelineColorAttachmentDescriptor', 'SCNPhysicsShape', 'UISearchController', 'SCNPhysicsBody', 'CTSubscriberInfo', 'AVPlayerItemAccessLog', 'MPMediaPropertyPredicate', 'CMLogItem', 'NSAutoreleasePool', 'NSSocketPort', 'AVAssetReaderTrackOutput', 'SKNode', 'UIMutableUserNotificationAction', 'SCNProgram', 'AVSpeechSynthesisVoice', 'CMAltimeter', 'AVCaptureAudioChannel', 'GKTurnBasedExchangeReply', 'AVVideoCompositionLayerInstruction', 'AVSpeechSynthesizer', 'GKChallengeEventHandler', 'AVCaptureFileOutput', 'UIControl', 'SCNPhysicsField', 'CKReference', 'LAContext', 'CKRecordID', 'ADInterstitialAd', 'AVAudioSessionDataSourceDescription', 'AVAudioBuffer', 'CIColorKernel', 'GCControllerDirectionPad', 'NSFileManager', 'AVMutableAudioMixInputParameters', 'UIScreenEdgePanGestureRecognizer', 'CAKeyframeAnimation', 'CKQueryNotification', 'PHAdjustmentData', 'EASession', 'AVAssetResourceRenewalRequest', 'UIInputView', 'NSFileWrapper', 'UIResponder', 'NSPointerFunctions', 'UIKeyCommand', 'NSHTTPCookieStorage', 'AVMediaSelectionOption', 'NSRunLoop', 'NSFileAccessIntent', 'CAAnimationGroup', 'MKCircle', 'UIAlertController', 'NSMigrationManager', 'NSDateIntervalFormatter', 'UICollectionViewUpdateItem', 'CKDatabaseOperation', 'PHImageRequestOptions', 'SKReachConstraints', 'CKRecord', 'CAInterAppAudioSwitcherView', 'WKWindowFeatures', 'GKInvite', 'NSMutableData', 'PHAssetCollectionChangeRequest', 'NSMutableParagraphStyle', 'UIDynamicBehavior', 'GLKEffectProperty', 'CKFetchRecordChangesOperation', 'SKShapeNode', 'MPMovieErrorLogEvent', 'MKPolygonView', 'MPContentItem', 'HMAction', 'NSScanner', 'GKAchievementChallenge', 'AVAudioPlayer', 'CKContainer', 'AVVideoComposition', 'NKLibrary', 'NSPersistentStore', 'AVCaptureMovieFileOutput', 'HMRoom', 'GKChallenge', 'UITextRange', 'NSURLProtectionSpace', 'ACAccountStore', 'MPSkipIntervalCommand', 'NSComparisonPredicate', 'HMHome', 'PHVideoRequestOptions', 'NSOutputStream', 'MPSkipIntervalCommandEvent', 'PKAddPassesViewController', 'UITextSelectionRect', 'CTTelephonyNetworkInfo', 'AVTextStyleRule', 'NSFetchedPropertyDescription', 'UIPageViewController', 'CATransformLayer', 'UICollectionViewController', 'AVAudioNode', 'MCNearbyServiceAdvertiser', 'NSObject', 'PHAsset', 'GKLeaderboardViewController', 'CKQueryCursor', 'MPMusicPlayerController', 'MKOverlayPathRenderer', 'CMPedometerData', 'HMService', 'SKFieldNode', 'GKAchievement', 'WKUserContentController', 'AVAssetTrack', 'TWRequest', 'SKLabelNode', 'AVCaptureBracketedStillImageSettings', 'MIDINetworkHost', 'MPMediaPredicate', 'AVFrameRateRange', 'MTLTextureDescriptor', 'MTLVertexBufferLayoutDescriptor', 'MPFeedbackCommandEvent', 'UIUserNotificationAction', 'HKStatisticsQuery', 'SCNParticleSystem', 'NSIndexPath', 'AVVideoCompositionRenderContext', 'CADisplayLink', 'HKObserverQuery', 'UIPopoverPresentationController', 'CKQueryOperation', 'CAEAGLLayer', 'NSMutableString', 'NSMessagePort', 'NSURLQueryItem', 'MTLStructMember', 'AVAudioSessionChannelDescription', 'GLKView', 'UIActivityViewController', 'GKAchievementViewController', 'GKTurnBasedParticipant', 'NSURLProtocol', 'NSUserDefaults', 'NSCalendar', 'SKKeyframeSequence', 'AVMetadataItemFilter', 'CKModifyRecordZonesOperation', 'WKPreferences', 'NSMethodSignature', 'NSRegularExpression', 'EAGLSharegroup', 'AVPlayerItemVideoOutput', 'PHContentEditingInputRequestOptions', 'GKMatch', 'CIColor', 'UIDictationPhrase'} COCOA_PROTOCOLS = {'SKStoreProductViewControllerDelegate', 'AVVideoCompositionInstruction', 'AVAudioSessionDelegate', 'GKMatchDelegate', 'NSFileManagerDelegate', 'UILayoutSupport', 'NSCopying', 'UIPrintInteractionControllerDelegate', 'QLPreviewControllerDataSource', 'SKProductsRequestDelegate', 'NSTextStorageDelegate', 'MCBrowserViewControllerDelegate', 'MTLComputeCommandEncoder', 'SCNSceneExportDelegate', 'UISearchResultsUpdating', 'MFMailComposeViewControllerDelegate', 'MTLBlitCommandEncoder', 'NSDecimalNumberBehaviors', 'PHContentEditingController', 'NSMutableCopying', 'UIActionSheetDelegate', 'UIViewControllerTransitioningDelegate', 'UIAlertViewDelegate', 'AVAudioPlayerDelegate', 'MKReverseGeocoderDelegate', 'NSCoding', 'UITextInputTokenizer', 'GKFriendRequestComposeViewControllerDelegate', 'UIActivityItemSource', 'NSCacheDelegate', 'UIAdaptivePresentationControllerDelegate', 'GKAchievementViewControllerDelegate', 'UIViewControllerTransitionCoordinator', 'EKEventEditViewDelegate', 'NSURLConnectionDelegate', 'UITableViewDelegate', 'GKPeerPickerControllerDelegate', 'UIGuidedAccessRestrictionDelegate', 'AVSpeechSynthesizerDelegate', 'AVAudio3DMixing', 'AVPlayerItemLegibleOutputPushDelegate', 'ADInterstitialAdDelegate', 'HMAccessoryBrowserDelegate', 'AVAssetResourceLoaderDelegate', 'UITabBarControllerDelegate', 'CKRecordValue', 'SKPaymentTransactionObserver', 'AVCaptureAudioDataOutputSampleBufferDelegate', 'UIInputViewAudioFeedback', 'GKChallengeListener', 'SKSceneDelegate', 'UIPickerViewDelegate', 'UIWebViewDelegate', 'UIApplicationDelegate', 'GKInviteEventListener', 'MPMediaPlayback', 'MyClassJavaScriptMethods', 'AVAsynchronousKeyValueLoading', 'QLPreviewItem', 'SCNBoundingVolume', 'NSPortDelegate', 'UIContentContainer', 'SCNNodeRendererDelegate', 'SKRequestDelegate', 'SKPhysicsContactDelegate', 'HMAccessoryDelegate', 'UIPageViewControllerDataSource', 'SCNSceneRendererDelegate', 'SCNPhysicsContactDelegate', 'MKMapViewDelegate', 'AVPlayerItemOutputPushDelegate', 'UICollectionViewDelegate', 'UIImagePickerControllerDelegate', 'MTLRenderCommandEncoder', 'PKPaymentAuthorizationViewControllerDelegate', 'UIToolbarDelegate', 'WKUIDelegate', 'SCNActionable', 'NSURLConnectionDataDelegate', 'MKOverlay', 'CBCentralManagerDelegate', 'JSExport', 'NSTextLayoutOrientationProvider', 'UIPickerViewDataSource', 'PKPushRegistryDelegate', 'UIViewControllerTransitionCoordinatorContext', 'NSLayoutManagerDelegate', 'MTLLibrary', 'NSFetchedResultsControllerDelegate', 'ABPeoplePickerNavigationControllerDelegate', 'MTLResource', 'NSDiscardableContent', 'UITextFieldDelegate', 'MTLBuffer', 'MTLSamplerState', 'GKGameCenterControllerDelegate', 'MPMediaPickerControllerDelegate', 'UISplitViewControllerDelegate', 'UIAppearance', 'UIPickerViewAccessibilityDelegate', 'UITraitEnvironment', 'UIScrollViewAccessibilityDelegate', 'ADBannerViewDelegate', 'MPPlayableContentDataSource', 'MTLComputePipelineState', 'NSURLSessionDelegate', 'MTLCommandBuffer', 'NSXMLParserDelegate', 'UIViewControllerRestoration', 'UISearchBarDelegate', 'UIBarPositioning', 'CBPeripheralDelegate', 'UISearchDisplayDelegate', 'CAAction', 'PKAddPassesViewControllerDelegate', 'MCNearbyServiceAdvertiserDelegate', 'MTLDepthStencilState', 'GKTurnBasedMatchmakerViewControllerDelegate', 'MPPlayableContentDelegate', 'AVCaptureVideoDataOutputSampleBufferDelegate', 'UIAppearanceContainer', 'UIStateRestoring', 'UITextDocumentProxy', 'MTLDrawable', 'NSURLSessionTaskDelegate', 'NSFilePresenter', 'AVAudioStereoMixing', 'UIViewControllerContextTransitioning', 'UITextInput', 'CBPeripheralManagerDelegate', 'UITextInputDelegate', 'NSFastEnumeration', 'NSURLAuthenticationChallengeSender', 'SCNProgramDelegate', 'AVVideoCompositing', 'SCNAnimatable', 'NSSecureCoding', 'MCAdvertiserAssistantDelegate', 'GKLocalPlayerListener', 'GLKNamedEffect', 'UIPopoverControllerDelegate', 'AVCaptureMetadataOutputObjectsDelegate', 'NSExtensionRequestHandling', 'UITextSelecting', 'UIPrinterPickerControllerDelegate', 'NCWidgetProviding', 'MTLCommandEncoder', 'NSURLProtocolClient', 'MFMessageComposeViewControllerDelegate', 'UIVideoEditorControllerDelegate', 'WKNavigationDelegate', 'GKSavedGameListener', 'UITableViewDataSource', 'MTLFunction', 'EKCalendarChooserDelegate', 'NSUserActivityDelegate', 'UICollisionBehaviorDelegate', 'NSStreamDelegate', 'MCNearbyServiceBrowserDelegate', 'HMHomeDelegate', 'UINavigationControllerDelegate', 'MCSessionDelegate', 'UIDocumentPickerDelegate', 'UIViewControllerInteractiveTransitioning', 'GKTurnBasedEventListener', 'SCNSceneRenderer', 'MTLTexture', 'GLKViewDelegate', 'EAAccessoryDelegate', 'WKScriptMessageHandler', 'PHPhotoLibraryChangeObserver', 'NSKeyedUnarchiverDelegate', 'AVPlayerItemMetadataOutputPushDelegate', 'NSMachPortDelegate', 'SCNShadable', 'UIPopoverBackgroundViewMethods', 'UIDocumentMenuDelegate', 'UIBarPositioningDelegate', 'ABPersonViewControllerDelegate', 'NSNetServiceBrowserDelegate', 'EKEventViewDelegate', 'UIScrollViewDelegate', 'NSURLConnectionDownloadDelegate', 'UIGestureRecognizerDelegate', 'UINavigationBarDelegate', 'AVAudioMixing', 'NSFetchedResultsSectionInfo', 'UIDocumentInteractionControllerDelegate', 'MTLParallelRenderCommandEncoder', 'QLPreviewControllerDelegate', 'UIAccessibilityReadingContent', 'ABUnknownPersonViewControllerDelegate', 'GLKViewControllerDelegate', 'UICollectionViewDelegateFlowLayout', 'UIPopoverPresentationControllerDelegate', 'UIDynamicAnimatorDelegate', 'NSTextAttachmentContainer', 'MKAnnotation', 'UIAccessibilityIdentification', 'UICoordinateSpace', 'ABNewPersonViewControllerDelegate', 'MTLDevice', 'CAMediaTiming', 'AVCaptureFileOutputRecordingDelegate', 'HMHomeManagerDelegate', 'UITextViewDelegate', 'UITabBarDelegate', 'GKLeaderboardViewControllerDelegate', 'UISearchControllerDelegate', 'EAWiFiUnconfiguredAccessoryBrowserDelegate', 'UITextInputTraits', 'MTLRenderPipelineState', 'GKVoiceChatClient', 'UIKeyInput', 'UICollectionViewDataSource', 'SCNTechniqueSupport', 'NSLocking', 'AVCaptureFileOutputDelegate', 'GKChallengeEventHandlerDelegate', 'UIObjectRestoration', 'CIFilterConstructor', 'AVPlayerItemOutputPullDelegate', 'EAGLDrawable', 'AVVideoCompositionValidationHandling', 'UIViewControllerAnimatedTransitioning', 'NSURLSessionDownloadDelegate', 'UIAccelerometerDelegate', 'UIPageViewControllerDelegate', 'MTLCommandQueue', 'UIDataSourceModelAssociation', 'AVAudioRecorderDelegate', 'GKSessionDelegate', 'NSKeyedArchiverDelegate', 'CAMetalDrawable', 'UIDynamicItem', 'CLLocationManagerDelegate', 'NSMetadataQueryDelegate', 'NSNetServiceDelegate', 'GKMatchmakerViewControllerDelegate', 'NSURLSessionDataDelegate'} COCOA_PRIMITIVES = {'ROTAHeader', '__CFBundle', 'MortSubtable', 'AudioFilePacketTableInfo', 'CGPDFOperatorTable', 'KerxStateEntry', 'ExtendedTempoEvent', 'CTParagraphStyleSetting', 'OpaqueMIDIPort', '_GLKMatrix3', '_GLKMatrix2', '_GLKMatrix4', 'ExtendedControlEvent', 'CAFAudioDescription', 'OpaqueCMBlockBuffer', 'CGTextDrawingMode', 'EKErrorCode', 'gss_buffer_desc_struct', 'AudioUnitParameterInfo', '__SCPreferences', '__CTFrame', '__CTLine', 'AudioFile_SMPTE_Time', 'gss_krb5_lucid_context_v1', 'OpaqueJSValue', 'TrakTableEntry', 'AudioFramePacketTranslation', 'CGImageSource', 'OpaqueJSPropertyNameAccumulator', 'JustPCGlyphRepeatAddAction', '__CFBinaryHeap', 'OpaqueMIDIThruConnection', 'opaqueCMBufferQueue', 'OpaqueMusicSequence', 'MortRearrangementSubtable', 'MixerDistanceParams', 'MorxSubtable', 'MIDIObjectPropertyChangeNotification', 'SFNTLookupSegment', 'CGImageMetadataErrors', 'CGPath', 'OpaqueMIDIEndpoint', 'AudioComponentPlugInInterface', 'gss_ctx_id_t_desc_struct', 'sfntFontFeatureSetting', 'OpaqueJSContextGroup', '__SCNetworkConnection', 'AudioUnitParameterValueTranslation', 'CGImageMetadataType', 'CGPattern', 'AudioFileTypeAndFormatID', 'CGContext', 'AUNodeInteraction', 'SFNTLookupTable', 'JustPCDecompositionAction', 'KerxControlPointHeader', 'AudioStreamPacketDescription', 'KernSubtableHeader', '__SecCertificate', 'AUMIDIOutputCallbackStruct', 'MIDIMetaEvent', 'AudioQueueChannelAssignment', 'AnchorPoint', 'JustTable', '__CFNetService', 'CF_BRIDGED_TYPE', 'gss_krb5_lucid_key', 'CGPDFDictionary', 'KerxSubtableHeader', 'CAF_UUID_ChunkHeader', 'gss_krb5_cfx_keydata', 'OpaqueJSClass', 'CGGradient', 'OpaqueMIDISetup', 'JustPostcompTable', '__CTParagraphStyle', 'AudioUnitParameterHistoryInfo', 'OpaqueJSContext', 'CGShading', 'MIDIThruConnectionParams', 'BslnFormat0Part', 'SFNTLookupSingle', '__CFHost', '__SecRandom', '__CTFontDescriptor', '_NSRange', 'sfntDirectory', 'AudioQueueLevelMeterState', 'CAFPositionPeak', 'PropLookupSegment', '__CVOpenGLESTextureCache', 'sfntInstance', '_GLKQuaternion', 'AnkrTable', '__SCNetworkProtocol', 'CAFFileHeader', 'KerxOrderedListHeader', 'CGBlendMode', 'STXEntryOne', 'CAFRegion', 'SFNTLookupTrimmedArrayHeader', 'SCNMatrix4', 'KerxControlPointEntry', 'OpaqueMusicTrack', '_GLKVector4', 'gss_OID_set_desc_struct', 'OpaqueMusicPlayer', '_CFHTTPAuthentication', 'CGAffineTransform', 'CAFMarkerChunk', 'AUHostIdentifier', 'ROTAGlyphEntry', 'BslnTable', 'gss_krb5_lucid_context_version', '_GLKMatrixStack', 'CGImage', 'KernStateEntry', 'SFNTLookupSingleHeader', 'MortLigatureSubtable', 'CAFUMIDChunk', 'SMPTETime', 'CAFDataChunk', 'CGPDFStream', 'AudioFileRegionList', 'STEntryTwo', 'SFNTLookupBinarySearchHeader', 'OpbdTable', '__CTGlyphInfo', 'BslnFormat2Part', 'KerxIndexArrayHeader', 'TrakTable', 'KerxKerningPair', '__CFBitVector', 'KernVersion0SubtableHeader', 'OpaqueAudioComponentInstance', 'AudioChannelLayout', '__CFUUID', 'MIDISysexSendRequest', '__CFNumberFormatter', 'CGImageSourceStatus', 'AudioFileMarkerList', 'AUSamplerBankPresetData', 'CGDataProvider', 'AudioFormatInfo', '__SecIdentity', 'sfntCMapExtendedSubHeader', 'MIDIChannelMessage', 'KernOffsetTable', 'CGColorSpaceModel', 'MFMailComposeErrorCode', 'CGFunction', '__SecTrust', 'AVAudio3DAngularOrientation', 'CGFontPostScriptFormat', 'KernStateHeader', 'AudioUnitCocoaViewInfo', 'CGDataConsumer', 'OpaqueMIDIDevice', 'KernVersion0Header', 'AnchorPointTable', 'CGImageDestination', 'CAFInstrumentChunk', 'AudioUnitMeterClipping', 'MorxChain', '__CTFontCollection', 'STEntryOne', 'STXEntryTwo', 'ExtendedNoteOnEvent', 'CGColorRenderingIntent', 'KerxSimpleArrayHeader', 'MorxTable', '_GLKVector3', '_GLKVector2', 'MortTable', 'CGPDFBox', 'AudioUnitParameterValueFromString', '__CFSocket', 'ALCdevice_struct', 'MIDINoteMessage', 'sfntFeatureHeader', 'CGRect', '__SCNetworkInterface', '__CFTree', 'MusicEventUserData', 'TrakTableData', 'GCQuaternion', 'MortContextualSubtable', '__CTRun', 'AudioUnitFrequencyResponseBin', 'MortChain', 'MorxInsertionSubtable', 'CGImageMetadata', 'gss_auth_identity', 'AudioUnitMIDIControlMapping', 'CAFChunkHeader', 'CGImagePropertyOrientation', 'CGPDFScanner', 'OpaqueMusicEventIterator', 'sfntDescriptorHeader', 'AudioUnitNodeConnection', 'OpaqueMIDIDeviceList', 'ExtendedAudioFormatInfo', 'BslnFormat1Part', 'sfntFontDescriptor', 'KernSimpleArrayHeader', '__CFRunLoopObserver', 'CGPatternTiling', 'MIDINotification', 'MorxLigatureSubtable', 'MessageComposeResult', 'MIDIThruConnectionEndpoint', 'MusicDeviceStdNoteParams', 'opaqueCMSimpleQueue', 'ALCcontext_struct', 'OpaqueAudioQueue', 'PropLookupSingle', 'CGInterpolationQuality', 'CGColor', 'AudioOutputUnitStartAtTimeParams', 'gss_name_t_desc_struct', 'CGFunctionCallbacks', 'CAFPacketTableHeader', 'AudioChannelDescription', 'sfntFeatureName', 'MorxContextualSubtable', 'CVSMPTETime', 'AudioValueRange', 'CGTextEncoding', 'AudioStreamBasicDescription', 'AUNodeRenderCallback', 'AudioPanningInfo', 'KerxOrderedListEntry', '__CFAllocator', 'OpaqueJSPropertyNameArray', '__SCDynamicStore', 'OpaqueMIDIEntity', '__CTRubyAnnotation', 'SCNVector4', 'CFHostClientContext', 'CFNetServiceClientContext', 'AudioUnitPresetMAS_SettingData', 'opaqueCMBufferQueueTriggerToken', 'AudioUnitProperty', 'CAFRegionChunk', 'CGPDFString', '__GLsync', '__CFStringTokenizer', 'JustWidthDeltaEntry', 'sfntVariationAxis', '__CFNetDiagnostic', 'CAFOverviewSample', 'sfntCMapEncoding', 'CGVector', '__SCNetworkService', 'opaqueCMSampleBuffer', 'AUHostVersionIdentifier', 'AudioBalanceFade', 'sfntFontRunFeature', 'KerxCoordinateAction', 'sfntCMapSubHeader', 'CVPlanarPixelBufferInfo', 'AUNumVersion', 'AUSamplerInstrumentData', 'AUPreset', '__CTRunDelegate', 'OpaqueAudioQueueProcessingTap', 'KerxTableHeader', '_NSZone', 'OpaqueExtAudioFile', '__CFRunLoopSource', '__CVMetalTextureCache', 'KerxAnchorPointAction', 'OpaqueJSString', 'AudioQueueParameterEvent', '__CFHTTPMessage', 'OpaqueCMClock', 'ScheduledAudioFileRegion', 'STEntryZero', 'AVAudio3DPoint', 'gss_channel_bindings_struct', 'sfntVariationHeader', 'AUChannelInfo', 'UIOffset', 'GLKEffectPropertyPrv', 'KerxStateHeader', 'CGLineJoin', 'CGPDFDocument', '__CFBag', 'KernOrderedListHeader', '__SCNetworkSet', '__SecKey', 'MIDIObjectAddRemoveNotification', 'AudioUnitParameter', 'JustPCActionSubrecord', 'AudioComponentDescription', 'AudioUnitParameterValueName', 'AudioUnitParameterEvent', 'KerxControlPointAction', 'AudioTimeStamp', 'KernKerningPair', 'gss_buffer_set_desc_struct', 'MortFeatureEntry', 'FontVariation', 'CAFStringID', 'LcarCaretClassEntry', 'AudioUnitParameterStringFromValue', 'ACErrorCode', 'ALMXGlyphEntry', 'LtagTable', '__CTTypesetter', 'AuthorizationOpaqueRef', 'UIEdgeInsets', 'CGPathElement', 'CAFMarker', 'KernTableHeader', 'NoteParamsControlValue', 'SSLContext', 'gss_cred_id_t_desc_struct', 'AudioUnitParameterNameInfo', 'CGDataConsumerCallbacks', 'ALMXHeader', 'CGLineCap', 'MIDIControlTransform', 'CGPDFArray', '__SecPolicy', 'AudioConverterPrimeInfo', '__CTTextTab', '__CFNetServiceMonitor', 'AUInputSamplesInOutputCallbackStruct', '__CTFramesetter', 'CGPDFDataFormat', 'STHeader', 'CVPlanarPixelBufferInfo_YCbCrPlanar', 'MIDIValueMap', 'JustDirectionTable', '__SCBondStatus', 'SFNTLookupSegmentHeader', 'OpaqueCMMemoryPool', 'CGPathDrawingMode', 'CGFont', '__SCNetworkReachability', 'AudioClassDescription', 'CGPoint', 'AVAudio3DVectorOrientation', 'CAFStrings', '__CFNetServiceBrowser', 'opaqueMTAudioProcessingTap', 'sfntNameRecord', 'CGPDFPage', 'CGLayer', 'ComponentInstanceRecord', 'CAFInfoStrings', 'HostCallbackInfo', 'MusicDeviceNoteParams', 'OpaqueVTCompressionSession', 'KernIndexArrayHeader', 'CVPlanarPixelBufferInfo_YCbCrBiPlanar', 'MusicTrackLoopInfo', 'opaqueCMFormatDescription', 'STClassTable', 'sfntDirectoryEntry', 'OpaqueCMTimebase', 'CGDataProviderDirectCallbacks', 'MIDIPacketList', 'CAFOverviewChunk', 'MIDIPacket', 'ScheduledAudioSlice', 'CGDataProviderSequentialCallbacks', 'AudioBuffer', 'MorxRearrangementSubtable', 'CGPatternCallbacks', 'AUDistanceAttenuationData', 'MIDIIOErrorNotification', 'CGPDFContentStream', 'IUnknownVTbl', 'MIDITransform', 'MortInsertionSubtable', 'CABarBeatTime', 'AudioBufferList', '__CVBuffer', 'AURenderCallbackStruct', 'STXEntryZero', 'JustPCDuctilityAction', 'OpaqueAudioQueueTimeline', 'VTDecompressionOutputCallbackRecord', 'OpaqueMIDIClient', '__CFPlugInInstance', 'AudioQueueBuffer', '__CFFileDescriptor', 'AudioUnitConnection', '_GKTurnBasedExchangeStatus', 'LcarCaretTable', 'CVPlanarComponentInfo', 'JustWidthDeltaGroup', 'OpaqueAudioComponent', 'ParameterEvent', '__CVPixelBufferPool', '__CTFont', 'CGColorSpace', 'CGSize', 'AUDependentParameter', 'MIDIDriverInterface', 'gss_krb5_rfc1964_keydata', '__CFDateFormatter', 'LtagStringRange', 'OpaqueVTDecompressionSession', 'gss_iov_buffer_desc_struct', 'AUPresetEvent', 'PropTable', 'KernOrderedListEntry', 'CF_BRIDGED_MUTABLE_TYPE', 'gss_OID_desc_struct', 'AudioUnitPresetMAS_Settings', 'AudioFileMarker', 'JustPCConditionalAddAction', 'BslnFormat3Part', '__CFNotificationCenter', 'MortSwashSubtable', 'AUParameterMIDIMapping', 'SCNVector3', 'OpaqueAudioConverter', 'MIDIRawData', 'sfntNameHeader', '__CFRunLoop', 'MFMailComposeResult', 'CATransform3D', 'OpbdSideValues', 'CAF_SMPTE_Time', '__SecAccessControl', 'JustPCAction', 'OpaqueVTFrameSilo', 'OpaqueVTMultiPassStorage', 'CGPathElementType', 'AudioFormatListItem', 'AudioUnitExternalBuffer', 'AudioFileRegion', 'AudioValueTranslation', 'CGImageMetadataTag', 'CAFPeakChunk', 'AudioBytePacketTranslation', 'sfntCMapHeader', '__CFURLEnumerator', 'STXHeader', 'CGPDFObjectType', 'SFNTLookupArrayHeader'} diff --git a/pygments/lexers/_lua_builtins.py b/pygments/lexers/_lua_builtins.py index ca3acb1c10..9186d081b5 100644 --- a/pygments/lexers/_lua_builtins.py +++ b/pygments/lexers/_lua_builtins.py @@ -13,8 +13,6 @@ :license: BSD, see LICENSE for details. """ -from __future__ import print_function - MODULES = {'basic': ('_G', '_VERSION', 'assert', @@ -288,7 +286,7 @@ def run(): print('>> %s' % full_function_name) m = get_function_module(full_function_name) modules.setdefault(m, []).append(full_function_name) - modules = {k: tuple(v) for k, v in modules.iteritems()} + modules = {k: tuple(v) for k, v in modules.items()} regenerate(__file__, modules) diff --git a/pygments/lexers/_mapping.py b/pygments/lexers/_mapping.py index 40189eff3b..f16b9a87bd 100644 --- a/pygments/lexers/_mapping.py +++ b/pygments/lexers/_mapping.py @@ -13,8 +13,6 @@ :license: BSD, see LICENSE for details. """ -from __future__ import print_function - LEXERS = { 'ABAPLexer': ('pygments.lexers.business', 'ABAP', ('abap',), ('*.abap', '*.ABAP'), ('text/x-abap',)), 'APLLexer': ('pygments.lexers.apl', 'APL', ('apl',), ('*.apl',), ()), diff --git a/pygments/lexers/_php_builtins.py b/pygments/lexers/_php_builtins.py index 44ef20530e..39a3905766 100644 --- a/pygments/lexers/_php_builtins.py +++ b/pygments/lexers/_php_builtins.py @@ -16,8 +16,6 @@ :license: BSD, see LICENSE for details. """ -from __future__ import print_function - MODULES = {'.NET': ('dotnet_load',), 'APC': ('apc_add', 'apc_bin_dump', diff --git a/pygments/lexers/_scilab_builtins.py b/pygments/lexers/_scilab_builtins.py index b26a00859d..4b6886f99d 100644 --- a/pygments/lexers/_scilab_builtins.py +++ b/pygments/lexers/_scilab_builtins.py @@ -3089,6 +3089,6 @@ def extract_completion(var_type): with open(__file__, 'w') as f: f.write(header) f.write('# Autogenerated\n\n') - for k, v in sorted(new_data.iteritems()): + for k, v in sorted(new_data.items()): f.write(format_lines(k + '_kw', v) + '\n\n') f.write(footer) diff --git a/pygments/lexers/_sourcemod_builtins.py b/pygments/lexers/_sourcemod_builtins.py index fa9671678e..8eb4597c78 100644 --- a/pygments/lexers/_sourcemod_builtins.py +++ b/pygments/lexers/_sourcemod_builtins.py @@ -12,8 +12,6 @@ :license: BSD, see LICENSE for details. """ -from __future__ import print_function - FUNCTIONS = ( 'OnEntityCreated', 'OnEntityDestroyed', diff --git a/pygments/lexers/css.py b/pygments/lexers/css.py index 4c77efe051..6209be0c2d 100644 --- a/pygments/lexers/css.py +++ b/pygments/lexers/css.py @@ -16,7 +16,6 @@ default, words, inherit from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ Number, Punctuation -from pygments.util import iteritems __all__ = ['CssLexer', 'SassLexer', 'ScssLexer', 'LessCssLexer'] @@ -612,7 +611,7 @@ class SassLexer(ExtendedRegexLexer): (r"\*/", Comment, '#pop'), ], } - for group, common in iteritems(common_sass_tokens): + for group, common in common_sass_tokens.items(): tokens[group] = copy.copy(common) tokens['value'].append((r'\n', Text, 'root')) tokens['selector'].append((r'\n', Text, 'root')) @@ -662,7 +661,7 @@ class ScssLexer(RegexLexer): (r"\*/", Comment, '#pop'), ], } - for group, common in iteritems(common_sass_tokens): + for group, common in common_sass_tokens.items(): tokens[group] = copy.copy(common) tokens['value'].extend([(r'\n', Text), (r'[;{}]', Punctuation, '#pop')]) tokens['selector'].extend([(r'\n', Text), (r'[;{}]', Punctuation, '#pop')]) diff --git a/pygments/lexers/dotnet.py b/pygments/lexers/dotnet.py index 458a9eb483..83946054a3 100644 --- a/pygments/lexers/dotnet.py +++ b/pygments/lexers/dotnet.py @@ -14,7 +14,7 @@ using, this, default, words from pygments.token import Punctuation, \ Text, Comment, Operator, Keyword, Name, String, Number, Literal, Other -from pygments.util import get_choice_opt, iteritems +from pygments.util import get_choice_opt from pygments import unistring as uni from pygments.lexers.html import XmlLexer @@ -71,7 +71,7 @@ class CSharpLexer(RegexLexer): tokens = {} token_variants = True - for levelname, cs_ident in iteritems(levels): + for levelname, cs_ident in levels.items(): tokens[levelname] = { 'root': [ # method names @@ -184,7 +184,7 @@ class NemerleLexer(RegexLexer): tokens = {} token_variants = True - for levelname, cs_ident in iteritems(levels): + for levelname, cs_ident in levels.items(): tokens[levelname] = { 'root': [ # method names diff --git a/pygments/lexers/javascript.py b/pygments/lexers/javascript.py index f290d84515..1dcf039fd2 100644 --- a/pygments/lexers/javascript.py +++ b/pygments/lexers/javascript.py @@ -15,7 +15,7 @@ this, words, combined from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ Number, Punctuation, Other -from pygments.util import get_bool_opt, iteritems +from pygments.util import get_bool_opt import pygments.unistring as uni __all__ = ['JavascriptLexer', 'KalLexer', 'LiveScriptLexer', 'DartLexer', @@ -767,9 +767,9 @@ def __init__(self, **options): self._members = set() if self.builtinshighlighting: from pygments.lexers._lasso_builtins import BUILTINS, MEMBERS - for key, value in iteritems(BUILTINS): + for key, value in BUILTINS.items(): self._builtins.update(value) - for key, value in iteritems(MEMBERS): + for key, value in MEMBERS.items(): self._members.update(value) RegexLexer.__init__(self, **options) diff --git a/pygments/lexers/php.py b/pygments/lexers/php.py index 680f0573da..4f06d216aa 100644 --- a/pygments/lexers/php.py +++ b/pygments/lexers/php.py @@ -15,8 +15,7 @@ this, words from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ Number, Punctuation, Other -from pygments.util import get_bool_opt, get_list_opt, iteritems, \ - shebang_matches +from pygments.util import get_bool_opt, get_list_opt, shebang_matches __all__ = ['ZephirLexer', 'PhpLexer'] @@ -245,7 +244,7 @@ def __init__(self, **options): self._functions = set() if self.funcnamehighlighting: from pygments.lexers._php_builtins import MODULES - for key, value in iteritems(MODULES): + for key, value in MODULES.items(): if key not in self.disabledmodules: self._functions.update(value) RegexLexer.__init__(self, **options) diff --git a/pygments/lexers/robotframework.py b/pygments/lexers/robotframework.py index 642c90c5c1..ddaddb22ea 100644 --- a/pygments/lexers/robotframework.py +++ b/pygments/lexers/robotframework.py @@ -27,7 +27,6 @@ from pygments.lexer import Lexer from pygments.token import Token -from pygments.util import text_type __all__ = ['RobotFrameworkLexer'] @@ -80,11 +79,11 @@ def get_tokens_unprocessed(self, text): for value, token in row_tokenizer.tokenize(row): for value, token in var_tokenizer.tokenize(value, token): if value: - yield index, token, text_type(value) + yield index, token, str(value) index += len(value) -class VariableTokenizer(object): +class VariableTokenizer: def tokenize(self, string, token): var = VariableSplitter(string, identifiers='$@%&') @@ -111,7 +110,7 @@ def _tokenize(self, var, string, orig_token): yield value, token -class RowTokenizer(object): +class RowTokenizer: def __init__(self): self._table = UnknownTable() @@ -159,7 +158,7 @@ def _tokenize(self, value, index, commented, separator, heading): yield value, token -class RowSplitter(object): +class RowSplitter: _space_splitter = re.compile('( {2,})') _pipe_splitter = re.compile(r'((?:^| +)\|(?: +|$))') @@ -185,7 +184,7 @@ def _split_from_pipes(self, row): yield rest -class Tokenizer(object): +class Tokenizer: _tokens = None def __init__(self): @@ -292,7 +291,7 @@ def _tokenize(self, value, index): return GherkinTokenizer().tokenize(value, KEYWORD) -class GherkinTokenizer(object): +class GherkinTokenizer: _gherkin_prefix = re.compile('^(Given|When|Then|And) ', re.IGNORECASE) def tokenize(self, value, token): @@ -320,7 +319,7 @@ def _tokenize(self, value, index): return token -class _Table(object): +class _Table: _tokenizer_class = None def __init__(self, prev_tokenizer=None): diff --git a/pygments/lexers/scripting.py b/pygments/lexers/scripting.py index 352f535fb7..a20c54bef8 100644 --- a/pygments/lexers/scripting.py +++ b/pygments/lexers/scripting.py @@ -15,7 +15,7 @@ words from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ Number, Punctuation, Error, Whitespace, Other -from pygments.util import get_bool_opt, get_list_opt, iteritems +from pygments.util import get_bool_opt, get_list_opt __all__ = ['LuaLexer', 'MoonScriptLexer', 'ChaiscriptLexer', 'LSLLexer', 'AppleScriptLexer', 'RexxLexer', 'MOOCodeLexer', 'HybrisLexer', @@ -142,7 +142,7 @@ def __init__(self, **options): self._functions = set() if self.func_name_highlighting: from pygments.lexers._lua_builtins import MODULES - for mod, func in iteritems(MODULES): + for mod, func in MODULES.items(): if mod not in self.disabled_modules: self._functions.update(func) RegexLexer.__init__(self, **options) diff --git a/pygments/lexers/special.py b/pygments/lexers/special.py index 4016c5949b..e97f194425 100644 --- a/pygments/lexers/special.py +++ b/pygments/lexers/special.py @@ -10,10 +10,11 @@ """ import re +from io import BytesIO from pygments.lexer import Lexer from pygments.token import Token, Error, Text -from pygments.util import get_choice_opt, text_type, BytesIO +from pygments.util import get_choice_opt __all__ = ['TextLexer', 'RawTokenLexer'] @@ -64,7 +65,7 @@ def __init__(self, **options): Lexer.__init__(self, **options) def get_tokens(self, text): - if isinstance(text, text_type): + if isinstance(text, str): # raw token stream never has any non-ASCII characters text = text.encode('ascii') if self.compress == 'gz': diff --git a/pygments/lexers/sql.py b/pygments/lexers/sql.py index afcaa6d4f7..0c45b14dcc 100644 --- a/pygments/lexers/sql.py +++ b/pygments/lexers/sql.py @@ -44,7 +44,6 @@ from pygments.token import Punctuation, Whitespace, Text, Comment, Operator, \ Keyword, Name, String, Number, Generic from pygments.lexers import get_lexer_by_name, ClassNotFound -from pygments.util import iteritems from pygments.lexers._postgres_builtins import KEYWORDS, DATATYPES, \ PSEUDO_TYPES, PLPGSQL_KEYWORDS @@ -106,7 +105,7 @@ def language_callback(lexer, match): yield (match.start(7), String, match.group(7)) -class PostgresBase(object): +class PostgresBase: """Base class for Postgres-related lexers. This is implemented as a mixin to avoid the Lexer metaclass kicking in. @@ -212,7 +211,7 @@ class PlPgsqlLexer(PostgresBase, RegexLexer): mimetypes = ['text/x-plpgsql'] flags = re.IGNORECASE - tokens = {k: l[:] for (k, l) in iteritems(PostgresLexer.tokens)} + tokens = {k: l[:] for (k, l) in PostgresLexer.tokens.items()} # extend the keywords list for i, pattern in enumerate(tokens['root']): @@ -246,7 +245,7 @@ class PsqlRegexLexer(PostgresBase, RegexLexer): aliases = [] # not public flags = re.IGNORECASE - tokens = {k: l[:] for (k, l) in iteritems(PostgresLexer.tokens)} + tokens = {k: l[:] for (k, l) in PostgresLexer.tokens.items()} tokens['root'].append( (r'\\[^\s]+', Keyword.Pseudo, 'psql-command')) @@ -271,7 +270,7 @@ class PsqlRegexLexer(PostgresBase, RegexLexer): r'FATAL|HINT|DETAIL|CONTEXT|LINE [0-9]+):)(.*?\n)') -class lookahead(object): +class lookahead: """Wrap an iterator and allow pushing back an item.""" def __init__(self, x): self.iter = iter(x) diff --git a/pygments/scanner.py b/pygments/scanner.py index bcb19ed9c6..c7f9ab50ad 100644 --- a/pygments/scanner.py +++ b/pygments/scanner.py @@ -25,7 +25,7 @@ class EndOfText(RuntimeError): """ -class Scanner(object): +class Scanner: """ Simple scanner diff --git a/pygments/sphinxext.py b/pygments/sphinxext.py index 282693e7e9..022548a62b 100644 --- a/pygments/sphinxext.py +++ b/pygments/sphinxext.py @@ -10,8 +10,6 @@ :license: BSD, see LICENSE for details. """ -from __future__ import print_function - import sys from docutils import nodes diff --git a/pygments/style.py b/pygments/style.py index 7326457774..8f50feb14c 100644 --- a/pygments/style.py +++ b/pygments/style.py @@ -10,7 +10,6 @@ """ from pygments.token import Token, STANDARD_TYPES -from pygments.util import add_metaclass # Default mapping of ansixxx to RGB colors. _ansimap = { @@ -169,8 +168,7 @@ def __len__(cls): return len(cls._styles) -@add_metaclass(StyleMeta) -class Style(object): +class Style(metaclass=StyleMeta): #: overall background color (``None`` means transparent) background_color = '#ffffff' diff --git a/pygments/unistring.py b/pygments/unistring.py index dd011cf0bf..466ebdb62e 100644 --- a/pygments/unistring.py +++ b/pygments/unistring.py @@ -156,10 +156,6 @@ def _handle_runs(char_list): # pragma: no cover if __name__ == '__main__': # pragma: no cover import unicodedata - # we need Py3 for the determination of the XID_* properties - if sys.version_info[:2] < (3, 3): - raise RuntimeError('this file must be regenerated with Python 3.3+') - categories_bmp = {'xid_start': [], 'xid_continue': []} categories_nonbmp = {'xid_start': [], 'xid_continue': []} diff --git a/pygments/util.py b/pygments/util.py index 59669d2b46..92e4f259ac 100644 --- a/pygments/util.py +++ b/pygments/util.py @@ -11,6 +11,7 @@ import re import sys +from io import TextIOWrapper split_path_re = re.compile(r'[/\\ ]') @@ -53,7 +54,7 @@ def get_bool_opt(options, optname, default=None): return string elif isinstance(string, int): return bool(string) - elif not isinstance(string, string_types): + elif not isinstance(string, str): raise OptionError('Invalid type %r for option %s; use ' '1/0, yes/no, true/false, on/off' % ( string, optname)) @@ -83,7 +84,7 @@ def get_int_opt(options, optname, default=None): def get_list_opt(options, optname, default=None): val = options.get(optname, default) - if isinstance(val, string_types): + if isinstance(val, str): return val.split() elif isinstance(val, (list, tuple)): return list(val) @@ -224,7 +225,7 @@ def unirange(a, b): if sys.maxunicode > 0xffff: # wide build - return u'[%s-%s]' % (unichr(a), unichr(b)) + return u'[%s-%s]' % (chr(a), chr(b)) else: # narrow build stores surrogates, and the 're' module handles them # (incorrectly) as characters. Since there is still ordering among @@ -232,24 +233,23 @@ def unirange(a, b): # background in http://bugs.python.org/issue3665 and # http://bugs.python.org/issue12749 # - # Additionally, the lower constants are using unichr rather than + # Additionally, the lower constants are using chr rather than # literals because jython [which uses the wide path] can't load this # file if they are literals. ah, al = _surrogatepair(a) bh, bl = _surrogatepair(b) if ah == bh: - return u'(?:%s[%s-%s])' % (unichr(ah), unichr(al), unichr(bl)) + return u'(?:%s[%s-%s])' % (chr(ah), chr(al), chr(bl)) else: buf = [] - buf.append(u'%s[%s-%s]' % - (unichr(ah), unichr(al), - ah == bh and unichr(bl) or unichr(0xdfff))) + buf.append(u'%s[%s-%s]' % (chr(ah), chr(al), + ah == bh and chr(bl) or chr(0xdfff))) if ah - bh > 1: buf.append(u'[%s-%s][%s-%s]' % - unichr(ah+1), unichr(bh-1), unichr(0xdc00), unichr(0xdfff)) + chr(ah+1), chr(bh-1), chr(0xdc00), chr(0xdfff)) if ah != bh: buf.append(u'%s[%s-%s]' % - (unichr(bh), unichr(0xdc00), unichr(bl))) + (chr(bh), chr(0xdc00), chr(bl))) return u'(?:' + u'|'.join(buf) + u')' @@ -289,7 +289,7 @@ def duplicates_removed(it, already_seen=()): return lst -class Future(object): +class Future: """Generic class to defer some work. Handled specially in RegexLexerMeta, to support regex string construction at @@ -345,44 +345,7 @@ def terminal_encoding(term): return locale.getpreferredencoding() -# Python 2/3 compatibility - -if sys.version_info < (3, 0): - unichr = unichr - xrange = xrange - string_types = (str, unicode) - text_type = unicode - u_prefix = 'u' - iteritems = dict.iteritems - itervalues = dict.itervalues - import StringIO - import cStringIO - # unfortunately, io.StringIO in Python 2 doesn't accept str at all - StringIO = StringIO.StringIO - BytesIO = cStringIO.StringIO -else: - unichr = chr - xrange = range - string_types = (str,) - text_type = str - u_prefix = '' - iteritems = dict.items - itervalues = dict.values - from io import StringIO, BytesIO, TextIOWrapper - - class UnclosingTextIOWrapper(TextIOWrapper): - # Don't close underlying buffer on destruction. - def close(self): - self.flush() - - -def add_metaclass(metaclass): - """Class decorator for creating a class with a metaclass.""" - def wrapper(cls): - orig_vars = cls.__dict__.copy() - orig_vars.pop('__dict__', None) - orig_vars.pop('__weakref__', None) - for slots_var in orig_vars.get('__slots__', ()): - orig_vars.pop(slots_var) - return metaclass(cls.__name__, cls.__bases__, orig_vars) - return wrapper +class UnclosingTextIOWrapper(TextIOWrapper): + # Don't close underlying buffer on destruction. + def close(self): + self.flush() diff --git a/scripts/check_sources.py b/scripts/check_sources.py index b1f3bccf07..571511920f 100755 --- a/scripts/check_sources.py +++ b/scripts/check_sources.py @@ -11,8 +11,6 @@ :license: BSD, see LICENSE for details. """ -from __future__ import print_function - import io import os import re diff --git a/scripts/debug_lexer.py b/scripts/debug_lexer.py index ef01a23f87..6963a5c0e2 100755 --- a/scripts/debug_lexer.py +++ b/scripts/debug_lexer.py @@ -12,8 +12,6 @@ :license: BSD, see LICENSE for details. """ -from __future__ import print_function - import os import sys diff --git a/scripts/detect_missing_analyse_text.py b/scripts/detect_missing_analyse_text.py index ab58558e7e..e9383421c4 100644 --- a/scripts/detect_missing_analyse_text.py +++ b/scripts/detect_missing_analyse_text.py @@ -1,4 +1,3 @@ -from __future__ import print_function import sys from pygments.lexers import get_all_lexers, find_lexer_class diff --git a/scripts/get_vimkw.py b/scripts/get_vimkw.py index a1b6873ec3..eecbc43f80 100644 --- a/scripts/get_vimkw.py +++ b/scripts/get_vimkw.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import re from pygments.util import format_lines diff --git a/scripts/vim2pygments.py b/scripts/vim2pygments.py index 42af0bbe14..50d69bc67c 100755 --- a/scripts/vim2pygments.py +++ b/scripts/vim2pygments.py @@ -11,8 +11,6 @@ :license: BSD, see LICENSE for details. """ -from __future__ import print_function - import sys import re from os import path @@ -863,7 +861,7 @@ def set(attrib, value): return default_token, color_map -class StyleWriter(object): +class StyleWriter: def __init__(self, code, name): self.code = code diff --git a/setup.py b/setup.py index 0c9f4f549d..62db3a562c 100755 --- a/setup.py +++ b/setup.py @@ -42,7 +42,7 @@ platforms = 'any', zip_safe = False, include_package_data = True, - python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*', + python_requires='>=3.5', classifiers = [ 'License :: OSI Approved :: BSD License', 'Intended Audience :: Developers', @@ -50,8 +50,6 @@ 'Intended Audience :: System Administrators', 'Development Status :: 6 - Mature', 'Programming Language :: Python', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', diff --git a/tests/test_basic_api.py b/tests/test_basic_api.py index 7d08c05ef5..7f71791e2e 100644 --- a/tests/test_basic_api.py +++ b/tests/test_basic_api.py @@ -7,9 +7,8 @@ :license: BSD, see LICENSE for details. """ -from __future__ import print_function - import random +from io import StringIO, BytesIO from os import path import pytest @@ -18,12 +17,12 @@ from pygments.token import _TokenType, Text from pygments.lexer import RegexLexer from pygments.formatters.img import FontNotFound -from pygments.util import text_type, StringIO, BytesIO, xrange, ClassNotFound +from pygments.util import ClassNotFound TESTDIR = path.dirname(path.abspath(__file__)) TESTFILE = path.join(TESTDIR, 'test_basic_api.py') -test_content = [chr(i) for i in xrange(33, 128)] * 5 +test_content = [chr(i) for i in range(33, 128)] * 5 random.shuffle(test_content) test_content = ''.join(test_content) + '\n' @@ -75,7 +74,7 @@ def test_random_input(cls): for token in tokens: assert isinstance(token, tuple) assert isinstance(token[0], _TokenType) - assert isinstance(token[1], text_type) + assert isinstance(token[1], str) txt += token[1] assert txt == test_content, "%s lexer roundtrip failed: %r != %r" % \ (cls.name, test_content, txt) @@ -176,7 +175,7 @@ def test_formatter_encodings(): fmt = HtmlFormatter() tokens = [(Text, u"ä")] out = format(tokens, fmt) - assert type(out) is text_type + assert type(out) is str assert u"ä" in out # encoding option @@ -206,7 +205,7 @@ def test_formatter_unicode_handling(cls): if cls.name != 'Raw tokens': out = format(tokens, inst) if cls.unicodeoutput: - assert type(out) is text_type, '%s: %r' % (cls, out) + assert type(out) is str, '%s: %r' % (cls, out) inst = cls(encoding='utf-8') out = format(tokens, inst) @@ -253,7 +252,7 @@ def test_bare_class_handler(): assert False, 'nothing raised' -class TestFilters(object): +class TestFilters: def test_basic(self): filters_args = [ @@ -272,7 +271,7 @@ def test_basic(self): with open(TESTFILE, 'rb') as fp: text = fp.read().decode('utf-8') tokens = list(lx.get_tokens(text)) - assert all(isinstance(t[1], text_type) for t in tokens), \ + assert all(isinstance(t[1], str) for t in tokens), \ '%s filter did not return Unicode' % x roundtext = ''.join([t[1] for t in tokens]) if x not in ('whitespace', 'keywordcase', 'gobble'): diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py index d56e2ae52f..b9b07c3cba 100644 --- a/tests/test_cmdline.py +++ b/tests/test_cmdline.py @@ -7,19 +7,17 @@ :license: BSD, see LICENSE for details. """ -from __future__ import print_function - import io import os import re import sys import tempfile +from io import BytesIO from os import path from pytest import raises from pygments import cmdline, highlight -from pygments.util import BytesIO, StringIO TESTDIR = path.dirname(path.abspath(__file__)) TESTFILE = path.join(TESTDIR, 'test_cmdline.py') @@ -41,17 +39,12 @@ def run_cmdline(*args, **kwds): saved_stdin = sys.stdin saved_stdout = sys.stdout saved_stderr = sys.stderr - if sys.version_info > (3,): - stdin_buffer = BytesIO() - stdout_buffer = BytesIO() - stderr_buffer = BytesIO() - new_stdin = sys.stdin = io.TextIOWrapper(stdin_buffer, 'utf-8') - new_stdout = sys.stdout = io.TextIOWrapper(stdout_buffer, 'utf-8') - new_stderr = sys.stderr = io.TextIOWrapper(stderr_buffer, 'utf-8') - else: - stdin_buffer = new_stdin = sys.stdin = StringIO() - stdout_buffer = new_stdout = sys.stdout = StringIO() - stderr_buffer = new_stderr = sys.stderr = StringIO() + stdin_buffer = BytesIO() + stdout_buffer = BytesIO() + stderr_buffer = BytesIO() + new_stdin = sys.stdin = io.TextIOWrapper(stdin_buffer, 'utf-8') + new_stdout = sys.stdout = io.TextIOWrapper(stdout_buffer, 'utf-8') + new_stderr = sys.stderr = io.TextIOWrapper(stderr_buffer, 'utf-8') new_stdin.write(kwds.get('stdin', '')) new_stdin.seek(0, 0) try: diff --git a/tests/test_crystal.py b/tests/test_crystal.py index f4909ac6aa..30177e410d 100644 --- a/tests/test_crystal.py +++ b/tests/test_crystal.py @@ -7,8 +7,6 @@ :license: BSD, see LICENSE for details. """ -from __future__ import unicode_literals - import pytest from pygments.token import Text, Operator, Keyword, Name, String, Number, \ diff --git a/tests/test_examplefiles.py b/tests/test_examplefiles.py index 491c1e0da4..2486f8767e 100644 --- a/tests/test_examplefiles.py +++ b/tests/test_examplefiles.py @@ -7,8 +7,6 @@ :license: BSD, see LICENSE for details. """ -from __future__ import print_function - import os import pprint import difflib diff --git a/tests/test_html_formatter.py b/tests/test_html_formatter.py index 952473986d..83b08e1f60 100644 --- a/tests/test_html_formatter.py +++ b/tests/test_html_formatter.py @@ -7,17 +7,15 @@ :license: BSD, see LICENSE for details. """ -from __future__ import print_function - import io import os import re import tempfile from os import path +from io import StringIO from pytest import raises -from pygments.util import StringIO from pygments.lexers import PythonLexer from pygments.formatters import HtmlFormatter, NullFormatter from pygments.formatters.html import escape_html diff --git a/tests/test_irc_formatter.py b/tests/test_irc_formatter.py index 046a0d19c7..af90731e40 100644 --- a/tests/test_irc_formatter.py +++ b/tests/test_irc_formatter.py @@ -7,9 +7,8 @@ :license: BSD, see LICENSE for details. """ -from __future__ import print_function +from io import StringIO -from pygments.util import StringIO from pygments.lexers import PythonLexer from pygments.formatters import IRCFormatter diff --git a/tests/test_latex_formatter.py b/tests/test_latex_formatter.py index 7ab0d7d079..2a1c911ea8 100644 --- a/tests/test_latex_formatter.py +++ b/tests/test_latex_formatter.py @@ -7,8 +7,6 @@ :license: BSD, see LICENSE for details. """ -from __future__ import print_function - import os import tempfile from os import path diff --git a/tests/test_modeline.py b/tests/test_modeline.py index b120694906..4d85a4361f 100644 --- a/tests/test_modeline.py +++ b/tests/test_modeline.py @@ -7,8 +7,6 @@ :license: BSD, see LICENSE for details. """ -from __future__ import print_function - from pygments import modeline diff --git a/tests/test_rtf_formatter.py b/tests/test_rtf_formatter.py index 35179df4d8..23d6695fc4 100644 --- a/tests/test_rtf_formatter.py +++ b/tests/test_rtf_formatter.py @@ -7,7 +7,8 @@ :license: BSD, see LICENSE for details. """ -from pygments.util import StringIO +from io import StringIO + from pygments.formatters import RtfFormatter from pygments.lexers.special import TextLexer diff --git a/tests/test_terminal_formatter.py b/tests/test_terminal_formatter.py index 98eab581df..02076f19cd 100644 --- a/tests/test_terminal_formatter.py +++ b/tests/test_terminal_formatter.py @@ -7,11 +7,9 @@ :license: BSD, see LICENSE for details. """ -from __future__ import print_function - import re +from io import StringIO -from pygments.util import StringIO from pygments.lexers.sql import PlPgsqlLexer from pygments.formatters import TerminalFormatter, Terminal256Formatter, \ HtmlFormatter, LatexFormatter diff --git a/tests/test_unistring.py b/tests/test_unistring.py index a4b58827ce..3a0acec97c 100644 --- a/tests/test_unistring.py +++ b/tests/test_unistring.py @@ -11,7 +11,6 @@ import random from pygments import unistring as uni -from pygments.util import unichr def test_cats_exist_and_compilable(): @@ -39,7 +38,7 @@ def test_spot_check_types(): random.seed(0) for i in range(1000): o = random.randint(0, 65535) - c = unichr(o) + c = chr(o) if o > 0xd800 and o <= 0xdfff and not uni.Cs: continue # Bah, Jython. print(hex(o)) diff --git a/tests/test_util.py b/tests/test_util.py index aa7b7acb89..94985a2539 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -14,7 +14,7 @@ from pygments import util, console -class FakeLexer(object): +class FakeLexer: def analyse(text): return text analyse = util.make_analysator(analyse) @@ -81,7 +81,7 @@ def test_analysator_returns_boolean(): def test_analysator_raises_exception(): # If an analysator wrapped by make_analysator raises an exception, # then the wrapper will return 0.0. - class ErrorLexer(object): + class ErrorLexer: def analyse(text): raise RuntimeError('something bad happened') analyse = util.make_analysator(analyse) @@ -193,17 +193,6 @@ class Term: assert s == (u'\xff', 'utf-8') -def test_add_metaclass(): - class Meta(type): - pass - - @util.add_metaclass(Meta) - class Cls: - pass - - assert type(Cls) is Meta - - def test_console_ansiformat(): f = console.ansiformat c = console.codes