Skip to content
Open
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
2 changes: 1 addition & 1 deletion .github/workflows/python-code-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
# renovate: datasource=pypi depName=bandit
BANDIT_VERSION: "1.9.4"
# renovate: datasource=pypi depName=ruff
RUFF_VERSION: "0.15.17"
RUFF_VERSION: "0.17.3"

runs-on: ${{ matrix.os }}
permissions:
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ repos:
- id: detect-private-key
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.15.17
rev: v0.17.3
hooks:
# Run the linter.
- id: ruff-check
Expand Down
8 changes: 4 additions & 4 deletions display/displaydrivers.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ import sys
import grass.script as gs
from grass.script import task as gtask

os.environ['GRASS_RENDER_IMMEDIATE'] = 'default'
os.environ['GRASS_RENDER_FILE'] = 'output.png'
os.environ["GRASS_RENDER_IMMEDIATE"] = "default"
os.environ["GRASS_RENDER_FILE"] = "output.png"

cmd, dcmd = gtask.cmdstring_to_tuple(sys.argv[1])

gs.run_command('d.text', text="Test of GRASS_RENDER_COMMAND redirection")
gs.run_command("d.text", text="Test of GRASS_RENDER_COMMAND redirection")

os.environ['GRASS_RENDER_FILE_READ'] = 'TRUE'
os.environ["GRASS_RENDER_FILE_READ"] = "TRUE"
gs.run_command(cmd, **dcmd)
```

Expand Down
35 changes: 19 additions & 16 deletions doc/development/style_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,14 +217,14 @@ def func(arg1, arg2):

Example:

>>> a=1
>>> b=2
>>> func(a,b)
>>> a = 1
>>> b = 2
>>> func(a, b)
True
"""

if arg1 == arg2:
raise ValueError('arg1 must not be equal to arg2')
raise ValueError("arg1 must not be equal to arg2")

return True
```
Expand Down Expand Up @@ -575,7 +575,9 @@ If different subprocesses need different regions, use different environments:

```python
with gs.RegionManager(raster=input_raster, env=os.environ.copy()) as manager:
gs.run_command("r.slope.aspect", elevation=input_raster, slope=slope, env=manager.env)
gs.run_command(
"r.slope.aspect", elevation=input_raster, slope=slope, env=manager.env
)
```

This approach makes the computational region completely safe for parallel
Expand All @@ -587,7 +589,7 @@ If you can't use a context manager, you can use `gs.use_temp_region()` and
```python
gs.use_temp_region() # From now on, use a separate region in the script.
# Set the computational region with g.region as needed.
grass.run_command('g.region', raster='input')
grass.run_command("g.region", raster="input")
gs.del_temp_region()
# Original region applies now.
```
Expand Down Expand Up @@ -689,7 +691,6 @@ def remove(name):
)



def main():
temporary = gs.append_node_pid("tmp_mapcalc")
atexit.register(remove, temporary)
Expand All @@ -707,13 +708,13 @@ Use gs.findfile() when there is a need to test if a map exists.

```python
# test for input raster map
result = gs.find_file(map_name, element='raster')
if not result['file']:
result = gs.find_file(map_name, element="raster")
if not result["file"]:
gs.fatal(_("Raster map <{}> not found").format(map_name))

# test for input vector map
result = gs.find_file(map_name, element='vector')
if not result['file']:
result = gs.find_file(map_name, element="vector")
if not result["file"]:
gs.fatal(_("Vector map <{}> not found").format(map_name))
```

Expand Down Expand Up @@ -922,7 +923,7 @@ def main():
try:
import pandas as pd # noqa: E402
except ModuleNotFoundError:
gs.fatal(_("Pandas library not installed"))
gs.fatal(_("Pandas library not installed"))
```

#### Tool name
Expand Down Expand Up @@ -1011,9 +1012,9 @@ instead of constructing string from several parts (bad example):
```python
# don't do this
if ...:
maplabel = 'raster map'
maplabel = "raster map"
else:
maplabel = '3D raster map'
maplabel = "3D raster map"
win.SetLabel(_("Name for new {} to create").format(maplabel))
```

Expand All @@ -1024,9 +1025,11 @@ string. The comment must start with GTC keyword and must be on a line before
string:

```python
self.bwizard = wx.Button(...,
self.bwizard = wx.Button(
...,
# GTC New location
label = _("N&ew"))
label=_("N&ew"),
)

# GTC %s will be replaced with name of current shell
gs.message(_("Running through {}").format(shellname))
Expand Down
3 changes: 1 addition & 2 deletions doc/development/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,7 @@ environment. Mark such a test so it is run on its own:

```python
@pytest.mark.needs_solo_run
def test_something_which_changes_the_environment(xy_dataset_session):
...
def test_something_which_changes_the_environment(xy_dataset_session): ...
```

## More information
Expand Down
1 change: 0 additions & 1 deletion doc/interfaces_overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ gs.create_project(path="path/to/my_project", epsg="3358")

# Initialize the GRASS session
with gs.setup.init("path/to/my_project") as session:

