Vai al contenuto

Gli identificatori

Urn rappresenta un URN NIR, l'indirizzo con cui Normattiva identifica gli atti. Si compone dai pezzi, si legge da una stringa con parse e si trasforma con i metodi con_*, che restituiscono sempre un URN nuovo. Nessuna di queste operazioni tocca la rete: un identificatore malformato viene rifiutato subito.

Come si usa, con gli esempi, sta in identificare un atto.

Le parti di un URN

urn:nir:stato:legge:1990-08-07;241:2~art5-com3!vig=2005-01-01
     │    │     │        │       │ │   │    │    │
     │    │     │        │       │ │   │    │    └── vigenza a una data
     │    │     │        │       │ │   │    └─────── comma
     │    │     │        │       │ │   └──────────── articolo
     │    │     │        │       │ └──────────────── allegato
     │    │     │        │       └────────────────── numero
     │    │     │        └────────────────────────── data di emanazione
     │    │     └─────────────────────────────────── denominazione
     │    └───────────────────────────────────────── autorità emanante
     └────────────────────────────────────────────── schema
Parte Attributo Obbligatoria
autorità emanante autorita sì, sempre stato
denominazione denominazione sì, nella forma NIR (regio.decreto)
data di emanazione data no: senza, l'URN porta solo l'anno
anno anno
numero numero sì, tranne per la Costituzione
allegato allegato solo per gli atti che rispondono da un allegato
articolo articolo no
comma comma no, e il servizio lo rifiuta in ingresso
vigenza versione no

Il campo si chiama versione perché nella grammatica NIR il suffisso dopo l'atto individua la versione del documento; vigenza è il nome con cui la si chiede, in con_vigenza e in dettaglio.

Urn dataclass

Urn(
    denominazione: str,
    anno: int,
    data: date | None = None,
    numero: str | None = None,
    autorita: str = "stato",
    allegato: str | None = None,
    articolo: str | None = None,
    comma: str | None = None,
    versione: date | Literal["originale"] | None = None,
)

Un identificatore NIR, scomposto nelle sue parti.

Il suffisso di versione fa parte dell'identificatore perché i rimandi dentro il testo restituito lo includono. Vale lo stesso per il comma, che però il servizio rifiuta in ingresso: senza_comma restituisce l'identificatore che si può davvero usare in una richiesta.

numero, allegato e articolo accettano anche interi e li conservano come stringhe: numero=300 e numero="300" costruiscono lo stesso URN. L'articolo viene inoltre normalizzato ("5-bis" non è ammesso, "5bis" sì).

senza_comma property

senza_comma: Urn

Lo stesso URN senza il comma, che il servizio rifiuta in ingresso.

permalink: str

Il link pubblico di Normattiva, per verificare sulla fonte.

parse classmethod

parse(testo: str | Urn) -> Urn

Costruisce un Urn dalla sua forma testuale.

Parametri:

Nome Tipo Descrizione Predefinito
testo str | Urn

la forma testuale, oppure un Urn già letto, che viene restituito com'è.

obbligatorio

Restituisce:

Tipo Descrizione
Urn

L'identificatore scomposto nelle sue parti.

Esempi:

>>> from normattiva import Urn
>>> Urn.parse("urn:nir:stato:legge:1990-08-07;241~art5").articolo
'5'

Solleva:

Tipo Descrizione
InvalidUrnError

il testo non rispetta la grammatica NIR, o porta una data che non esiste.

Codice sorgente in src/normattiva/urn.py
@classmethod
def parse(cls, testo: str | Urn) -> Urn:
    """Costruisce un `Urn` dalla sua forma testuale.

    Args:
        testo: la forma testuale, oppure un `Urn` già letto, che viene
            restituito com'è.

    Returns:
        L'identificatore scomposto nelle sue parti.

    Examples:
        >>> from normattiva import Urn
        >>> Urn.parse("urn:nir:stato:legge:1990-08-07;241~art5").articolo
        '5'

    Raises:
        InvalidUrnError: il testo non rispetta la grammatica NIR, o porta
            una data che non esiste.
    """
    if isinstance(testo, Urn):
        return testo
    pezzi = _GRAMMATICA.match(str(testo).strip().lower())
    if pezzi is None:
        raise InvalidUrnError(testo)
    grezza = pezzi["data"]
    data = _leggi_data(grezza) if len(grezza) > 4 else None
    vigenza = pezzi["vigenza"]
    versione: date | Literal["originale"] | None = None
    if vigenza:
        versione = _leggi_data(vigenza)
    elif pezzi["originale"]:
        versione = "originale"
    return cls(
        denominazione=pezzi["denominazione"],
        anno=data.year if data else int(grezza),
        data=data,
        numero=pezzi["numero"],
        autorita=pezzi["autorita"],
        allegato=pezzi["allegato"],
        articolo=pezzi["articolo"],
        comma=pezzi["comma"],
        versione=versione,
    )

