Repository: sympy/sympy

Issue:
make ray intersection more robust
The intersection of two rays is being rejected:

```
def bisectors(p, prec=None):
    """Return angle bisectors of a polygon. If prec is given
    then approximate the point defining the ray to that precision.

    The distance between the points defining the bisector ray is 1.

    Examples
    ========

    >>> from sympy import Polygon, Point
    >>> p = Polygon(Point(0, 0), Point(2, 0), Point(1, 1), Point(0, 3)
    >>> for k, v in bisectors(p,2).items():
    ...     print (k, v)
    ...
    (Point2D(2, 0), Ray2D(Point2D(2, 0), Point2D(1.1, 0.38)))
    (Point2D(0, 3), Ray2D(Point2D(0, 3), Point2D(0.23, 2.0)))
    (Point2D(0, 0), Ray2D(Point2D(0, 0), Point2D(0.71, 0.71)))
    (Point2D(1, 1), Ray2D(Point2D(1, 1), Point2D(0.19, 0.42)))
    """
    b = {}
    pts = list(p.args)
    pts.append(pts[0])  # close it
    for v, a in p.angles.items():
        i = pts.index(v)
        ray = Ray(pts[i], pts[i + 1]).rotate(a/2, v)
        # normalize so distance from p1 to p2 is 1
        dir = ray.direction
        ray = Ray(ray.p1, ray.p1 + dir/dir.distance((0,0)))
        if prec is not None:
            ray = Ray(ray.p1, ray.p2.n(prec))
        b[v] = ray
    return b

p=Polygon((0,0),(3,0),(4,10),(0,1))
b = bisectors(p, 2)
for s in p.sides:
 r1, r2 = [b[i] for i in s.args]
 s.args, r1.intersection(r2), Line(r1).intersection(Line(r2))
```
Output is:
```
((Point2D(0, 0), Point2D(3, 0)), [Point2D(1.6, 1.6)], [Point2D(1.6, 1.6)])
((Point2D(3, 0), Point2D(4, 10)), [], [Point2D(1.7, 1.4)])
((Point2D(0, 1), Point2D(4, 10)), [], [Point2D(1.5, 0.68)])
((Point2D(0, 0), Point2D(0, 1)), [], [Point2D(0.82, 0.82)])
```

(The last 3 should have given ray intersection identical to the Line-wrapped ray intersections.)

Discussion:

Patch:
diff --git a/.mailmap b/.mailmap
index ef894343dd..1443f929a6 100644
--- a/.mailmap
+++ b/.mailmap
@@ -64,8 +64,14 @@
 *Marc-Etienne M.Leveille <protonyc@gmail.com>
 *Ulrich Hecht <ulrich.hecht@gmail.com>
 2torus <boris.ettinger@gmail.com>
+<abrombo@verizon.net> <brombo@GA.(none)>
+<aterrel@uchicago.edu> <andy.terrel@gmail.com>
+<aterrel@uchicago.edu> <aterrel@enthought.com>
 <felix.kaiser@fxkr.net> <kaiser.fx@gmail.com>
+<felix.kaiser@fxkr.net> <whatfxkr@gmail.com>
 <fredrik.johansson@gmail.com> <fredrik@airy.(none)>
+<jnebos@gmail.com> Jurjen N.E. Bos <devnull@localhost>
+<jo@durchholz.org> <toolforger@durchholz.org>
 Aadit Kamat <aadit.k12@gmail.com>
 Aaditya Nair <aadityanair6494@gmail.com>
 Aaron Meurer <asmeurer@gmail.com>
@@ -119,8 +125,6 @@ Akshay Siramdas <akshaysiramdas@gmail.com>
 Akshay Srinivasan <akshaysrinivasan@gmail.com>
 Akshit Agarwal <akshit.jiit@gmail.com>
 AkuBrain <76952313+Franck2111@users.noreply.github.com>
-Alan Bromborsky <abrombo@verizon.net> <abrombo@verizon.net>
-Alan Bromborsky <abrombo@verizon.net> <brombo@GA.(none)>
 Alec Kalinin <alec.kalinin@gmail.com>
 Aleksandar Makelov <amakelov@college.harvard.edu>
 Alex Argunov <sajkoooo@gmail.com>
@@ -170,10 +174,6 @@ Andrew Straw <strawman@astraw.com>
 Andrew Taber <andrew.e.taber@gmail.com>
 Andrey Grozin <A.G.Grozin@inp.nsk.su>
 Andrey Lekar <andrey_lekar@adoriasoft.com> blackyblack <andrey_lekar@adoriasoft.com>
-Andy R. Terrel <aterrel@uchicago.edu> <andy.terrel@gmail.com>
-Andy R. Terrel <aterrel@uchicago.edu> <aterrel@enthought.com>
-Andy R. Terrel <aterrel@uchicago.edu> <aterrel@uchicago.edu>
-Andy R. Terrel <aterrel@uchicago.edu> <aterrel@uchicago.edu>
 Angad Sandhu <55819847+angadsinghsandhu@users.noreply.github.com>
 Angadh Nanjangud <angadh.n@gmail.com>
 Angus Griffith <16sn6uv@gmail.com>
@@ -356,7 +356,6 @@ Dhruv Kothari <dhruvkothari22@gmail.com>
 Dhruv Mendiratta <dhruvmendiratta6@gmail.com> Dhruv Mendiratta <42745880+dhruvmendiratta6@users.noreply.github.com>
 Dhruv Mendiratta <dhruvmendiratta6@gmail.com> dhruvmendiratta6 <dhruvmendiratta6@gmail.com>
 Dhruvesh Vijay Parikh <parikhdhruvesh1@gmail.com>
-Diane Tchuindjo <dtchuindjo@gmail.com>
 Dimas Abreu Archanjo Dutra <dimasad@ufmg.br>
 Dimitra Konomi <t8130064@dias.aueb.gr>
 Divyanshu Thakur <divyanshu@iiitmanipur.ac.in> Divyanshu <divyanshu@iiitmanipur.ac.in>
@@ -399,8 +398,6 @@ Fabian Pedregosa <fabian@fseoane.net> <fabian@debian.(none)>
 Faisal Anees <faisal.iiit@gmail.com>
 Faisal Riyaz <faisalriyaz011@gmail.com>
 Fawaz Alazemi <Mba7eth@gmail.com>
-Felix Kaiser <felix.kaiser@fxkr.net> <felix.kaiser@fxkr.net>
-Felix Kaiser <felix.kaiser@fxkr.net> <whatfxkr@gmail.com>
 Felix Yan <felixonmars@archlinux.org>
 Fermi Paradox <FermiParadox@users.noreply.github.com>
 Fernando Perez <Fernando.Perez@berkeley.edu>
@@ -543,7 +540,6 @@ Jens Jørgen Mortensen <jj@smoerhul.dk>
 Jeremey Gluck <jeremygluck@yahoo.com>
 Jeremias Yehdegho <j.yehdegho@gmail.com> <aevirex@aleph.(none)>
 Jeremy <twobitlogic@gmail.com>
