diff -up build/pkgs/sagenb/src/sagenb/misc/support.py.orig build/pkgs/sagenb/src/sagenb/misc/support.py --- build/pkgs/sagenb/src/sagenb/misc/support.py.orig 2019-02-01 06:34:20.000000000 -0700 +++ build/pkgs/sagenb/src/sagenb/misc/support.py 2019-04-08 12:02:29.162692936 -0600 @@ -178,7 +178,7 @@ def completions(s, globs, format=False, try: if not '.' in s and not '(' in s: v = [x for x in globs.keys() if x[:n] == s] + \ - [x for x in __builtins__.keys() if x[:n] == s] + [x for x in builtins.keys() if x[:n] == s] else: if not ')' in s: i = s.rfind('.') diff -up build/pkgs/sagenb/src/sagenb/notebook/docHTMLProcessor.py.orig build/pkgs/sagenb/src/sagenb/notebook/docHTMLProcessor.py --- build/pkgs/sagenb/src/sagenb/notebook/docHTMLProcessor.py.orig 2019-02-01 05:37:36.000000000 -0700 +++ build/pkgs/sagenb/src/sagenb/notebook/docHTMLProcessor.py 2019-04-08 11:59:49.259545960 -0600 @@ -25,7 +25,7 @@ This module contains three classes: .. NOTE:: - This extension of htmllib.HTMLParser was partly inspired by Mark + This extension of html.parser.HTMLParser was partly inspired by Mark Pilgrim's 'Dive Into Python' examples. AUTHORS: @@ -155,7 +155,7 @@ class genericHTMLProcessor(HTMLParser): u'

Title

\n\n

nSome text

\n\n\n\n' """ - # self.feed() is a HTMLParser method and starts everything + # self.feed() is an HTMLParser method and starts everything # off; Most of the functions here are extensions to # HTMLParser, and may never actually be visibly called here. diff -up build/pkgs/sagenb/src/sagenb/notebook/wiki2html.py.orig build/pkgs/sagenb/src/sagenb/notebook/wiki2html.py --- build/pkgs/sagenb/src/sagenb/notebook/wiki2html.py.orig 2019-02-01 05:37:36.000000000 -0700 +++ build/pkgs/sagenb/src/sagenb/notebook/wiki2html.py 2019-04-08 11:59:49.260545943 -0600 @@ -59,7 +59,7 @@ class Parser: 'parent': r'(?:%s)?' % re.escape(PARENT_PREFIX), } url_rule = r'%(url_guard)s(%(url)s)\:([^\s\<%(punct)s]|([%(punct)s][^\s\<%(punct)s]))+' % { - 'url_guard': ur'(^|(?. ## -from __future__ import print_function import json import sys import time import re -import urllib +import urllib.request, urllib.parse, urllib.error import hashlib import os import os.path @@ -156,7 +155,7 @@ class RemoteSage: '\n*(?P.*)', re.DOTALL) self._404 = re.compile('404 Not Found') self._session = self._get_url('login', - urllib.urlencode({'username': user, + urllib.parse.urlencode({'username': user, 'password': password}))['session'] self._codewrap = """try: @@ -176,18 +175,18 @@ except: _p_.save(filename=plotfilename, **kwargs)""") def _encode(self, d): - return 'session={0}&'.format(self._session) + urllib.urlencode(d) + return 'session={0}&'.format(self._session) + urllib.parse.urlencode(d) def _get_url(self, action, u): - with closing(urllib.urlopen(self._srv + '/simple/' + action + - '?' + u)) as h: + with closing(urllib.request.urlopen(self._srv + '/simple/' + action + + '?' + u)) as h: data = self._response.match(h.read()) result = json.loads(data.group('header')) result['output'] = data.group('output').rstrip() return result def _get_file(self, fn, cell, ofn=None): - with closing(urllib.urlopen(self._srv + '/simple/' + 'file' + '?' + + with closing(urllib.request.urlopen(self._srv + '/simple/' + 'file' + '?' + self._encode({'cell': cell, 'file': fn}))) as h: myfn = ofn if ofn else fn data = h.read() @@ -277,13 +276,13 @@ if login_info_file: password = get_val(line) if not server: - server = raw_input('Enter server: ') + server = input('Enter server: ') if not server.startswith('http'): server = 'https://' + server if not username: - username = raw_input('Enter username: ') + username = input('Enter username: ') if not password: from getpass import getpass diff -up build/pkgs/sagetex/src/sagetexparse.py.orig build/pkgs/sagetex/src/sagetexparse.py --- build/pkgs/sagetex/src/sagetexparse.py.orig 2019-01-09 09:51:28.000000000 -0700 +++ build/pkgs/sagetex/src/sagetexparse.py 2019-09-10 12:24:06.752516723 -0600 @@ -132,7 +132,7 @@ class SageCodeExtractor(): def plotout(self, s, l, t): self.result += '# \\sageplot{} from line %s:\n' % lineno(l, s) - if t.format is not '': + if t.format != '': self.result += '# format: %s' % t.format[0][1:-1] + '\n' self.result += t.code[1:-1] + '\n\n' diff -up src/doc/common/conf.py.orig src/doc/common/conf.py --- src/doc/common/conf.py.orig 2019-06-26 14:41:04.000000000 -0600 +++ src/doc/common/conf.py 2019-06-27 11:33:54.099080488 -0600 @@ -566,7 +566,7 @@ skip_picklability_check_modules = [ #'sage.misc.nested_class_test', # for test only 'sage.misc.latex', 'sage.misc.explain_pickle', - '__builtin__', + 'builtins', ] def check_nested_class_picklability(app, what, name, obj, skip, options): @@ -615,7 +615,7 @@ def skip_member(app, what, name, obj, sk if 'SAGE_CHECK_NESTED' in os.environ: check_nested_class_picklability(app, what, name, obj, skip, options) - if getattr(obj, '__module__', None) == '__builtin__': + if getattr(obj, '__module__', None) == 'builtins': return True objname = getattr(obj, "__name__", None) diff -up src/sage/coding/linear_code.py.orig src/sage/coding/linear_code.py --- src/sage/coding/linear_code.py.orig 2019-06-26 14:41:04.000000000 -0600 +++ src/sage/coding/linear_code.py 2019-09-10 12:21:10.421332817 -0600 @@ -3793,7 +3793,7 @@ class LinearCode(AbstractLinearCode): [1 2 1] [2 1 1] """ - if encoder_name is None or encoder_name is 'GeneratorMatrix': + if encoder_name is None or encoder_name == 'GeneratorMatrix': g = self._generator_matrix else: g = super(LinearCode, self).generator_matrix(encoder_name, **kwargs) diff -up src/sage/combinat/finite_state_machine.py.orig src/sage/combinat/finite_state_machine.py --- src/sage/combinat/finite_state_machine.py.orig 2019-06-26 14:41:04.000000000 -0600 +++ src/sage/combinat/finite_state_machine.py 2019-06-27 11:36:38.804783269 -0600 @@ -936,7 +936,7 @@ from six.moves import range, zip_longest from six import itervalues from IPython.lib.pretty import pretty -import collections +import collections, collections.abc import itertools from copy import copy, deepcopy @@ -14207,7 +14207,7 @@ def is_FSMProcessIterator(PI): class FSMProcessIterator(SageObject, - collections.Iterator): + collections.abc.Iterator): """ This class takes an input, feeds it into a finite state machine (automaton or transducer, in particular), tests whether this was diff -up src/sage/combinat/multiset_partition_into_sets_ordered.py.orig src/sage/combinat/multiset_partition_into_sets_ordered.py --- src/sage/combinat/multiset_partition_into_sets_ordered.py.orig 2019-06-26 14:41:04.000000000 -0600 +++ src/sage/combinat/multiset_partition_into_sets_ordered.py 2019-09-10 12:20:47.787694285 -0600 @@ -1952,7 +1952,7 @@ class OrderedMultisetPartitionsIntoSets( # slice by 'order' if "alphabet" in fc: - no_alpha = {k: v for (k, v) in iteritems(self.constraints) if k is not "alphabet"} + no_alpha = {k: v for (k, v) in iteritems(self.constraints) if k != "alphabet"} return OrderedMultisetPartitionsIntoSets(fc["alphabet"], size, **no_alpha) # slice by 'size' diff -up src/sage/combinat/root_system/branching_rules.py.orig src/sage/combinat/root_system/branching_rules.py --- src/sage/combinat/root_system/branching_rules.py.orig 2019-06-26 14:41:04.000000000 -0600 +++ src/sage/combinat/root_system/branching_rules.py 2019-09-09 15:08:59.383139652 -0600 @@ -1750,7 +1750,7 @@ def branching_rule(Rtype, Stype, rule="d elif rule == "tensor" or rule == "tensor-debug": if not Stype.is_compound(): raise ValueError("Tensor product requires more than one factor") - if len(stypes) is not 2: + if len(stypes) != 2: raise ValueError("Not implemented") if Rtype[0] == 'A': nr = Rtype[1]+1 diff -up src/sage/cpython/dict_del_by_value.pyx.orig src/sage/cpython/dict_del_by_value.pyx --- src/sage/cpython/dict_del_by_value.pyx.orig 2019-06-26 14:41:04.000000000 -0600 +++ src/sage/cpython/dict_del_by_value.pyx 2019-09-09 15:32:24.921024261 -0600 @@ -291,7 +291,7 @@ ELIF PY_VERSION_HEX>=0x03060000: #general lookup function (which can deal with DKIX_DUMMY) PyDict_GetItemWithError(mp,None) #this can actually fail if mp is a dictionary with split table - assert DK_LOOKUP(mp) == lookdict + #assert DK_LOOKUP(mp) == lookdict cdef del_dictitem_by_exact_value(PyDictObject *mp, PyObject *value, Py_hash_t hash): """ @@ -347,8 +347,8 @@ ELIF PY_VERSION_HEX>=0x03060000: cdef MyPyDictKeysObject * keys = (mp.ma_keys) cdef size_t perturb cdef size_t mask = keys.dk_size-1 - cdef PyDictKeyEntry *entries, *ep - entries = DK_ENTRIES(keys) + cdef PyDictKeyEntry *ep + cdef PyDictKeyEntry *entries = DK_ENTRIES(keys) if mp.ma_values != NULL: print ("del_dictitem_by_exact_value cannot be applied to a shared key dict") diff -up src/sage/geometry/triangulation/point_configuration.py.orig src/sage/geometry/triangulation/point_configuration.py --- src/sage/geometry/triangulation/point_configuration.py.orig 2019-06-26 14:41:04.000000000 -0600 +++ src/sage/geometry/triangulation/point_configuration.py 2019-06-27 11:33:54.103080432 -0600 @@ -623,7 +623,7 @@ class PointConfiguration(UniqueRepresent ['{{0,1,2,4},{1,2,3,4}}'] """ timeout = 600 - proc = pexpect.spawn(executable, timeout=timeout) + proc = pexpect.spawn(executable, timeout=timeout, encoding='utf-8') proc.expect(r'Evaluating Commandline Options \.\.\.') proc.expect(r'\.\.\. done\.') proc.setecho(0) diff -up src/sage/graphs/graph_latex.py.orig src/sage/graphs/graph_latex.py --- src/sage/graphs/graph_latex.py.orig 2019-06-26 14:41:04.000000000 -0600 +++ src/sage/graphs/graph_latex.py 2019-09-10 12:23:28.891121378 -0600 @@ -1156,7 +1156,7 @@ class GraphLatex(SageObject): # elif name in color_dicts: if not isinstance(value, dict): - raise TypeError('%s option must be a dictionary, not %s' (name, value)) + raise TypeError('%s option must be a dictionary, not %s' % (name, value)) else: for key, c in value.items(): try: @@ -1165,42 +1165,42 @@ class GraphLatex(SageObject): raise ValueError('%s option for %s needs to be a matplotlib color (always as a string), not %s' % (name, key, c)) elif name in positive_scalar_dicts: if not isinstance(value, dict): - raise TypeError('%s option must be a dictionary, not %s' (name, value)) + raise TypeError('%s option must be a dictionary, not %s' % (name, value)) else: for key, x in value.items(): if not type(x) in [int, Integer, float, RealLiteral] or not x >= 0.0: raise ValueError('%s option for %s needs to be a positive number, not %s' % (name, key, x)) elif name in boolean_dicts: if not isinstance(value, dict): - raise TypeError('%s option must be a dictionary, not %s' (name, value)) + raise TypeError('%s option must be a dictionary, not %s' % (name, value)) else: for key, b in value.items(): if not isinstance(b, bool): raise ValueError('%s option for %s needs to be True or False, not %s' % (name, key, b)) elif name == 'vertex_shapes': if not isinstance(value, dict): - raise TypeError('%s option must be a dictionary, not %s' (name, value)) + raise TypeError('%s option must be a dictionary, not %s' % (name, value)) else: for key, s in value.items(): if s not in shape_names: raise ValueError('%s option for %s needs to be a vertex shape, not %s' % (name, key, s)) elif name == 'vertex_label_placements': if not isinstance(value, dict): - raise TypeError('%s option must be a dictionary, not %s' (name, value)) + raise TypeError('%s option must be a dictionary, not %s' % (name, value)) else: for key, p in value.items(): if not(p == 'center') and not(isinstance(p, tuple) and len(p) == 2 and type(p[0]) in number_types and p[0] >= 0 and type(p[1]) in number_types and p[1] >= 0): raise ValueError('%s option for %s needs to be None or a pair of positive numbers, not %s' % (name, key, p)) elif name == 'edge_label_placements': if not isinstance(value, dict): - raise TypeError('%s option must be a dictionary, not %s' (name, value)) + raise TypeError('%s option must be a dictionary, not %s' % (name, value)) else: for key, p in value.items(): if not(type(p) in [float, RealLiteral] and (0 <= p) and (p <= 1)) and not(p in label_places): raise ValueError('%s option for %s needs to be a number between 0.0 and 1.0 or a place (like "above"), not %s' % (name, key, p)) elif name == 'loop_placements': if not isinstance(value, dict): - raise TypeError('%s option must be a dictionary, not %s' (name, value)) + raise TypeError('%s option must be a dictionary, not %s' % (name, value)) else: for key, p in value.items(): if not((isinstance(p, tuple)) and (len(p) == 2) and (p[0] >= 0) and (p[1] in compass_points)): diff -up src/sage/interfaces/frobby.py.orig src/sage/interfaces/frobby.py --- src/sage/interfaces/frobby.py.orig 2019-06-26 14:41:04.000000000 -0600 +++ src/sage/interfaces/frobby.py 2019-06-27 11:33:54.103080432 -0600 @@ -77,7 +77,7 @@ class Frobby: print("Frobby command: ", repr(command)) print("Frobby input:\n", input) - process = Popen(command, stdin = PIPE, stdout = PIPE, stderr = PIPE) + process = Popen(command, stdin = PIPE, stdout = PIPE, stderr = PIPE, encoding='utf-8') output, err = process.communicate(input = input) if verbose: diff -up src/sage/interfaces/gfan.py.orig src/sage/interfaces/gfan.py --- src/sage/interfaces/gfan.py.orig 2019-06-26 14:41:04.000000000 -0600 +++ src/sage/interfaces/gfan.py 2019-06-27 11:33:54.104080419 -0600 @@ -66,7 +66,7 @@ class Gfan(object): if six.PY2: enc_kwargs = {} else: - enc_kwargs = {'encoding': 'latin-1'} + enc_kwargs = {'encoding': 'utf-8'} gfan_processes = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, **enc_kwargs) diff -up src/sage/interfaces/gp.py.orig src/sage/interfaces/gp.py --- src/sage/interfaces/gp.py.orig 2019-06-26 14:41:04.000000000 -0600 +++ src/sage/interfaces/gp.py 2019-06-27 11:33:54.104080419 -0600 @@ -934,17 +934,6 @@ class GpElement(ExpectElement): """ return repr(self.type()) == 't_STR' - def __long__(self): - """ - Return Python long. - - EXAMPLES:: - - sage: long(gp(10)) - 10L - """ - return long(str(self)) - def __float__(self): """ Return Python float. diff -up src/sage/interfaces/latte.py.orig src/sage/interfaces/latte.py --- src/sage/interfaces/latte.py.orig 2019-06-26 14:41:04.000000000 -0600 +++ src/sage/interfaces/latte.py 2019-06-27 11:33:54.104080419 -0600 @@ -148,6 +148,7 @@ def count(arg, ehrhart_polynomial=False, latte_proc = Popen(args, stdin=PIPE, stdout=PIPE, stderr=(None if verbose else PIPE), + encoding='utf-8', cwd=str(SAGE_TMP)) ans, err = latte_proc.communicate(arg) @@ -355,6 +356,7 @@ def integrate(arg, polynomial=None, algo latte_proc = Popen(args, stdin=PIPE, stdout=PIPE, stderr=(None if verbose else PIPE), + encoding='utf-8', cwd=str(SAGE_TMP)) ans, err = latte_proc.communicate(arg) diff -up src/sage/interfaces/sagespawn.pyx.orig src/sage/interfaces/sagespawn.pyx --- src/sage/interfaces/sagespawn.pyx.orig 2019-06-26 14:41:04.000000000 -0600 +++ src/sage/interfaces/sagespawn.pyx 2019-06-27 11:33:54.104080419 -0600 @@ -1,6 +1,6 @@ """ Sage wrapper around pexpect's ``spawn`` class and -the ptyprocess's ``PtyProcess`` class. +the ptyprocess's ``PtyProcessUnicode`` class. AUTHOR: @@ -21,7 +21,7 @@ AUTHOR: #***************************************************************************** from pexpect import * -from ptyprocess import PtyProcess +from ptyprocess import PtyProcessUnicode from cpython.ref cimport Py_INCREF from libc.signal cimport * @@ -30,7 +30,6 @@ from posix.unistd cimport getpid, getpgi from time import sleep -from sage.cpython.string cimport str_to_bytes from sage.interfaces.process cimport ContainChildren @@ -171,7 +170,7 @@ class SageSpawn(spawn): return ret -class SagePtyProcess(PtyProcess): +class SagePtyProcess(PtyProcessUnicode): def close(self, force=None): """ Quit the child process: send the quit string, close the @@ -192,11 +191,7 @@ class SagePtyProcess(PtyProcess): if self.quit_string is not None: try: # This can fail if the process already exited - # PtyProcess.write takes bytes; ideally we would use - # an encoding picked specifically for the target process - # but the default (UTF-8) will do now, since I don't - # think we have any non-ASCII quit_strings anyways. - self.write(str_to_bytes(self.quit_string)) + self.write(self.quit_string) except (OSError, IOError): pass self.fileobj.close() diff -up src/sage/libs/coxeter3/coxeter.pyx.orig src/sage/libs/coxeter3/coxeter.pyx --- src/sage/libs/coxeter3/coxeter.pyx.orig 2019-06-26 14:41:05.000000000 -0600 +++ src/sage/libs/coxeter3/coxeter.pyx 2019-09-12 14:57:59.755712128 -0600 @@ -32,7 +32,7 @@ cdef class String: EXAMPLES:: sage: from sage.libs.coxeter3.coxeter import String # optional - coxeter3 - sage: s = String("hello"); s # optional - coxeter3 + sage: s = String(b"hello"); s # optional - coxeter3 hello sage: del s # optional - coxeter3 """ @@ -43,11 +43,11 @@ cdef class String: EXAMPLES:: sage: from sage.libs.coxeter3.coxeter import String # optional - coxeter3 - sage: s = String('Hi') # optional - coxeter3 + sage: s = String(b'Hi') # optional - coxeter3 sage: s # optional - coxeter3 Hi """ - return self.x.ptr() + return self.x.ptr().decode('utf-8') def __hash__(self): """ @@ -59,7 +59,7 @@ cdef class String: EXAMPLES:: sage: from sage.libs.coxeter3.coxeter import String # optional - coxeter3 - sage: s = String('hello') # optional - coxeter3 + sage: s = String(b'hello') # optional - coxeter3 sage: hash(s) == hash('hello') # optional - coxeter3 True """ @@ -70,9 +70,9 @@ cdef class String: EXAMPLES:: sage: from sage.libs.coxeter3.coxeter import String # optional - coxeter3 - sage: ta1 = String('A') # optional - coxeter3 - sage: ta2 = String('A') # optional - coxeter3 - sage: tb = String('b') # optional - coxeter3 + sage: ta1 = String(b'A') # optional - coxeter3 + sage: ta2 = String(b'A') # optional - coxeter3 + sage: tb = String(b'b') # optional - coxeter3 sage: ta1 == ta2 # optional - coxeter3 True sage: tb != ta1 # optional - coxeter3 @@ -108,7 +108,7 @@ cdef class String: EXAMPLES:: sage: from sage.libs.coxeter3.coxeter import String # optional - coxeter3 - sage: s = String('Hi') # optional - coxeter3 + sage: s = String(b'Hi') # optional - coxeter3 sage: len(s) # optional - coxeter3 2 """ @@ -119,7 +119,7 @@ cdef class String: EXAMPLES:: sage: from sage.libs.coxeter3.coxeter import String # optional - coxeter3 - sage: s = String('Hi') # optional - coxeter3 + sage: s = String(b'Hi') # optional - coxeter3 sage: TestSuite(s).run() # optional - coxeter3 """ return (String, (repr(self),) ) @@ -133,7 +133,7 @@ cdef class Type: EXAMPLES:: sage: from sage.libs.coxeter3.coxeter import Type # optional - coxeter3 - sage: t = Type('A'); t # optional - coxeter3 + sage: t = Type(b'A'); t # optional - coxeter3 A sage: del t # optional - coxeter3 """ @@ -144,17 +144,17 @@ cdef class Type: EXAMPLES:: sage: from sage.libs.coxeter3.coxeter import Type # optional - coxeter3 - sage: t = Type('A'); t # optional - coxeter3 + sage: t = Type(b'A'); t # optional - coxeter3 A """ - return self.x.name().ptr() + return self.x.name().ptr().decode('utf-8') def name(self): """ EXAMPLES:: sage: from sage.libs.coxeter3.coxeter import Type # optional - coxeter3 - sage: t = Type('A') # optional - coxeter3 + sage: t = Type(b'A') # optional - coxeter3 sage: t.name() # optional - coxeter3 A """ @@ -170,8 +170,8 @@ cdef class Type: EXAMPLES:: sage: from sage.libs.coxeter3.coxeter import Type # optional - coxeter3 - sage: a = Type('A') # optional - coxeter3 - sage: b = Type('B') # optional - coxeter3 + sage: a = Type(b'A') # optional - coxeter3 + sage: b = Type(b'B') # optional - coxeter3 sage: hash(a) == hash(b) # optional - coxeter3 False sage: d = {a: 1, b: 2} # optional - coxeter3 @@ -183,9 +183,9 @@ cdef class Type: EXAMPLES:: sage: from sage.libs.coxeter3.coxeter import Type # optional - coxeter3 - sage: ta1 = Type('A') # optional - coxeter3 - sage: ta2 = Type('A') # optional - coxeter3 - sage: tb = Type('b') # optional - coxeter3 + sage: ta1 = Type(b'A') # optional - coxeter3 + sage: ta2 = Type(b'A') # optional - coxeter3 + sage: tb = Type(b'b') # optional - coxeter3 sage: ta1 == ta2 # optional - coxeter3 True sage: tb != ta1 # optional - coxeter3 @@ -219,7 +219,7 @@ cdef class Type: EXAMPLES:: sage: from sage.libs.coxeter3.coxeter import Type # optional - coxeter3 - sage: t = Type('A') # optional - coxeter3 + sage: t = Type(b'A') # optional - coxeter3 sage: TestSuite(t).run() # optional - coxeter3 """ return (Type, (repr(self), )) @@ -256,7 +256,7 @@ cdef class CoxGroup(SageObject): type = type.lower() rank = rank + 1 - type = 'B' if type == 'C' else type + type = b'B' if type == 'C' else type.encode('utf-8') if rank == 0: raise NotImplementedError("Coxeter group of type ['A',0] using Coxeter 3 not yet implemented") diff -up src/sage/misc/parser.pyx.orig src/sage/misc/parser.pyx --- src/sage/misc/parser.pyx.orig 2019-06-26 14:41:05.000000000 -0600 +++ src/sage/misc/parser.pyx 2019-06-27 11:33:54.105080405 -0600 @@ -96,7 +96,7 @@ def token_to_str(int token): cdef inline bint is_alphanumeric(char c): - return 'a' <= c <= 'z' or 'A' <= c <= 'Z' or '0' <= c <= '9' or c == '_' + return c'a' <= c <= c'z' or c'A' <= c <= c'Z' or c'0' <= c <= c'9' or c == c'_' cdef inline bint is_whitespace(char c): return (c != 0) & (strchr(" \t\n\r", c) != NULL) @@ -247,23 +247,23 @@ cdef class Tokenizer: return EOS # dipthongs - if s[pos+1] == '=': - if s[pos] == '<': + if s[pos+1] == c'=': + if s[pos] == c'<': self.pos += 2 return LESS_EQ - elif s[pos] == '>': + elif s[pos] == c'>': self.pos += 2 return GREATER_EQ - elif s[pos] == '!': + elif s[pos] == c'!': self.pos += 2 return NOT_EQ - elif s[pos] == '=': + elif s[pos] == c'=': self.pos += 2 - return '=' + return c'=' - elif s[pos] == '*' and s[pos+1] == '*': + elif s[pos] == c'*' and s[pos+1] == c'*': self.pos += 2 - return '^' + return c'^' # simple tokens if strchr("+-*/^()=<>,[]{}!", s[pos]): @@ -272,29 +272,29 @@ cdef class Tokenizer: return type # numeric literals - if '0' <= s[pos] <= '9' or s[pos] == '.': + if c'0' <= s[pos] <= c'9' or s[pos] == c'.': type = INT seen_exp = False seen_decimal = False while True: - if '0' <= s[pos] <= '9': + if c'0' <= s[pos] <= c'9': pass - elif s[pos] == '.': + elif s[pos] == c'.': if seen_decimal or seen_exp: self.pos = pos return type else: type = FLOAT seen_decimal = True - elif s[pos] == 'e' or s[pos] == 'E': + elif s[pos] == c'e' or s[pos] == c'E': if seen_exp: self.pos = pos return type else: type = FLOAT seen_exp = True - elif s[pos] == '+' or s[pos] == '-': - if not (seen_exp and (s[pos-1] == 'e' or s[pos-1] == 'E')): + elif s[pos] == c'+' or s[pos] == c'-': + if not (seen_exp and (s[pos-1] == c'e' or s[pos-1] == c'E')): self.pos = pos return type else: @@ -573,13 +573,13 @@ cdef class Parser: """ cdef int token all = [] - if tokens.next() == '(': - token = ',' - while token == ',': + if tokens.next() == c'(': + token = c',' + while token == c',': all.append(self.p_list(tokens)) token = tokens.next() - if token == ')': + if token == c')': from sage.matrix.constructor import matrix return matrix(all) else: @@ -601,8 +601,8 @@ cdef class Parser: [(1, 2, 3), [a + 1, b + 2, c + 3, (d + 4,)]] """ all = [] - cdef int token = ',' - while token == ',': + cdef int token = c',' + while token == c',': token = tokens.peek() if token == MATRIX: tokens.next() @@ -615,14 +615,14 @@ cdef class Parser: else: tokens.backtrack() obj = self.p_eqn(tokens) - elif token == '[': + elif token == c'[': obj = self.p_list(tokens) - elif token == '(': + elif token == c'(': obj = self.p_tuple(tokens) elif token == EOS: return all - elif token == ']' or token == ')': - tokens.token = ',' + elif token == c']' or token == c')': + tokens.token = c',' return all else: obj = self.p_eqn(tokens) @@ -646,11 +646,11 @@ cdef class Parser: [] """ cdef int token = tokens.next() - if token != '[': + if token != c'[': self.parse_error(tokens, "Malformed list") all = self.p_sequence(tokens) token = tokens.next() - if token != ']': + if token != c']': self.parse_error(tokens, "Malformed list") return all @@ -668,20 +668,20 @@ cdef class Parser: cdef int start = tokens.pos cdef int token = tokens.next() cdef bint real_tuple = True - if token != '(': + if token != c'(': self.parse_error(tokens, "Malformed tuple") all = self.p_sequence(tokens) if len(all) == 1: if tokens.last() != c',': real_tuple = False token = tokens.next() - if token != ')': + if token != c')': self.parse_error(tokens, "Malformed tuple") if real_tuple: return tuple(all) else: token = tokens.peek() - if token == ',' or token == EOS: + if token == c',' or token == EOS: return all[0] else: # we have to reparse the entire thing as an expression @@ -717,15 +717,15 @@ cdef class Parser: """ lhs = self.p_expr(tokens) cdef int op = tokens.next() - if op == '=': + if op == c'=': return lhs == self.p_expr(tokens) elif op == NOT_EQ: return lhs != self.p_expr(tokens) - elif op == '<': + elif op == c'<': return lhs < self.p_expr(tokens) elif op == LESS_EQ: return lhs <= self.p_expr(tokens) - elif op == '>': + elif op == c'>': return lhs > self.p_expr(tokens) elif op == GREATER_EQ: return lhs >= self.p_expr(tokens) @@ -757,9 +757,9 @@ cdef class Parser: cdef int op operand1 = self.p_term(tokens) op = tokens.next() - while op == '+' or op == '-': + while op == c'+' or op == c'-': operand2 = self.p_term(tokens) - if op == '+': + if op == c'+': operand1 = operand1 + operand2 else: operand1 = operand1 - operand2 @@ -792,17 +792,17 @@ cdef class Parser: operand1 = self.p_factor(tokens) op = tokens.next() if op == NAME and self.implicit_multiplication: - op = '*' + op = c'*' tokens.backtrack() - while op == '*' or op == '/': + while op == c'*' or op == c'/': operand2 = self.p_factor(tokens) - if op == '*': + if op == c'*': operand1 = operand1 * operand2 else: operand1 = operand1 / operand2 op = tokens.next() if op == NAME and self.implicit_multiplication: - op = '*' + op = c'*' tokens.backtrack() tokens.backtrack() return operand1 @@ -826,9 +826,9 @@ cdef class Parser: t^11 """ cdef int token = tokens.next() - if token == '+': + if token == c'+': return self.p_factor(tokens) - elif token == '-': + elif token == c'-': return -self.p_factor(tokens) else: tokens.backtrack() @@ -862,13 +862,13 @@ cdef class Parser: """ operand1 = self.p_atom(tokens) cdef int token = tokens.next() - if token == '^': + if token == c'^': operand2 = self.p_factor(tokens) return operand1 ** operand2 - elif token == "!": + elif token == c'!': from sage.functions.all import factorial operand1 = factorial(operand1) - if tokens.peek() == '^': + if tokens.peek() == c'^': tokens.next() operand2 = self.p_factor(tokens) return operand1 ** operand2 @@ -913,20 +913,20 @@ cdef class Parser: elif token == NAME: name = tokens.last_token_string() token = tokens.next() - if token == '(': + if token == c'(': func = self.callable_constructor(name) args, kwds = self.p_args(tokens) token = tokens.next() - if token != ')': + if token != c')': self.parse_error(tokens, "Bad function call") return func(*args, **kwds) else: tokens.backtrack() return self.variable_constructor(name) - elif token == '(': + elif token == c'(': expr = self.p_expr(tokens) token = tokens.next() - if token != ')': + if token != c')': self.parse_error(tokens, "Mismatched parentheses") return expr else: @@ -948,10 +948,10 @@ cdef class Parser: """ args = [] kwds = {} - if tokens.peek() == ')': + if tokens.peek() == c')': return args, kwds - cdef int token = ',' - while token == ',': + cdef int token = c',' + while token == c',': arg = self.p_arg(tokens) if isinstance(arg, tuple): name, value = arg @@ -993,11 +993,11 @@ cdef class Parser: """ cdef int token = tokens.next() - if token == NAME and tokens.peek() == '=': + if token == NAME and tokens.peek() == c'=': name = tokens.last_token_string() tokens.next() return name, self.p_expr(tokens) - if token == "[" : + if token == c'[' : tokens.backtrack() return self.p_list(tokens) else: diff -up src/sage/modular/abvar/abvar.py.orig src/sage/modular/abvar/abvar.py --- src/sage/modular/abvar/abvar.py.orig 2019-06-26 14:41:05.000000000 -0600 +++ src/sage/modular/abvar/abvar.py 2019-09-09 15:08:24.875810751 -0600 @@ -3703,7 +3703,7 @@ class ModularAbelianVariety_abstract(Par C = self.__complement except AttributeError: pass - if self.dimension() is 0: + if self.dimension() == 0: if A is None: C = self.ambient_variety() else: diff -up src/sage/plot/plot3d/plot3d.py.orig src/sage/plot/plot3d/plot3d.py --- src/sage/plot/plot3d/plot3d.py.orig 2019-06-26 14:41:05.000000000 -0600 +++ src/sage/plot/plot3d/plot3d.py 2019-06-27 11:33:54.105080405 -0600 @@ -188,7 +188,8 @@ class _Coordinates(object): sage: arb((x+z,y*z,z), z, (x,y)) Arbitrary Coordinates coordinate transform (z in terms of x, y) """ - all_vars = sage_getargspec(self.transform).args[1:] + args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, ann = inspect.getfullargspec(self.transform) + all_vars=args[1:] if set(all_vars) != set(indep_vars + [dep_var]): raise ValueError('variables were specified incorrectly for this coordinate system; incorrect variables were %s'%list(set(all_vars).symmetric_difference(set(indep_vars+[dep_var])))) self.dep_var = dep_var diff -up src/sage/plot/point.py.orig src/sage/plot/point.py --- src/sage/plot/point.py.orig 2019-06-26 14:41:05.000000000 -0600 +++ src/sage/plot/point.py 2019-06-27 11:33:54.105080405 -0600 @@ -29,7 +29,7 @@ TESTS:: from sage.misc.decorators import options, rename_keyword from sage.plot.colors import to_mpl_color from sage.plot.primitive import GraphicPrimitive_xydata -import collections +import collections.abc # TODO: create _allowed_options for 3D point classes to @@ -343,7 +343,7 @@ def point(points, **kwds): sage: point(iter([(1,2),(3,5)])) Graphics object consisting of 1 graphics primitive """ - if isinstance(points, collections.Iterator): + if isinstance(points, collections.abc.Iterator): points = list(points) try: diff -up src/sage/repl/display/fancy_repr.py.orig src/sage/repl/display/fancy_repr.py --- src/sage/repl/display/fancy_repr.py.orig 2019-06-26 14:41:05.000000000 -0600 +++ src/sage/repl/display/fancy_repr.py 2019-06-27 11:33:54.106080391 -0600 @@ -15,7 +15,7 @@ Representations of objects. import types from IPython.lib.pretty import ( - _safe_getattr, _baseclass_reprs, + _safe_getattr, _type_pprinters, ) @@ -264,7 +264,7 @@ class PlainPythonRepr(ObjectReprABC): """ klass = _safe_getattr(obj, '__class__', None) or type(obj) klass_repr = _safe_getattr(klass, '__repr__', None) - if klass_repr in _baseclass_reprs: + if klass_repr is object.__repr__: p.text(klass_repr(obj)) else: # A user-provided repr. Find newlines and replace them with p.break_() diff -up src/sage/repl/ipython_kernel/interact.py.orig src/sage/repl/ipython_kernel/interact.py --- src/sage/repl/ipython_kernel/interact.py.orig 2019-06-26 14:41:05.000000000 -0600 +++ src/sage/repl/ipython_kernel/interact.py 2019-06-27 11:33:54.106080391 -0600 @@ -35,7 +35,8 @@ EXAMPLES:: from ipywidgets.widgets import SelectionSlider, ValueWidget, ToggleButtons from ipywidgets.widgets.interaction import interactive, signature -from collections import Iterable, Iterator, OrderedDict +from collections.abc import Iterable, Iterator +from collections import OrderedDict from .widgets import EvalText, SageColorPicker from .widgets_sagenb import input_grid from sage.structure.element import parent diff -up src/sage/rings/integer.pyx.orig src/sage/rings/integer.pyx --- src/sage/rings/integer.pyx.orig 2019-06-26 14:41:05.000000000 -0600 +++ src/sage/rings/integer.pyx 2019-06-27 11:33:54.107080377 -0600 @@ -6989,7 +6989,7 @@ cdef int mpz_set_str_python(mpz_ptr z, c while x[0] == c' ': x += 1 # Strip spaces # Disallow a sign here - if x[0] == '-' or x[0] == '+': + if x[0] == c'-' or x[0] == c'+': x = "" # Force an error below assert base >= 2 diff -up src/sage/rings/multi_power_series_ring_element.py.orig src/sage/rings/multi_power_series_ring_element.py --- src/sage/rings/multi_power_series_ring_element.py.orig 2019-06-26 14:41:05.000000000 -0600 +++ src/sage/rings/multi_power_series_ring_element.py 2019-09-09 15:01:45.746217568 -0600 @@ -1417,7 +1417,7 @@ class MPowerSeries(PowerSeries): # at this stage, self is probably a non-zero # element of the base ring for a in range(len(self._bg_value.list())): - if self._bg_value.list()[a] is not 0: + if self._bg_value.list()[a] != 0: return a def is_nilpotent(self): diff -up src/sage/rings/polynomial/pbori.pyx.orig src/sage/rings/polynomial/pbori.pyx --- src/sage/rings/polynomial/pbori.pyx.orig 2019-06-26 14:41:05.000000000 -0600 +++ src/sage/rings/polynomial/pbori.pyx 2019-06-27 11:33:54.123080154 -0600 @@ -4765,8 +4765,7 @@ cdef class PolynomialConstruct: # So, it is just a conversion. [Simon King] return (ring)._element_constructor_(x) - raise TypeError("Cannot generate Boolean polynomial from %s , %s%" % - (type(x), type(ring))) + raise TypeError(f"Cannot generate Boolean polynomial from {type(x)}, {type(ring)}") cdef class MonomialConstruct: diff -up src/sage/rings/real_mpfi.pyx.orig src/sage/rings/real_mpfi.pyx --- src/sage/rings/real_mpfi.pyx.orig 2019-06-26 14:41:05.000000000 -0600 +++ src/sage/rings/real_mpfi.pyx 2019-06-27 11:33:54.124080141 -0600 @@ -1943,12 +1943,12 @@ cdef class RealIntervalFieldElement(Ring cdef long digits digits = strlen(lower_s) - if lower_s[0] == '-': + if lower_s[0] == c'-': digits -= 1 lower_expo -= digits digits = strlen(upper_s) - if upper_s[0] == '-': + if upper_s[0] == c'-': digits -= 1 upper_expo -= digits @@ -2117,7 +2117,7 @@ cdef class RealIntervalFieldElement(Ring raise MemoryError("Unable to allocate memory for the mantissa of an interval") mpz_get_str(tmp_cstr, base, lower_mpz) digits = strlen(tmp_cstr) - if tmp_cstr[0] == '-': + if tmp_cstr[0] == c'-': digits -= 1 mant_string = bytes_to_str(tmp_cstr+1) sign_string = bytes_to_str(b'-') diff -up src/sage/rings/real_mpfr.pyx.orig src/sage/rings/real_mpfr.pyx --- src/sage/rings/real_mpfr.pyx.orig 2019-06-26 14:41:05.000000000 -0600 +++ src/sage/rings/real_mpfr.pyx 2019-06-27 11:33:54.125080127 -0600 @@ -2039,7 +2039,7 @@ cdef class RealNumber(sage.structure.ele if s is NULL: raise RuntimeError("unable to convert an mpfr number to a string") # t contains just digits (no sign, decimal point or exponent) - if s[0] == '-': + if s[0] == c'-': sgn = "-" t = char_to_str(s + 1) else: diff -up src/sage/structure/sage_object.pyx.orig src/sage/structure/sage_object.pyx --- src/sage/structure/sage_object.pyx.orig 2019-06-26 14:41:05.000000000 -0600 +++ src/sage/structure/sage_object.pyx 2019-06-27 11:33:54.126080113 -0600 @@ -665,7 +665,7 @@ cdef class SageObject: try: s = self._interface_init_(I) except Exception: - raise NotImplementedError("coercion of object %s to %s not implemented:\n%s\n%s" % (repr(self), I)) + raise NotImplementedError(f"coercion of object {repr(self)} to {I} not implemented") X = I(s) if c: try: diff -up src/sage/symbolic/expression.pyx.orig src/sage/symbolic/expression.pyx --- src/sage/symbolic/expression.pyx.orig 2019-06-26 14:41:05.000000000 -0600 +++ src/sage/symbolic/expression.pyx 2019-06-27 11:33:54.128080085 -0600 @@ -12960,7 +12960,7 @@ cdef class hold_class: sage: SR(2)^5 32 """ - g_set_state('hold', True) + g_set_state(b'hold', True) def __exit__(self, *args): """ @@ -12973,7 +12973,7 @@ cdef class hold_class: sage: SR(2)^5 32 """ - g_set_state('hold', False) + g_set_state(b'hold', False) def start(self): """ diff -up src/setup.py.orig src/setup.py --- src/setup.py.orig 2019-06-27 11:30:20.794201914 -0600 +++ src/setup.py 2019-06-27 11:33:54.128080085 -0600 @@ -232,7 +232,7 @@ class sage_build_cython(Command): cdivision=True, embedsignature=True, fast_getattr=True, - language_level="2", + language_level=3, preliminary_late_includes_cy28=True, profile=self.profile, )