Skip to content

Commit 1e7c0af

Browse files
authored
Merge pull request #6349 from LMFDB/main
main -> dev
2 parents fa63960 + c4663e2 commit 1e7c0af

9 files changed

Lines changed: 66 additions & 36 deletions

File tree

lmfdb/artin_representations/math_classes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@ def GaloisLabel(self):
424424
return self._data['GaloisLabel']
425425

426426
def group(self):
427-
n, t = [int(z) for z in self._data['GaloisLabel'].split("T")]
427+
n, t = (int(z) for z in self._data['GaloisLabel'].split("T"))
428428
return group_display_short(n, t)
429429

430430
def pretty_galois_knowl(self):

lmfdb/classical_modular_forms/download.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -492,13 +492,13 @@ def _magma_MakeCharacters(self, newform, hecke_nf):
492492
self.explain.append(explain)
493493
out += [
494494
explain,
495-
'function MakeCharacter_%d_%s_Hecke(Kf)' % (newform.level, newform.char_orbit_label),
495+
'function MakeCharacter_%d_%s_Hecke( : Kf := None)' % (newform.level, newform.char_orbit_label),
496496
' ' + magma.assign('N', level).rstrip('\n'), # level
497497
' ' + magma.assign('order', order).rstrip('\n'), # order of the character
498498
' ' + magma.assign('char_gens', char_gens).rstrip('\n'), # generators
499499
' ' + magma.assign('char_values', char_values).rstrip('\n'), # chi(gens[i]) = zeta_n^exp[i]
500500
' assert UnitGenerators(DirichletGroup(N)) eq char_gens;',
501-
' values := ConvertToHeckeField(char_values : pass_field := true, Kf := Kf); // the value of chi on the gens as elements in the Hecke field',
501+
' values := ConvertToHeckeField(char_values : pass_field := ISA(Type(Kf), Fld), Kf := Kf); // the value of chi on the gens as elements in the Hecke field',
502502
' F := Universe(values);// the Hecke field',
503503
' chi := DirichletCharacterFromValuesOnUnitGenerators(DirichletGroup(N,F),values);',
504504
' return chi;',
@@ -557,7 +557,7 @@ def _magma_qexpCoeffs(self, newform, hecke_nf):
557557
' ' + magma.assign('weight', newform.weight).rstrip('\n'),
558558
' ' + magma.assign('raw_aps', hecke_nf['ap']).rstrip('\n'),
559559
' aps := ConvertToHeckeField(raw_aps);',
560-
' chi := MakeCharacter_%d_%s_Hecke(Universe(aps));' % (newform.level, newform.char_orbit_label),
560+
' chi := MakeCharacter_%d_%s_Hecke( : Kf := Universe(aps));' % (newform.level, newform.char_orbit_label),
561561
' return ExtendMultiplicatively(weight, aps, chi);',
562562
'end function;',
563563
]

lmfdb/groups/abstract/web_groups.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1977,7 +1977,7 @@ def pad(X, m):
19771977
st_latex += "1"
19781978
else:
19791979
st_latex += "0"
1980-
if (i+1)%d == 0:
1980+
if (i + 1) % d == 0:
19811981
st_latex += r' \\ '
19821982
else:
19831983
st_latex += ' & '

lmfdb/knowledge/knowl.py

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# the basic knowledge object, with database awareness, …
22

3-
from datetime import datetime, timedelta
43
from collections import defaultdict
5-
import time
4+
from datetime import datetime, timedelta
5+
import re
66
import subprocess
7-
import sys
7+
import time
88

99
from psycodict.base import PostgresBase
1010
from psycodict import DelayCommit
@@ -17,7 +17,7 @@
1717
from psycopg2.sql import SQL, Identifier, Placeholder
1818
from sage.all import cached_function
1919