-Jeremy Monat <jemonat@calalum.org>
 Jerry James <loganjerry@gmail.com>
 Jerry Li <jerry@jerryli.ca>
 Jezreel Ng <jezreel@gmail.com>
@@ -555,8 +551,6 @@ Jiri Kuncar <jiri.kuncar@gmail.com>
 Jisoo Song <jeesoo9595@snu.ac.kr> JSS95 <52185322+JSS95@users.noreply.github.com>
 Jisoo Song <jeesoo9595@snu.ac.kr> mcpl-sympy <59268464+mcpl-sympy@users.noreply.github.com>
 Jithin D. George <jithindgeorge93@gmail.com>
-Joachim Durchholz <jo@durchholz.org> <jo@durchholz.org>
-Joachim Durchholz <jo@durchholz.org> <toolforger@durchholz.org>
 Joan Creus <joan.creus.c@gmail.com>
 Joannah Nanjekye <joannah.nanjekye@ibm.com> Joannah Nanjekye <jnanjekye@python.org>
 Joannah Nanjekye <joannah.nanjekye@ibm.com> nanjekyejoannah <joannah.nanjekye@ibm.com>
@@ -592,8 +586,6 @@ Julien Palard <julien@palard.fr>
 Julien Rioux <julien.rioux@gmail.com>
 Julio Idichekop Filho <idichekop@yahoo.com.br>
 Jun Lin <junlin0604@gmail.com> wate123 <junlin0604@gmail.com>
-Jurjen N.E. Bos <jnebos@gmail.com> <jnebos@gmail.com>
-Jurjen N.E. Bos <jnebos@gmail.com> Jurjen N.E. Bos <devnull@localhost>
 Justin Blythe <jblythe29@gmail.com>
 Ka Yi <chua.kayi@yahoo.com.sg>
 Kaifeng Zhu <cafeeee@gmail.com>
@@ -793,7 +785,7 @@ Nicolas Pourcelot <nicolas.pourcelot@gmail.com>
 Nicolás Guarín-Zapata <nicoguarin@gmail.com>
 Nihir Agarwal <f20180701@pilani.bits-pilani.ac.in>
 Nijso Beishuizen <nijso@koolmees.numerically-related.com>
-Nikhil Date <nikhil.s.date@gmail.com> NikhilSDate <47920034+NikhilSDate@users.noreply.github.com>
+Nikhil Date <nikhil.s.date@gmail.com>
 Nikhil Gopalam <gopalamn@umich.edu> gopalamn <gopalamn@umich.edu>
 Nikhil Maan <nikhilmaan22@gmail.com> Nikhil Maan <nikhilman22@gmail.com>
 Nikhil Pappu <nkhlpappu@gmail.com>
@@ -1137,7 +1129,6 @@ Timothy Reluga <treluga@math.psu.edu> me <none@none>
 TitanSnow <sweeto@live.cn>
 Tobias Lenz <t_lenz94@web.de>
 Tom Bachmann <e_mc_h2@web.de> <ness987@googlemail.com>
-Tom Fryers <61272761+TomFryers@users.noreply.github.com>
 Tom Gijselinck <tomgijselinck@gmail.com>
 Tomasz Buchert <thinred@gmail.com>
 Tomasz Pytel <tompytel@gmail.com>
@@ -1220,7 +1211,6 @@ Zeel Shah <kshah215@gmail.com>
 Zhi-Qiang Zhou <zzq_890709@hotmail.com> zhouzq-thu <zzq_890709@hotmail.com>
 Zhongshi <zj495@nyu.edu>
 Zlatan Vasović <zlatanvasovic@gmail.com>
-Zouhair <zouhair.mahboubi@gmail.com>
 Zulfikar <zulfikar97@gmail.com>
 abhinav28071999 <41710346+abhinav28071999@users.noreply.github.com>
 adhoc-king <46354827+adhoc-king@users.noreply.github.com>
@@ -1290,7 +1280,6 @@ sfoo <sfoohei@gmail.com>
 sharma-kunal <kunalsharma6914@gmail.com>
 shiksha11 <shiksharawat01@gmail.com> shiksha11 <33157995+shiksha11@users.noreply.github.com>
 shruti <shrutishrm512@gmail.com>
-shubhayu09 <guptashubhayu601@gmail.com> shubhayu09 <87441886+shubhayu09@users.noreply.github.com>
 sirnicolaf <43586954+sirnicolaf@users.noreply.github.com>
 slacker404 <pchantza@gmail.com>
 soumi7 <soumibardhan10@gmail.com>
@@ -1306,7 +1295,6 @@ wuyudi <wuyudi119@163.com>
 ylemkimon <ylemkimon@naver.com> <mail@ylem.kim>
 znxftw <vishnu2101@gmail.com>
 zsc347 <zsc347@gmail.com>
-zzj <29055749+zjzh@users.noreply.github.com>
 Óscar Nájera <najera.oscar@gmail.com>
 Øyvind Jensen <jensen.oyvind@gmail.com>
 Łukasz Pankowski <lukpank@o2.pl>
