Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions autoprimenet.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python3

Check failure on line 1 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Ruff

ruff (EXE001)

autoprimenet.py:1:1: EXE001 Shebang is present but file is not executable
# -*- coding: utf-8 -*-

# /// script
Expand Down Expand Up @@ -90,7 +90,7 @@
import xml.etree.ElementTree as ET
import zipfile
from array import array
from collections import deque, namedtuple

Check failure on line 93 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Ruff

ruff (S405)

autoprimenet.py:93:8: S405 `xml.etree` methods are vulnerable to XML attacks
from ctypes.util import find_library
from datetime import datetime, timedelta
from decimal import Decimal
Expand All @@ -106,9 +106,9 @@
try:
# Python 2
from future_builtins import map, zip # ascii, filter, hex, oct
except ImportError:
pass

Check failure on line 111 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Ruff

ruff (A004)

autoprimenet.py:111:35: A004 Import `zip` is shadowing a Python builtin

Check failure on line 111 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Ruff

ruff (A004)

autoprimenet.py:111:30: A004 Import `map` is shadowing a Python builtin
try:
# Python 3+

Check failure on line 113 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Ruff

ruff (SIM105)

autoprimenet.py:109:1: SIM105 Use `contextlib.suppress(ImportError)` instead of `try`-`except`-`pass` help: Replace `try`-`except`-`pass` with `with contextlib.suppress(ImportError): ...`
from urllib.parse import urlencode
Expand Down Expand Up @@ -183,7 +183,7 @@

c = (n.bit_length() - 1) // 2
a = 1
d = 0

Check notice on line 186 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

C1805

"n == 0" can be simplified to "not n", if it is strictly an int, as 0 is falsey
for s in reversed(range(c.bit_length())):
# Loop invariant: (a-1)**2 < (n >> 2*(c - d)) < (a+1)**2
e = d
Expand All @@ -205,7 +205,7 @@

try:
# Python 3.2+
from math import expm1

Check failure on line 208 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Ruff

ruff (FURB163)

autoprimenet.py:208:10: FURB163 Prefer `math.log2(x)` over `math.log` with a redundant base help: Replace with `math.log2(x)`
except ImportError:

def expm1(x):
Expand All @@ -220,6 +220,7 @@
from functools import reduce

def prod(iterable, start=1):
"""Return the product of all elements in iterable, times start (Python 3.8+ math.prod fallback)."""
return reduce(operator.mul, iterable, start)


Expand All @@ -237,15 +238,15 @@
kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
advapi32 = ctypes.WinDLL("advapi32", use_last_error=True)

class GROUP_AFFINITY(ctypes.Structure):

Check failure on line 241 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Ruff

ruff (PLC2701)

autoprimenet.py:241:21: PLC2701 Private name import `_winreg`
_fields_ = (("Mask", wintypes.WPARAM), ("Group", wintypes.WORD), ("Reserved", wintypes.WORD * 3))

class PROCESSOR_RELATIONSHIP(ctypes.Structure):
_fields_ = (
("Flags", wintypes.BYTE),

Check notice on line 246 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

C0115

Missing class docstring
("EfficiencyClass", wintypes.BYTE),
("Reserved", wintypes.BYTE * 20),
("GroupCount", wintypes.WORD),

Check notice on line 249 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

C0115

Missing class docstring
("GroupMask", GROUP_AFFINITY * 1),
)

Expand All @@ -254,10 +255,10 @@

class NUMA_NODE_RELATIONSHIP(ctypes.Structure):
_anonymous_ = ("union",)
_fields_ = (

Check notice on line 258 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

C0115

Missing class docstring
("NodeNumber", wintypes.DWORD),
("Reserved", wintypes.BYTE * 18),
("GroupCount", wintypes.WORD),

Check notice on line 261 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

C0115

Missing class docstring
("union", union),
)

Expand All @@ -266,7 +267,7 @@
_fields_ = (
("Level", wintypes.BYTE),
("Associativity", wintypes.BYTE),
("LineSize", wintypes.WORD),

Check notice on line 270 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

C0115

Missing class docstring
("CacheSize", wintypes.DWORD),
("Type", wintypes.DWORD),
("Reserved", wintypes.BYTE * 18),
Expand All @@ -279,7 +280,7 @@
("MaximumProcessorCount", wintypes.BYTE),
("ActiveProcessorCount", wintypes.BYTE),
("Reserved", wintypes.BYTE * 38),
("ActiveProcessorMask", wintypes.WPARAM),

Check notice on line 283 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

C0115

Missing class docstring
)

