Skip to content

whl2conda.settings

Settings for whl2conda.

Internally, the settings are accessed through the settings global variable, which is an instance of Whl2CondaSettings

The settings are loaded from a persistent JSON file, whose default location depends on the operating system, e.g.:

OS Path
Windows ~/AppData/Local/whl2conda/whl2conda/settings.json
Linux ~/.config/whl2conda/settings.json
MacOS ~/Library/Application Support/whl2conda/settings.json

The location of the settings file may also be overridden by --settings command line argument to whl2conda.

Use the settings_file attribute to get the path used to load a given settings object.

Settings may be viewed and modified at the command line using whl2conda config.

Attributes

settings module-attribute

settings = from_file()

User settings.

Classes

Whl2CondaSettings dataclass

User settings for whl2conda.

These are accessed through the global settings variable.

The following settings are currently supported:

Source code in src/whl2conda/settings.py
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
@dataclasses.dataclass(**dataclass_args)
class Whl2CondaSettings:
    """
    User settings for whl2conda.

    These are accessed through the global [settings][(m).] variable.

    The following settings are currently supported:

    * [auto_update_std_renames][.] - whether to automatically update std rename mappings
    * [conda_format][.] - default output conda package format
    * [pypi_indexes][.] - table of known extra pypi indexes

    """

    SETTINGS_FILENAME: ClassVar[str] = "settings.json"
    """Default base filename for saved settings."""

    DEFAULT_SETTINGS_FILE: ClassVar[Path] = (
        user_config_path("whl2conda") / SETTINGS_FILENAME
    )
    """Default filepath for saved settings."""

    # TODO:
    #   - difftool
    #   - pyproject defaults

    auto_update_std_renames: _BoolField = _BoolField()
    """
    Whether to automatically update the standard renames for operations
    that need them. Default is false.
    """

    conda_format: _CondaPackageFormatField = _CondaPackageFormatField()
    """
    The default output conda package format if not specified. Default is V2.
    """

    pypi_indexes: _SettingsField = _SettingsField(default=dict)
    """
    Dictionary of aliases for pypi package indexes from which wheels can be
    downloaded. Default is empty.
    """

    #
    # Internal attributes
    #

    _settings_file: Path = dataclasses.field(
        default=DEFAULT_SETTINGS_FILE, compare=False
    )
    """
    Location of underlying settings file.
    """

    _fieldnames: ClassVar[frozenset[str]] = frozenset()
    """
    Set of public field names.
    """

    @property
    def settings_file(self) -> Path:
        """
        Settings file for this settings object.

        Set from [from_file][..] constructor or else will be
        [DEFAULT_SETTINGS_FILE][(c).].
        """
        return self._settings_file

    #
    # Settings access/modification methods
    #

    def to_dict(self) -> dict[str, Any]:
        """
        Return dictionary containing public settings data.
        """
        return {
            k: v for k, v in dataclasses.asdict(self).items() if not k.startswith("_")
        }

    def get(self, key: str) -> Any:
        """
        Get a value from the settings by string key.

        The key may either be just the field name (e.g. 'conda-format')
        or can refer to am entry within dictionary-valued field
        (e.g. 'pypi-indexes.acme'). Note that the dashes in the first
        component of the key will be converted to underscores.
        """
        name, subkey = self._split_key(key)
        value = getattr(self, name)

        if subkey:
            if not isinstance(value, dict):
                raise KeyError(
                    f"Bad settings key '{key}': '{name}' is not a dictionary"
                )
            if subkey not in value:
                raise KeyError(f"'{key}' is not set'")
            value = value[subkey]

        return value

    def set(self, key: str, value: Any) -> None:
        """
        Set a value in the settings by string key.

        See [get][..] for details on key format.

        This does not save the settings file.
        """
        name, subkey = self._split_key(key)

        if not subkey:
            setattr(self, name, value)

        else:
            d = getattr(self, name)
            if not isinstance(d, dict):
                raise KeyError(
                    f"Bad settings key '{key}': '{name}' is not a dictionary"
                )
            d[subkey] = value

    def unset(self, key: str) -> None:
        """
        Unset attribute with given key.

        The setting will revert to its original value.

        See [get][..] for details on key format.

        This does not save the settings file.
        """
        name, subkey = self._split_key(key)

        if not subkey:
            delattr(self, name)

        else:
            d = getattr(self, name)
            if not isinstance(d, dict):
                raise KeyError(
                    f"Bad settings key '{key}': '{name}' is not a dictionary"
                )
            try:
                del d[subkey]
            except KeyError:
                pass

    def unset_all(self) -> None:
        """
        Unset all settings, and revert to default values.
        """
        for k in self._fieldnames:
            self.unset(k)

    #
    # File operations
    #

    @classmethod
    def from_file(cls, filename: Union[Path, str] = "") -> Whl2CondaSettings:
        """
        Return settings read from file.

        Arguments:
            filename: relative path to settings file (may start with '~')
                defaults to [DEFAULT_SETTINGS_FILE][(c).] if not specified.
        """
        settings = cls()
        settings.load(filename or cls.DEFAULT_SETTINGS_FILE)
        return settings

    def load(self, filename: Union[Path, str], reset_all: bool = False) -> None:
        """
        Reload settings from file

        Args:
            filename: relative path to settings file (may start with '~')
            reset_all: if True, then all settings will be unset and reverted
                to default value prior to loading.
        """
        filepath = Path(Path(filename).expanduser())
        self._settings_file = filepath
        if reset_all:
            self.unset_all()
        if filepath.exists():
            contents = filepath.read_text("utf8")
            json_obj = json.loads(contents)
            for k, v in json_obj.items():
                if k in self._fieldnames:
                    try:
                        setattr(self, k, v)
                    except Exception as ex:
                        print(
                            f"Cannot read '{k}' from '{filepath}': {ex}",
                            file=sys.stderr,
                        )

    def save(self, filename: Union[Path, str] = "") -> None:
        """
        Write settings to specified file in JSON format.

        Args:
            filename: file to write. Defaults to [settings_file][..]
        """
        filepath = Path(filename or self._settings_file)
        json_obj = self.to_dict()
        json_obj["$whl2conda-version"] = __version__
        json_obj["$created"] = str(dt.datetime.now())
        filepath.parent.mkdir(parents=True, exist_ok=True)
        filepath.write_text(json.dumps(json_obj, indent=2))

    #
    # Internal methods
    #

    def _split_key(self, key: str) -> tuple[str, str]:
        parts = key.split(".", maxsplit=1)
        name = _toidentifier(parts[0])
        if name not in self._fieldnames:
            raise KeyError(f"Unknown settings key '{key}'")
        return name, parts[1] if len(parts) > 1 else ""