diff --git a/README.md b/README.md
index 3c3bb8fa0b..db5a0e2304 100644
--- a/README.md
+++ b/README.md
@@ -9,14 +9,14 @@
 [![SymPy Banner](https://github.com/sympy/sympy/raw/master/banner.svg)](https://sympy.org/)
 
 
-See the [AUTHORS](AUTHORS) file for the list of authors.
+See the AUTHORS file for the list of authors.
 
 And many more people helped on the SymPy mailing list, reported bugs,
 helped organize SymPy's participation in the Google Summer of Code, the
 Google Highly Open Participation Contest, Google Code-In, wrote and
 blogged about SymPy...
 
-License: New BSD License (see the [LICENSE](LICENSE) file for details) covers all
+License: New BSD License (see the LICENSE file for details) covers all
 files in the sympy repository unless stated otherwise.
 
 Our mailing list is at
diff --git a/bin/mailmap_check.py b/bin/mailmap_check.py
deleted file mode 100755
index cb76501a04..0000000000
--- a/bin/mailmap_check.py
+++ /dev/null
@@ -1,300 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-"""
-A tool to generate AUTHORS. We started tracking authors before moving to git,
-so we have to do some manual rearrangement of the git history authors in order
-to get the order in AUTHORS. bin/mailmap_check.py should be run before
-committing the results.
-
-See here for instructions on using this script:
-https://github.com/sympy/sympy/wiki/Development-workflow#update-mailmap
-"""
-
-from __future__ import unicode_literals
-from __future__ import print_function
-
-import sys
-import os
-from pathlib import Path
-from subprocess import run, PIPE
-from collections import OrderedDict, defaultdict
-from argparse import ArgumentParser
-
-if sys.version_info < (3, 7):
-    sys.exit("This script requires Python 3.7 or newer")
-
-def sympy_dir():
-    return Path(__file__).resolve().parent.parent
-
-# put sympy on the path
-sys.path.insert(0, str(sympy_dir()))
-import sympy
-from sympy.utilities.misc import filldedent
-from sympy.external.importtools import version_tuple
-
-
-def main(*args):
-
-    parser = ArgumentParser(description='Update the .mailmap and/or AUTHORS files')
-    parser.add_argument('--update-authors', action='store_true',
-            help=filldedent("""
-            Also update the AUTHORS file. Note that it
-            should only necessary for the release manager to do this as part of
-            the release process for SymPy."""))
-    args = parser.parse_args(args)
-
-    if not check_git_version():
-        return 1
-
-    # find who git knows ahout
-    try:
-        git_people = get_authors_from_git()
-    except AssertionError as msg:
-        print(red(msg))
-        return 1
-
-    lines_mailmap = read_lines(mailmap_path())
-
-    def key(line):
-        # return lower case first address on line or
-        # raise an error if not an entry
-        if '#' in line:
-            line = line.split('#')[0]
-        L, R = line.count("<"), line.count(">")
-        assert L == R and L in (1, 2)
-        return line.split(">", 1)[0].split("<")[1].lower()
-
-    who = OrderedDict()
-    for i, line in enumerate(lines_mailmap):
-        try:
-            who.setdefault(key(line), []).append(line)
-        except AssertionError:
-            who[i] = [line]
-
-    problems = False
-    missing = False
-    ambiguous = False
-    dups = defaultdict(list)
-
-    for person in git_people:
-        email = key(person)
-        dups[email].append(person)
-        if email not in who:
-            print(red("This author is not included in the .mailmap file:"))
-            print(person)
-            missing = True
-        elif not any(p.startswith(person) for p in who[email]):
-            print(red("Ambiguous names in .mailmap"))
-            print(red("This email address appears for multiple entries:"))
-            print('Person:', person)
-            print('Mailmap entries:')
-            for line in who[email]:
-                print(line)
-            ambiguous = True
-
-    if missing:
-        print(red(filldedent("""
-        The .mailmap file needs to be updated because there are commits with
-        unrecognised author/email metadata.
-        """)))
-        problems = True
-
-    if ambiguous:
-        print(red(filldedent("""
-        Lines should be added to .mailmap to indicate the correct name and
-        email aliases for all commits.
-        """)))
-        problems = True
-
-    for email, commitauthors in dups.items():
-        if len(commitauthors) > 2:
-            print(red(filldedent("""
-            The following commits are recorded with different metadata but the
-            same/ambiguous email address. The .mailmap file will need to be
-            updated.""")))
-            for author in commitauthors:
-                print(author)
-            problems = True
-
-    lines_mailmap_sorted = sort_lines_mailmap(lines_mailmap)
-    write_lines(mailmap_path(), lines_mailmap_sorted)
-
-    if lines_mailmap_sorted != lines_mailmap:
-        problems = True
-        print(red("The mailmap file was reordered"))
-
-    if problems:
-        print(red(filldedent("""
-        For instructions on updating the .mailmap file see:
-        https://github.com/sympy/sympy/wiki/Development-workflow#update-mailmap""")))
-    else:
-        print(green("No changes needed in .mailmap"))
-
-    # Check if changes to AUTHORS file are also needed
-    lines_authors = make_authors_file_lines(git_people)
-    old_lines_authors = read_lines(authors_path())
-    update_authors_file(lines_authors, old_lines_authors, args.update_authors)
-
-    return int(problems)
-
-
-def update_authors_file(lines, old_lines, update_yesno):
-
-    if old_lines == lines:
-        print(green('No changes needed in AUTHORS.'))
-        return 0
-
-    # Actually write changes to the file?
-    if update_yesno:
-        write_lines(authors_path(), lines)
-        print(red("Changes were made in the authors file"))
-
-    # check for new additions
-    new_authors = []
-    for i in sorted(set(lines) - set(old_lines)):
-        try:
-            author_name(i)
-            new_authors.append(i)
-        except AssertionError:
-            continue
-
-    if new_authors:
-        if update_yesno:
-            print(yellow("The following authors were added to AUTHORS."))
-        else:
-            print(green(filldedent("""
-                The following authors will be added to the AUTHORS file at the
-                time of the next SymPy release.""")))
-        print()
-        for i in sorted(new_authors, key=lambda x: x.lower()):
-            print('\t%s' % i)
-
-
-def check_git_version():
-    # check git version
-    minimal = '1.8.4.2'
-    git_ver = run(['git', '--version'], stdout=PIPE, encoding='utf-8').stdout[12:]
-    if version_tuple(git_ver) < version_tuple(minimal):
-        print(yellow("Please use a git version >= %s" % minimal))
-        return False
-    else:
-        return True
-
-
-def authors_path():
-    return sympy_dir() / 'AUTHORS'
-
-
-def mailmap_path():
-    return sympy_dir() / '.mailmap'
-
-
-def red(text):
-    return "\033[31m%s\033[0m" % text
-
-
-def yellow(text):
-    return "\033[33m%s\033[0m" % text
-
-
-def green(text):
-    return "\033[32m%s\033[0m" % text
-
-
-def author_name(line):
-    assert line.count("<") == line.count(">") == 1
-    assert line.endswith(">")
-    return line.split("<", 1)[0].strip()
-
-
-def get_authors_from_git():
-    git_command = ["git", "log", "--topo-order", "--reverse", "--format=%aN <%aE>"]
-    git_people = run(git_command, stdout=PIPE, encoding='utf-8').stdout.strip().split("\n")
-
-    # remove duplicates, keeping the original order
-    git_people = list(OrderedDict.fromkeys(git_people))
-
-    # Do the few changes necessary in order to reproduce AUTHORS:
-    def move(l, i1, i2, who):
-        x = l.pop(i1)
-        # this will fail if the .mailmap is not right
-        assert who == author_name(x), \
-            '%s was not found at line %i' % (who, i1)
-        l.insert(i2, x)
-
-    move(git_people, 2, 0, 'Ondřej Čertík')
-    move(git_people, 42, 1, 'Fabian Pedregosa')
-    move(git_people, 22, 2, 'Jurjen N.E. Bos')
-    git_people.insert(4, "*Marc-Etienne M.Leveille <protonyc@gmail.com>")
-    move(git_people, 10, 5, 'Brian Jorgensen')
-    git_people.insert(11, "*Ulrich Hecht <ulrich.hecht@gmail.com>")
-    # this will fail if the .mailmap is not right
-    assert 'Kirill Smelkov' == author_name(git_people.pop(12)
-        ), 'Kirill Smelkov was not found at line 12'
-    move(git_people, 12, 32, 'Sebastian Krämer')
-    move(git_people, 227, 35, 'Case Van Horsen')
-    git_people.insert(43, "*Dan <coolg49964@gmail.com>")
-    move(git_people, 57, 59, 'Aaron Meurer')
-    move(git_people, 58, 57, 'Andrew Docherty')
-    move(git_people, 67, 66, 'Chris Smith')
-    move(git_people, 79, 76, 'Kevin Goodsell')
-    git_people.insert(84, "*Chu-Ching Huang <cchuang@mail.cgu.edu.tw>")
-    move(git_people, 93, 92, 'James Pearson')
-    # this will fail if the .mailmap is not right
-    assert 'Sergey B Kirpichev' == author_name(git_people.pop(226)
-        ), 'Sergey B Kirpichev was not found at line 226.'
-
-    index = git_people.index(
-        "azure-pipelines[bot] " +
-        "<azure-pipelines[bot]@users.noreply.github.com>")
-    git_people.pop(index)
-    index = git_people.index(
-        "whitesource-bolt-for-github[bot] " +
-        "<whitesource-bolt-for-github[bot]@users.noreply.github.com>")
-    git_people.pop(index)
-
-    return git_people
-
-
-def make_authors_file_lines(git_people):
-    # define new lines for the file
-    header = filldedent("""
-        All people who contributed to SymPy by sending at least a patch or
-        more (in the order of the date of their first contribution), except
-        those who explicitly didn't want to be mentioned. People with a * next
-        to their names are not found in the metadata of the git history. This
-        file is generated automatically by running `./bin/authors_update.py`.
-        """).lstrip()
-    header_extra = f"There are a total of {len(git_people)} authors."""
-    lines = header.splitlines()
-    lines.append('')
-    lines.append(header_extra)
-    lines.append('')
-    lines.extend(git_people)
-    return lines
-
-
-def sort_lines_mailmap(lines):
-    for n, line in enumerate(lines):
-        if not line.startswith('#'):
-            header_end = n
-            break
-    header = lines[:header_end]
-    mailmap_lines = lines[header_end:]
-    return header + sorted(mailmap_lines)
-
-
-def read_lines(path):
-    with open(path) as fin:
-        return [line.strip() for line in fin.readlines()]
-
-
-def write_lines(path, lines):
-    with open(path, 'w') as fout:
-        fout.write('\n'.join(lines))
-        fout.write('\n')
-
-
-if __name__ == "__main__":
-    import sys
-    sys.exit(main(*sys.argv[1:]))
diff --git a/sympy/core/basic.py b/sympy/core/basic.py
index 8e7db29a6e..1b509f47ad 100644
--- a/sympy/core/basic.py
+++ b/sympy/core/basic.py
@@ -7,14 +7,14 @@
 from .assumptions import ManagedProperties
 from .cache import cacheit
 from .core import BasicMeta
-from .sympify import _sympify, sympify, SympifyError, _external_converter
+from .sympify import _sympify, sympify, SympifyError
 from .sorting import ordered
 from .kind import Kind, UndefinedKind
 from ._print_helpers import Printable
 
 from sympy.utilities.decorator import deprecated
 from sympy.utilities.exceptions import SymPyDeprecationWarning
-from sympy.utilities.iterables import iterable, numbered_symbols
+from sympy.utilities.iterables import iterable, numbered_symbols, NotIterable
 from sympy.utilities.misc import filldedent, func_name
 
 from inspect import getmro
@@ -319,25 +319,6 @@ def inner_key(arg):
         args = len(args), tuple([inner_key(arg) for arg in args])
         return self.class_key(), args, S.One.sort_key(), S.One
 
-    def _do_eq_sympify(self, other):
-        """Returns a boolean indicating whether a == b when either a
-        or b is not a Basic. This is only done for types that were either
-        added to `converter` by a 3rd party or when the object has `_sympy_`
-        defined. This essentially reuses the code in `_sympify` that is
-        specific for this use case. Non-user defined types that are meant
-        to work with SymPy should be handled directly in the __eq__ methods
-        of the `Basic` classes it could equate to and not be converted. Note
-        that after conversion, `==`  is used again since it is not
-        neccesarily clear whether `self` or `other`'s __eq__ method needs
-        to be used."""
-        for superclass in type(other).__mro__:
-            conv = _external_converter.get(superclass)
-            if conv is not None:
-                return self == conv(other)
-        if hasattr(other, '_sympy_'):
-            return self == other._sympy_()
-        return NotImplemented
-
     def __eq__(self, other):
         """Return a boolean indicating whether a == b on the basis of
         their symbolic trees.
@@ -363,7 +344,16 @@ def __eq__(self, other):
             return True
 
         if not isinstance(other, Basic):
-            return self._do_eq_sympify(other)
+            if iterable(other, exclude=(str, NotIterable)
+                    ) and not hasattr(other, '_sympy_'):
+                # XXX iterable self should have it's own __eq__
+                # method if the path gives a false negative
+                # comparison
+                return False
+            try:
+                other = _sympify(other)
+            except (SympifyError, SyntaxError):
+                return NotImplemented
 
         # check for pure number expr
         if  not (self.is_Number and other.is_Number) and (
diff --git a/sympy/core/containers.py b/sympy/core/containers.py
index aabcedfa5b..b5a8186a9d 100644
--- a/sympy/core/containers.py
+++ b/sympy/core/containers.py
@@ -12,7 +12,7 @@
 
 from .basic import Basic
 from .sorting import default_sort_key, ordered
-from .sympify import _sympify, sympify, _sympy_converter, SympifyError
+from .sympify import _sympify, sympify, converter, SympifyError
 from sympy.utilities.iterables import iterable
 from sympy.utilities.misc import as_int
 
@@ -145,7 +145,7 @@ def index(self, value, start=None, stop=None):
             return self.args.index(value, start, stop)
 
 
-_sympy_converter[tuple] = lambda tup: Tuple(*tup)
+converter[tuple] = lambda tup: Tuple(*tup)
 
 
 
@@ -302,7 +302,7 @@ def __eq__(self, other):
     __hash__ : Callable[[Basic], Any] = Basic.__hash__
 
 # this handles dict, defaultdict, OrderedDict
-_sympy_converter[dict] = lambda d: Dict(*d.items())
+converter[dict] = lambda d: Dict(*d.items())
 
 class OrderedSet(MutableSet):
     def __init__(self, iterable=None):
diff --git a/sympy/core/numbers.py b/sympy/core/numbers.py
index 1bb64c3d17..ede89d52a3 100644
--- a/sympy/core/numbers.py
+++ b/sympy/core/numbers.py
@@ -8,8 +8,8 @@
 from typing import Set as tSet, Tuple as tTuple
 
 from .containers import Tuple
-from .sympify import (SympifyError, _sympy_converter, sympify, _convert_numpy_types,
-              _sympify, _is_numpy_instance)
+from .sympify import (SympifyError, converter, sympify, _convert_numpy_types, _sympify,
+                      _is_numpy_instance)
 from .singleton import S, Singleton
 from .basic import Basic
 from .expr import Expr, AtomicExpr
@@ -1485,7 +1485,7 @@ def __format__(self, format_spec):
 
 
 # Add sympify converters
-_sympy_converter[float] = _sympy_converter[decimal.Decimal] = Float
+converter[float] = converter[decimal.Decimal] = Float
 
 # this is here to work nicely in Sage
 RealNumber = Float
@@ -2510,7 +2510,7 @@ def __invert__(self):
         return Integer(~self.p)
 
 # Add sympify converters
-_sympy_converter[int] = Integer
+converter[int] = Integer
 
 
 class AlgebraicNumber(Expr):
@@ -4481,7 +4481,7 @@ def _eval_is_eq(self, other): # noqa: F811
 def sympify_fractions(f):
     return Rational(f.numerator, f.denominator, 1)
 
-_sympy_converter[fractions.Fraction] = sympify_fractions
+converter[fractions.Fraction] = sympify_fractions
 
 if HAS_GMPY:
     def sympify_mpz(x):
@@ -4493,28 +4493,28 @@ def sympify_mpz(x):
     def sympify_mpq(x):
         return Rational(int(x.numerator), int(x.denominator))
 
-    _sympy_converter[type(gmpy.mpz(1))] = sympify_mpz
-    _sympy_converter[type(gmpy.mpq(1, 2))] = sympify_mpq
+    converter[type(gmpy.mpz(1))] = sympify_mpz
+    converter[type(gmpy.mpq(1, 2))] = sympify_mpq
 
 
 def sympify_mpmath_mpq(x):
     p, q = x._mpq_
     return Rational(p, q, 1)
 
-_sympy_converter[type(mpmath.rational.mpq(1, 2))] = sympify_mpmath_mpq
+converter[type(mpmath.rational.mpq(1, 2))] = sympify_mpmath_mpq
 
 
 def sympify_mpmath(x):
     return Expr._from_mpmath(x, x.context.prec)
 
-_sympy_converter[mpnumeric] = sympify_mpmath
+converter[mpnumeric] = sympify_mpmath
 
 
 def sympify_complex(a):
     real, imag = list(map(sympify, (a.real, a.imag)))
     return real + S.ImaginaryUnit*imag
 
-_sympy_converter[complex] = sympify_complex
+converter[complex] = sympify_complex
 
 from .power import Pow, integer_nthroot
 from .mul import Mul
diff --git a/sympy/core/sympify.py b/sympy/core/sympify.py
index 13ad610261..591e784133 100644
--- a/sympy/core/sympify.py
+++ b/sympy/core/sympify.py
@@ -28,13 +28,9 @@ def __str__(self):
             str(self.base_exc)))
 
 
+# See sympify docstring.
 converter = {}  # type: tDict[Type[Any], Callable[[Any], Basic]]
 
-#holds the conversions defined in SymPy itself, i.e. non-user defined conversions
-_sympy_converter = {} # type: tDict[Type[Any], Callable[[Any], Basic]]
-
-#alias for clearer use in the library
-_external_converter = converter
 
 class CantSympify:
     """
@@ -81,7 +77,7 @@ def _convert_numpy_types(a, **sympify_args):
     import numpy as np
     if not isinstance(a, np.floating):
         if np.iscomplex(a):
-            return _sympy_converter[complex](a.item())
+            return converter[complex](a.item())
         else:
             return sympify(a.item(), **sympify_args)
     else:
@@ -362,18 +358,18 @@ def sympify(a, locals=None, convert_xor=True, strict=False, rational=False,
 
     if isinstance(a, CantSympify):
         raise SympifyError(a)
-
     cls = getattr(a, "__class__", None)
+    if cls is None:
+        cls = type(a)  # Probably an old-style class
+    conv = converter.get(cls, None)
+    if conv is not None:
+        return conv(a)
 
-    #Check if there exists a converter for any of the types in the mro
     for superclass in getmro(cls):
-        #First check for user defined converters
-        conv = _external_converter.get(superclass)
-        if conv is None:
-            #if none exists, check for SymPy defined converters
-            conv = _sympy_converter.get(superclass)
-        if conv is not None:
-            return conv(a)
+        try:
+            return converter[superclass](a)
+        except KeyError:
+            continue
 
     if cls is type(None):
         if strict:
diff --git a/sympy/geometry/line.py b/sympy/geometry/line.py
index 13dff6533d..f7e881a2a5 100644
--- a/sympy/geometry/line.py
+++ b/sympy/geometry/line.py
@@ -20,7 +20,7 @@
 from sympy.core.containers import Tuple
 from sympy.core.evalf import N
 from sympy.core.expr import Expr
-from sympy.core.numbers import Rational, oo
+from sympy.core.numbers import Rational, oo, Float
 from sympy.core.relational import Eq
 from sympy.core.singleton import S
 from sympy.core.sorting import ordered
@@ -36,6 +36,7 @@
 from sympy.matrices import Matrix
 from sympy.sets.sets import Intersection
 from sympy.simplify.simplify import simplify
+from sympy.solvers.solvers import solve
 from sympy.solvers.solveset import linear_coeffs
 from sympy.utilities.decorator import deprecated
 from sympy.utilities.exceptions import SymPyDeprecationWarning
@@ -530,7 +531,7 @@ def intersect_parallel_segments(seg1, seg2):
                 coeff = m_rref[0, 2]
                 line_intersection = l1.direction*coeff + self.p1
 
-                # if we're both lines, we can skip a containment check
+                # if both are lines, skip a containment check
                 if isinstance(self, Line) and isinstance(other, Line):
                     return [line_intersection]
 
@@ -538,6 +539,31 @@ def intersect_parallel_segments(seg1, seg2):
                      self.contains(line_intersection)) and
                         other.contains(line_intersection)):
                     return [line_intersection]
+                if not self.atoms(Float) and not other.atoms(Float):
+                    # if it can fail when there are no Floats then
+                    # maybe the following parametric check should be
+                    # done
+                    return []
+                # floats may fail exact containment so check that the
+                # arbitrary points, when  equal, both give a
+                # non-negative parameter when the arbitrary point
+                # coordinates are equated
+                t, u = [Dummy(i) for i in 'tu']
+                tu = solve(self.arbitrary_point(t) - other.arbitrary_point(u),
+                    t, u, dict=True)[0]
+                def ok(p, l):
+                    if isinstance(l, Line):
+                        # p > -oo
+                        return True
+                    if isinstance(l, Ray):
+                        # p >= 0
+                        return p.is_nonnegative
+                    if isinstance(l, Segment):
+                        # 0 <= p <= 1
+                        return p.is_nonnegative and (1 - p).is_nonnegative
+                    raise ValueError("unexpected line type")
+                if ok(tu[t], self) and ok(tu[u], other):
+                    return [line_intersection]
                 return []
             else:
                 # we're skew
diff --git a/sympy/logic/boolalg.py b/sympy/logic/boolalg.py
index b0e6e1983a..62036184d1 100644
--- a/sympy/logic/boolalg.py
+++ b/sympy/logic/boolalg.py
@@ -15,7 +15,7 @@
 from sympy.core.operations import LatticeOp
 from sympy.core.singleton import Singleton, S
 from sympy.core.sorting import ordered
-from sympy.core.sympify import _sympy_converter, _sympify, sympify
+from sympy.core.sympify import converter, _sympify, sympify
 from sympy.utilities.iterables import sift, ibin
 from sympy.utilities.misc import filldedent
 
@@ -348,13 +348,6 @@ def __bool__(self):
     def __hash__(self):
         return hash(True)
 
-    def __eq__(self, other):
-        if other is True:
-            return True
-        if other is False:
-            return False
-        return super().__eq__(other)
-
     @property
     def negated(self):
         return S.false
@@ -423,13 +416,6 @@ def __bool__(self):
     def __hash__(self):
         return hash(False)
 
-    def __eq__(self, other):
-        if other is True:
-            return False
-        if other is False:
-            return True
-        return super().__eq__(other)
-
     @property
     def negated(self):
         return S.true
@@ -457,7 +443,7 @@ def as_set(self):
 S.true = true
 S.false = false
 
-_sympy_converter[bool] = lambda x: S.true if x else S.false
+converter[bool] = lambda x: S.true if x else S.false
 
 
 class BooleanFunction(Application, Boolean):
diff --git a/sympy/matrices/immutable.py b/sympy/matrices/immutable.py
index f93e2954f7..21476b83a9 100644
--- a/sympy/matrices/immutable.py
+++ b/sympy/matrices/immutable.py
@@ -3,7 +3,7 @@
 from sympy.core import Basic, Dict, Tuple
 from sympy.core.numbers import Integer
 from sympy.core.cache import cacheit
-from sympy.core.sympify import _sympy_converter as sympify_converter, _sympify
+from sympy.core.sympify import converter as sympify_converter, _sympify
 from sympy.matrices.dense import DenseMatrix
 from sympy.matrices.expressions import MatrixExpr
 from sympy.matrices.matrices import MatrixBase
diff --git a/sympy/parsing/latex/_parse_latex_antlr.py b/sympy/parsing/latex/_parse_latex_antlr.py
index a4d4764907..92c2e3764a 100644
--- a/sympy/parsing/latex/_parse_latex_antlr.py
+++ b/sympy/parsing/latex/_parse_latex_antlr.py
@@ -189,7 +189,8 @@ def convert_postfix_list(arr, i=0):
                         sympy.Symbol)
                     # if the left and right sides contain no variables and the
                     # symbol in between is 'x', treat as multiplication.