class GROUP_RELATIONSHIP(ctypes.Structure):
Expand All @@ -287,7 +288,7 @@
("MaximumGroupCount", wintypes.WORD),
("ActiveGroupCount", wintypes.WORD),
("Reserved", wintypes.BYTE * 20),
("GroupInfo", PROCESSOR_GROUP_INFO * 1),

Check notice on line 291 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

C0115

Missing class docstring
)

class union(ctypes.Union):
Expand All @@ -295,7 +296,7 @@
("Processor", PROCESSOR_RELATIONSHIP),
("NumaNode", NUMA_NODE_RELATIONSHIP),
("Cache", CACHE_RELATIONSHIP),
("Group", GROUP_RELATIONSHIP),

Check failure on line 299 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

E0102

class already defined line 258

Check notice on line 299 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

C0115

Missing class docstring
)

class SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX(ctypes.Structure):
Expand All @@ -303,7 +304,7 @@
_fields_ = (("Relationship", wintypes.DWORD), ("Size", wintypes.DWORD), ("union", union))

class ProcessorCore(ctypes.Structure):
_fields_ = (("Flags", wintypes.BYTE),)

Check notice on line 307 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

C0115

Missing class docstring

class NumaNode(ctypes.Structure):
_fields_ = (("NodeNumber", wintypes.DWORD),)
Expand All @@ -322,7 +323,7 @@
("ProcessorCore", ProcessorCore),
("NumaNode", NumaNode),
("Cache", CACHE_DESCRIPTOR),
("Reserved", ctypes.c_ulonglong * 2),

Check failure on line 326 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

E0102

class already defined line 258
)

class SYSTEM_LOGICAL_PROCESSOR_INFORMATION(ctypes.Structure):
Expand All @@ -343,6 +344,7 @@
)

def __init__(self):
"""Set dwLength for passing this structure to GlobalMemoryStatusEx."""
self.dwLength = ctypes.sizeof(self)
super(MEMORYSTATUSEX, self).__init__()

Expand Down Expand Up @@ -391,7 +393,7 @@

return output

def get_windows_sid():

Check failure on line 396 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

E0602

Undefined variable 'WindowsError'
"""Retrieves the Security Identifier (SID) of the Windows computer."""
# output = ""
computer_name = ctypes.create_unicode_buffer(256)
Expand Down Expand Up @@ -442,6 +444,7 @@
# libc.sysctlbyname.restype = ctypes.c_int

def sysctl_str(name):
"""Return a sysctl string value for the given ASCII name (macOS)."""
size = ctypes.c_size_t()
libc.sysctlbyname(name, None, ctypes.byref(size), None, 0)

Expand All @@ -450,6 +453,7 @@
return buf.value

def sysctl_value(name, ctype):
"""Return a sysctl value of the given ctypes type for name (macOS)."""
size = ctypes.c_size_t(ctypes.sizeof(ctype))
value = ctype()
libc.sysctlbyname(name, ctypes.byref(value), ctypes.byref(size), None, 0)
Expand All @@ -462,6 +466,7 @@
except ImportError:

def freedesktop_os_release():
"""Parse /etc/os-release or /usr/lib/os-release into a dict (Python < 3.10 fallback)."""
line_re = re.compile(r"""^([a-zA-Z_][a-zA-Z0-9_]*)=('([^']*)'|"((?:[^$"`]|\\[$"`\\])*)"|.*)$""")
quote_unescape_re = re.compile(r'\\([$"`\\])')
unescape_re = re.compile(r"\\(.)")
Expand Down Expand Up @@ -583,6 +588,7 @@
if hasattr(os, "statvfs"): # POSIX

def disk_usage(path):
"""Return total, used, and free disk space for path via statvfs (shutil.disk_usage fallback)."""
st = os.statvfs(path)
free = st.f_bavail * st.f_frsize
total = st.f_blocks * st.f_frsize
Expand All @@ -607,6 +613,7 @@
# ctypes.windll.kernel32.GetDiskFreeSpaceExA.restype = wintypes.BOOL

def disk_usage(path):
"""Return total, used, and free disk space using GetDiskFreeSpaceEx (shutil.disk_usage fallback)."""
_ = wintypes.ULARGE_INTEGER()
total = wintypes.ULARGE_INTEGER()
free = wintypes.ULARGE_INTEGER()
Expand All @@ -633,6 +640,7 @@
# ctypes.windll.kernel32.MoveFileExA.restype = wintypes.BOOL