Attributes

DEFAULT_SETTINGS_FILE class-attribute
DEFAULT_SETTINGS_FILE: Path = (
    user_config_path("whl2conda") / SETTINGS_FILENAME
)

Default filepath for saved settings.

SETTINGS_FILENAME class-attribute
SETTINGS_FILENAME: str = 'settings.json'

Default base filename for saved settings.

auto_update_std_renames class-attribute instance-attribute
auto_update_std_renames: _BoolField = _BoolField()

Whether to automatically update the standard renames for operations that need them. Default is false.

conda_format class-attribute instance-attribute
conda_format: _CondaPackageFormatField = (
    _CondaPackageFormatField()
)

The default output conda package format if not specified. Default is V2.

pypi_indexes class-attribute instance-attribute
pypi_indexes: _SettingsField = _SettingsField(default=dict)

Dictionary of aliases for pypi package indexes from which wheels can be downloaded. Default is empty.

settings_file property
settings_file: Path

Settings file for this settings object.

Set from from_file constructor or else will be DEFAULT_SETTINGS_FILE.

Functions

from_file classmethod
from_file(
    filename: Union[Path, str] = ""
) -> Whl2CondaSettings

Return settings read from file.

PARAMETER DESCRIPTION
filename

relative path to settings file (may start with '~') defaults to DEFAULT_SETTINGS_FILE if not specified.

TYPE: Union[Path, str] DEFAULT: ''

Source code in src/whl2conda/settings.py
328
329
330
331
332
333
334
335
336
337
338
339
@classmethod
def from_file(cls, filename: Union[Path, str] = "") -> Whl2CondaSettings:
    """
    Return settings read from file.

    Arguments:
        filename: relative path to settings file (may start with '~')
            defaults to [DEFAULT_SETTINGS_FILE][(c).] if not specified.
    """
    settings = cls()
    settings.load(filename or cls.DEFAULT_SETTINGS_FILE)
    return settings
get
get(key: str) -> Any

Get a value from the settings by string key.

The key may either be just the field name (e.g. 'conda-format') or can refer to am entry within dictionary-valued field (e.g. 'pypi-indexes.acme'). Note that the dashes in the first component of the key will be converted to underscores.