20-
import re
20+
2121
text_keywords = re.compile(r"\b[a-zA-Z0-9-]{3,}\b")
2222
top_knowl_re = re.compile(r"(.*)\.top$")
2323
comment_knowl_re = re.compile(r"(.*)\.(\d+)\.comment$")
@@ -582,11 +582,8 @@ def code_references(self, knowl):
582582
matches = []
583583
for kid in kids:
584584
try:
585-
if sys.version_info[0] == 3:
586-
matches.extend(subprocess.check_output(['git', 'grep', '--full-name', '--line-number', '--context', '2', """['"]%s['"]""" % (kid.replace('.',r'\.'))],encoding='utf-8').split('\n--\n'))
587-
else:
588-
matches.extend(subprocess.check_output(['git', 'grep', '--full-name', '--line-number', '--context', '2', """['"]%s['"]""" % (kid.replace('.',r'\.'))]).split('\n--\n'))
589-
except subprocess.CalledProcessError: # no matches
585+
matches.extend(subprocess.check_output(['git', 'grep', '--full-name', '--line-number', '--context', '2', """['"]%s['"]""" % (kid.replace('.',r'\.'))],encoding='utf-8').split('\n--\n'))
586+
except subprocess.CalledProcessError: # no matches
590587
pass
591588
return [self._process_git_grep(match) for match in matches]
592589

@@ -600,11 +597,8 @@ def check_sed_safety(self, knowlid):
600597
- -1 if the knowl is referenced but cannot be safely replaced.
601598
"""
602599
try:
603-
if sys.version_info[0] == 3:
604-
matches = subprocess.check_output(['git', 'grep', """['"]%s['"]""" % (knowlid.replace('.',r'\.'))],encoding='utf-8').split('\n')
605-
else:
606-
matches = subprocess.check_output(['git', 'grep', """['"]%s['"]""" % (knowlid.replace('.',r'\.'))]).split('\n')
607-
except subprocess.CalledProcessError: # no matches
600+
matches = subprocess.check_output(['git', 'grep', """['"]%s['"]""" % (knowlid.replace('.',r'\.'))],encoding='utf-8').split('\n')
601+
except subprocess.CalledProcessError: # no matches
608602
return 0
609603

