python / python/cpython

Add backend parameter to dbm.open() and shelve.open() for explicit DBM backend selection

Abierto
#137,881 3 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

3.15 stdlib type-feature
Lenguaje dominante
Python
Estrellas
77.2k
Forks
35.9k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

Feature or enhancement

Proposal:

Summary

Add an optional backend parameter to dbm.open() and shelve.open() functions to allow explicit selection of DBM backend implementations, improving compatibility and predictability across different systems.

Motivation

Currently, Python's DBM module automatically selects an available backend implementation in priority order (dbm.sqlite3, dbm.gnu, dbm.ndbm, dbm.dumb). This can cause compatibility issues when:

  1. Custom serializers work with some backends but not others (e.g., gdbm type restrictions)
  2. Cross-platform consistency is needed across different environments
  3. Predictable behavior is required regardless of which backends are installed
  4. Testing needs to validate behavior with specific backends
Real-world example
# This works with dbm.sqlite3 but fails with dbm.gnu
def custom_serializer(obj, protocol):
    if protocol == 5 and isinstance(obj, bytearray):
        return obj  # Causes "gdbm mappings have bytes or string indices only"
    return pickle.dumps(obj, protocol)

# Currently no way to ensure consistent backend
with shelve.open('data.db', serializer=custom_serializer) as shelf:
    shelf['key'] = bytearray(b'data')  # May fail depending on system

See: https://github.com/python/cpython/issues/137829

Proposed Solution

Add an optional backend parameter to both functions:

# dbm.open()
dbm.open(file, flag='r', mode=0o666, backend=None)

# shelve.open() 
shelve.open(filename, flag='c', protocol=None, writeback=False, 
            backend=None, *, serializer=None, deserializer=None)
Usage Examples:
import dbm
import shelve

# Explicit backend selection
with dbm.open('data.db', 'c', backend='dbm.dumb') as db:
    db[b'key'] = b'value'

# Cross-platform consistency 
with shelve.open('data.shelf', backend='dbm.sqlite3') as shelf:
    shelf['key'] = complex_object

# Testing with specific backends
for backend in ['dbm.gnu', 'dbm.ndbm', 'dbm.dumb']:
    with shelve.open(f'test_{backend}.db', backend=backend) as shelf:
        test_serialization_compatibility(shelf)
Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

No response

Linked PRs
  • gh-137882
  • gh-138007

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Empieza examinando los puntos de entrada dbm.open() y shelve.open() y el comportamiento existente de selección del backend descrito en el issue. Revisa los PRs vinculados gh-137882 y gh-138007 antes de empezar, ya que indican que el trabajo ya se ha trasladado a otro lugar. Se considerará terminado cuando exista una API acordada para la selección del backend y cobertura para las elecciones explícitas de backend en todas las implementaciones compatibles.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
python
Área
databases
Tipo de issue
Nueva funcionalidad
Dificultad
5/5
Tiempo estimado
Más de una semana
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
25/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.