Source code in src/whl2conda/settings.py
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
def get(self, key: str) -> Any:
    """
    Get a value from the settings by string key.

    The key may either be just the field name (e.g. 'conda-format')
    or can refer to am entry within dictionary-valued field
    (e.g. 'pypi-indexes.acme'). Note that the dashes in the first
    component of the key will be converted to underscores.
    """
    name, subkey = self._split_key(key)
    value = getattr(self, name)

    if subkey:
        if not isinstance(value, dict):
            raise KeyError(
                f"Bad settings key '{key}': '{name}' is not a dictionary"
            )
        if subkey not in value:
            raise KeyError(f"'{key}' is not set'")
        value = value[subkey]

    return value
load
load(
    filename: Union[Path, str], reset_all: bool = False
) -> None

Reload settings from file

PARAMETER DESCRIPTION
filename

relative path to settings file (may start with '~')

TYPE: Union[Path, str]

reset_all

if True, then all settings will be unset and reverted to default value prior to loading.

TYPE: bool DEFAULT: False

Source code in src/whl2conda/settings.py
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
def load(self, filename: Union[Path, str], reset_all: bool = False) -> None:
    """
    Reload settings from file

    Args:
        filename: relative path to settings file (may start with '~')
        reset_all: if True, then all settings will be unset and reverted
            to default value prior to loading.
    """
    filepath = Path(Path(filename).expanduser())
    self._settings_file = filepath
    if reset_all:
        self.unset_all()
    if filepath.exists():
        contents = filepath.read_text("utf8")
        json_obj = json.loads(contents)
        for k, v in json_obj.items():
            if k in self._fieldnames:
                try:
                    setattr(self, k, v)
                except Exception as ex:
                    print(
                        f"Cannot read '{k}' from '{filepath}': {ex}",
                        file=sys.stderr,
                    )
save
save(filename: Union[Path, str] = '') -> None

Write settings to specified file in JSON format.

PARAMETER DESCRIPTION
filename

file to write. Defaults to settings_file

TYPE: Union[Path, str] DEFAULT: ''

Source code in src/whl2conda/settings.py
367
368
369
370
371
372
373
374
375
376
377
378
379
def save(self, filename: Union[Path, str] = "") -> None:
    """
    Write settings to specified file in JSON format.

    Args:
        filename: file to write. Defaults to [settings_file][..]
    """
    filepath = Path(filename or self._settings_file)
    json_obj = self.to_dict()
    json_obj["$whl2conda-version"] = __version__
    json_obj["$created"] = str(dt.datetime.now())
    filepath.parent.mkdir(parents=True, exist_ok=True)
    filepath.write_text(json.dumps(json_obj, indent=2))
set
set(key: str, value: Any) -> None

Set a value in the settings by string key.

See get for details on key format.

This does not save the settings file.

Source code in src/whl2conda/settings.py
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
def set(self, key: str, value: Any) -> None:
    """
    Set a value in the settings by string key.

    See [get][..] for details on key format.

    This does not save the settings file.
    """
    name, subkey = self._split_key(key)

    if not subkey:
        setattr(self, name, value)

    else:
        d = getattr(self, name)
        if not isinstance(d, dict):
            raise KeyError(
                f"Bad settings key '{key}': '{name}' is not a dictionary"
            )
        d[subkey] = value
to_dict
to_dict() -> dict[str, Any]

Return dictionary containing public settings data.

Source code in src/whl2conda/settings.py
239
240
241
242
243
244
245
def to_dict(self) -> dict[str, Any]:
    """
    Return dictionary containing public settings data.
    """
    return {
        k: v for k, v in dataclasses.asdict(self).items() if not k.startswith("_")
    }
unset
unset(key: str) -> None

Unset attribute with given key.

The setting will revert to its original value.

See get for details on key format.

This does not save the settings file.

Source code in src/whl2conda/settings.py
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
def unset(self, key: str) -> None:
    """
    Unset attribute with given key.

    The setting will revert to its original value.

    See [get][..] for details on key format.

    This does not save the settings file.
    """
    name, subkey = self._split_key(key)

    if not subkey:
        delattr(self, name)

    else:
        d = getattr(self, name)
        if not isinstance(d, dict):
            raise KeyError(
                f"Bad settings key '{key}': '{name}' is not a dictionary"
            )
        try:
            del d[subkey]
        except KeyError:
            pass
unset_all
unset_all() -> None

Unset all settings, and revert to default values.

Source code in src/whl2conda/settings.py
317
318
319
320
321
322
def unset_all(self) -> None:
    """
    Unset all settings, and revert to default values.
    """
    for k in self._fieldnames:
        self.unset(k)