diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index fb13c841..6be219ea 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -21,5 +21,5 @@ jobs:
apt:
- pandoc
envs: |
- - linux: py311
+ - linux: py312
- linux: linkcheck
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 2fd377a3..acd959a9 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -2,38 +2,45 @@ ci:
autofix_prs: false
autoupdate_schedule: "quarterly"
repos:
- - repo: https://github.com/psf/black
- rev: 24.3.0
+ - repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: "v0.3.7"
hooks:
- - id: black
- - repo: https://github.com/PyCQA/isort
- rev: 5.13.2
+ - id: ruff
+ args: ["--fix", "--unsafe-fixes"]
+ - id: ruff-format
+ - repo: https://github.com/PyCQA/autoflake
+ rev: v2.3.1
hooks:
- - id: isort
+ - id: autoflake
+ args:
+ [
+ "--in-place",
+ "--remove-all-unused-imports",
+ "--remove-unused-variable",
+ ]
+ - repo: https://github.com/PyCQA/docformatter
+ rev: v1.7.5
+ hooks:
+ - id: docformatter
+ args: ["--make-summary-multi-line", "--pre-summary-newline", "-ri"]
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v4.0.0-alpha.8
hooks:
- id: prettier
+ types_or: [css, scss, javascript, rst, json, yaml, toml, markdown]
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.5.0
+ rev: v4.6.0
hooks:
- id: check-ast
- id: check-case-conflict
- - id: trailing-whitespace
- - id: mixed-line-ending
- - id: end-of-file-fixer
+ - id: check-json
+ - id: check-toml
- id: check-yaml
- id: debug-statements
- - repo: https://github.com/PyCQA/autoflake
- rev: v2.3.1
- hooks:
- - id: autoflake
- args:
- [
- "--in-place",
- "--remove-all-unused-imports",
- "--remove-unused-variable",
- ]
+ - id: end-of-file-fixer
+ - id: mixed-line-ending
+ args: ["--fix=lf"]
+ - id: trailing-whitespace
- repo: https://github.com/codespell-project/codespell
rev: v2.2.6
hooks:
diff --git a/conf.py b/conf.py
index f33a5369..48fe3e5f 100644
--- a/conf.py
+++ b/conf.py
@@ -1,8 +1,8 @@
-import os
import sys
+from pathlib import Path
from urllib.request import urlretrieve
-sys.path.append(os.path.abspath("exts"))
+sys.path.append(Path("exts").absolute().as_posix())
extensions = [
"cards",
"myst_parser",
@@ -51,17 +51,14 @@
".tox/*",
]
master_doc = "index"
-project = "SunPy"
-author = "SunPy Project"
-copyright = "SunPy Project"
+project = "sunpy.org"
+author = "The SunPy Community"
+copyright = "The SunPy Community" # NOQA: A001
show_sphinx = True
version = ""
release = "main"
language = "en"
-
pygments_style = "sphinx"
-
-
default_role = "obj"
html_theme = "sunpy"
html_title = "sunpy.org"
@@ -71,11 +68,9 @@
"show_prev_next": False,
"sst_is_root": True,
}
-
html_css_files = [
"sunpy_org.css",
]
-
blog_sidebars = [
"ablog/postcard.html",
"ablog/recentposts.html",
@@ -83,7 +78,6 @@
"ablog/categories.html",
"ablog/archives.html",
]
-
html_sidebars = {
"*": [],
"about": ["about-sidebar.html"],
@@ -93,14 +87,12 @@
"blog": blog_sidebars,
"blog/**": blog_sidebars,
}
-
redirects = {
"project/meetings": "about/meetings",
"project/roles": "about/roles",
"project": "about/project",
"project/affiliated": "affiliated",
}
-
# nbsphinx options
nbsphinx_prolog = r"""
{% set docname = env.doc2path(env.docname, base=None) %}
@@ -123,18 +115,16 @@
ogp_image = "https://raw.githubusercontent.com/sunpy/sunpy-logo/master/generated/sunpy_logo_word.png"
ogp_description_length = 300
ogp_type = "website"
-
urlretrieve(
"https://raw.githubusercontent.com/sunpy/sunpy/main/sunpy/CITATION.rst",
filename="CITATION.rst",
)
-
# These links have anchors that linkcheck does not like
linkcheck_ignore = [
"https://app.element.io/#/room/#sunpy:openastronomy.org",
]
linkcheck_anchors_ignore = [
- "/projects\?project=develop_sunkit-image",
+ r"/projects\?project=develop_sunkit-image",
"the-executive",
"acceptance-process-for-affiliated-packages",
"detailed-description",
diff --git a/exts/cards/__init__.py b/exts/cards/__init__.py
index c6860e29..b17446d9 100644
--- a/exts/cards/__init__.py
+++ b/exts/cards/__init__.py
@@ -1,4 +1,3 @@
-import os
from pathlib import Path
from docutils import nodes
@@ -15,9 +14,7 @@ def visit_card_node(self, node):
key = title or node["github"]
key = key.lower().replace(" ", "-")
title = f"
{title}
" if len(title) > 0 else ""
-
col_extra_class = "column-half" if title else ""
-
body = f"""
{title}
@@ -46,7 +43,6 @@ def depart_card_node(self, node):
"""
-
self.body.append(body)
@@ -54,7 +50,7 @@ class Card(Directive):
has_content = True
required_arguments = 1
optional_arguments = 6
- option_spec = {
+ option_spec = { # NOQA: RUF012
"img_name": directives.unchanged,
"title": directives.unchanged,
"github": directives.unchanged,
@@ -65,37 +61,14 @@ class Card(Directive):
}
def run(self):
- if "title" in self.options:
- title = self.options.get("title")
- else:
- title = ""
- if "img_name" in self.options:
- img_name = self.options.get("img_name")
- else:
- img_name = "sunpy_icon.svg"
- if "github" in self.options:
- github = self.options.get("github")
- else:
- github = ""
- if "aff_name" in self.options:
- aff_name = self.options.get("aff_name")
- else:
- aff_name = ""
- if "aff_link" in self.options:
- aff_link = self.options.get("aff_link")
- else:
- aff_link = ""
- if "date" in self.options:
- date = self.options.get("date")
- else:
- date = ""
- if "desc" in self.options:
- desc = self.options.get("desc")
- else:
- desc = "N/A"
-
+ title = self.options.get("title") if "title" in self.options else ""
+ img_name = self.options.get("img_name") if "img_name" in self.options else "sunpy_icon.svg"
+ github = self.options.get("github") if "github" in self.options else ""
+ aff_name = self.options.get("aff_name") if "aff_name" in self.options else ""
+ aff_link = self.options.get("aff_link") if "aff_link" in self.options else ""
+ date = self.options.get("date") if "date" in self.options else ""
+ desc = self.options.get("desc") if "desc" in self.options else "N/A"
name = " ".join(self.arguments)
-
out = card(
name=name,
img_name=img_name,
@@ -106,26 +79,21 @@ def run(self):
date=date,
desc=desc,
)
-
self.state.nested_parse(self.content, 0, out)
-
return [out]
def copy_asset_files(app, exc):
- if exc is None: # build succeeded
+ if exc is None: # Build succeeded
for path in (Path(__file__).parent / "static").glob("*"):
- copy_asset(str(path), os.path.join(app.outdir, "_static"))
+ copy_asset(str(path), str(Path(app.outdir) / Path("_static")))
def setup(app):
app.add_node(card, html=(visit_card_node, depart_card_node))
-
app.add_css_file("cards.css")
app.add_directive("custom-card", Card)
-
app.connect("build-finished", copy_asset_files)
-
return {
"parallel_read_safe": True,
"parallel_write_safe": True,
diff --git a/exts/rawfiles.py b/exts/rawfiles.py
index 3ee85e18..18dd05e4 100644
--- a/exts/rawfiles.py
+++ b/exts/rawfiles.py
@@ -1,12 +1,12 @@
-import os
import shutil
+from pathlib import Path
def on_html_collect_pages(app):
for f in app.builder.config.rawfiles:
- src = os.path.join(app.srcdir, f)
- dst = os.path.join(app.builder.outdir, f)
- if os.path.isfile(src):
+ src = str(Path(app.srcdir) / Path(f))
+ dst = str(Path(app.builder.outdir) / Path(f))
+ if Path(src).is_file():
shutil.copy(src, dst)
else:
shutil.copytree(src, dst)
diff --git a/github_submodule b/github_submodule
index d3bbbe7e..00a91fca 160000
--- a/github_submodule
+++ b/github_submodule
@@ -1 +1 @@
-Subproject commit d3bbbe7e16d7d8df11bacb421abaeb4607657283
+Subproject commit 00a91fca5014c648fb9bd19f34b087f57be8774c
diff --git a/posts/2024/2024-04-03-eclipse.ipynb b/posts/2024/2024-04-03-eclipse.ipynb
index e7930fc0..c62828cd 100644
--- a/posts/2024/2024-04-03-eclipse.ipynb
+++ b/posts/2024/2024-04-03-eclipse.ipynb
@@ -456,7 +456,9 @@
"metadata": {},
"outputs": [],
"source": [
- "eclipse_map.plot()\n",
+ "fig = plt.figure(figsize=(9,9))\n",
+ "ax = plt.subplot(projection=eclipse_map)\n",
+ "eclipse_map.plot(axes=ax)\n",
"plt.show()"
]
},
diff --git a/posts/2024/eclipse_helpers.py b/posts/2024/eclipse_helpers.py
index 77c92d55..63a8fab0 100644
--- a/posts/2024/eclipse_helpers.py
+++ b/posts/2024/eclipse_helpers.py
@@ -6,7 +6,8 @@
def _convert_to_degress(value):
"""
- Helper function to convert the GPS coordinates stored in the EXIF to degrees
+ Helper function to convert the GPS coordinates stored in the EXIF to
+ degrees.
"""
d = value.values[0].num / value.values[0].den * u.degree
m = value.values[1].num / value.values[1].den * u.arcminute
@@ -17,7 +18,8 @@ def _convert_to_degress(value):
def get_exif_location(exif_data):
"""
- Returns the latitude, longitude, and altitude, if available, from the provided exif_data
+ Returns the latitude, longitude, and altitude, if available, from the
+ provided exif_data.
"""
lat = None
lon = None
@@ -48,16 +50,12 @@ def get_camera_metadata(tags):
camera_metadata = {}
if "EXIF ExposureTime" in tags:
exposure_tag = tags["EXIF ExposureTime"]
- camera_metadata["exposure_time"] = (
- exposure_tag.values[0].num / exposure_tag.values[0].den * u.s
- )
+ camera_metadata["exposure_time"] = exposure_tag.values[0].num / exposure_tag.values[0].den * u.s
if "Image Artist" in tags:
camera_metadata["author"] = tags["Image Artist"].values
if "EXIF DateTimeOriginal" in tags:
datetime_str = tags["EXIF DateTimeOriginal"].values.replace(" ", ":").split(":")
- camera_metadata["time"] = parse_time(
- f"{'-'.join(datetime_str[:3])} {':'.join(datetime_str[3:])}"
- )
+ camera_metadata["time"] = parse_time(f"{'-'.join(datetime_str[:3])} {':'.join(datetime_str[3:])}")
if "Image Model" in tags:
camera_metadata["camera_model"] = tags["Image Model"].values
diff --git a/requirements.txt b/requirements.txt
index 1af32ae9..bd234410 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,23 +1,21 @@
-# RC versions are needed as netfily does not support modern python
-ablog>=0.11.0rc1
-sunpy-sphinx-theme>=2.0.0
+ablog>=0.11.0
ipykernel
ipython
jupyter_client
myst-parser
nbsphinx
sphinx
-sphinxext-opengraph
-sphinx-design
sphinx_reredirects
+sphinx-design
sphinxcontrib-youtube
+sphinxext-opengraph
+sunpy-sphinx-theme>=2.0.0
-# eclipse notebooks
+# Eclipse notebook
+astropy
exifread
-numpy
+ipywidgets
matplotlib
-astropy
+numpy
scikit-image
sunpy[map,net]
-photutils
-ipywidgets
diff --git a/ruff.toml b/ruff.toml
new file mode 100644
index 00000000..1209f362
--- /dev/null
+++ b/ruff.toml
@@ -0,0 +1,83 @@
+# Allow unused variables when underscore-prefixed.
+lint.dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
+target-version = "py39"
+line-length = 120
+exclude=[
+ ".git,",
+ "__pycache__",
+ "build",
+ "tools/**",
+]
+lint.select = [
+ "A",
+ "ARG",
+ "ASYNC",
+ "B",
+ "BLE",
+ "C4",
+ "COM",
+ "DTZ",
+ "E",
+ "EM",
+ "ERA",
+ "EXE",
+ "F",
+ "FBT",
+ "FLY",
+ "G",
+ "I",
+ "ICN",
+ "INP",
+ "INT",
+ "ISC",
+ "LOG",
+ "NPY",
+ "PERF",
+ "PGH",
+ "PIE",
+ "PLE",
+ "PT",
+ "PTH",
+ "PYI",
+ "Q",
+ "RET",
+ "RSE",
+ "RUF",
+ "SIM",
+ "SLF",
+ "SLOT",
+ "T10",
+ "T20",
+ "TCH",
+ "TID",
+ "TRIO",
+ "TRY",
+ "UP",
+ "W",
+ "YTT",
+]
+lint.extend-ignore = [
+ "COM812", # May cause conflicts when used with the formatter
+ "E501", # Line too long
+ "ISC001", # May cause conflicts when used with the formatter
+ "T201", # Print statements
+]
+
+[lint.per-file-ignores]
+"exts/rawfiles.py" = [
+ "INP001", # Part of an implicit namespace package
+]
+"posts/2024/eclipse_helpers.py" = [
+ "INP001", # Part of an implicit namespace package
+]
+"docs/conf.py" = [
+ "INP001", # Part of an implicit namespace package
+]
+
+[lint.pydocstyle]
+convention = "numpy"
+
+[format]
+docstring-code-format = true
+indent-style = "space"
+quote-style = "double"
diff --git a/tox.ini b/tox.ini
index dafb33e6..31584a9e 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,7 +1,7 @@
[tox]
minversion = 4.0
envlist =
- py{39,310,311}
+ py{39,310,311,312}
codestyle
linkcheck