# Run GRASS tools
tools = Tools(session=session)
tools.r_import(input="/path/to/elevation.tif", output="elevation")
Expand Down
39 changes: 17 additions & 22 deletions doc/jupyter_intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ m.d_legend(
at=(1, 50, 1, 8),
title="Elevation (m)",
border_color="none",
flags="bt"
flags="bt",
)

# Add a scale bar to the map
Expand Down Expand Up @@ -161,12 +161,11 @@ elevation_3dmap.render(
perspective=10,
height=5000,
resolution_fine=1,
zexag=5
zexag=5,
)
elevation_3dmap.overlay.d_legend(
raster="landuse", at=(0, 30, 87, 100), flags="b", border_color="none"
)
elevation_3dmap.overlay.d_legend(raster="landuse",
at=(0, 30, 87, 100),
flags="b",
border_color="none")
elevation_3dmap.show()
```

Expand All @@ -184,10 +183,7 @@ maps and play a continuous loop.
# Create a series of relief maps with different angles
directions = [0, 90, 180, 270]
for azimuth in directions:
tools.r_relief(
input="elevation",
output=f"relief_{azimuth}",
azimuth=azimuth)
tools.r_relief(input="elevation", output=f"relief_{azimuth}", azimuth=azimuth)
m = gj.SeriesMap()
m.add_rasters(f"relief_{azimuth}" for azimuth in directions)
m.d_vect(map="roads")
Expand All @@ -212,19 +208,16 @@ tools.g_region(n=226040, s=223780, e=639170, w=636190)
tools.r_slope_aspect(elevation="elevation", dx="dx", dy="dy")
# Compute overland flow
tools.r_sim_water(
flags="t",
elevation="elevation",
dx="dx",
dy="dy",
depth="depth",
duration=30)
flags="t", elevation="elevation", dx="dx", dy="dy", depth="depth", duration=30
)

# Create a time series
tools.t_create(
output="depth",
temporaltype="relative",
title="Overland flow depth",
description="Overland flow depth")
description="Overland flow depth",
)
# Register the time series
maps = [
item["fullname"]
Expand All @@ -243,11 +236,13 @@ flow_map.add_raster_series("depth", values="0.025-1.25")
flow_map.d_vect(map="streets")

# Add map features
flow_map.d_legend(raster="depth.30",
title="Depth [m]",
flags="bt",
border_color="none",
at=(1, 50, 0, 5))
flow_map.d_legend(
raster="depth.30",
title="Depth [m]",
flags="bt",
border_color="none",
at=(1, 50, 0, 5),
)

# Display the map
flow_map.show()
Expand Down
48 changes: 16 additions & 32 deletions doc/migration_to_grass_tools_python_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -386,10 +386,7 @@ result = gs.list_strings("raster")
Extract the *fullname* field from the JSON output:

```python
result = [
item["fullname"]
for item in tools.g_list(type="raster", format="json")
]
result = [item["fullname"] for item in tools.g_list(type="raster", format="json")]
```

The *list_pairs* returns tuples:
Expand Down Expand Up @@ -456,20 +453,16 @@ configure the *Tools* object accordingly.
The *run_command* approach uses *errors="status"*:

```python
returncode = gs.run_command(
"r.mask.status",
flags="t",
errors="status"
)
returncode = gs.run_command("r.mask.status", flags="t", errors="status")
# Returns: 1 (if no mask exists)
```

Configure the *Tools* object to ignore errors and always return result objects:

```python
tools_with_returncode = Tools(
errors="ignore",
consistent_return_value=True,
errors="ignore",
consistent_return_value=True,
)
result = tools_with_returncode.r_mask_status(flags="t")
returncode = result.returncode
Expand Down Expand Up @@ -630,27 +623,21 @@ import grass.script as gs
with gs.setup.init("path/to/project") as session:
# Import raster
gs.run_command(
"r.import",
input="/path/to/elevation.tif",
output="elevation",
env=session.env
"r.import", input="/path/to/elevation.tif", output="elevation", env=session.env
)

# Set region
gs.run_command("g.region", raster="elevation", env=session.env)

# Calculate slope
gs.run_command(
"r.slope.aspect",
elevation="elevation",
slope="slope",
env=session.env
"r.slope.aspect", elevation="elevation", slope="slope", env=session.env
)

# Get region info
region_info = gs.region(env=session.env)
print(f"Rows: {region_info['rows']}")

# List rasters
rasters = gs.list_strings("raster", env=session.env)
print(f"Rasters: {rasters}")
Expand All @@ -664,25 +651,22 @@ from grass.tools import Tools

with gs.setup.init("path/to/project") as session:
tools = Tools(session=session)

# Import raster
tools.r_import(input="/path/to/elevation.tif", output="elevation")

# Set region
tools.g_region(raster="elevation")

# Calculate slope
tools.r_slope_aspect(elevation="elevation", slope="slope")

# Get region info
region_info = tools.g_region(flags="p", format="json")
print(f"Rows: {region_info['rows']}")

# List rasters
rasters = [
item["fullname"]
for item in tools.g_list(type="raster", format="json")
]
rasters = [item["fullname"] for item in tools.g_list(type="raster", format="json")]
print(f"Rasters: {rasters}")
```

Expand Down
Loading
Loading