610604
easy_matches = subprocess.check_output(['git', 'grep', knowlid.replace('.',r'\.')],encoding='utf-8').split('\n')
@@ -705,10 +699,7 @@ def broken_links_code(self):
705699
ids that show up in an expression of the form ``KNOWL('BAD_ID')``.
706700
"""
707701
all_kids = {k['id'] for k in self.get_all_knowls(['id'])}
708-
if sys.version_info[0] == 3:
709-
matches = subprocess.check_output(['git', 'grep', '-E', '--full-name', '--line-number', '--context', '2', link_finder_re.pattern],encoding='utf-8').split('\n--\n')
710-
else:
711-
matches = subprocess.check_output(['git', 'grep', '-E', '--full-name', '--line-number', '--context', '2', link_finder_re.pattern]).split('\n--\n')
702+
matches = subprocess.check_output(['git', 'grep', '-E', '--full-name', '--line-number', '--context', '2', link_finder_re.pattern],encoding='utf-8').split('\n--\n')
712703
results = []
713704
for match in matches:
714705
lines = match.split('\n')

lmfdb/lfunctions/main.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
from lmfdb.classical_modular_forms.main import set_Trn, process_an_constraints
4545
from lmfdb.artin_representations.main import parse_artin_label
4646
from lmfdb.utils.search_parsing import (
47-
parse_bool, parse_ints, parse_floats, parse_noop, parse_mod1,
47+
parse_bool, parse_ints, parse_ints_to_list, parse_floats, parse_noop, parse_mod1,
4848
parse_element_of, parse_not_element_of, search_parser)
4949
from lmfdb.utils import (
5050
to_dict, signtocolour, rgbtohex, key_for_numerically_sort, display_float,
@@ -349,6 +349,14 @@ def common_parse(info, query):
349349
download_col="instance_urls")],
350350
db_cols=['algebraic', 'analytic_conductor', 'bad_primes', 'central_character', 'conductor', 'degree', 'instance_urls', 'label', 'motivic_weight', 'mu_real', 'mu_imag', 'nu_real_doubled', 'nu_imag', 'order_of_vanishing', 'primitive', 'rational', 'root_analytic_conductor', 'root_angle', 'self_dual', 'z1'])
351351

352+
euler_factor_columns = SearchColumns([
353+
MultiProcessedCol("label", "lfunction.label", "Label",
354+
["label", "url"],
355+
lambda label, url: '<a href="%s">%s</a>' % (url, label),
356+
download_col="label")] +
357+
[MathCol("euler%s" % p, "lfunction.euler_factor", r"$F_%s(T)$" % p, default=False) for p in prime_range(100)],
358+
db_cols=1)
359+
352360
class LfuncDownload(Downloader):
353361
table = db.lfunc_search
354362
def postprocess(self, rec, info, query):
@@ -419,7 +427,8 @@ def parse_euler(inp, query, qfield, p=None, d=None):
419427
table=db.lfunc_search,
420428
title="L-function Euler product search",
421429
err_title="L-function search input error",
422-
shortcuts={'jump':jump_box},
430+
columns=euler_factor_columns,
431+
shortcuts={'jump':jump_box, 'download': LfuncDownload()},
423432
postprocess=process_euler,
424433
learnmore=learnmore_list,
425434
bread=lambda: get_bread(breads=[("Search results", " ")]))
@@ -435,6 +444,8 @@ def euler_search(info, query):
435444
flash_error("To search on <span style='color:black'>Euler factors</span>, you must specify one <span style='color:black'>degree</span>.")
436445
info['err'] = ''
437446
raise ValueError("To search on Euler factors, you must specify one degree")
447+
p_range = parse_ints_to_list(info['n'])
448+
info["showcol"] = ".".join(["euler%s" % p for p in prime_range(100) if p in p_range])
438449
for p in prime_range(100):
439450
parse_euler(info, query, 'euler_constraints', qfield='euler%s' % p, p=p, d=d)
440451

lmfdb/local_fields/main.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,22 @@ def lf_display_knowl(label, name=None):
116116
def local_algebra_display_knowl(labels):
117117
return '<a title = "{0} [lf.algebra.data]" knowl="lf.algebra.data" kwargs="labels={0}">{0}</a>' % (labels)
118118

119+
def eisensteinformlatex(pol, unram):
120+
# pol=coeffs, unram =string
121+
R = PolynomialRing(QQ, 'y')
122+
Rx = PolynomialRing(R, 'x')
123+
unram2 = R(unram.replace('t', 'y'))
124+
unram = latex(Rx(unram.replace('t', 'x')))
125+
pol = R(pol)
126+
l = []
127+
while pol != 0:
128+
qr = pol.quo_rem(unram2)
129+
l.append(qr[1])
130+
pol = qr[0]
131+
newpol = latex(Rx(l))
132+
newpol = newpol.replace('x', '(' + unram + ')')
133+
newpol = newpol.replace('y', 'x')
134+
return newpol
119135

120136
def plot_polygon(verts, polys, inds, p):
121137
verts = [tuple(pt) for pt in verts]
@@ -316,6 +332,7 @@ def intcol(j):
316332
return 'not computed'
317333
return f'${j}$'
318334

335+
319336
lf_columns = SearchColumns([
320337
LinkCol("label", "lf.field.label", "Label", url_for_label),
321338
MathCol("n", "lf.degree", "$n$", short_title="degree", default=False),
@@ -460,14 +477,19 @@ def render_field_webpage(args):
460477
else:
461478
wild_inertia = 'Not computed'
462479

480+
if data['f'] == 1 or data['e'] == 1:
481+
thepolynomial = raw_typeset(polynomial)
482+
else:
483+
eform = '$' + eisensteinformlatex(data['coeffs'], data['unram']) + '$'
484+
thepolynomial = raw_typeset(polynomial, eform)
463485
info.update({
464-
'polynomial': raw_typeset(polynomial),
486+
'polynomial': thepolynomial,
465487
'n': data['n'],
466488
'p': p,
467489
'c': data['c'],
468490
'e': data['e'],
469491
'f': data['f'],
470-
'rf': lf_display_knowl( rflabel, name=printquad(data['rf'], p)),
492+
'rf': lf_display_knowl(rflabel, name=printquad(data['rf'], p)),
471493
'base': lf_display_knowl(str(p)+'.1.0.1', name='$%s$' % Qp),
472494
'hw': data['hw'],
473495
'visible': show_slopes(data['visible']),
@@ -505,7 +527,7 @@ def render_field_webpage(args):
505527
friends.append(('Discriminant root field', rffriend))
506528
if data['is_completion']:
507529
friends.append(('Number fields with this completion',
508-
url_for('number_fields.number_field_render_webpage')+"?completions={}".format(label) ))
530+
url_for('number_fields.number_field_render_webpage')+"?completions={}".format(label)))
509531
downloads = [('Underlying data', url_for('.lf_data', label=label))]
510532

511533
bread = get_bread([(label, ' ')])

lmfdb/nfutils/psort.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ def prime_label(P):
170170
def prime_from_label(K, lab):
171171
"""Return the prime of K from a label, or 0 is there is no such prime
172172
"""
173-
n, j = [ZZ(c) for c in lab.split(".")]
173+
n, j = (ZZ(c) for c in lab.split("."))
174174
p, f = n.factor()[0]
175175
make_keys(K,p)
176176
d = K.psort_dict[p]
@@ -316,15 +316,17 @@ def ppower_norm_ideal_key(Q):
316316
"""
317317
return (Q.norm(), ppower_norm_ideal_index(Q))
318318