-                    if not (left_syms or right_syms) and str(res) == 'x':
+                    if len(left_syms) == 0 and len(right_syms) == 0 and str(
+                            res) == "x":
                         return convert_postfix_list(arr, i + 1)
             # multiply by next
             return sympy.Mul(
diff --git a/sympy/polys/domains/pythonrational.py b/sympy/polys/domains/pythonrational.py
index 87b56d6c92..3749c8cd75 100644
--- a/sympy/polys/domains/pythonrational.py
+++ b/sympy/polys/domains/pythonrational.py
@@ -9,7 +9,7 @@
 
 
 from sympy.core.numbers import Rational
-from sympy.core.sympify import _sympy_converter
+from sympy.core.sympify import converter
 from sympy.utilities import public
 from sympy.external.pythonmpq import PythonMPQ
 
@@ -19,4 +19,4 @@
 
 def sympify_pythonrational(arg):
     return Rational(arg.numerator, arg.denominator)
-_sympy_converter[PythonRational] = sympify_pythonrational
+converter[PythonRational] = sympify_pythonrational
diff --git a/sympy/sets/fancysets.py b/sympy/sets/fancysets.py
index 40d61f0316..78b119bad5 100644
--- a/sympy/sets/fancysets.py
+++ b/sympy/sets/fancysets.py
@@ -11,7 +11,7 @@
 from sympy.core.relational import Eq, is_eq
 from sympy.core.singleton import Singleton, S
 from sympy.core.symbol import Dummy, symbols, Symbol
-from sympy.core.sympify import _sympify, sympify, _sympy_converter
+from sympy.core.sympify import _sympify, sympify, converter
 from sympy.logic.boolalg import And, Or
 from .sets import Set, Interval, Union, FiniteSet, ProductSet
 from sympy.utilities.misc import filldedent
@@ -1007,7 +1007,7 @@ def as_relational(self, x):
         return And(in_seq, ints, range_cond)
 
 
-_sympy_converter[range] = lambda r: Range(r.start, r.stop, r.step)
+converter[range] = lambda r: Range(r.start, r.stop, r.step)
 
 def normalize_theta_set(theta):
     r"""
diff --git a/sympy/sets/sets.py b/sympy/sets/sets.py
index 60f3790310..1bb6ba21f0 100644
--- a/sympy/sets/sets.py
+++ b/sympy/sets/sets.py
@@ -18,7 +18,7 @@
 from sympy.core.singleton import Singleton, S
 from sympy.core.sorting import ordered
 from sympy.core.symbol import symbols, Symbol, Dummy, uniquely_named_symbol
-from sympy.core.sympify import _sympify, sympify, _sympy_converter
+from sympy.core.sympify import _sympify, sympify, converter
 from sympy.functions.elementary.miscellaneous import Max, Min
 from sympy.logic.boolalg import And, Or, Not, Xor, true, false
 from sympy.utilities.decorator import deprecated
@@ -1975,8 +1975,8 @@ def __eq__(self, other):
 
     __hash__ : Callable[[Basic], Any] = Basic.__hash__
 
-_sympy_converter[set] = lambda x: FiniteSet(*x)
-_sympy_converter[frozenset] = lambda x: FiniteSet(*x)
+converter[set] = lambda x: FiniteSet(*x)
+converter[frozenset] = lambda x: FiniteSet(*x)
 
 
 class SymmetricDifference(Set):
diff --git a/sympy/tensor/array/expressions/conv_array_to_matrix.py b/sympy/tensor/array/expressions/conv_array_to_matrix.py
index 6ce40b35c3..1d7f2c31c9 100644
--- a/sympy/tensor/array/expressions/conv_array_to_matrix.py
+++ b/sympy/tensor/array/expressions/conv_array_to_matrix.py
@@ -4,7 +4,7 @@
 from functools import singledispatch
 from itertools import accumulate
 
-from sympy import MatMul, Basic, Wild, KroneckerProduct
+from sympy import MatMul, Basic, Wild
 from sympy.assumptions.ask import (Q, ask)
 from sympy.core.mul import Mul
 from sympy.core.singleton import S
@@ -167,29 +167,6 @@ def _find_trivial_matrices_rewrite(expr: ArrayTensorProduct):
     return _array_tensor_product(*[i for i in args if i is not None]), removed
 
 
-def _find_trivial_kronecker_products_broadcast(expr: ArrayTensorProduct):
-    newargs: List[Basic] = []
-    removed = []
-    count_dims = 0
-    for i, arg in enumerate(expr.args):
-        count_dims += get_rank(arg)
-        shape = get_shape(arg)
-        current_range = [count_dims-i for i in range(len(shape), 0, -1)]
-        if (shape == (1, 1) and len(newargs) > 0 and 1 not in get_shape(newargs[-1]) and
-            isinstance(newargs[-1], MatrixExpr) and isinstance(arg, MatrixExpr)):
-            # KroneckerProduct object allows the trick of broadcasting:
-            newargs[-1] = KroneckerProduct(newargs[-1], arg)
-            removed.extend(current_range)
-        elif 1 not in shape and len(newargs) > 0 and get_shape(newargs[-1]) == (1, 1):
-            # Broadcast:
-            newargs[-1] = KroneckerProduct(newargs[-1], arg)
-            prev_range = [i for i in range(min(current_range)) if i not in removed]
-            removed.extend(prev_range[-2:])
-        else:
-            newargs.append(arg)
-    return _array_tensor_product(*newargs), removed
-
-
 @singledispatch
 def _array2matrix(expr):
     return expr
@@ -418,9 +395,6 @@ def _(expr: ArrayTensorProduct):
     if isinstance(newexpr, ArrayTensorProduct):
         newexpr, newremoved2 = _find_trivial_matrices_rewrite(newexpr)
         newremoved = _combine_removed(-1, newremoved, newremoved2)
-    if isinstance(newexpr, ArrayTensorProduct):
-        newexpr, newremoved2 = _find_trivial_kronecker_products_broadcast(newexpr)
-        newremoved = _combine_removed(-1, newremoved, newremoved2)
     return newexpr, newremoved
 
 
diff --git a/sympy/utilities/enumerative.py b/sympy/utilities/enumerative.py
index 4189b8192a..402c3c7963 100644
--- a/sympy/utilities/enumerative.py
+++ b/sympy/utilities/enumerative.py
@@ -842,15 +842,18 @@ def enum_small(self, multiplicities, ub):
             return
         self._initialize_enumeration(multiplicities)
         while True:
+            good_partition = True
             while self.spread_part_multiplicity():
-                self.db_trace('spread 1')
+                self.db_trace("spread 1")
                 if self.lpart >= ub:
                     self.discarded += 1
-                    self.db_trace('  Discarding')
+                    good_partition = False
+                    self.db_trace("  Discarding")
                     self.lpart = ub - 2
                     break
-            else:
-                # M4  Visit a partition
+
+            # M4  Visit a partition
+            if good_partition:
                 state = [self.f, self.lpart, self.pstack]
                 yield state
 


Test patch:
diff --git a/.github/workflows/runtests.yml b/.github/workflows/runtests.yml
index fbe5c5cb1c..eed7f8f15d 100644
--- a/.github/workflows/runtests.yml
+++ b/.github/workflows/runtests.yml
@@ -71,22 +71,6 @@ jobs:
       - name: Run mypy on the sympy package
         run: mypy sympy
 
-  # --------------------------- check authors ---------------------- #
-
-  authors:
-    needs: code-quality
-    runs-on: ubuntu-20.04
-    steps:
-      - uses: actions/checkout@v2
-        with:
-          fetch-depth: 0
-      - uses: actions/setup-python@v2
-        with:
-          python-version: '3.9'
-      - run: python -m pip install --upgrade pip
-      - run: pip install mpmath
-      - run: bin/mailmap_check.py
-
   # -------------------- Doctests latest Python -------------------- #
 
   doctests-latest:
diff --git a/sympy/geometry/tests/test_line.py b/sympy/geometry/tests/test_line.py
index 968870aa8e..b02a66d211 100644
--- a/sympy/geometry/tests/test_line.py
+++ b/sympy/geometry/tests/test_line.py
@@ -820,3 +820,14 @@ def test_issue_8615():
     a = Line3D(Point3D(6, 5, 0), Point3D(6, -6, 0))
     b = Line3D(Point3D(6, -1, 19/10), Point3D(6, -1, 0))
     assert a.intersection(b) == [Point3D(6, -1, 0)]
+
+
+def test_issue_12598():
+    r1 = Ray(Point(0, 1), Point(0.98, 0.79).n(2))
+    r2 = Ray(Point(0, 0), Point(0.71, 0.71).n(2))
+    assert str(r1.intersection(r2)[0]) == 'Point2D(0.82, 0.82)'
+    l1 = Line((0, 0), (1, 1))
+    l2 = Segment((-1, 1), (0, -1)).n(2)
+    assert str(l1.intersection(l2)[0]) == 'Point2D(-0.33, -0.33)'
+    l2 = Segment((-1, 1), (-1/2, 1/2)).n(2)
+    assert not l1.intersection(l2)
diff --git a/sympy/matrices/expressions/tests/test_derivatives.py b/sympy/matrices/expressions/tests/test_derivatives.py
index 4647363f7a..e60fddebe5 100644
--- a/sympy/matrices/expressions/tests/test_derivatives.py
+++ b/sympy/matrices/expressions/tests/test_derivatives.py
@@ -3,7 +3,6 @@
 
 http://www.math.uwaterloo.ca/~hwolkowi//matrixcookbook.pdf
 """
-from sympy import KroneckerProduct
 from sympy.combinatorics import Permutation
 from sympy.concrete.summations import Sum
 from sympy.core.numbers import Rational
@@ -173,11 +172,6 @@ def test_matrix_derivative_vectors_and_scalars():
     assert str(expr[0, 0].diff(X[m, n]).doit()) == \
         'b[n, 0]*Sum((c[_i_1, 0] + Sum(X[_i_1, _i_3]*b[_i_3, 0], (_i_3, 0, k - 1)))*D[_i_1, m], (_i_1, 0, k - 1)) + Sum((c[_i_2, 0] + Sum(X[_i_2, _i_4]*b[_i_4, 0], (_i_4, 0, k - 1)))*D[m, _i_2]*b[n, 0], (_i_2, 0, k - 1))'
 
-    # See https://github.com/sympy/sympy/issues/16504#issuecomment-1018339957
-    expr = x*x.T*x
-    I = Identity(k)
-    assert expr.diff(x) == KroneckerProduct(I, x.T*x) + 2*x*x.T
-
 
 def test_matrix_derivatives_of_traces():
 
diff --git a/sympy/sets/tests/test_sets.py b/sympy/sets/tests/test_sets.py
index a8014523a6..7a931f5167 100644
--- a/sympy/sets/tests/test_sets.py
+++ b/sympy/sets/tests/test_sets.py
@@ -994,7 +994,7 @@ def test_finite_basic():
     assert FiniteSet((1, 2, 3)) != FiniteSet(1, 2, 3)
 
     # Ensure a variety of types can exist in a FiniteSet
-    assert FiniteSet((1, 2), A, -5, x, 'eggs', x**2)
+    assert FiniteSet((1, 2), Float, A, -5, x, 'eggs', x**2, Interval)
 
     assert (A > B) is False
     assert (A >= B) is False
diff --git a/sympy/stats/tests/test_stochastic_process.py b/sympy/stats/tests/test_stochastic_process.py
index df87f713d2..7b12a7c051 100644
--- a/sympy/stats/tests/test_stochastic_process.py
+++ b/sympy/stats/tests/test_stochastic_process.py
@@ -63,7 +63,7 @@ def test_DiscreteMarkovChain():
     # any hashable object should be a valid state
     # states should be valid as a tuple/set/list/Tuple/Range
     sym, rainy, cloudy, sunny = symbols('a Rainy Cloudy Sunny', real=True)
-    state_spaces = [(1, 2, 3), [Str('Hello'), sym, DiscreteMarkovChain("Y", (1,2,3))],
+    state_spaces = [(1, 2, 3), [Str('Hello'), sym, DiscreteMarkovChain],
                     Tuple(S(1), exp(sym), Str('World'), sympify=False), Range(-1, 5, 2),
                     [rainy, cloudy, sunny]]
     chains = [DiscreteMarkovChain("Y", state_space) for state_space in state_spaces]
@@ -125,11 +125,11 @@ def test_DiscreteMarkovChain():
     assert P(Lt(X[1], 2) & Gt(X[1], 0), Eq(X[0], 2) &
         StochasticStateSpaceOf(X, [0, 1, 2]) & TransitionMatrixOf(X, TO1)) == Rational(1, 4)
     assert P(Lt(X[1], 2) & Gt(X[1], 0), Eq(X[0], 2) &
-             StochasticStateSpaceOf(X, [S(0), '0', 1]) & TransitionMatrixOf(X, TO1)) == Rational(1, 4)
+             StochasticStateSpaceOf(X, [None, 'None', 1]) & TransitionMatrixOf(X, TO1)) == Rational(1, 4)
     assert P(Ne(X[1], 2) & Ne(X[1], 1), Eq(X[0], 2) &
         StochasticStateSpaceOf(X, [0, 1, 2]) & TransitionMatrixOf(X, TO1)) is S.Zero
     assert P(Ne(X[1], 2) & Ne(X[1], 1), Eq(X[0], 2) &
-             StochasticStateSpaceOf(X, [S(0), '0', 1]) & TransitionMatrixOf(X, TO1)) is S.Zero
+             StochasticStateSpaceOf(X, [None, 'None', 1]) & TransitionMatrixOf(X, TO1)) is S.Zero
     assert P(And(Eq(Y[2], 1), Eq(Y[1], 1), Eq(Y[0], 0)), Eq(Y[1], 1)) == 0.1*Probability(Eq(Y[0], 0))
 
     # testing properties of Markov chain