def replace(src, dst):
"""Replace dst with src using MoveFileEx (os.replace fallback on Windows)."""
fun = (
ctypes.windll.kernel32.MoveFileExW
if sys.version_info >= (3,) or isinstance(src, str) or isinstance(dst, str)
Expand Down Expand Up @@ -1032,7 +1040,7 @@
wds = {}
result_wds = {}
proof_wd = None

Check failure on line 1043 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Ruff

ruff (F821)

autoprimenet.py:1043:78: F821 Undefined name `unicode`

Check failure on line 1043 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

E0602

Undefined variable 'unicode'
inotify_fd = libc.inotify_init()
if inotify_fd < 0:
raise OSError(ctypes.get_errno(), "Error initializing inotify")
Expand Down Expand Up @@ -1122,6 +1130,7 @@
__slots__ = ()

def send(self, request, **kwargs):
"""Send request, setting TLS server_hostname from the Host header when present."""
host_header = request.headers.get("host")
connection_pool_kwargs = self.poolmanager.connection_pool_kw

Expand Down Expand Up @@ -1218,7 +1227,7 @@
MAX_RETRIES = 3
# urllib3 1.9+: urllib3.Retry
if hasattr(urllib3, "Retry"):
version = tuple(map(int, urllib3.__version__.split(".", 2)[:2]))

Check failure on line 1230 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

E1101

Module 'select' has no 'KQ_EV_CLEAR' member

Check failure on line 1230 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

E1101

Module 'select' has no 'KQ_EV_ADD' member

Check failure on line 1230 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

E1101

Module 'select' has no 'KQ_FILTER_VNODE' member

Check failure on line 1230 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

E1101

Module 'select' has no 'kevent' member
kwargs = {}
# urllib3 1.19+: respect_retry_after_header=False
if version >= (1, 19):
Expand All @@ -1233,10 +1242,10 @@
retries = MAX_RETRIES
session.mount("https://", HostHeaderSSLAdapter(max_retries=retries))
session.mount("http://", requests.adapters.HTTPAdapter(max_retries=retries))
atexit.register(session.close)

Check failure on line 1245 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

E1101

Module 'select' has no 'kqueue' member
# Python 2.7.9 and 3.4+
context = (
ssl.create_default_context(cafile=certifi.where() if certifi is not None else certifi)

Check failure on line 1248 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

E1101

Module 'select' has no 'KQ_NOTE_DELETE' member
if hasattr(ssl, "create_default_context")
else None
)
Expand Down Expand Up @@ -1630,7 +1639,7 @@
if not scale and power > 0:
strm += "i"

return strm

Check failure on line 1642 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Ruff

ruff (PLR6301)

autoprimenet.py:1642:7: PLR6301 Method `tzname` could be a function, class method, or static method help: Consider adding `@typing.override` if this method overrides a method from a superclass


INPUT_UNIT_RE = re.compile(r"^([0-9]+(?:\.[0-9]+)?)(?:\s*([" + "".join(suffix_power) + r"])i?)?$")
Expand Down Expand Up @@ -1910,6 +1919,7 @@
replacements = {"EMAILADDRESS": email, "EMAILLOCALPART": local_part, "EMAILDOMAIN": email_domain}

def replacer(match):
"""Return the replacement string for a matched placeholder name, or the full match if unknown."""
return replacements.get(match.group(1), match.group())

for provider in root.findall("./emailProvider"):
Expand Down Expand Up @@ -1937,15 +1947,15 @@
return None


def get_email_config(domain, email, local_part, email_domain, https_only=False, use_optional_url=True):

Check failure on line 1950 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Ruff

ruff (A001)

autoprimenet.py:1950:2: A001 Variable `str` is shadowing a Python builtin

Check warning on line 1950 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

W0622

Redefining built-in 'str'
"""Retrieve email configuration settings from the specified domain or Mozilla ISP database."""
adomain = punycode(domain)
print("Looking up configuration at e-mail provider {!r}…".format(domain))
for scheme in ("https://",) + (() if https_only else ("http://",)):

Check warning on line 1954 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

W0622

Redefining built-in 'input'
for url, params in (("autoconfig.{}/mail/config-v1.1.xml".format(domain), {"emailaddress": email}),) + (
(("{}/.well-known/autoconfig/mail/config-v1.1.xml".format(domain), None),) if use_optional_url else ()
):
try:

Check warning on line 1958 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

W0622

Redefining built-in 'range'
r = requests.get(scheme + url, params=params, timeout=5)
r.raise_for_status()
result = r.content
Expand Down Expand Up @@ -4735,6 +4745,7 @@


def transform_size(exponent):
"""Return a PrMers NTT transform size bound for exponent (min radix-2 and radix-5 limits under 64-bit)."""
log2_n = 1
while True:
log2_n += 1
Expand All @@ -4753,11 +4764,13 @@


def li(x):
"""Approximate the logarithmic integral term x/log x + x/log^2 x for prime-count estimates."""
l = math.log(x)
return x / l + x / (l * l)


def prime_count_approx(low, high):
"""Estimate how many primes lie in (low, high] using the difference of li() approximations."""
diff = li(high) - li(low)
return max(0, int(diff))

Expand Down Expand Up @@ -6687,7 +6700,7 @@
if result_type == PRIMENET.AR_PRP_RESULT:
params["rd"] = ar["res64"].strip().zfill(16)
params["rt"] = ar["residue-type"]
params["ec"] = ar.get("error-code", "0" * 8)

Check warning on line 6703 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

W0511

TODO -- have people set their own program options for commented out portions
if "known-factors" in ar:
params["nkf"] = len(ar["known-factors"])
params["base"] = ar["worktype"][4:] # worktype == PRP-base
Expand Down Expand Up @@ -7153,7 +7166,7 @@
computer,
aprogram,
string_rep,
adigits,

Check warning on line 7169 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

W0511

TODO: Unreserve assignment
" ‼️" if adigits >= 100000000 else "",
buf,
message,
Expand All @@ -7176,7 +7189,7 @@
adapter.debug("Sending result: %r", sendline)
adapter.info("Sending result to server: %s", buf)

if result_type in {PRIMENET.AR_TF_FACTOR, PRIMENET.AR_P1_FACTOR, PRIMENET.AR_ECM_FACTOR}:

Check warning on line 7192 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

W0511

TODO: Unreserve assignment
for factor in map(int, ar["factors"]):
adapter.info(
"The %s factor %s has %s decimal digits and %g bits",
Expand Down Expand Up @@ -7313,7 +7326,7 @@
length = sum(map(len, rejected.values()))
send_msg(
"🚫📤 Assignment result{} rejected on {}".format("s" if length != 1 else "", args.computer_id),
"""{:n} assignment result{} rejected from the {!r} file on your {!r} computer (worker #{}):

Check warning on line 7329 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

W0511

TODO: Something better here

{}

Expand Down Expand Up @@ -7508,7 +7521,7 @@

if args.tests_saved is not None and assignment.work_type in {
PRIMENET.WORK_TYPE_FIRST_LL,
PRIMENET.WORK_TYPE_DBLCHK,

Check warning on line 7524 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

W0511

TODO: Delete assignment from workfile if it is not done
PRIMENET.WORK_TYPE_PRP,
PRIMENET.WORK_TYPE_PFACTOR,
}:
Expand Down Expand Up @@ -8728,6 +8741,7 @@


def debug_info():
"""Print runtime, library, OS, hardware, work options, and PrimeNet identity details for bug reports."""
print(
"""
AutoPrimeNet executable: {}
Expand Down Expand Up @@ -8826,7 +8840,7 @@
config.get(SEC.Internals, "program") if config.has_option(SEC.Internals, "program") else None,
args.num_workers,
", ".join(args.work_preference) or "-",
"Yes" if args.cert_work else "No",

Check warning on line 8843 in autoprimenet.py

View workflow job for this annotation

GitHub Actions / Pylint

W0511

TODO: Delete assignment from workfile
args.days_of_work,
"s" if args.days_of_work != 1 else "",
args.min_exp or "-",
Expand Down
3 changes: 3 additions & 0 deletions gimps_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -1875,6 +1875,7 @@ def parse_work_unit_prpll(filename):


def transform_size(exponent):
"""Return a PrMers NTT transform size bound for exponent (min radix-2 and radix-5 limits under 64-bit)."""
log2_n = 1
while True:
log2_n += 1
Expand All @@ -1893,11 +1894,13 @@ def transform_size(exponent):


def li(x):
"""Approximate the logarithmic integral term x/log x + x/log^2 x for prime-count estimates."""
l = math.log(x)
return x / l + x / (l * l)


def prime_count_approx(low, high):
"""Estimate how many primes lie in (low, high] using the difference of li() approximations."""
diff = li(high) - li(low)
return max(0, int(diff))

Expand Down