319+
319320
def ppower_norm_ideal_label(Q):
320321
r""" return the label of an ideal of prime-power norm.
321322
"""
322323
return "{}.{}".format(Q.norm(),ppower_norm_ideal_index(Q))
323324

325+
324326
def ppower_norm_ideal_from_label(K,lab):
325327
r""" return the ideal of prime-power norm from its label.
326328
"""
327-
n, i = [int(c) for c in lab.split(".")]
329+
n, i = (int(c) for c in lab.split("."))
328330
p, f = ZZ(n).factor()[0]
329331
make_keys(K,p)
330332
PP = K.primes_dict[p]
@@ -369,12 +371,14 @@ def ideal_label(I):
369371
"""
370372
return "{}.{}".format(I.norm(),ideal_norm_index(I))
371373

374+
372375
def ideal_from_label(K,lab):
373376
r""" Return the ideal with a given label.
374377
"""
375-
n, j = [int(c) for c in lab.split(".")]
378+
n, j = (int(c) for c in lab.split("."))
376379
return ideals_of_norm(K,ZZ(n))[j-1]
377380

381+
378382
def ideals_iterator(K,minnorm=1,maxnorm=Infinity):
379383
r""" Return an iterator over all ideals of norm n up to maxnorm (sorted).
380384
"""

lmfdb/number_fields/number_field.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,10 @@ def number_field_search(info, query):
913913
opts = multiquad
914914
if "degree" in info:
915915
opts = {n: opts[n] for n in integer_options(info["degree"], contained_in=list(opts), lower_bound=1, upper_bound=47) if n in opts}
916+
# Catch if signature is specified
917+
# We already parsed it, which sets degree to a single value
918+
if "signature" in info:
919+
opts = {n: opts[n] for n in integer_options(str(query["degree"]), contained_in=list(opts), lower_bound=1, upper_bound=47) if n in opts}
916920
if "galois_label" in query:
917921
# Added by parse_galgrp, so we intersect with opts
918922
if isinstance(query["galois_label"], dict):

lmfdb/users/main.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,6 @@ def admin():
319319
@app.route("/restartserver")
320320
@admin_required
321321
def restart():
322-
import sys
323322
from subprocess import Popen, PIPE
324323
from urllib.parse import urlparse
325324
urlparts = urlparse(request.url)
@@ -330,14 +329,12 @@ def restart():
330329
else:
331330
command = None
332331
if command:
333-
if sys.version_info[0] == 3:
334-
out = Popen(command, stdout=PIPE, encoding='utf-8').communicate()[0]
335-
else:
336-
out = Popen(command, stdout=PIPE).communicate()[0]
332+
out = Popen(command, stdout=PIPE, encoding='utf-8').communicate()[0]
337333
return out.replace('\n', '<br>')
338334
else:
339335
return "Only supported in beta.lmfdb.org, prodweb1.lmfdb.xyz, and prodweb2.lmfdb.xyz"
340336

337+
341338
class Reviewer(Uploader):
342339
"""
343340
This uploader is used to collect UploadSection objects from different sections of the LMFDB that use them.
@@ -346,6 +343,7 @@ def __init__(self):
346343
from lmfdb.modular_curves.upload import Points, PointCompleteness, GonalityBounds, Models, UniversalEC, MultiKnowl
347344
super().__init__([Points(), PointCompleteness(), GonalityBounds(), Models(), UniversalEC(), MultiKnowl()])
348345

346+
349347
@login_page.route("/uploads", methods=["GET", "POST"])
350348
@login_required
351349
def review_uploads():

0 commit comments

Comments
 (0)