Skip to content

Commit

Permalink
Remove setup.py (#158)
Browse files Browse the repository at this point in the history
  • Loading branch information
lukeshingles authored Feb 20, 2024
1 parent 5c38d8c commit a6278ce
Show file tree
Hide file tree
Showing 11 changed files with 136 additions and 102 deletions.
1 change: 0 additions & 1 deletion .github/workflows/deploypypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ jobs:
- name: Install dependencies
run: |
python3 -m pip install --upgrade pip
python3 -m pip install -r requirements.txt
python3 -m pip install --upgrade setuptools setuptools_scm[toml] wheel twine build
- name: Build
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/deploytestpypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ jobs:
- name: Install dependencies
run: |
python3 -m pip install --upgrade pip
python3 -m pip install -r requirements.txt
python3 -m pip install --upgrade setuptools setuptools_scm[toml] wheel twine build
- name: Build
Expand Down
14 changes: 13 additions & 1 deletion .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,18 @@ jobs:
with:
python-version: ${{ matrix.python-version }}

- name: Cache venv
uses: actions/cache@v4
with:
path: .venv
key: py${{ matrix.python-version }}-venv

- name: Install artistools
run: |
python3 -m pip install --upgrade uv
uv venv
if [ ! -d ".venv" ]; then uv venv .venv; fi
source .venv/bin/activate
echo "PATH=$PWD/.venv/bin:$PATH" >> $GITHUB_ENV
uv pip install -e .
- name: Cache test data
Expand All @@ -54,6 +61,11 @@ jobs:
working-directory: tests/data/
run: source ./setuptestdata.sh

- name: Check artistools command line tool
run: |
.venv/bin/artistools --help
.venv/bin/artistools setupcompletions
- name: Test with pytest
run: |
source .venv/bin/activate
Expand Down
13 changes: 10 additions & 3 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
recursive-include artistools *.csv
recursive-include artistools *.txt
recursive-include artistools matplotlibrc
global-include *.pyi
global-include *.typed
global-include *.md
global-include *.cff
include LICENSE.txt
include LICENSE.txt
recursive-exclude dist *
recursive-exclude build *
prune **/.*
prune **/*.egg*
prune tests
prune build
prune lib
prune dist
prune images
8 changes: 4 additions & 4 deletions artistools/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@
import argcomplete

from artistools.commands import CommandType
from artistools.commands import dictcommands as atdictcommands
from artistools.commands import subcommandtree as atdictcommands
from artistools.misc import CustomArgHelpFormatter


def addsubparsers(
parser: argparse.ArgumentParser, parentcommand: str, dictcommands: CommandType, depth: int = 1
parser: argparse.ArgumentParser, parentcommand: str, subcommandtree: CommandType, depth: int = 1
) -> None:
def func(args: t.Any) -> None:
parser.print_help()

parser.set_defaults(func=func)
subparsers = parser.add_subparsers(dest=f"{parentcommand} command", required=False)

for subcommand, subcommands in dictcommands.items():
for subcommand, subcommands in subcommandtree.items():
strhelp: str | None
if isinstance(subcommands, dict):
strhelp = "command group"
Expand All @@ -40,7 +40,7 @@ def func(args: t.Any) -> None:
subparser.set_defaults(func=func)
else:
assert not isinstance(subcommands, tuple)
addsubparsers(parser=subparser, parentcommand=subcommand, dictcommands=subcommands, depth=depth + 1)
addsubparsers(parser=subparser, parentcommand=subcommand, subcommandtree=subcommands, depth=depth + 1)


def addargs(parser: argparse.ArgumentParser) -> None:
Expand Down
56 changes: 24 additions & 32 deletions artistools/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,32 @@
import typing as t
from pathlib import Path

# top-level commands (one file installed per command)
# we generally should phase this out except for a couple of main ones like at and artistools
COMMANDS = [
"at",
"artistools",
"makeartismodel1dslicefromcone",
"makeartismodel",
"plotartisdensity",
"plotartisdeposition",
"plotartisestimators",
"plotartislightcurve",
"plotartislinefluxes",
"plotartismacroatom",
"plotartisnltepops",
"plotartisnonthermal",
"plotartisradfield",
"plotartisspectrum",
"plotartistransitions",
"plotartisinitialcomposition",
"plotartisviewingangles",
]

CommandType: t.TypeAlias = dict[str, t.Union[tuple[str, str], "CommandType"]]

# new subparser based list
dictcommands: CommandType = {
subcommandtree: CommandType = {
"comparetogsinetwork": ("gsinetwork", "main"),
"deposition": ("deposition", "main_analytical"),
"describeinputmodel": ("inputmodel.describeinputmodel", "main"),
Expand Down Expand Up @@ -52,36 +74,6 @@
}


def get_commandlist() -> dict[str, tuple[str, str]]:
# direct commands (one file installed per command)
# we generally should phase this out except for a couple of main ones like at and artistools
return {
"at": ("artistools", "main"),
"artistools": ("artistools", "main"),
"makeartismodel1dslicefromcone": ("artistools.inputmodel.slice1dfromconein3dmodel", "main"),
"makeartismodel": ("artistools.inputmodel.makeartismodel", "main"),
"plotartisdensity": ("artistools.inputmodel.plotdensity", "main"),
"plotartisdeposition": ("artistools.deposition", "main"),
"plotartisestimators": ("artistools.estimators.plotestimators", "main"),
"plotartislightcurve": ("artistools.lightcurve.plotlightcurve", "main"),
"plotartislinefluxes": ("artistools.linefluxes", "main"),
"plotartismacroatom": ("artistools.macroatom", "main"),
"plotartisnltepops": ("artistools.nltepops.plotnltepops", "main"),
"plotartisnonthermal": ("artistools.nonthermal", "main"),
"plotartisradfield": ("artistools.radfield", "main"),
"plotartisspectrum": ("artistools.spectra.plotspectra", "main"),
"plotartistransitions": ("artistools.transitions", "main"),
"plotartisinitialcomposition": ("artistools.inputmodel.plotinitialcomposition", "main"),
"plotartisviewingangles": ("artistools.viewing_angles_visualization", "main"),
}


def get_console_scripts() -> list[str]:
return [
f"{command} = {submodulename}:{funcname}" for command, (submodulename, funcname) in get_commandlist().items()
]


def setup_completions(*args: t.Any, **kwargs: t.Any) -> None:
# Add the following lines to your .zshrc file to get command completion:
# autoload -U bashcompinit
Expand All @@ -105,7 +97,7 @@ def setup_completions(*args: t.Any, **kwargs: t.Any) -> None:
f.write(strsplit)
f.write("\n\n")

for command in get_commandlist():
for command in COMMANDS:
completecommand = strcommandregister.replace("__MY_COMMAND__", command)
f.write(completecommand + "\n")

Expand Down
17 changes: 8 additions & 9 deletions artistools/nonthermal/_nonthermal_core.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python3


import argparse
import math
from collections import namedtuple
from math import atan
Expand Down Expand Up @@ -284,7 +284,7 @@ def lossfunction(energy_ev, nne_cgs):
return lossfunc / EV # return as [eV / cm]


def Psecondary(e_p, ionpot_ev, J, e_s=-1, epsilon=-1):
def Psecondary(e_p: float, ionpot_ev: float, J: float, e_s: float = -1, epsilon: float = -1) -> float:
# probability distribution function for secondaries energy e_s [eV] (or equivalently the energy loss of
# the primary electron epsilon [eV]) given a primary energy e_p [eV] for an impact ionisation event

Expand Down Expand Up @@ -1257,7 +1257,7 @@ def calculate_Latom_ionisation(ions, ionpopdict, dfcollion, nntot, nne, en_ev, n
return L_atom_sum


def workfunction_tests(modelpath, args):
def workfunction_tests(modelpath: str | Path, args: argparse.Namespace) -> None:
electron_binding = read_binding_energies()
dfcollion = at.nonthermal.read_colliondata()

Expand All @@ -1266,14 +1266,11 @@ def workfunction_tests(modelpath, args):
)
axes = [axes]

ionpopdict = {
# (16, 2): 3e5,
ionpopdict: dict[tuple[int, int], float] = {
(26, 2): 1e5,
}

# keep only the ion populations, not element or total populations
ions = [key for key in ionpopdict if isinstance(key, tuple) and len(key) == 2]
ions.sort()
ions = sorted(ionpopdict.keys())

nntot = get_nntot(ions=ions, ionpopdict=ionpopdict)
nnetot = get_nnetot(ions=ions, ionpopdict=ionpopdict) # total electrons: free and bound included
Expand Down Expand Up @@ -1454,7 +1451,9 @@ def workfunction_tests(modelpath, args):
integrand = arr_xs / (L / EV)
# arr_workfn_integrated[i] is the en_ev / (integral xs / L dE from EMIN to E[i])
with np.errstate(divide="ignore"):
arr_workfn_integrated = [arr_en_ev[i] / (sum((integrand * delta_en_ev)[:i])) for i in range(len(arr_en_ev))]
arr_workfn_integrated = np.array(
[arr_en_ev[i] / (sum((integrand * delta_en_ev)[:i])) for i in range(len(arr_en_ev))]
)

print(f"\n workfn_integral_Emin_Emax: {arr_workfn_integrated[-1]:.2f} eV")
print(f" eta_ion {ionpot_valence_ev / arr_workfn_integrated[-1]:.3f}")
Expand Down
25 changes: 18 additions & 7 deletions artistools/test_artistools.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#!/usr/bin/env python3
import contextlib
import hashlib
import importlib
import inspect
import math
import typing as t
from pathlib import Path

import artistools as at

Expand All @@ -23,12 +25,21 @@ def funcname() -> str:


def test_commands() -> None:
# ensure that the commands are pointing to valid submodule.function() targets
for _command, (submodulename, funcname) in sorted(at.commands.get_commandlist().items()):
submodule = importlib.import_module(submodulename)
assert hasattr(submodule, funcname) or (
funcname == "main" and hasattr(importlib.import_module(f"{submodulename}.__main__"), funcname)
)
commands: dict[str, tuple[str, str]] = {}

with contextlib.suppress(ImportError):
import tomllib

with Path("pyproject.toml").open("rb") as f:
pyproj = tomllib.load(f)
commands = {k: tuple(v.split(":")) for k, v in pyproj["project"]["scripts"].items()}

# ensure that the commands are pointing to valid submodule.function() targets
for command, (submodulename, funcname) in commands.items():
submodule = importlib.import_module(submodulename)
assert hasattr(submodule, funcname) or (
funcname == "main" and hasattr(importlib.import_module(f"{submodulename}.__main__"), funcname)
), f"{submodulename}.{funcname} not found for command {command}"

def recursive_check(dictcmd: dict[str, t.Any]) -> None:
for cmdtarget in dictcmd.values():
Expand All @@ -43,7 +54,7 @@ def recursive_check(dictcmd: dict[str, t.Any]) -> None:
funcname == "main" and hasattr(importlib.import_module(f"{namestr}.__main__"), funcname)
)

recursive_check(at.commands.dictcommands)
recursive_check(at.commands.subcommandtree)


def test_timestep_times() -> None:
Expand Down
Loading

0 comments on commit a6278ce

Please sign in to comment.