blob: 3a95451eeaea82943b2df6b91947c278ecd5a784 [file] [log] [blame]
# Copyright (C) 2008-2020 Andrey Petrov and contributors.
# Copyright (C) 2023 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import sys
if sys.version_info < (3, 9): # noqa: UP036
raise ImportError("webkitpy requires Python 3.9")
import os
import platform
# We always want the real system version
os.environ['SYSTEM_VERSION_COMPAT'] = '0'
libraries = os.path.join(os.path.abspath(os.path.dirname(os.path.dirname(__file__))), 'libraries')
webkitcorepy_path = os.path.join(libraries, 'webkitcorepy')
if webkitcorepy_path not in sys.path:
sys.path.insert(0, webkitcorepy_path)
import webkitcorepy
if sys.platform == 'darwin':
is_root = not os.getuid()
does_own_libraries = os.stat(libraries).st_uid == os.getuid()
directory_writeable = os.access(libraries, os.W_OK)
if any([is_root, not does_own_libraries, not directory_writeable]):
libraries = os.path.expanduser('~/Library/webkitpy')
from webkitcorepy import AutoInstall, Package, Version
AutoInstall.set_directory(os.path.join(libraries, 'autoinstalled', 'python-{}-{}'.format(sys.version_info[0], platform.machine())))
AutoInstall.register(Package('pylint', Version(2, 13, 9)))
AutoInstall.register(
Package("pytest", Version(7, 2, 0),
implicit_deps=["attr", "pluggy", "iniconfig"]
+ (["exceptiongroup"] if sys.version_info < (3, 11) else []),
aliases=["_pytest"] # Technically also a stub "py" module, but this conflicts with the py project.
)
)
AutoInstall.register(Package('pytest_asyncio', Version(0, 18, 3), pypi_name='pytest-asyncio', implicit_deps=['pytest'], wheel=True))
AutoInstall.register(Package('pytest_timeout', Version(2, 1, 0), pypi_name='pytest-timeout', implicit_deps=['pytest'], wheel=True))
AutoInstall.register(Package('websockets', Version(12, 0), wheel=True))
if sys.version_info < (3, 11):
AutoInstall.register(Package('exceptiongroup', Version(1, 1, 0), wheel=True))
AutoInstall.register(Package('importlib_metadata', Version(4, 8, 1)))
AutoInstall.register(Package('typing_extensions', Version(4, 12, 2), wheel=True))
AutoInstall.register(Package('atomicwrites', Version(1, 1, 5)))
AutoInstall.register(Package('attrs', Version(21, 3, 0), aliases=['attr']))
AutoInstall.register(Package('bs4', Version(4, 12, 0), pypi_name='beautifulsoup4'))
AutoInstall.register(Package('configparser', Version(4, 0, 2), implicit_deps=['pyparsing'], aliases=['backports.configparser']))
AutoInstall.register(Package('contextlib2', Version(0, 6, 0)))
AutoInstall.register(Package('coverage', Version(7, 6, 1), wheel=True))
AutoInstall.register(Package('funcsigs', Version(1, 0, 2)))
AutoInstall.register(Package('html5lib', Version(1, 1)))
AutoInstall.register(Package('iniconfig', Version(1, 1, 1)))
AutoInstall.register(Package('mechanize', Version(0, 4, 5)))
AutoInstall.register(Package('more_itertools', Version(4, 2, 0), pypi_name='more-itertools', wheel=True))
AutoInstall.register(Package('mozprocess', Version(1, 3, 0)))
AutoInstall.register(Package('mozlog', Version(7, 1, 0), wheel=True))
AutoInstall.register(Package('mozterm', Version(1, 0, 0)))
AutoInstall.register(Package('pluggy', Version(0, 13, 1)))
AutoInstall.register(Package('pycodestyle', Version(2, 14, 0)))
AutoInstall.register(Package('pyfakefs', Version(5, 7, 3)))
AutoInstall.register(Package('soupsieve', Version(2, 2, 1)))
if sys.platform == 'linux':
# Keep websocket toplevel for WebDriverTests' imported selenium
AutoInstall.register(Package('websocket', Version(1, 8, 0), pypi_name='websocket-client'))
AutoInstall.register(Package('selenium', Version(4, 24, 0), wheel=True, implicit_deps=['websocket']))
else:
AutoInstall.register(Package('selenium', Version(4, 12, 0), wheel=True))
AutoInstall.register(Package('toml', Version(0, 10, 1), implicit_deps=['pyparsing']))
AutoInstall.register(Package('wcwidth', Version(0, 2, 5)))
AutoInstall.register(Package('webencodings', Version(0, 5, 1)))
AutoInstall.register(Package('zipp', Version(1, 2, 0)))
AutoInstall.register(Package('zope.interface', Version(7, 0, 1), aliases=['zope'], pypi_name='zope-interface', wheel=True))
AutoInstall.register(Package('webkitscmpy', Version(4, 0, 0)), local=True)
AutoInstall.register(Package('webkitbugspy', Version(0, 3, 1)), local=True)
AutoInstall.register(Package('yaml', Version(6, 0, 2), pypi_name='PyYAML'))
import webkitscmpy
# Disable IPV6 if Bugzilla can't use IPV6.
try:
import socket
import urllib3
HAS_CHECKED_IPV6 = False
FIRST_IPV6_TIMEOUT = 3
# Pulled from urllib3, https://github.com/urllib3/urllib3/blob/main/src/urllib3/util/connection.py
# Disable IPV6 if the first attempt to connect to an IPV6 address fails
def create_connection(
address,
timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
source_address=None,
socket_options=None,
):
global HAS_CHECKED_IPV6
host, port = address
if host.startswith("["):
host = host.strip("[]")
err = None
family = urllib3.util.connection.allowed_gai_family()
try:
host.encode("idna")
except UnicodeError as e:
raise LocationParseError("'%s', label empty or too long" % host) from e
for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
af, socktype, proto, canonname, sa = res
is_first_ipv6 = not HAS_CHECKED_IPV6 and af == socket.AF_INET6
if af == socket.AF_INET6 and not urllib3.util.connection.HAS_IPV6:
continue
sock = None
try:
sock = socket.socket(af, socktype, proto)
urllib3.util.connection._set_socket_options(sock, socket_options)
if is_first_ipv6 and (not timeout or timeout > FIRST_IPV6_TIMEOUT):
sock.settimeout(FIRST_IPV6_TIMEOUT)
elif timeout is not socket._GLOBAL_DEFAULT_TIMEOUT:
sock.settimeout(timeout)
if source_address:
sock.bind(source_address)
sock.connect(sa)
return sock
except socket.error as e:
err = e
if sock is not None:
sock.close()
sock = None
if is_first_ipv6:
sys.stderr.write('IPV6 request to {} has failed, disabling IPV6\n'.format(host))
urllib3.util.connection.HAS_IPV6 = False
finally:
if af == socket.AF_INET6:
HAS_CHECKED_IPV6 = True
if err is not None:
raise err
raise socket.error("getaddrinfo returns an empty list")
urllib3.util.connection.create_connection = create_connection
except ModuleNotFoundError:
pass
except ImportError:
pass