legge classmethod

legge(
    anno: int,
    numero: int | str,
    *,
    articolo: int | str | None = None,
    data: date | None = None,
) -> Urn

Costruisce l'URN di una legge.

Parametri:

Nome Tipo Descrizione Predefinito
anno int

anno di emanazione.

obbligatorio
numero int | str

numero della legge, come intero o come stringa.

obbligatorio
articolo int | str | None

l'articolo da indirizzare, se ne serve uno solo.

None
data date | None

la data esatta di emanazione. Rende l'URN più preciso e disambigua fra due atti con lo stesso numero nello stesso anno.

None

Esempi:

>>> from normattiva import Urn
>>> str(Urn.legge(1990, 241, articolo=5))
'urn:nir:stato:legge:1990;241~art5'
Codice sorgente in src/normattiva/urn.py
@classmethod
def legge(
    cls,
    anno: int,
    numero: int | str,
    *,
    articolo: int | str | None = None,
    data: date | None = None,
) -> Urn:
    """Costruisce l'URN di una legge.

    Args:
        anno: anno di emanazione.
        numero: numero della legge, come intero o come stringa.
        articolo: l'articolo da indirizzare, se ne serve uno solo.
        data: la data esatta di emanazione. Rende l'URN più preciso e
            disambigua fra due atti con lo stesso numero nello stesso anno.

    Examples:
        >>> from normattiva import Urn
        >>> str(Urn.legge(1990, 241, articolo=5))
        'urn:nir:stato:legge:1990;241~art5'
    """
    return cls._di_tipo(LEGGE, anno, numero, articolo=articolo, data=data)

decreto_legge classmethod

decreto_legge(
    anno: int,
    numero: int | str,
    *,
    articolo: int | str | None = None,
    data: date | None = None,
) -> Urn

Costruisce l'URN di un decreto-legge.

Codice sorgente in src/normattiva/urn.py
@classmethod
def decreto_legge(
    cls,
    anno: int,
    numero: int | str,
    *,
    articolo: int | str | None = None,
    data: date | None = None,
) -> Urn:
    """Costruisce l'URN di un decreto-legge."""
    return cls._di_tipo(DECRETO_LEGGE, anno, numero, articolo=articolo, data=data)

decreto_legislativo classmethod

decreto_legislativo(
    anno: int,
    numero: int | str,
    *,
    articolo: int | str | None = None,
    data: date | None = None,
) -> Urn

Costruisce l'URN di un decreto legislativo.

Codice sorgente in src/normattiva/urn.py
@classmethod
def decreto_legislativo(
    cls,
    anno: int,
    numero: int | str,
    *,
    articolo: int | str | None = None,
    data: date | None = None,
) -> Urn:
    """Costruisce l'URN di un decreto legislativo."""
    return cls._di_tipo(DECRETO_LEGISLATIVO, anno, numero, articolo=articolo, data=data)

dpr classmethod

dpr(
    anno: int,
    numero: int | str,
    *,
    articolo: int | str | None = None,
    data: date | None = None,
) -> Urn

Costruisce l'URN di un decreto del Presidente della Repubblica.

Codice sorgente in src/normattiva/urn.py
@classmethod
def dpr(
    cls,
    anno: int,
    numero: int | str,
    *,
    articolo: int | str | None = None,
    data: date | None = None,
) -> Urn:
    """Costruisce l'URN di un decreto del Presidente della Repubblica."""
    return cls._di_tipo(DPR, anno, numero, articolo=articolo, data=data)

regio_decreto classmethod

regio_decreto(
    anno: int,
    numero: int | str,
    *,
    articolo: int | str | None = None,
    data: date | None = None,
) -> Urn

Costruisce l'URN di un regio decreto.

Codice sorgente in src/normattiva/urn.py
@classmethod
def regio_decreto(
    cls,
    anno: int,
    numero: int | str,
    *,
    articolo: int | str | None = None,
    data: date | None = None,
) -> Urn:
    """Costruisce l'URN di un regio decreto."""
    return cls._di_tipo(REGIO_DECRETO, anno, numero, articolo=articolo, data=data)

con_articolo

con_articolo(articolo: int | str) -> Urn

Costruisce lo stesso atto, indirizzato a uno dei suoi articoli.

Codice sorgente in src/normattiva/urn.py
def con_articolo(self, articolo: int | str) -> Urn:
    """Costruisce lo stesso atto, indirizzato a uno dei suoi articoli."""
    return replace(self, articolo=str(articolo), comma=None)

con_vigenza

con_vigenza(vigenza: date | Literal['originale']) -> Urn

Restituisce lo stesso URN con la data di vigenza indicata.

Codice sorgente in src/normattiva/urn.py
def con_vigenza(self, vigenza: date | Literal["originale"]) -> Urn:
    """Restituisce lo stesso URN con la data di vigenza indicata."""
    return replace(self, versione=vigenza)