pydata / pydata/xarray

Problem using assign_attrs() in map()

Open
#11,019 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

needs triage
Dominant language
Python
Stars
4.2k
Forks
1.4k
Avg merge
2d 15h
Merged PRs (30d)
14

Description

What is your issue?

In MetPy we have an attribute managing helper that calls DataArray.assign_attrs() within a callable passed to Dataset.map(). With recent versions of xarray, it is impossible to have the attributes assigned using assign_attrs() to be present in the result. See the following example:

import numpy as np
import xarray as xr

ds = xr.DataArray(np.zeros((3)),
    coords={'b': xr.DataArray(np.arange(3), dims='b')},
    dims=['b'], attrs={'units': 'kelvin'}, name='test').to_dataset()

def add_attr(da):
    d = da.assign_attrs(my_attr='foobar')
    return d

ds2 = ds.map(add_attr, keep_attrs=True)

print(ds2['test'].attrs)

This gives {'units': 'kelvin'}. If instead, keep_attrs=False is used, then we get {}.

This boils down to the fact that there are only two options for a DataArray processed within map():

  1. Get a direct copy (really, reference) to the original DataArray's .attrs
  2. Have .attrs set to {}

There's no option to tell map() to just leave the created DataArray alone. The only work-around I've found is to modify the original DataArray directly instead of using assign_attrs(), which is suboptimal. Things worked fine as recently as xarray 2025.6.1. I know the keep_attrs default changed to True this fall, but I'm surprised setting to False doesn't restore the previous behavior.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the provided Python reproduction with Dataset.map(), DataArray.assign_attrs(), and both keep_attrs settings. Trace how map handles the returned DataArray attributes and compare the result with the expected preservation of my_attr alongside the original attrs. Done means the example retains the attributes assigned inside the callable without breaking existing keep_attrs behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
numpy, python
Domain
data
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.