# Versión del programa

**URL:** <https://pyar.discourse.group/t/version-del-programa/1106>\
**Category:** Sin categoría\
**Created:** [15 Abril, 2023 15:37 UTC](https://pyar.discourse.group/t/version-del-programa/1106 "2023-04-15T15:37:18Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![facundo](https://yyz2.discourse-cdn.com/free1/user_avatar/pyar.discourse.group/facundo/32/7_2.png) [@facundo](https://pyar.discourse.group/u/facundo)\
**Post date:** [15 Abril, 2023 15:37 UTC](https://pyar.discourse.group/t/version-del-programa/1106/1 "2023-04-15T15:37:19Z")

</div>

¡Buenas!

Algo que no tengo del todo resuelto en mis proyectos es como manejar la versión de lo que se está ejecutando/instalando/empaquetando.

No me refiero a _qué número usar_, para esta post es lo mismo si la versión es “42” o “5.2.1-alpha”, me refiero a cómo obtener ese valor en las distintas instancias.

Tampoco me refiero a “cómo calcular la versión”, lo cual puede ser un valor constante (`version = "17"`) o calculada a partir de parámetros como el commit de `git` o whatever.

El problema base, claro, es tener la información de versión en un único lugar, que la fuente de verdad sea una sola, y usar ese valor tanto del `setup.py` (o cómo sea que empaqueten e instalen el proyecto) y desde el mismo proyecto (cuando corren al programa con `--version` o van a “Acerca de…” en el menú).

¿Ideas? ¿Experiencias? ¿Soluciones?

Se agradece.

---

<div class="post-metadata">

**Author:** ![SAn](https://yyz2.discourse-cdn.com/free1/user_avatar/pyar.discourse.group/san/32/247_2.png) [@SAn](https://pyar.discourse.group/u/SAn)\
**Post date:** [15 Abril, 2023 17:11 UTC](https://pyar.discourse.group/t/version-del-programa/1106/2 "2023-04-15T17:11:16Z")

</div>

Es una muy buena pregunta. La última vez que vi cómo resolverlo encontré que en un codebase moderno se puede usar importlib.metadata [Using importlib.metadata — Python 3.11.3 documentation](https://docs.python.org/3/library/importlib.metadata.html) . Algo tipo esto [setuptools/version.py at main · pypa/setuptools · GitHub](https://github.com/pypa/setuptools/blob/main/setuptools/version.py)  
Creo que no hay una solución que abarca todos los casos de uso.

---

<div class="post-metadata">

**Author:** ![sofide](https://yyz2.discourse-cdn.com/free1/user_avatar/pyar.discourse.group/sofide/32/17_2.png) [@sofide](https://pyar.discourse.group/u/sofide)\
**Post date:** [17 Abril, 2023 00:16 UTC](https://pyar.discourse.group/t/version-del-programa/1106/3 "2023-04-17T00:16:17Z")

</div>

Buenas!  
En el laburo nos chocamos varias veces con este tema, y lo que solemos usar es [pgk\_resources](https://setuptools.pypa.io/en/latest/pkg_resources.html#).

Estoy viendo que la documentación no es muy feliz, pero basicamente hacemos:

```auto
import pkg_resources

lib_version = pkg_resources.get_distribution(lib_name).version

```

Lo único que es medio meta es que el código tiene que “tener conciencia” del nombre de la lib que lo instala 😛  
Pero bueno, a fines prácticos, solo tenes que tener hardcodeado en algún lado el nombre de tu lib 🙂

---

<div class="post-metadata">

**Author:** ![sofide](https://yyz2.discourse-cdn.com/free1/user_avatar/pyar.discourse.group/sofide/32/17_2.png) [@sofide](https://pyar.discourse.group/u/sofide)\
**Post date:** [17 Abril, 2023 00:19 UTC](https://pyar.discourse.group/t/version-del-programa/1106/4 "2023-04-17T00:19:41Z")

</div>

Igual por lo que estoy chusmeando, lo que compartió San, pinta mejor que el pkg\_resources (y de hecho dice literal " this package can eliminate the need to use the older and less efficient `pkg_resources` package." jajaa 😃

---

<div class="post-metadata">

**Author:** ![facundo](https://yyz2.discourse-cdn.com/free1/user_avatar/pyar.discourse.group/facundo/32/7_2.png) [@facundo](https://pyar.discourse.group/u/facundo)\
**Post date:** [17 Abril, 2023 17:07 UTC](https://pyar.discourse.group/t/version-del-programa/1106/5 "2023-04-17T17:07:39Z")

</div>

@SAn @sofide gracias por la info!

Pero, si no entiendo mal, las soluciones que uds indican me dan la versión del _paquete instalado_. Si vamos por ese lado, con hardcodear la versión en el `setup.py` alcanza.

Yo, además de eso, quiero que esa versión sea accesible cuando el programa se ejecuta desde el proyecto. Y en ese caso no es tan fácil acceder a la info de `setup.py`…

---

<div class="post-metadata">

**Author:** ![sofide](https://yyz2.discourse-cdn.com/free1/user_avatar/pyar.discourse.group/sofide/32/17_2.png) [@sofide](https://pyar.discourse.group/u/sofide)\
**Post date:** [17 Abril, 2023 17:53 UTC](https://pyar.discourse.group/t/version-del-programa/1106/6 "2023-04-17T17:53:10Z")

</div>

@facundo no me queda claro eso de ejecutar el programa desde el proyecto, a que te referis? Entiendo que te referis a ejecutarlo desde el código fuente directamente, sin tenerlo instalado?

No me queda claro que versión te serviría mostrar en esos casos, si es que no tenes realmente una versión instalada.

---

<div class="post-metadata">

**Author:** ![SAn](https://yyz2.discourse-cdn.com/free1/user_avatar/pyar.discourse.group/san/32/247_2.png) [@SAn](https://pyar.discourse.group/u/SAn)\
**Post date:** [17 Abril, 2023 20:31 UTC](https://pyar.discourse.group/t/version-del-programa/1106/7 "2023-04-17T20:31:54Z")

</div>

Claro, por eso decia que no se ajustaba a todos los casos de uso y no hay una forma que sea genial para todo creo.

Si lo estas ejecutando desde “el proyecto” sin instalarlo supongo que es en “modo desarrollo”, si es así en realidad vas a querer que te muestre el git hash por ejemplo en vez del numero de versión porque sino va a ser siempre 0.-dev y no vas a saber que commit e inclusive vas a querer que te diga si esta dirty el repo o no, o todo eso combinado, y mas detalles que empiezan a ser importantes para tu uso especifico. Y ahi ya es muy especifico del ciclo de trabajo del repo me parece y hay varias formas.  
Lo mas facil para mi es mostrar esa versión de qué esta instalado (si está) y ademas mostrar un git hash si está en un repo, y no mezclar ambas cosas.

---

<div class="post-metadata">

**Author:** ![facundo](https://yyz2.discourse-cdn.com/free1/user_avatar/pyar.discourse.group/facundo/32/7_2.png) [@facundo](https://pyar.discourse.group/u/facundo)\
**Post date:** [18 Abril, 2023 11:53 UTC](https://pyar.discourse.group/t/version-del-programa/1106/8 "2023-04-18T11:53:08Z")

</div>

@sofide sí, “desde el proyecto” es clonarlo y ejecutarlo, sin instalar; incluso habiendo tocado el código, y eso se tiene que reflejar en la versión.

@SAn exacto, hash del último commit, idealmente cantidad de commits luego del release y versión de ese release. Para [Charmcraft](https://github.com/canonical/charmcraft/) Chipaca había armado [algo que tiene esas consideraciones](https://github.com/canonical/charmcraft/blob/main/charmcraft/version.py) pero depende de que tagees el branch correctamente y la integración con el `setup.py` no es trivial.

---

<div class="post-metadata">

**Author:** ![SAn](https://yyz2.discourse-cdn.com/free1/user_avatar/pyar.discourse.group/san/32/247_2.png) [@SAn](https://pyar.discourse.group/u/SAn)\
**Post date:** [19 Abril, 2023 16:30 UTC](https://pyar.discourse.group/t/version-del-programa/1106/9 "2023-04-19T16:30:46Z")

</div>

Vos necesitas que se relacione lo del git hash con el setup.py? Porque eso le agrega una complejidad extra importante que para mi (salvo proyectos puntuales) puede solucionarse justamente con no relacionar el setup.py con el git hash.  
Una forma podria ser que mostras ambas cosas: installed\_version y executed\_from\_repo\_version. installed\_version lo sacas del setup.py (y puede no corresponder a lo que esta corriendo, porque puede estar instalado version X pero vos estas corriendo del repo version Y). executed\_from\_repo\_version lo sacas del githash si existe. Si, no es lo mas feliz del mundo pero todo lo otro en mi experiencia es peor. Si a vos alguien te da installed\_version y executed\_from\_repo\_version vos podes saber que es realmente lo que esta corriendo, no?

---

<div class="post-metadata">

**Author:** ![facundo](https://yyz2.discourse-cdn.com/free1/user_avatar/pyar.discourse.group/facundo/32/7_2.png) [@facundo](https://pyar.discourse.group/u/facundo)\
**Post date:** [20 Abril, 2023 07:00 UTC](https://pyar.discourse.group/t/version-del-programa/1106/10 "2023-04-20T07:00:37Z")

</div>

Sí, más o menos. A ver, resumiendo tu propuesta:

- si está instalado ( **lo normal** ): sacás la info de `metadata.version()` y usás eso; a nivel “implementación”, tenés la versión hardcodeada en `setup.py`, se usa solamente para empaquetar/releasear, y listo

- corriendo desde el proyecto (raro, o no tanto, ver detalle abajo): mostrás directamente el hash del commit donde estás parado y listo; a nivel implementación no hay que hacer nada

Eso funciona, pero…

- **Detalle 1** : para cuando corre del proyecto, si yo te digo “version ffcb8220d7” eso no te dice nada; si yo te digo “version 2.0+5@ffcb8220d7” (“estás parado en ffcb8220d7, que son cinco commits luego de 2.0”) te da un montón de info sin tener que andar buscando nada

- **Detalle 2** : justamente algo como “version 2.0+5@ffcb8220d7” es **genial** para “nightly releases”, que lo puede estar usando un montón de gente, más allá que la versión estable es 2.0…

---

<div class="post-metadata">

**Author:** ![SAn](https://yyz2.discourse-cdn.com/free1/user_avatar/pyar.discourse.group/san/32/247_2.png) [@SAn](https://pyar.discourse.group/u/SAn)\
**Post date:** [20 Abril, 2023 11:24 UTC](https://pyar.discourse.group/t/version-del-programa/1106/11 "2023-04-20T11:24:44Z")

</div>

Le podes pedir a git que te de esa info, me parece, pidiendole “el tag mas cercano” y otros detalles, no tengo a mano cómo era pero esta por ahi la info de como hacerlo ya que alguna vez lo hice.

---

<div class="post-metadata">

**Author:** ![facundo](https://yyz2.discourse-cdn.com/free1/user_avatar/pyar.discourse.group/facundo/32/7_2.png) [@facundo](https://pyar.discourse.group/u/facundo)\
**Post date:** [20 Abril, 2023 11:50 UTC](https://pyar.discourse.group/t/version-del-programa/1106/12 "2023-04-20T11:50:52Z")

</div>

Y se me ocurre que el `setup.py` valide que haya un tag con la versión que tiene hardcodeada… seguimos teniendo la versión “en dos lados”, pero al menos es validable que coincidan.

---

<div class="post-metadata">

**Author:** ![sofide](https://yyz2.discourse-cdn.com/free1/user_avatar/pyar.discourse.group/sofide/32/17_2.png) [@sofide](https://pyar.discourse.group/u/sofide)\
**Post date:** [28 Abril, 2023 21:05 UTC](https://pyar.discourse.group/t/version-del-programa/1106/13 "2023-04-28T21:05:49Z")

</div>

Me intriga saber para que proyecto estás tramando esto 😄

Sobre esto:

> [@facundo](#):
>
> algo como “version 2.0+5@ffcb8220d7” es **genial** para “nightly releases”, que lo puede estar usando un montón de gente, más allá que la versión estable es 2.0…

Me parece que lo ideal debería ser tener esos “nightly releases” directamente en pypi, usando versiones con el sufijo `dev`, por ejemplo `1.0.1-dev1`). Así es más fácil para tus users tener acceso a los early releases sin tener que tener tu repo clonado y actualizado… Pero obvio que esto igual depende del proyecto.

---

<div class="post-metadata">

**Author:** ![facundo](https://yyz2.discourse-cdn.com/free1/user_avatar/pyar.discourse.group/facundo/32/7_2.png) [@facundo](https://pyar.discourse.group/u/facundo)\
**Post date:** [28 Abril, 2023 21:53 UTC](https://pyar.discourse.group/t/version-del-programa/1106/14 "2023-04-28T21:53:16Z")

</div>

Para ninguno en particular. Pero en cada proyecto que arranco (y arranqué dos en estas semanas, ahora que estoy desempleado y tengo tiempo) me enfrento al mismo problema y me “molesta” que no haya nada resuelto de manera que sea fácil tener una solución completa…