diff --git a/sympy/tensor/array/expressions/tests/test_convert_array_to_matrix.py b/sympy/tensor/array/expressions/tests/test_convert_array_to_matrix.py
index 93783ccb03..bd42cb81e4 100644
--- a/sympy/tensor/array/expressions/tests/test_convert_array_to_matrix.py
+++ b/sympy/tensor/array/expressions/tests/test_convert_array_to_matrix.py
@@ -1,4 +1,4 @@
-from sympy import Lambda, S, Dummy, KroneckerProduct
+from sympy import Lambda, S, Dummy
 from sympy.core.symbol import symbols
 from sympy.functions.elementary.miscellaneous import sqrt
 from sympy.functions.elementary.trigonometric import cos, sin
@@ -672,18 +672,3 @@ def test_array2matrix():
     expr = PermuteDims(ArrayContraction(ArrayTensorProduct(x, I, I1, x), (0, 3), (1, 7)), Permutation(2, 3))
     expected = PermuteDims(ArrayTensorProduct(x*x.T, I1), Permutation(3)(1, 2))
     assert _array2matrix(expr) == expected
-
-
-def test_recognize_broadcasting():
-    expr = ArrayTensorProduct(x.T*x, A)
-    assert _remove_trivial_dims(expr) == (KroneckerProduct(x.T*x, A), [0, 1])
-
-    expr = ArrayTensorProduct(A, x.T*x)
-    assert _remove_trivial_dims(expr) == (KroneckerProduct(A, x.T*x), [2, 3])
-
-    expr = ArrayTensorProduct(A, B, x.T*x, C)
-    assert _remove_trivial_dims(expr) == (ArrayTensorProduct(A, KroneckerProduct(B, x.T*x), C), [4, 5])
-
-    # Always prefer matrix multiplication to Kronecker product, if possible:
-    expr = ArrayTensorProduct(a, b, x.T*x)
-    assert _remove_trivial_dims(expr) == (a*x.T*x*b.T, [1, 3, 4, 5])
diff --git a/sympy/tensor/tests/test_functions.py b/sympy/tensor/tests/test_functions.py
index ae40865d1b..adddffb816 100644
--- a/sympy/tensor/tests/test_functions.py
+++ b/sympy/tensor/tests/test_functions.py
@@ -21,7 +21,7 @@ def test_TensorProduct_construction():
     expr = TensorProduct(TensorProduct(A, B), C)
     assert expr == TensorProduct(A, B, C)
 
