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 sì
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)