-    expr = TensorProduct(Matrix.eye(2), Array([[0, -1], [1, 0]]))
+    expr = TensorProduct(Matrix.eye(2), [[0, -1], [1, 0]])
     assert expr == Array([
         [
             [[0, -1], [1, 0]],
@@ -40,14 +40,14 @@ def test_TensorProduct_shape():
     assert expr.shape == ()
     assert expr.rank() == 0
 
-    expr = TensorProduct(Array([1, 2]), Array([x, y]), evaluate=False)
+    expr = TensorProduct([1, 2], [x, y], evaluate=False)
     assert expr.shape == (2, 2)
     assert expr.rank() == 2
     expr = TensorProduct(expr, expr, evaluate=False)
     assert expr.shape == (2, 2, 2, 2)
     assert expr.rank() == 4
 
-    expr = TensorProduct(Matrix.eye(2), Array([[0, -1], [1, 0]]), evaluate=False)
+    expr = TensorProduct(Matrix.eye(2), [[0, -1], [1, 0]], evaluate=False)
     assert expr.shape == (2, 2, 2, 2)
     assert expr.rank() == 4
 
diff --git a/sympy/testing/quality_unicode.py b/sympy/testing/quality_unicode.py
index a739097ea5..dfcf0026e1 100644
--- a/sympy/testing/quality_unicode.py
+++ b/sympy/testing/quality_unicode.py
@@ -19,7 +19,6 @@
 unicode_whitelist = [
     # Author names can include non-ASCII characters
     r'*/bin/authors_update.py',
-    r'*/bin/mailmap_check.py',
 
     # These files have functions and test functions for unicode input and
     # output.