pcobra


Namepcobra JSON
Version 10.0.12 PyPI version JSON
download
home_pageNone
SummaryUn lenguaje de programación en español para simulaciones y más.
upload_time2025-11-01 11:26:54
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseMIT License Copyright (c) 2024 Adolfo González Hernández Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords cobra lenguaje cli
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            # Proyecto Cobra
[![Codecov](https://codecov.io/gh/Alphonsus411/pCobra/branch/work/graph/badge.svg)](https://codecov.io/gh/Alphonsus411/pCobra/branch/work)
[![Versión estable](https://img.shields.io/github/v/release/Alphonsus411/pCobra?label=stable)](https://github.com/Alphonsus411/pCobra/releases/latest)
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/Alphonsus411/pCobra/HEAD?labpath=notebooks/playground.ipynb)


## Qué es pCobra

Versión 10.0.9

- Ajustes en `SafeUnpickler` para admitir `core.ast_nodes` y `cobra.core.ast_nodes`.
- `corelibs.sistema.ejecutar` ahora requiere una lista blanca mediante `permitidos` o `COBRA_EJECUTAR_PERMITIDOS`.
- Caché incremental respaldada por SQLitePlus para AST y tokens.
- Actualización a Agix 1.4.0.

[English version available here](docs/README.en.md)

pCobra es un lenguaje de programación escrito en español y pensado para la creación de herramientas, simulaciones y análisis en disciplinas como biología, computación y astrofísica. El proyecto integra un lexer, parser y un sistema de transpilación capaz de generar código en Python, JavaScript, ensamblador, Rust, C++, Go, Kotlin, Swift, R, Julia, Java, COBOL, Fortran, Pascal, Ruby, PHP, Perl, VisualBasic, Matlab, Mojo, LaTeX, C y WebAssembly, facilitando su despliegue en distintos entornos.

El objetivo de pCobra es brindar a la comunidad hispanohablante una alternativa cercana para aprender y construir software, reduciendo la barrera del idioma y fomentando la colaboración abierta. A medida que evoluciona, el proyecto busca ampliar su ecosistema, mejorar la transpilación y proveer herramientas que sirvan de puente entre la educación y el desarrollo profesional.


## Tabla de Contenidos

- Descripción del Proyecto
- Arquitectura centrada en Hololang
- Instalación
- Cómo usar la CLI
- Descargas
- Estructura del Proyecto
- Herramientas y scripts soportados
- Características Principales
- Uso
- Tokens y reglas léxicas
- Ejemplo de Uso
- Conversión desde otros lenguajes
- Pruebas
- Ejemplos de prueba
- Generar documentación
- Análisis con CodeQL
- [CobraHub](docs/frontend/cobrahub.rst)
- Hitos y Roadmap
- Contribuciones
- [Guía de Contribución](CONTRIBUTING.md)
- [Proponer extensiones](docs/frontend/rfc_plugins.rst)
- Extensión para VS Code
- [Comunidad](docs/comunidad.md)
- Licencia
- [Manual de Cobra](docs/MANUAL_COBRA.md)
- [Manual de Cobra en formato reStructuredText](docs/MANUAL_COBRA.rst)
- [Manual de Cobra en PDF](https://alphonsus411.github.io/pCobra/proyectocobra.pdf)
- [Guía básica](docs/guia_basica.md)
- [Especificación técnica](docs/especificacion_tecnica.md)
- [Blog del minilenguaje](docs/blog_minilenguaje.md)
- [Cheatsheet](docs/cheatsheet.tex) – compílalo a PDF con LaTeX
- [Casos de uso reales](docs/casos_reales.md)
- [Limitaciones del sandbox de Node](docs/limitaciones_node_sandbox.md)
- [Limitaciones del sandbox de C++](docs/limitaciones_cpp_sandbox.md)
- Notebooks de ejemplo y casos reales
- Probar Cobra en línea
- [Historial de cambios](CHANGELOG.md)

## Ejemplos

Proyectos de demostración disponibles en el [repositorio de ejemplos](https://github.com/Alphonsus411/pCobra/tree/HEAD/examples).
Este repositorio incluye ejemplos básicos en la carpeta `examples/`, por
ejemplo `examples/funciones_principales.co` que muestra condicionales, bucles y
definición de funciones en Cobra.
Para ejemplos interactivos revisa los cuadernos en `notebooks/casos_reales/`.

### Ejemplos avanzados

En [examples/avanzados/](examples/avanzados/) se incluyen programas que profundizan
en Cobra con ejercicios de control de flujo, funciones recursivas e interacción
de clases. Cada tema cuenta con su propia carpeta:

- [examples/avanzados/control_flujo/](examples/avanzados/control_flujo/)
- [examples/avanzados/funciones/](examples/avanzados/funciones/)
- [examples/avanzados/clases/](examples/avanzados/clases/)

## Notebooks de ejemplo

En la carpeta `notebooks/` se incluye el cuaderno `ejemplo_basico.ipynb` con un ejemplo básico de uso de Cobra. Además, los cuadernos de `notebooks/casos_reales/` muestran cómo ejecutar los ejemplos avanzados. Para abrirlo ejecuta:

```bash
cobra jupyter --notebook notebooks/ejemplo_basico.ipynb
```
Si omites el argumento ``--notebook`` se abrirá Jupyter Notebook de manera convencional y podrás escoger el archivo desde la interfaz web.



## Probar Cobra en línea

Puedes experimentar con Cobra directamente en tu navegador:

- [Replit](https://replit.com/github/Alphonsus411/pCobra)
- [Binder](https://mybinder.org/v2/gh/Alphonsus411/pCobra/HEAD?labpath=notebooks/playground.ipynb)
- [GitHub Codespaces](https://codespaces.new/Alphonsus411/pCobra)

## Descripción del Proyecto

Cobra está diseñado para facilitar la programación en español, permitiendo que los desarrolladores utilicen un lenguaje más accesible. A través de su lexer, parser y transpiladores, Cobra puede analizar, ejecutar y convertir código a otros lenguajes, brindando soporte para variables, funciones, estructuras de control y estructuras de datos como listas, diccionarios y clases.
Para un tutorial paso a paso consulta el [Manual de Cobra](docs/MANUAL_COBRA.rst).
La especificación completa del lenguaje se encuentra en [SPEC_COBRA.md](docs/SPEC_COBRA.md).

## Arquitectura centrada en Hololang

La cadena de herramientas de Cobra se articula alrededor de Hololang, un lenguaje intermedio diseñado para describir los programas de forma explícita y portable. El flujo principal funciona de la siguiente manera:

1. El front-end analiza el código fuente y construye el AST de Cobra.
2. Ese AST se normaliza y se transforma en representaciones Hololang que capturan estructuras de control, módulos y tipos.
3. Los transpiladores consumen el IR Hololang para generar código en los distintos backends soportados.

Hololang actúa como contrato estable entre el front-end y los generadores de código, permitiendo incorporar nuevos destinos sin modificar el parser original. Gracias a esta capa intermedia, Cobra ofrece un generador de ensamblador que produce instrucciones simbólicas optimizadas para depuración y diagnóstico de rendimiento. El comando `cobra transpilar` puede emitir directamente los ficheros Hololang o derivarlos a `asm` para obtener la salida en ensamblador.

## Instalación

```bash
pip install pcobra
```

### Instalación con pipx

```bash
pipx install pcobra
```

### Instalación desde repositorio

Consulta [docs/instalacion.md](docs/instalacion.md#instalacion-desde-repositorio) para instrucciones avanzadas (gramáticas, plugins, scripts y uso de Docker).

## Cómo usar la CLI

Ejecuta un archivo de Cobra con:

```bash
cobra archivo.co
```

Para listar las opciones disponibles ejecuta:

```bash
cobra --help
```

El intérprete se ejecuta en modo seguro por defecto. Si deseas desactivarlo utiliza la opción `--no-seguro`:

```bash
cobra archivo.co --no-seguro
```

### Ejemplo de transpilación

```bash
cobra transpilar hola.co --lenguaje python
```

Esto generará `hola.py`. Para conocer otros destinos y opciones, consulta la [documentación detallada](docs/) o revisa [docs/frontend](docs/frontend).

## Descarga de binarios

Para cada lanzamiento se generan ejecutables para Linux, Windows y macOS mediante
GitHub Actions. Puedes encontrarlos en la pestaña
[Releases](https://github.com/Alphonsus411/pCobra/releases) del repositorio.
Solo descarga el archivo correspondiente a tu sistema operativo desde la versión
más reciente y ejecútalo directamente.

Crear un tag `vX.Y.Z` en GitHub desencadena la publicación automática del
paquete en PyPI y la actualización de la imagen Docker.

Si prefieres generar el ejecutable manualmente ejecuta desde la raíz del
repositorio en tu sistema (Windows, macOS o Linux):

```bash
pip install pyinstaller
cobra empaquetar --output dist
```
El nombre del binario puede ajustarse con la opción `--name`. También puedes
usar un archivo `.spec` propio o agregar datos adicionales mediante
``--spec`` y ``--add-data``:

```bash
cobra empaquetar --spec build/cobra.spec \
  --add-data "all-bytes.dat;all-bytes.dat" --output dist
```

## Crear un ejecutable con PyInstaller

Para compilar Cobra de forma independiente primero crea y activa un entorno virtual:

```bash
python -m venv .venv
source .venv/bin/activate  # En Windows usa .\\.venv\\Scripts\\activate
```

Instala la distribución publicada y PyInstaller:

```bash
pip install pcobra
pip install pyinstaller
```

Luego genera el binario con:

```bash
pyinstaller --onefile src/pcobra/cli/cli.py -n cobra
```

El ejecutable aparecerá en el directorio `dist/`.

Para realizar una prueba rápida puedes ejecutar el script
`scripts/test_pyinstaller.sh`. Este script crea un entorno virtual temporal,
instala `pcobra` desde el repositorio (o desde PyPI si se ejecuta fuera
de él) y ejecuta PyInstaller sobre `src/pcobra/cli/cli.py` o el script `cobra-init`.
El binario resultante se
guardará por defecto en `dist/`.

```bash
scripts/test_pyinstaller.sh
```


## Descargas

Los ejecutables precompilados para Cobra se publican en la sección de [Releases](https://github.com/Alphonsus411/pCobra/releases).

| Versión | Plataforma | Enlace |
| --- | --- | --- |
| 10.0.9 | Linux x86_64 | [cobra-linux](https://github.com/Alphonsus411/pCobra/releases/download/v10.0.9/cobra-linux) |
| 10.0.9 | Windows x86_64 | [cobra.exe](https://github.com/Alphonsus411/pCobra/releases/download/v10.0.9/cobra.exe) |
| 10.0.9 | macOS arm64 | [cobra-macos](https://github.com/Alphonsus411/pCobra/releases/download/v10.0.9/cobra-macos) |

Para comprobar la integridad del archivo descargado calcula su hash SHA256 y compáralo con el publicado:

```bash
sha256sum cobra-linux
```

En Windows utiliza:

```powershell
CertUtil -hashfile cobra.exe SHA256
```

# Estructura del Proyecto

El proyecto se organiza en las siguientes carpetas:

- `src/pcobra/`: Código fuente del paquete.
- `docs/`: Documentación del proyecto.
- `tests/`: Pruebas automáticas.
- `examples/`: Ejemplos de uso.
- `extensions/`: Extensiones oficiales, como la de VS Code.
- `scripts/`: Scripts de utilidad.
- `notebooks/`: Cuadernos interactivos.
- `docker/`: Archivos de configuración para contenedores.
- `binder/`: Archivos para ejecutar el proyecto en Binder.

Los archivos `requirements.txt` y `pyproject.toml` en la raíz definen las dependencias del proyecto.

# Herramientas y scripts soportados

El proyecto soporta oficialmente:

- `Makefile` para automatizar tareas como `make install`, `make test` y `make clean`.
- `scripts/run.sh` para ejecutar Cobra con variables definidas en `.env`.
- `scripts/install.sh` para preparar el entorno de desarrollo.
- Scripts auxiliares en `scripts/`.
- Configuraciones Docker en `docker/`.

# Características Principales

- Lexer y Parser: Implementación de un lexer para la tokenización del código fuente y un parser para la construcción de un árbol de sintaxis abstracta (AST).
- Transpiladores a Python, JavaScript, ensamblador, Rust, C++, Go, Kotlin, Swift, R, Julia, Java, COBOL, Fortran, Pascal, Ruby, PHP, Perl, VisualBasic, Matlab, Mojo, LaTeX, C y WebAssembly: Cobra puede convertir el código en estos lenguajes, facilitando su integración con aplicaciones externas.
- Soporte de Estructuras Avanzadas: Permite la declaración de variables, funciones, clases, listas y diccionarios, así como el uso de bucles y condicionales.
- Módulos nativos con funciones de E/S, utilidades matemáticas y estructuras de datos para usar directamente desde Cobra.
- Instalación de paquetes en tiempo de ejecución mediante la instrucción `usar`.
- Manejo de Errores: El sistema captura y reporta errores de sintaxis, facilitando la depuración.
- Visualización y Depuración: Salida detallada de tokens, AST y errores de sintaxis para un desarrollo más sencillo.
- Decoradores de rendimiento: la biblioteca ``smooth-criminal`` ofrece
  funciones como ``optimizar`` y ``perfilar`` para mejorar y medir la
  ejecución de código Python desde Cobra.
- Benchmarking: ejemplos completos de medición de rendimiento están
  disponibles en `docs/frontend/benchmarking.rst`.
- Ejemplos de Código y Documentación: Ejemplos prácticos que ilustran el uso del lexer, parser y transpiladores.
- Ejemplos Avanzados: Revisa `docs/frontend/ejemplos_avanzados.rst` para conocer casos con clases, hilos y manejo de errores.
- Identificadores en Unicode: Puedes nombrar variables y funciones utilizando
  caracteres como `á`, `ñ` o `Ω` para una mayor flexibilidad.

## Rendimiento

Los benchmarks más recientes se ejecutaron con
`scripts/benchmarks/compare_backends.py` para comparar varios backends. El
tiempo aproximado fue de **0.68 s** para Cobra y Python,
**0.07 s** para JavaScript y **0.04 s** para Rust, sin consumo
significativo de memoria.

Ejecuta el script con:

```bash
python scripts/benchmarks/compare_backends.py --output bench_results.json
```

El archivo [bench_results.json](bench_results.json) se guarda en el directorio
actual y puede analizarse con el cuaderno
[notebooks/benchmarks_resultados.ipynb](notebooks/benchmarks_resultados.ipynb).

Para ver la evolución entre versiones ejecuta:

```bash
python scripts/benchmarks/compare_releases.py --output benchmarks_compare.json
```

Los resultados históricos se publican como archivos `benchmarks.json` en la
[sección de Releases](https://github.com/Alphonsus411/pCobra/releases), donde
puedes consultar las métricas de cada versión.

Para comparar el rendimiento de los hilos ejecuta `cobra benchthreads`:

```bash
cobra benchthreads --output threads.json
```

El resultado contiene tres entradas (secuencial, cli_hilos y kernel_hilos) con
los tiempos y uso de CPU.

Para generar binarios en C, C++ y Rust y medir su rendimiento ejecuta:

```bash
cobra bench --binary
```

Los resultados se guardan en `binary_bench.json`.

# Uso

Para ejecutar el proyecto directamente desde el repositorio se incluye el
script `scripts/run.sh`. Este cargará las variables definidas en `.env` si dicho archivo
existe y luego llamará a `python -m pcobra` pasando todos los argumentos
recibidos. Úsalo de la siguiente forma:

```bash
./scripts/run.sh [opciones]
```

También puedes ejecutar la interfaz de línea de comandos directamente desde la
raíz del proyecto:

```bash
python -m pcobra
```

Para conocer las opciones avanzadas del modo seguro revisa
`docs/frontend/modo_seguro.rst`. Los ejemplos de medición de rendimiento
están disponibles en `docs/frontend/benchmarking.rst`.

Para ejecutar pruebas unitarias, utiliza pytest:

````bash
PYTHONPATH=$PWD pytest tests --cov=pcobra --cov-report=term-missing \
  --cov-fail-under=95
````

También puedes ejecutar suites específicas ubicadas en `tests`:

````bash
python -m tests.suite_cli           # Solo pruebas de la CLI
python -m tests.suite_core          # Pruebas de lexer, parser e intérprete
python -m tests.suite_transpiladores  # Pruebas de los transpiladores
````

## Uso directo desde el repositorio

El archivo `sitecustomize.py` se carga automáticamente cuando Python se
ejecuta desde la raíz del proyecto. Este módulo añade la carpeta `src` a
`sys.path`, permitiendo importar paquetes como `src.modulo` sin instalar
el paquete ni modificar `PYTHONPATH`.

Para probar Cobra de esta forma realiza lo siguiente:

```bash
python -m venv .venv
source .venv/bin/activate  # En Unix
.\.venv\Scripts\activate  # En Windows
make run                   # o bien: python -m pcobra
```

## Tokens y reglas léxicas

El analizador léxico convierte el código en tokens de acuerdo con las
expresiones regulares definidas en `lexer.py`. En la siguiente tabla se
describen todos los tokens disponibles:

| Token | Descripción |
|-------|-------------|
| DIVIDIR | Palabra clave o instrucción "dividir" |
| MULTIPLICAR | Palabra clave o instrucción "multiplicar" |
| CLASE | Palabra clave "clase" |
| DICCIONARIO | Palabra clave "diccionario" |
| LISTA | Palabra clave "lista" |
| RBRACE | Símbolo "}" |
| DEF | Palabra clave "def" |
| IN | Palabra clave "in" |
| LBRACE | Símbolo "{" |
| FOR | Palabra clave "for" |
| DOSPUNTOS | Símbolo ":" |
| VAR | Palabra clave "var" |
| FUNC | Palabra clave "func" o "definir" |
| SI | Palabra clave "si" |
| SINO | Palabra clave "sino" |
| MIENTRAS | Palabra clave "mientras" |
| PARA | Palabra clave "para" |
| IMPORT | Palabra clave "import" |
| USAR | Palabra clave "usar" |
| MACRO | Palabra clave "macro" |
| HOLOBIT | Palabra clave "holobit" |
| PROYECTAR | Palabra clave "proyectar" |
| TRANSFORMAR | Palabra clave "transformar" |
| GRAFICAR | Palabra clave "graficar" |
| TRY | Palabra clave "try" o "intentar" |
| CATCH | Palabra clave "catch" o "capturar" |
| THROW | Palabra clave "throw" o "lanzar" |
| ENTERO | Número entero |
| FLOTANTE | Número con punto decimal |
| CADENA | Cadena de caracteres |
| BOOLEANO | Literal booleano |
| IDENTIFICADOR | Nombre de variable o función |
| ASIGNAR | Símbolo "=" |
| SUMA | Operador "+" |
| RESTA | Operador "-" |
| MULT | Operador "*" |
| DIV | Operador "/" |
| MAYORQUE | Operador ">" |
| MENORQUE | Operador "<" |
| MAYORIGUAL | Operador ">=" |
| MENORIGUAL | Operador "<=" |
| IGUAL | Operador "==" |
| DIFERENTE | Operador "!=" |
| AND | Operador lógico "&&" |
| OR | Operador lógico "||" |
| NOT | Operador "!" |
| MOD | Operador "%" |
| LPAREN | Símbolo "(" |
| RPAREN | Símbolo ")" |
| LBRACKET | Símbolo "[" |
| RBRACKET | Símbolo "]" |
| COMA | Símbolo "," |
| RETORNO | Palabra clave "retorno" |
| FIN | Palabra clave "fin" |
| EOF | Fin de archivo |
| IMPRIMIR | Palabra clave "imprimir" |
| HILO | Palabra clave "hilo" |
| ASINCRONICO | Palabra clave "asincronico" |
| DECORADOR | Símbolo "@" |
| YIELD | Palabra clave "yield" |
| ESPERAR | Palabra clave "esperar" |
| ROMPER | Palabra clave "romper" |
| CONTINUAR | Palabra clave "continuar" |
| PASAR | Palabra clave "pasar" |
| AFIRMAR | Palabra clave "afirmar" |
| ELIMINAR | Palabra clave "eliminar" |
| GLOBAL | Palabra clave "global" |
| NOLOCAL | Palabra clave "nolocal" |
| LAMBDA | Palabra clave "lambda" |
| CON | Palabra clave "con" |
| FINALMENTE | Palabra clave "finalmente" |
| DESDE | Palabra clave "desde" |
| COMO | Palabra clave "como" |
| SWITCH | Palabra clave "switch" o "segun" |
| CASE | Palabra clave "case" o "caso" |

Las expresiones regulares se agrupan en `especificacion_tokens` y se procesan en orden para encontrar coincidencias. Las palabras clave usan patrones como `\bvar\b` o `\bfunc\b`, los números emplean `\d+` o `\d+\.\d+` y las cadenas se detectan con `"[^\"]*"` o `'[^']*'`. Los identificadores permiten caracteres Unicode mediante `[^\W\d_][\w]*`. Operadores y símbolos utilizan patrones directos como `==`, `&&` o `\(`. Antes del análisis se eliminan los comentarios de línea y de bloque con `re.sub`.

# Ejemplo de Uso

Puedes probar el lexer y parser con un código como el siguiente:

```python
from cobra.core import Lexer, Parser
from cobra.transpilers.transpiler.to_python import TranspiladorPython

codigo = """
var x = 10
si x > 5 :
    proyectar(x, "2D")
sino :
    graficar(x)
"""

lexer = Lexer(codigo)
tokens = lexer.analizar_token()

parser = Parser(tokens)

arbol = parser.parsear()
print(arbol)

transpiler = TranspiladorPython()
codigo_python = transpiler.generate_code(arbol)
print(codigo_python)
```

## Ejemplo de imprimir, holobits y bucles

A continuación se muestra un fragmento que utiliza `imprimir`, holobits y bucles:

````cobra
codigo = '''
var h = holobit([0.8, -0.5, 1.2])
imprimir(h)

var contador = 0
mientras contador < 3 :
    imprimir(contador)
    contador += 1

para var i en rango(2) :
    imprimir(i)
'''
````

Al generar código para Python, `imprimir` se convierte en `print`, `mientras` en `while` y `para` en `for`. En JavaScript estos elementos se transforman en `console.log`, `while` y `for...of` respectivamente. Para el modo ensamblador se generan instrucciones `PRINT`, `WHILE` y `FOR`. En Rust se produce código equivalente con `println!`, `while` y `for`. En C++ se obtienen construcciones con `std::cout`, `while` y `for`. El tipo `holobit` se traduce a la llamada `holobit([...])` en Python, `new Holobit([...])` en JavaScript, `holobit(vec![...])` en Rust o `holobit({ ... })` en C++. En Go se genera `fmt.Println`, en Kotlin `println`, en Swift `print`, en R se usa `print` y en Julia `println`; en Java se usa `System.out.println`, en COBOL `DISPLAY`, en Fortran `print *` y en Pascal `writeln`, en VisualBasic `Console.WriteLine`, en Ruby `puts`, en PHP `echo`, en Matlab `disp`, en Mojo `print` y en LaTeX `\texttt{}`.

## Integración con holobit-sdk

El proyecto instala automáticamente la librería `holobit-sdk`, utilizada para visualizar y manipular holobits. Las funciones `graficar`, `proyectar`, `transformar`, `escalar` y `mover` de `src.core.holobits` delegan en esta API. Desde la versión ``1.0.8`` del SDK se incluyen las operaciones ``escalar`` y ``mover``; en versiones anteriores Cobra calcula estos efectos manualmente.

```python
from core.holobits import Holobit, graficar, proyectar, transformar, escalar, mover

h = Holobit([0.8, -0.5, 1.2, 0.0, 0.0, 0.0])
proyectar(h, "2D")
graficar(h)
transformar(h, "rotar", "z", 90)
escalar(h, 2.0)
mover(h, 1.0, 0.0, -1.0)
```

## Ejemplo de carga de módulos

Puedes dividir el código en varios archivos y cargarlos con `import`:

````cobra
# modulo.co
var saludo = 'Hola desde módulo'

# programa.co
import 'modulo.co'
imprimir(saludo)
````

Al ejecutar `programa.co`, se procesará primero `modulo.co` y luego se imprimirá `Hola desde módulo`.

## Instrucción `usar` para dependencias dinámicas

La sentencia `usar "paquete"` intenta importar un módulo de Python. Si el
paquete no está disponible, Cobra ejecutará `pip install paquete` para
instalarlo y luego lo cargará en tiempo de ejecución. El módulo queda
registrado en el entorno bajo el mismo nombre para su uso posterior.
Para restringir qué dependencias pueden instalarse se emplea la variable
`USAR_WHITELIST` definida en `src/pcobra/cobra/usar_loader.py`. Basta con
añadir o quitar nombres de paquetes en dicho conjunto para modificar la lista
autorizada. Si la lista se deja vacía la función `obtener_modulo` lanzará
`PermissionError`, por lo que es necesario poblarla antes de permitir
instalaciones dinámicas.

Para habilitar la instalación automática define la variable de entorno
`COBRA_USAR_INSTALL=1`. Cuando esta variable no esté establecida,
`obtener_modulo()` rechazará instalar dependencias y lanzará un
`RuntimeError` si el paquete no se encuentra.

## Archivo de mapeo de módulos

Los transpiladores consultan `cobra.mod` para resolver las importaciones.
Este archivo sigue un esquema YAML sencillo donde cada clave es la ruta del
módulo Cobra y sus valores indican las rutas de los archivos generados.

Ejemplo de formato:

```yaml
modulo.co:
  version: "1.0.0"
  python: modulo.py
  js: modulo.js
```

Si una entrada no se encuentra, el transpilador cargará directamente el archivo
indicado en la instrucción `import`. Para añadir o modificar rutas basta con
editar `cobra.mod` y volver a ejecutar las pruebas.

## Invocar el transpilador

La carpeta [`src/pcobra/cobra/transpilers/transpiler`](src/pcobra/cobra/transpilers/transpiler)
contiene la implementación de los transpiladores a Python, JavaScript, ensamblador, Rust, C++, Go, Kotlin, Swift, R, Julia, Java, COBOL, Fortran, Pascal, Ruby, PHP, Perl, VisualBasic, Matlab, Mojo, LaTeX, C y WebAssembly. Una vez
instaladas las dependencias, puedes llamar al transpilador desde tu propio
script de la siguiente manera:

```python
from cobra.transpilers.transpiler.to_python import TranspiladorPython
from cobra.core import Parser

codigo = "imprimir('hola')"
parser = Parser(codigo)
arbol = parser.parsear()
transpiler = TranspiladorPython()
resultado = transpiler.generate_code(arbol)
print(resultado)
```

Para otros lenguajes puedes invocar los nuevos transpiladores así:

```python
from cobra.transpilers.transpiler.to_cobol import TranspiladorCOBOL
from cobra.transpilers.transpiler.to_fortran import TranspiladorFortran
from cobra.transpilers.transpiler.to_pascal import TranspiladorPascal
from cobra.transpilers.transpiler.to_ruby import TranspiladorRuby
from cobra.transpilers.transpiler.to_php import TranspiladorPHP
from cobra.transpilers.transpiler.to_perl import TranspiladorPerl
from cobra.transpilers.transpiler.to_visualbasic import TranspiladorVisualBasic
from cobra.transpilers.transpiler.to_kotlin import TranspiladorKotlin
from cobra.transpilers.transpiler.to_swift import TranspiladorSwift
from cobra.transpilers.transpiler.to_matlab import TranspiladorMatlab
from cobra.transpilers.transpiler.to_mojo import TranspiladorMojo
from cobra.transpilers.transpiler.to_latex import TranspiladorLatex

codigo_cobol = TranspiladorCOBOL().generate_code(arbol)
codigo_fortran = TranspiladorFortran().generate_code(arbol)
codigo_pascal = TranspiladorPascal().generate_code(arbol)
codigo_ruby = TranspiladorRuby().generate_code(arbol)
codigo_php = TranspiladorPHP().generate_code(arbol)
codigo_perl = TranspiladorPerl().generate_code(arbol)
codigo_visualbasic = TranspiladorVisualBasic().generate_code(arbol)
codigo_kotlin = TranspiladorKotlin().generate_code(arbol)
codigo_swift = TranspiladorSwift().generate_code(arbol)
codigo_matlab = TranspiladorMatlab().generate_code(arbol)
codigo_mojo = TranspiladorMojo().generate_code(arbol)
codigo_latex = TranspiladorLatex().generate_code(arbol)
```

Tras obtener el código con ``generate_code`` puedes guardarlo usando ``save_file``:

```python
transpiler.save_file("salida.py")
```

Requiere tener instalado el paquete en modo editable y todas las dependencias
de `requirements.txt`. Si necesitas generar archivos a partir de módulos Cobra,
consulta el mapeo definido en `cobra.mod`.

## Ejemplo de concurrencia

Es posible lanzar funciones en hilos con la palabra clave `hilo`:

````cobra
func tarea():
    imprimir('trabajo')
fin

hilo tarea()
imprimir('principal')
````

Al generar código para estas funciones, se crean llamadas `asyncio.create_task` en Python y `Promise.resolve().then` en JavaScript.

## Uso desde la CLI

Una vez instalado el paquete, la herramienta `cobra` ofrece varios subcomandos:

### Autocompletado

La CLI soporta autocompletado de argumentos mediante
[argcomplete](https://kislyuk.github.io/argcomplete/). Para habilitarlo en tu
terminal ejecuta uno de los siguientes comandos según tu *shell*:

- **bash**:

  ```bash
  eval "$(register-python-argcomplete cobra)"
  ```

- **zsh**:

  ```bash
  autoload -U bashcompinit
  bashcompinit
  eval "$(register-python-argcomplete cobra)"
  ```

- **fish**:

  ```bash
  register-python-argcomplete --shell fish cobra | source
  ```

```bash
# Compilar un archivo a Python, JavaScript, ensamblador, Rust, C++, Go, Kotlin, Swift, R, Julia, Java, COBOL, Fortran, Pascal, Ruby, PHP, Perl, VisualBasic, Matlab, Mojo, LaTeX, C o WebAssembly
cobra compilar programa.co --tipo python

# Transpilar inverso de Python a JavaScript
cobra transpilar-inverso script.py --origen=python --destino=js

# Ejemplo de mensaje de error al compilar un archivo inexistente
cobra compilar noexiste.co
# Salida:
# Error: El archivo 'noexiste.co' no existe


# Gestionar módulos instalados
cobra modulos listar
cobra modulos instalar ruta/al/modulo.co
cobra modulos remover modulo.co
# Crear e instalar paquetes Cobra
cobra paquete crear src demo.cobra
cobra paquete instalar demo.cobra
# Generar documentación HTML y API
cobra docs
# Crear un ejecutable independiente
cobra empaquetar --output dist
# Perfilar un programa y guardar los resultados
cobra profile programa.co --output salida.prof
# O mostrar el perfil directamente en pantalla
cobra profile programa.co
# Verificar la salida en Python y JavaScript
cobra verificar ejemplo.co --lenguajes=python,js
# Iniciar el iddle gráfico (requiere Flet)
cobra gui
```

Si deseas desactivar los colores usa `--no-color`:

```bash
cobra --no-color ejecutar programa.co
```

Para aumentar el nivel de detalle de los mensajes añade `-v` o `--verbose`.
Por defecto el nivel de registro es `INFO`; con `-v` o más se cambia a `DEBUG`:

```bash
cobra -v ejecutar programa.co
```

Los archivos con extensión ``.cobra`` representan paquetes completos, mientras que los scripts individuales se guardan como ``.co``.

El subcomando `docs` ejecuta `sphinx-apidoc` para generar la documentación de la API antes de compilar el HTML.
El subcomando `gui` abre el iddle integrado y requiere tener instalado Flet.

## Conversión desde otros lenguajes a Cobra

Puedes usar `cobra transpilar-inverso` para leer un archivo en otro lenguaje,
convertirlo al AST de Cobra y luego generarlo en cualquier backend soportado.

```bash
cobra transpilar-inverso script.py --origen=python --destino=cobra
```

El proceso intenta mapear instrucciones básicas, pero características muy específicas pueden requerir ajustes manuales. Actualmente la cobertura varía según el lenguaje y puede que ciertas construcciones no estén implementadas.

Actualmente es posible convertir a Cobra código escrito en ensamblador, C, C++, COBOL, Fortran, Go, Java, JavaScript, Julia, Kotlin, LaTeX, Matlab, Mojo, Pascal, Perl, PHP, Python, R, Ruby, Rust, Swift, VisualBasic y WebAssembly.

### Diseño extensible de la CLI

La CLI está organizada en clases dentro de `src/pcobra/cli/commands`. Cada subcomando
hereda de `BaseCommand` y define su nombre, los argumentos que acepta y la acción
a ejecutar. En `src/pcobra/cli/cli.py` se instancian automáticamente y se registran en
`argparse`, por lo que para añadir un nuevo comando solo es necesario crear un
archivo con la nueva clase y llamar a `register_subparser` y `run`.
Para un tutorial completo de creación de plugins revisa
[`docs/frontend/plugins.rst`](docs/frontend/plugins.rst).

## Modo seguro

El intérprete y la CLI ejecutan el código en modo seguro de forma predeterminada. Este modo valida el AST y prohíbe primitivas como `leer_archivo`, `escribir_archivo`, `obtener_url`, `hilo`, `leer`, `escribir`, `existe`, `eliminar` y `enviar_post`. El validador `ValidadorProhibirReflexion` también bloquea llamadas a `eval`, `exec` y otras funciones de reflexión, además de impedir el acceso a atributos internos. Asimismo, las instrucciones `import` solo están permitidas para módulos instalados o incluidos en `IMPORT_WHITELIST`. Antes de cargar el código las rutas se normalizan con `os.path.realpath` y se comparan con `os.path.commonpath`, por lo que un enlace simbólico o un directorio como `modules_fake` no pueden evadir el filtro. Si el programa intenta utilizar estas funciones o importar otros archivos se lanzará `PrimitivaPeligrosaError`.
La validación se realiza mediante una cadena de validadores configurada por la
función `construir_cadena`, lo que facilita añadir nuevas comprobaciones en el
futuro.

## Ejecución en sandbox (--sandbox)

Algunos comandos permiten ejecutar código Python dentro de una "sandbox" gracias
a la biblioteca `RestrictedPython`. Esto limita las operaciones disponibles y
evita acciones potencialmente peligrosas como leer archivos o importar módulos
externos. Para activar esta opción utiliza `--sandbox` en los subcomandos
`ejecutar` e `interactive`.

El código se compila con `compile_restricted` y luego se ejecuta mediante
`exec`. **No** se recurre a `compile()` cuando la compilación segura falla,
sino que se propaga la excepción. El uso de `exec` sigue siendo peligroso,
por lo que se recomienda mantener el entorno de ejecución lo más pequeño
posible para reducir riesgos.

# Pruebas

Las pruebas están ubicadas en la carpeta `tests/` y utilizan pytest para la
ejecución. **Antes de correr cualquier prueba instala el paquete en modo
editable junto con las dependencias de desarrollo:**

```bash
pip install -e .[dev]
```

Además, cada cambio en los workflows de GitHub Actions se valida con
[`actionlint`](https://github.com/rhysd/actionlint) mediante el workflow
[Validar workflows](.github/workflows/validate-workflows.yml). Este proceso se
ejecuta automáticamente en los eventos `push` y `pull_request` cuando se
modifican archivos dentro de `.github/workflows/`, evitando que se integren
definiciones inválidas en la canalización de CI.

Esta instrucción añade el proyecto al `PYTHONPATH` e instala todas las
dependencias listadas en `requirements-dev.txt`, las cuales están incluidas en
el extra `dev` de `pyproject.toml`. Sin estas bibliotecas las pruebas fallarán
debido a módulos no encontrados.

Si prefieres ejecutar las pruebas directamente desde el repositorio sin
instalar el paquete, utiliza el script `scripts/test.sh`:

```bash
./scripts/test.sh
```

Este comando exporta `PYTHONPATH=$PWD` e invoca `pytest` con los argumentos
definidos en `pyproject.toml`.

````bash
PYTHONPATH=$PWD pytest tests --cov=pcobra --cov-report=term-missing \
  --cov-fail-under=95
````

 Algunas pruebas generan código en distintos lenguajes (por ejemplo C++, JavaScript o Go) y verifican que la sintaxis sea correcta. Para que estas pruebas se ejecuten con éxito es necesario contar con los compiladores o intérpretes correspondientes instalados en el sistema. En particular se requiere:

- Node.js
- gcc y g++
- Go (`golang-go`)
- Ruby (`ruby`)
- Rust (`rustc`)
- Java (`default-jdk`)

Con estas herramientas disponibles puedes ejecutar todo el conjunto con:

```bash
PYTHONPATH=$PWD pytest
```

En la integración continua se emplea:

```bash
pytest --cov=pcobra tests/
```

El reporte se guarda como `coverage.xml` y se utiliza en el CI.

### Ejemplos de prueba

En `tests/data` se incluyen programas mínimos utilizados en las
pruebas de entrada y salida de la CLI:

- `hola.cobra`: imprime el saludo «Hola Cobra».
- `suma.cobra`: define la función `sumar` y muestra la suma de dos
  números.

El archivo `tests/test_ejemplos_io.py` ejecuta estos ejemplos y compara
la salida con los archivos `.out` correspondientes. Para probarlos
manualmente:

```bash
cobra ejecutar tests/data/hola.cobra
cobra ejecutar tests/data/suma.cobra
```

También puedes transpilar los ejemplos para ver el código Python generado:

```bash
cobra transpilar tests/data/hola.cobra
cobra transpilar tests/data/suma.cobra
```

### Pruebas de rendimiento

El archivo `cobra.toml` incluye una sección `[rendimiento]` con el parámetro
`tiempo_max_transpilacion_seg`, que define en segundos el tiempo máximo
permitido para transpilar un archivo.

Para ejecutar únicamente las pruebas de rendimiento utiliza:

```bash
pytest -m performance
```

Si tu entorno es más lento o más rápido, ajusta el valor de
`tiempo_max_transpilacion_seg` en `cobra.toml` según tus necesidades.

Se han incluido pruebas que verifican los códigos de salida de la CLI. Los
subcomandos devuelven `0` al finalizar correctamente y un valor distinto en caso
de error.

### Ejemplos de subcomandos

````bash
cobra compilar programa.co --tipo=python
cobra compilar programa.co --tipo=asm
cobra compilar programa.co --tipo=cpp
cobra compilar programa.co --tipo=go
cobra compilar programa.co --tipo=ruby
cobra compilar programa.co --tipo=r
cobra compilar programa.co --tipo=julia
cobra compilar programa.co --tipo=java
cobra compilar programa.co --tipo=cobol
cobra compilar programa.co --tipo=fortran
cobra compilar programa.co --tipo=pascal
cobra compilar programa.co --tipo=php
echo $?  # 0 al compilar sin problemas

cobra ejecutar inexistente.co
# El archivo 'inexistente.co' no existe
echo $?  # 1
````

### Errores comunes

- `El archivo '<archivo>' no existe`: la ruta es incorrecta o el archivo no está disponible.
- `El módulo <nombre> no existe`: se intenta eliminar un módulo no instalado.
- `Primitiva peligrosa: <nombre>`: se usó una función restringida en modo seguro.
- `Acción de módulos no reconocida`: el subcomando indicado es inválido.

## Selección de idioma

La CLI utiliza `gettext` para mostrar los mensajes en distintos idiomas.
Puedes definir el idioma estableciendo la variable de entorno `COBRA_LANG`
o pasando el argumento `--lang` al ejecutar `cobra`.

```bash
COBRA_LANG=en cobra --ayuda
cobra --lang en compilar archivo.co
```

Si deseas añadir otro idioma, crea una carpeta `docs/frontend/locale/<cod>/LC_MESSAGES`
con los archivos `.po` de traducción y envía un pull request.

Para obtener un reporte de cobertura en la terminal ejecuta:

````bash
pytest --cov=src --cov-report=term-missing --cov-fail-under=95
````

## Caché del AST y SQLitePlus

A partir de la migración a **SQLitePlus**, la caché incremental de AST y tokens
se almacena en una base de datos `SQLite` cifrada en lugar de archivos sueltos.
La ruta por defecto es `~/.cobra/sqliteplus/core.db`, que se crea
automáticamente al primer acceso. Para inicializar la conexión es obligatoria la
variable de entorno `SQLITE_DB_KEY`, cuyo valor actúa como clave de cifrado.
Si necesitas una ubicación distinta configura `COBRA_DB_PATH`; cuando se
proporciona, el valor de `SQLITE_DB_KEY` se mantiene como clave incluso si
contiene `/` u otros separadores.

```bash
export SQLITE_DB_KEY="clave-local"          # Obligatorio para abrir la base
export COBRA_DB_PATH="$HOME/.cobra/sqliteplus/core.db"  # Opcional; usa el
                                                        # valor por defecto
# Para despliegues sin cifrado puedes usar un prefijo explícito:
export SQLITE_DB_KEY="path:/var/cache/pcobra/core.db"
```

Si necesitas ubicar la base de datos en otro sitio, ajusta `COBRA_DB_PATH` a la
ubicación deseada antes de ejecutar `cobra`. Como compatibilidad adicional, un
valor de `SQLITE_DB_KEY` que empiece por `path:` o `file:` se interpreta como
ruta explícita y desactiva el cifrado; en cualquier otro caso el valor se trata
como clave aunque contenga separadores y se emitirá una advertencia si parece
una ruta. La antigua variable
`COBRA_AST_CACHE` continúa disponible únicamente como alias de compatibilidad:
si la defines, el sistema derivará automáticamente una ruta `cache.db` en ese
directorio y mostrará una advertencia de depreciación.

### Limpieza y mantenimiento

El comando `cobra cache` sigue siendo el método soportado para borrar la caché y
ahora opera directamente sobre la base de datos. Incluye la opción `--vacuum`
para recompac tar la base tras la limpieza:

```bash
cobra cache --vacuum
```

### Migración de cachés JSON anteriores

Si conservas el directorio `cache/` con los archivos `.ast`/`.tok` utilizados en
versiones anteriores, puedes importarlos a SQLitePlus con el siguiente flujo:

1. Define `SQLITE_DB_KEY` (y `COBRA_DB_PATH` si deseas una ruta distinta).
2. Ejecuta el script auxiliar desde la raíz del proyecto, indicando la carpeta
   donde se encuentran los archivos heredados:

   ```bash
   python scripts/migrar_cache_sqliteplus.py --origen /ruta/al/cache
   ```

   El script convierte cada hash almacenado en JSON y recrea los fragmentos en
   la tabla SQLite. Las ejecuciones posteriores reutilizarán esa información sin
   necesidad de reanalizar tus fuentes.

3. Verifica la migración listando el contenido con cualquier visor SQLite o
   ejecutando nuevamente `cobra cache --vacuum` para comprobar que la conexión se
   inicializa correctamente.

Tras la migración, los ficheros JSON pueden eliminarse si ya no son necesarios.

## Generar documentación

Para obtener la documentación HTML puedes usar `cobra docs` o
`make html` desde la raíz del proyecto. El subcomando `docs` ejecuta
`sphinx-apidoc` y luego compila el HTML en la carpeta de salida configurada.

Puedes compilar la documentación de dos maneras:

1. **Con la CLI de Cobra**. Ejecuta `cobra docs`.

2. **Con Make**. Ejecuta `make html` para compilar los archivos ubicados en
   `docs/frontend`.

3. **Con pdoc**. Para generar documentación de la API con [pdoc](https://pdoc.dev),
   ejecuta `python scripts/generar_pdoc.py`. El resultado se guardará en
   la carpeta de salida configurada para la API.

A partir de esta versión, la API se genera de forma automática antes de
cada compilación para mantener la documentación actualizada.
Para aprender a desarrollar plugins revisa
[`docs/frontend/plugin_dev.rst`](docs/frontend/plugin_dev.rst).
Para conocer en detalle la interfaz disponible consulta
[`docs/frontend/plugin_sdk.rst`](docs/frontend/plugin_sdk.rst).

## Análisis con CodeQL

Este proyecto cuenta con un workflow de GitHub Actions definido en
`.github/workflows/codeql.yml`. Dicho flujo se ejecuta en cada *push* y
*pull request*, inicializando CodeQL para el lenguaje Python y aplicando
reglas personalizadas ubicadas en `.github/codeql/custom/`.

Las reglas proporcionan comprobaciones adicionales sobre el AST y los
transpiladores:

- **ast-no-type-validation.ql** verifica que las clases de nodos cuyo
  nombre empieza por `Nodo` incluyan validaciones de tipo en
  `__post_init__`.
- **missing-codegen-exception.ql** detecta métodos `generate_code` sin
  manejo de excepciones.
- **unsafe-eval-exec.ql** avisa cuando se usa `eval` o `exec` fuera del sandbox.

Para ejecutar el análisis de CodeQL de forma local puedes usar la CLI:

```bash
curl -L -o codeql.zip \
  https://github.com/github/codeql-cli-binaries/releases/latest/download/codeql-linux64.zip
unzip codeql.zip
./codeql/codeql database create db-python --language=python --source-root=.
./codeql/codeql database analyze db-python \
  .github/codeql/custom/codeql-config.yml
```

Esto te permitirá validar los cambios antes de subirlos al repositorio.
## Hitos y Roadmap

El proyecto avanza en versiones incrementales. Puedes consultar las tareas planeadas en [ROADMAP.md](docs/ROADMAP.md).


# Contribuciones

Las contribuciones son bienvenidas. Si deseas contribuir, sigue estos pasos:

- Haz un fork del proyecto.
- Crea una nueva rama (`git checkout -b feature/nueva-caracteristica`).
- Las ramas que comiencen con `feature/`, `bugfix/` o `doc/` recibirán etiquetas
  automáticas al abrir un pull request.
- Sigue las convenciones de estilo indicadas en `CONTRIBUTING.md`
  (formateo con `black`, longitud máxima de línea 88 y uso de `ruff`, `mypy`
  y `bandit`).
- Realiza tus cambios y haz commit (`git commit -m 'Añadir nueva característica'`).
- Ejecuta `make lint` para verificar el código con *ruff*, *mypy* y *bandit*. `bandit` analizará el directorio `src`.
- Ejecuta `make typecheck` para la verificación estática con *mypy* (y
  opcionalmente *pyright* si está instalado).
- Ejecuta `make secrets` para buscar credenciales expuestas usando *gitleaks*.
- Para lanzar todas las validaciones en un solo paso ejecuta `python scripts/check.py`.
  Este script corre *ruff*, *mypy*, *bandit*, *pytest* y *pyright*.
- El CI de GitHub Actions ejecuta automáticamente estas herramientas en cada pull request.
- Envía un pull request.
- Consulta [CONTRIBUTING.md](CONTRIBUTING.md) para más detalles sobre cómo abrir
  issues y preparar pull requests.
- Para proponer nuevas extensiones consulta [docs/frontend/rfc_plugins.rst](docs/frontend/rfc_plugins.rst).

## Dependabot y seguridad

Este repositorio cuenta con [Dependabot](.github/dependabot.yml) para mantener
actualizadas las dependencias de Python y las acciones de GitHub. Cada semana se
crean PR automáticos contra la rama `work` con las versiones más recientes.

Además, en el flujo de CI se incluye un paso de **safety check** que revisa la
lista de paquetes instalados en busca de vulnerabilidades conocidas. Si se
detecta alguna, la acción devolverá un reporte detallado y el trabajo fallará.
Consulta el log del paso "Seguridad de dependencias" para ver los paquetes
afectados y las recomendaciones de actualización.
De igual forma, se ejecuta *gitleaks* para asegurarse de que no existan
credenciales accidentales en el repositorio.

El repositorio también ejecuta CodeQL con reglas personalizadas para detectar
patrones de código riesgosos, como el uso de `eval` o `exec` fuera del sandbox.

## Comunidad

Únete a nuestro servidor de Discord para recibir anuncios, resolver dudas y colaborar en el desarrollo en [https://discord.gg/cobra](https://discord.gg/cobra).
También contamos con un canal de **Telegram** y una cuenta de **Twitter** donde difundimos eventos y actualizaciones.

## Desarrollo

Para verificar el tipado de forma local ejecuta:

```bash
mypy src
pyright
```

Tanto `mypy` como `pyright` utilizan la configuración presente en `pyproject.toml`.

Para ejecutar los linters puedes usar el comando de Make:

```bash
make lint
make secrets
```
El segundo comando ejecuta *gitleaks* para detectar posibles secretos en el repositorio.

Esto ejecutará `ruff` y `mypy` sobre `src`, y `bandit` revisará el directorio `src`. Si prefieres lanzar las herramientas de
manera individual utiliza:

```bash
ruff check src
mypy src
```

## Desarrollo de plugins

La CLI puede ampliarse mediante plugins externos. Desde esta versión todo el SDK
de plugins se encuentra en ``src.cobra.cli.plugin``. Para crear uno, define una clase
que herede de ``PluginCommand`` y declara el ``entry point`` en la sección
``[project.entry-points."cobra.plugins"]`` de tu ``pyproject.toml``. También es
necesario configurar un ``[build-system]`` moderno, como el basado en
``setuptools``:

```toml
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"

[project.entry-points."cobra.plugins"]
saludo = "mi_paquete.mi_modulo:SaludoCommand"
```

Tras instalar el paquete con `pip install -e .`, Cobra detectará automáticamente
el nuevo comando.

### Ejemplo de plugin

```python
from cobra.cli.plugin import PluginCommand


class HolaCommand(PluginCommand):
    name = "hola"
    version = "1.0"
    author = "Tu Nombre"
    description = "Dice hola desde un plugin"

    def register_subparser(self, subparsers):
        parser = subparsers.add_parser(self.name, help="Muestra un saludo")
        parser.set_defaults(cmd=self)

    def run(self, args):
        print("¡Hola desde un plugin!")
```
## Extensión para VS Code

La extensión para Visual Studio Code se encuentra en [`extensions/vscode`](extensions/vscode). Instala las dependencias con `npm install`. Desde VS Code puedes pulsar `F5` para probarla o ejecutar `vsce package` para generar el paquete `.vsix`. Consulta [extensions/vscode/README.md](extensions/vscode/README.md) para más detalles.

## Versionado Semántico

Este proyecto sigue el esquema [SemVer](https://semver.org/lang/es/). Los numeros se interpretan como Mayor.Menor.Parche. Cada incremento de version refleja cambios compatibles o rupturas segun esta norma.

## Historial de Cambios

 - Versión 10.0.9: ajustes en `SafeUnpickler`, restricciones en `corelibs.sistema.ejecutar`, caché incremental en formato JSON para AST y tokens, y actualización a Agix 1.4.0.

## Publicar una nueva versión

Al crear y subir una etiqueta `vX.Y.Z` se ejecuta el workflow [`release.yml`](.github/workflows/release.yml), que construye el paquete, los ejecutables y la imagen Docker.

El workflow [`Deploy Docs`](.github/workflows/pages.yml) generará la documentación cuando haya un push en `main` o al etiquetar una nueva versión.

Consulta la [guía de lanzamiento](docs/release.md) para más detalles sobre el etiquetado, secretos y el flujo de la pipeline.

```bash
git tag v10.0.9
git push origin v10.0.9
```

Para más información consulta el [CHANGELOG](CHANGELOG.md) y la [configuración de GitHub Actions](.github/workflows).

## Lenguajes soportados

- Python
- JavaScript
- ensamblador
- Rust
- C++
- Go
- Kotlin
- Swift
- R
- Julia
- Java
- COBOL
- Fortran
- Pascal
- Ruby
- PHP
- Perl
- Visual Basic
- Matlab
- Mojo
- LaTeX
- C
- WebAssembly

Esta lista debe mantenerse sincronizada con la documentación en inglés. Consulta la [traducción al inglés](docs/README.en.md) para más detalles.

# Licencia

Este proyecto está bajo la [Licencia MIT](LICENSE).


### Notas

- **Documentación y Ejemplos Actualizados**: El README ha sido actualizado para reflejar las capacidades de transpilación. Consulta la sección [Lenguajes soportados](#lenguajes-soportados) para ver la lista de lenguajes compatibles.
- **Ejemplos de Código y Nuevas Estructuras**: Incluye ejemplos con el uso de estructuras avanzadas como clases y diccionarios en el lenguaje Cobra.

Si deseas agregar o modificar algo, házmelo saber.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "pcobra",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "cobra, lenguaje, cli",
    "author": null,
    "author_email": "Adolfo Gonz\u00e1lez Hern\u00e1ndez <adolfogonzal@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/e4/af/6bb2c3c47adbb977f52a72d31ae21caf63095878788fac8f50791e926bbd/pcobra-10.0.12.tar.gz",
    "platform": null,
    "description": "# Proyecto Cobra\r\n[![Codecov](https://codecov.io/gh/Alphonsus411/pCobra/branch/work/graph/badge.svg)](https://codecov.io/gh/Alphonsus411/pCobra/branch/work)\r\n[![Versi\u00f3n estable](https://img.shields.io/github/v/release/Alphonsus411/pCobra?label=stable)](https://github.com/Alphonsus411/pCobra/releases/latest)\r\n[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/Alphonsus411/pCobra/HEAD?labpath=notebooks/playground.ipynb)\r\n\r\n\r\n## Qu\u00e9 es pCobra\r\n\r\nVersi\u00f3n 10.0.9\r\n\r\n- Ajustes en `SafeUnpickler` para admitir `core.ast_nodes` y `cobra.core.ast_nodes`.\r\n- `corelibs.sistema.ejecutar` ahora requiere una lista blanca mediante `permitidos` o `COBRA_EJECUTAR_PERMITIDOS`.\r\n- Cach\u00e9 incremental respaldada por SQLitePlus para AST y tokens.\r\n- Actualizaci\u00f3n a Agix 1.4.0.\r\n\r\n[English version available here](docs/README.en.md)\r\n\r\npCobra es un lenguaje de programaci\u00f3n escrito en espa\u00f1ol y pensado para la creaci\u00f3n de herramientas, simulaciones y an\u00e1lisis en disciplinas como biolog\u00eda, computaci\u00f3n y astrof\u00edsica. El proyecto integra un lexer, parser y un sistema de transpilaci\u00f3n capaz de generar c\u00f3digo en Python, JavaScript, ensamblador, Rust, C++, Go, Kotlin, Swift, R, Julia, Java, COBOL, Fortran, Pascal, Ruby, PHP, Perl, VisualBasic, Matlab, Mojo, LaTeX, C y WebAssembly, facilitando su despliegue en distintos entornos.\r\n\r\nEl objetivo de pCobra es brindar a la comunidad hispanohablante una alternativa cercana para aprender y construir software, reduciendo la barrera del idioma y fomentando la colaboraci\u00f3n abierta. A medida que evoluciona, el proyecto busca ampliar su ecosistema, mejorar la transpilaci\u00f3n y proveer herramientas que sirvan de puente entre la educaci\u00f3n y el desarrollo profesional.\r\n\r\n\r\n## Tabla de Contenidos\r\n\r\n- Descripci\u00f3n del Proyecto\r\n- Arquitectura centrada en Hololang\r\n- Instalaci\u00f3n\r\n- C\u00f3mo usar la CLI\r\n- Descargas\r\n- Estructura del Proyecto\r\n- Herramientas y scripts soportados\r\n- Caracter\u00edsticas Principales\r\n- Uso\r\n- Tokens y reglas l\u00e9xicas\r\n- Ejemplo de Uso\r\n- Conversi\u00f3n desde otros lenguajes\r\n- Pruebas\r\n- Ejemplos de prueba\r\n- Generar documentaci\u00f3n\r\n- An\u00e1lisis con CodeQL\r\n- [CobraHub](docs/frontend/cobrahub.rst)\r\n- Hitos y Roadmap\r\n- Contribuciones\r\n- [Gu\u00eda de Contribuci\u00f3n](CONTRIBUTING.md)\r\n- [Proponer extensiones](docs/frontend/rfc_plugins.rst)\r\n- Extensi\u00f3n para VS Code\r\n- [Comunidad](docs/comunidad.md)\r\n- Licencia\r\n- [Manual de Cobra](docs/MANUAL_COBRA.md)\r\n- [Manual de Cobra en formato reStructuredText](docs/MANUAL_COBRA.rst)\r\n- [Manual de Cobra en PDF](https://alphonsus411.github.io/pCobra/proyectocobra.pdf)\r\n- [Gu\u00eda b\u00e1sica](docs/guia_basica.md)\r\n- [Especificaci\u00f3n t\u00e9cnica](docs/especificacion_tecnica.md)\r\n- [Blog del minilenguaje](docs/blog_minilenguaje.md)\r\n- [Cheatsheet](docs/cheatsheet.tex) \u2013 comp\u00edlalo a PDF con LaTeX\r\n- [Casos de uso reales](docs/casos_reales.md)\r\n- [Limitaciones del sandbox de Node](docs/limitaciones_node_sandbox.md)\r\n- [Limitaciones del sandbox de C++](docs/limitaciones_cpp_sandbox.md)\r\n- Notebooks de ejemplo y casos reales\r\n- Probar Cobra en l\u00ednea\r\n- [Historial de cambios](CHANGELOG.md)\r\n\r\n## Ejemplos\r\n\r\nProyectos de demostraci\u00f3n disponibles en el [repositorio de ejemplos](https://github.com/Alphonsus411/pCobra/tree/HEAD/examples).\r\nEste repositorio incluye ejemplos b\u00e1sicos en la carpeta `examples/`, por\r\nejemplo `examples/funciones_principales.co` que muestra condicionales, bucles y\r\ndefinici\u00f3n de funciones en Cobra.\r\nPara ejemplos interactivos revisa los cuadernos en `notebooks/casos_reales/`.\r\n\r\n### Ejemplos avanzados\r\n\r\nEn [examples/avanzados/](examples/avanzados/) se incluyen programas que profundizan\r\nen Cobra con ejercicios de control de flujo, funciones recursivas e interacci\u00f3n\r\nde clases. Cada tema cuenta con su propia carpeta:\r\n\r\n- [examples/avanzados/control_flujo/](examples/avanzados/control_flujo/)\r\n- [examples/avanzados/funciones/](examples/avanzados/funciones/)\r\n- [examples/avanzados/clases/](examples/avanzados/clases/)\r\n\r\n## Notebooks de ejemplo\r\n\r\nEn la carpeta `notebooks/` se incluye el cuaderno `ejemplo_basico.ipynb` con un ejemplo b\u00e1sico de uso de Cobra. Adem\u00e1s, los cuadernos de `notebooks/casos_reales/` muestran c\u00f3mo ejecutar los ejemplos avanzados. Para abrirlo ejecuta:\r\n\r\n```bash\r\ncobra jupyter --notebook notebooks/ejemplo_basico.ipynb\r\n```\r\nSi omites el argumento ``--notebook`` se abrir\u00e1 Jupyter Notebook de manera convencional y podr\u00e1s escoger el archivo desde la interfaz web.\r\n\r\n\r\n\r\n## Probar Cobra en l\u00ednea\r\n\r\nPuedes experimentar con Cobra directamente en tu navegador:\r\n\r\n- [Replit](https://replit.com/github/Alphonsus411/pCobra)\r\n- [Binder](https://mybinder.org/v2/gh/Alphonsus411/pCobra/HEAD?labpath=notebooks/playground.ipynb)\r\n- [GitHub Codespaces](https://codespaces.new/Alphonsus411/pCobra)\r\n\r\n## Descripci\u00f3n del Proyecto\r\n\r\nCobra est\u00e1 dise\u00f1ado para facilitar la programaci\u00f3n en espa\u00f1ol, permitiendo que los desarrolladores utilicen un lenguaje m\u00e1s accesible. A trav\u00e9s de su lexer, parser y transpiladores, Cobra puede analizar, ejecutar y convertir c\u00f3digo a otros lenguajes, brindando soporte para variables, funciones, estructuras de control y estructuras de datos como listas, diccionarios y clases.\r\nPara un tutorial paso a paso consulta el [Manual de Cobra](docs/MANUAL_COBRA.rst).\r\nLa especificaci\u00f3n completa del lenguaje se encuentra en [SPEC_COBRA.md](docs/SPEC_COBRA.md).\r\n\r\n## Arquitectura centrada en Hololang\r\n\r\nLa cadena de herramientas de Cobra se articula alrededor de Hololang, un lenguaje intermedio dise\u00f1ado para describir los programas de forma expl\u00edcita y portable. El flujo principal funciona de la siguiente manera:\r\n\r\n1. El front-end analiza el c\u00f3digo fuente y construye el AST de Cobra.\r\n2. Ese AST se normaliza y se transforma en representaciones Hololang que capturan estructuras de control, m\u00f3dulos y tipos.\r\n3. Los transpiladores consumen el IR Hololang para generar c\u00f3digo en los distintos backends soportados.\r\n\r\nHololang act\u00faa como contrato estable entre el front-end y los generadores de c\u00f3digo, permitiendo incorporar nuevos destinos sin modificar el parser original. Gracias a esta capa intermedia, Cobra ofrece un generador de ensamblador que produce instrucciones simb\u00f3licas optimizadas para depuraci\u00f3n y diagn\u00f3stico de rendimiento. El comando `cobra transpilar` puede emitir directamente los ficheros Hololang o derivarlos a `asm` para obtener la salida en ensamblador.\r\n\r\n## Instalaci\u00f3n\r\n\r\n```bash\r\npip install pcobra\r\n```\r\n\r\n### Instalaci\u00f3n con pipx\r\n\r\n```bash\r\npipx install pcobra\r\n```\r\n\r\n### Instalaci\u00f3n desde repositorio\r\n\r\nConsulta [docs/instalacion.md](docs/instalacion.md#instalacion-desde-repositorio) para instrucciones avanzadas (gram\u00e1ticas, plugins, scripts y uso de Docker).\r\n\r\n## C\u00f3mo usar la CLI\r\n\r\nEjecuta un archivo de Cobra con:\r\n\r\n```bash\r\ncobra archivo.co\r\n```\r\n\r\nPara listar las opciones disponibles ejecuta:\r\n\r\n```bash\r\ncobra --help\r\n```\r\n\r\nEl int\u00e9rprete se ejecuta en modo seguro por defecto. Si deseas desactivarlo utiliza la opci\u00f3n `--no-seguro`:\r\n\r\n```bash\r\ncobra archivo.co --no-seguro\r\n```\r\n\r\n### Ejemplo de transpilaci\u00f3n\r\n\r\n```bash\r\ncobra transpilar hola.co --lenguaje python\r\n```\r\n\r\nEsto generar\u00e1 `hola.py`. Para conocer otros destinos y opciones, consulta la [documentaci\u00f3n detallada](docs/) o revisa [docs/frontend](docs/frontend).\r\n\r\n## Descarga de binarios\r\n\r\nPara cada lanzamiento se generan ejecutables para Linux, Windows y macOS mediante\r\nGitHub Actions. Puedes encontrarlos en la pesta\u00f1a\r\n[Releases](https://github.com/Alphonsus411/pCobra/releases) del repositorio.\r\nSolo descarga el archivo correspondiente a tu sistema operativo desde la versi\u00f3n\r\nm\u00e1s reciente y ejec\u00fatalo directamente.\r\n\r\nCrear un tag `vX.Y.Z` en GitHub desencadena la publicaci\u00f3n autom\u00e1tica del\r\npaquete en PyPI y la actualizaci\u00f3n de la imagen Docker.\r\n\r\nSi prefieres generar el ejecutable manualmente ejecuta desde la ra\u00edz del\r\nrepositorio en tu sistema (Windows, macOS o Linux):\r\n\r\n```bash\r\npip install pyinstaller\r\ncobra empaquetar --output dist\r\n```\r\nEl nombre del binario puede ajustarse con la opci\u00f3n `--name`. Tambi\u00e9n puedes\r\nusar un archivo `.spec` propio o agregar datos adicionales mediante\r\n``--spec`` y ``--add-data``:\r\n\r\n```bash\r\ncobra empaquetar --spec build/cobra.spec \\\r\n  --add-data \"all-bytes.dat;all-bytes.dat\" --output dist\r\n```\r\n\r\n## Crear un ejecutable con PyInstaller\r\n\r\nPara compilar Cobra de forma independiente primero crea y activa un entorno virtual:\r\n\r\n```bash\r\npython -m venv .venv\r\nsource .venv/bin/activate  # En Windows usa .\\\\.venv\\\\Scripts\\\\activate\r\n```\r\n\r\nInstala la distribuci\u00f3n publicada y PyInstaller:\r\n\r\n```bash\r\npip install pcobra\r\npip install pyinstaller\r\n```\r\n\r\nLuego genera el binario con:\r\n\r\n```bash\r\npyinstaller --onefile src/pcobra/cli/cli.py -n cobra\r\n```\r\n\r\nEl ejecutable aparecer\u00e1 en el directorio `dist/`.\r\n\r\nPara realizar una prueba r\u00e1pida puedes ejecutar el script\r\n`scripts/test_pyinstaller.sh`. Este script crea un entorno virtual temporal,\r\ninstala `pcobra` desde el repositorio (o desde PyPI si se ejecuta fuera\r\nde \u00e9l) y ejecuta PyInstaller sobre `src/pcobra/cli/cli.py` o el script `cobra-init`.\r\nEl binario resultante se\r\nguardar\u00e1 por defecto en `dist/`.\r\n\r\n```bash\r\nscripts/test_pyinstaller.sh\r\n```\r\n\r\n\r\n## Descargas\r\n\r\nLos ejecutables precompilados para Cobra se publican en la secci\u00f3n de [Releases](https://github.com/Alphonsus411/pCobra/releases).\r\n\r\n| Versi\u00f3n | Plataforma | Enlace |\r\n| --- | --- | --- |\r\n| 10.0.9 | Linux x86_64 | [cobra-linux](https://github.com/Alphonsus411/pCobra/releases/download/v10.0.9/cobra-linux) |\r\n| 10.0.9 | Windows x86_64 | [cobra.exe](https://github.com/Alphonsus411/pCobra/releases/download/v10.0.9/cobra.exe) |\r\n| 10.0.9 | macOS arm64 | [cobra-macos](https://github.com/Alphonsus411/pCobra/releases/download/v10.0.9/cobra-macos) |\r\n\r\nPara comprobar la integridad del archivo descargado calcula su hash SHA256 y comp\u00e1ralo con el publicado:\r\n\r\n```bash\r\nsha256sum cobra-linux\r\n```\r\n\r\nEn Windows utiliza:\r\n\r\n```powershell\r\nCertUtil -hashfile cobra.exe SHA256\r\n```\r\n\r\n# Estructura del Proyecto\r\n\r\nEl proyecto se organiza en las siguientes carpetas:\r\n\r\n- `src/pcobra/`: C\u00f3digo fuente del paquete.\r\n- `docs/`: Documentaci\u00f3n del proyecto.\r\n- `tests/`: Pruebas autom\u00e1ticas.\r\n- `examples/`: Ejemplos de uso.\r\n- `extensions/`: Extensiones oficiales, como la de VS Code.\r\n- `scripts/`: Scripts de utilidad.\r\n- `notebooks/`: Cuadernos interactivos.\r\n- `docker/`: Archivos de configuraci\u00f3n para contenedores.\r\n- `binder/`: Archivos para ejecutar el proyecto en Binder.\r\n\r\nLos archivos `requirements.txt` y `pyproject.toml` en la ra\u00edz definen las dependencias del proyecto.\r\n\r\n# Herramientas y scripts soportados\r\n\r\nEl proyecto soporta oficialmente:\r\n\r\n- `Makefile` para automatizar tareas como `make install`, `make test` y `make clean`.\r\n- `scripts/run.sh` para ejecutar Cobra con variables definidas en `.env`.\r\n- `scripts/install.sh` para preparar el entorno de desarrollo.\r\n- Scripts auxiliares en `scripts/`.\r\n- Configuraciones Docker en `docker/`.\r\n\r\n# Caracter\u00edsticas Principales\r\n\r\n- Lexer y Parser: Implementaci\u00f3n de un lexer para la tokenizaci\u00f3n del c\u00f3digo fuente y un parser para la construcci\u00f3n de un \u00e1rbol de sintaxis abstracta (AST).\r\n- Transpiladores a Python, JavaScript, ensamblador, Rust, C++, Go, Kotlin, Swift, R, Julia, Java, COBOL, Fortran, Pascal, Ruby, PHP, Perl, VisualBasic, Matlab, Mojo, LaTeX, C y WebAssembly: Cobra puede convertir el c\u00f3digo en estos lenguajes, facilitando su integraci\u00f3n con aplicaciones externas.\r\n- Soporte de Estructuras Avanzadas: Permite la declaraci\u00f3n de variables, funciones, clases, listas y diccionarios, as\u00ed como el uso de bucles y condicionales.\r\n- M\u00f3dulos nativos con funciones de E/S, utilidades matem\u00e1ticas y estructuras de datos para usar directamente desde Cobra.\r\n- Instalaci\u00f3n de paquetes en tiempo de ejecuci\u00f3n mediante la instrucci\u00f3n `usar`.\r\n- Manejo de Errores: El sistema captura y reporta errores de sintaxis, facilitando la depuraci\u00f3n.\r\n- Visualizaci\u00f3n y Depuraci\u00f3n: Salida detallada de tokens, AST y errores de sintaxis para un desarrollo m\u00e1s sencillo.\r\n- Decoradores de rendimiento: la biblioteca ``smooth-criminal`` ofrece\r\n  funciones como ``optimizar`` y ``perfilar`` para mejorar y medir la\r\n  ejecuci\u00f3n de c\u00f3digo Python desde Cobra.\r\n- Benchmarking: ejemplos completos de medici\u00f3n de rendimiento est\u00e1n\r\n  disponibles en `docs/frontend/benchmarking.rst`.\r\n- Ejemplos de C\u00f3digo y Documentaci\u00f3n: Ejemplos pr\u00e1cticos que ilustran el uso del lexer, parser y transpiladores.\r\n- Ejemplos Avanzados: Revisa `docs/frontend/ejemplos_avanzados.rst` para conocer casos con clases, hilos y manejo de errores.\r\n- Identificadores en Unicode: Puedes nombrar variables y funciones utilizando\r\n  caracteres como `\u00e1`, `\u00f1` o `\u03a9` para una mayor flexibilidad.\r\n\r\n## Rendimiento\r\n\r\nLos benchmarks m\u00e1s recientes se ejecutaron con\r\n`scripts/benchmarks/compare_backends.py` para comparar varios backends. El\r\ntiempo aproximado fue de **0.68&nbsp;s** para Cobra y Python,\r\n**0.07&nbsp;s** para JavaScript y **0.04&nbsp;s** para Rust, sin consumo\r\nsignificativo de memoria.\r\n\r\nEjecuta el script con:\r\n\r\n```bash\r\npython scripts/benchmarks/compare_backends.py --output bench_results.json\r\n```\r\n\r\nEl archivo [bench_results.json](bench_results.json) se guarda en el directorio\r\nactual y puede analizarse con el cuaderno\r\n[notebooks/benchmarks_resultados.ipynb](notebooks/benchmarks_resultados.ipynb).\r\n\r\nPara ver la evoluci\u00f3n entre versiones ejecuta:\r\n\r\n```bash\r\npython scripts/benchmarks/compare_releases.py --output benchmarks_compare.json\r\n```\r\n\r\nLos resultados hist\u00f3ricos se publican como archivos `benchmarks.json` en la\r\n[secci\u00f3n de Releases](https://github.com/Alphonsus411/pCobra/releases), donde\r\npuedes consultar las m\u00e9tricas de cada versi\u00f3n.\r\n\r\nPara comparar el rendimiento de los hilos ejecuta `cobra benchthreads`:\r\n\r\n```bash\r\ncobra benchthreads --output threads.json\r\n```\r\n\r\nEl resultado contiene tres entradas (secuencial, cli_hilos y kernel_hilos) con\r\nlos tiempos y uso de CPU.\r\n\r\nPara generar binarios en C, C++ y Rust y medir su rendimiento ejecuta:\r\n\r\n```bash\r\ncobra bench --binary\r\n```\r\n\r\nLos resultados se guardan en `binary_bench.json`.\r\n\r\n# Uso\r\n\r\nPara ejecutar el proyecto directamente desde el repositorio se incluye el\r\nscript `scripts/run.sh`. Este cargar\u00e1 las variables definidas en `.env` si dicho archivo\r\nexiste y luego llamar\u00e1 a `python -m pcobra` pasando todos los argumentos\r\nrecibidos. \u00dasalo de la siguiente forma:\r\n\r\n```bash\r\n./scripts/run.sh [opciones]\r\n```\r\n\r\nTambi\u00e9n puedes ejecutar la interfaz de l\u00ednea de comandos directamente desde la\r\nra\u00edz del proyecto:\r\n\r\n```bash\r\npython -m pcobra\r\n```\r\n\r\nPara conocer las opciones avanzadas del modo seguro revisa\r\n`docs/frontend/modo_seguro.rst`. Los ejemplos de medici\u00f3n de rendimiento\r\nest\u00e1n disponibles en `docs/frontend/benchmarking.rst`.\r\n\r\nPara ejecutar pruebas unitarias, utiliza pytest:\r\n\r\n````bash\r\nPYTHONPATH=$PWD pytest tests --cov=pcobra --cov-report=term-missing \\\r\n  --cov-fail-under=95\r\n````\r\n\r\nTambi\u00e9n puedes ejecutar suites espec\u00edficas ubicadas en `tests`:\r\n\r\n````bash\r\npython -m tests.suite_cli           # Solo pruebas de la CLI\r\npython -m tests.suite_core          # Pruebas de lexer, parser e int\u00e9rprete\r\npython -m tests.suite_transpiladores  # Pruebas de los transpiladores\r\n````\r\n\r\n## Uso directo desde el repositorio\r\n\r\nEl archivo `sitecustomize.py` se carga autom\u00e1ticamente cuando Python se\r\nejecuta desde la ra\u00edz del proyecto. Este m\u00f3dulo a\u00f1ade la carpeta `src` a\r\n`sys.path`, permitiendo importar paquetes como `src.modulo` sin instalar\r\nel paquete ni modificar `PYTHONPATH`.\r\n\r\nPara probar Cobra de esta forma realiza lo siguiente:\r\n\r\n```bash\r\npython -m venv .venv\r\nsource .venv/bin/activate  # En Unix\r\n.\\.venv\\Scripts\\activate  # En Windows\r\nmake run                   # o bien: python -m pcobra\r\n```\r\n\r\n## Tokens y reglas l\u00e9xicas\r\n\r\nEl analizador l\u00e9xico convierte el c\u00f3digo en tokens de acuerdo con las\r\nexpresiones regulares definidas en `lexer.py`. En la siguiente tabla se\r\ndescriben todos los tokens disponibles:\r\n\r\n| Token | Descripci\u00f3n |\r\n|-------|-------------|\r\n| DIVIDIR | Palabra clave o instrucci\u00f3n \"dividir\" |\r\n| MULTIPLICAR | Palabra clave o instrucci\u00f3n \"multiplicar\" |\r\n| CLASE | Palabra clave \"clase\" |\r\n| DICCIONARIO | Palabra clave \"diccionario\" |\r\n| LISTA | Palabra clave \"lista\" |\r\n| RBRACE | S\u00edmbolo \"}\" |\r\n| DEF | Palabra clave \"def\" |\r\n| IN | Palabra clave \"in\" |\r\n| LBRACE | S\u00edmbolo \"{\" |\r\n| FOR | Palabra clave \"for\" |\r\n| DOSPUNTOS | S\u00edmbolo \":\" |\r\n| VAR | Palabra clave \"var\" |\r\n| FUNC | Palabra clave \"func\" o \"definir\" |\r\n| SI | Palabra clave \"si\" |\r\n| SINO | Palabra clave \"sino\" |\r\n| MIENTRAS | Palabra clave \"mientras\" |\r\n| PARA | Palabra clave \"para\" |\r\n| IMPORT | Palabra clave \"import\" |\r\n| USAR | Palabra clave \"usar\" |\r\n| MACRO | Palabra clave \"macro\" |\r\n| HOLOBIT | Palabra clave \"holobit\" |\r\n| PROYECTAR | Palabra clave \"proyectar\" |\r\n| TRANSFORMAR | Palabra clave \"transformar\" |\r\n| GRAFICAR | Palabra clave \"graficar\" |\r\n| TRY | Palabra clave \"try\" o \"intentar\" |\r\n| CATCH | Palabra clave \"catch\" o \"capturar\" |\r\n| THROW | Palabra clave \"throw\" o \"lanzar\" |\r\n| ENTERO | N\u00famero entero |\r\n| FLOTANTE | N\u00famero con punto decimal |\r\n| CADENA | Cadena de caracteres |\r\n| BOOLEANO | Literal booleano |\r\n| IDENTIFICADOR | Nombre de variable o funci\u00f3n |\r\n| ASIGNAR | S\u00edmbolo \"=\" |\r\n| SUMA | Operador \"+\" |\r\n| RESTA | Operador \"-\" |\r\n| MULT | Operador \"*\" |\r\n| DIV | Operador \"/\" |\r\n| MAYORQUE | Operador \">\" |\r\n| MENORQUE | Operador \"<\" |\r\n| MAYORIGUAL | Operador \">=\" |\r\n| MENORIGUAL | Operador \"<=\" |\r\n| IGUAL | Operador \"==\" |\r\n| DIFERENTE | Operador \"!=\" |\r\n| AND | Operador l\u00f3gico \"&&\" |\r\n| OR | Operador l\u00f3gico \"||\" |\r\n| NOT | Operador \"!\" |\r\n| MOD | Operador \"%\" |\r\n| LPAREN | S\u00edmbolo \"(\" |\r\n| RPAREN | S\u00edmbolo \")\" |\r\n| LBRACKET | S\u00edmbolo \"[\" |\r\n| RBRACKET | S\u00edmbolo \"]\" |\r\n| COMA | S\u00edmbolo \",\" |\r\n| RETORNO | Palabra clave \"retorno\" |\r\n| FIN | Palabra clave \"fin\" |\r\n| EOF | Fin de archivo |\r\n| IMPRIMIR | Palabra clave \"imprimir\" |\r\n| HILO | Palabra clave \"hilo\" |\r\n| ASINCRONICO | Palabra clave \"asincronico\" |\r\n| DECORADOR | S\u00edmbolo \"@\" |\r\n| YIELD | Palabra clave \"yield\" |\r\n| ESPERAR | Palabra clave \"esperar\" |\r\n| ROMPER | Palabra clave \"romper\" |\r\n| CONTINUAR | Palabra clave \"continuar\" |\r\n| PASAR | Palabra clave \"pasar\" |\r\n| AFIRMAR | Palabra clave \"afirmar\" |\r\n| ELIMINAR | Palabra clave \"eliminar\" |\r\n| GLOBAL | Palabra clave \"global\" |\r\n| NOLOCAL | Palabra clave \"nolocal\" |\r\n| LAMBDA | Palabra clave \"lambda\" |\r\n| CON | Palabra clave \"con\" |\r\n| FINALMENTE | Palabra clave \"finalmente\" |\r\n| DESDE | Palabra clave \"desde\" |\r\n| COMO | Palabra clave \"como\" |\r\n| SWITCH | Palabra clave \"switch\" o \"segun\" |\r\n| CASE | Palabra clave \"case\" o \"caso\" |\r\n\r\nLas expresiones regulares se agrupan en `especificacion_tokens` y se procesan en orden para encontrar coincidencias. Las palabras clave usan patrones como `\\bvar\\b` o `\\bfunc\\b`, los n\u00fameros emplean `\\d+` o `\\d+\\.\\d+` y las cadenas se detectan con `\"[^\\\"]*\"` o `'[^']*'`. Los identificadores permiten caracteres Unicode mediante `[^\\W\\d_][\\w]*`. Operadores y s\u00edmbolos utilizan patrones directos como `==`, `&&` o `\\(`. Antes del an\u00e1lisis se eliminan los comentarios de l\u00ednea y de bloque con `re.sub`.\r\n\r\n# Ejemplo de Uso\r\n\r\nPuedes probar el lexer y parser con un c\u00f3digo como el siguiente:\r\n\r\n```python\r\nfrom cobra.core import Lexer, Parser\r\nfrom cobra.transpilers.transpiler.to_python import TranspiladorPython\r\n\r\ncodigo = \"\"\"\r\nvar x = 10\r\nsi x > 5 :\r\n    proyectar(x, \"2D\")\r\nsino :\r\n    graficar(x)\r\n\"\"\"\r\n\r\nlexer = Lexer(codigo)\r\ntokens = lexer.analizar_token()\r\n\r\nparser = Parser(tokens)\r\n\r\narbol = parser.parsear()\r\nprint(arbol)\r\n\r\ntranspiler = TranspiladorPython()\r\ncodigo_python = transpiler.generate_code(arbol)\r\nprint(codigo_python)\r\n```\r\n\r\n## Ejemplo de imprimir, holobits y bucles\r\n\r\nA continuaci\u00f3n se muestra un fragmento que utiliza `imprimir`, holobits y bucles:\r\n\r\n````cobra\r\ncodigo = '''\r\nvar h = holobit([0.8, -0.5, 1.2])\r\nimprimir(h)\r\n\r\nvar contador = 0\r\nmientras contador < 3 :\r\n    imprimir(contador)\r\n    contador += 1\r\n\r\npara var i en rango(2) :\r\n    imprimir(i)\r\n'''\r\n````\r\n\r\nAl generar c\u00f3digo para Python, `imprimir` se convierte en `print`, `mientras` en `while` y `para` en `for`. En JavaScript estos elementos se transforman en `console.log`, `while` y `for...of` respectivamente. Para el modo ensamblador se generan instrucciones `PRINT`, `WHILE` y `FOR`. En Rust se produce c\u00f3digo equivalente con `println!`, `while` y `for`. En C++ se obtienen construcciones con `std::cout`, `while` y `for`. El tipo `holobit` se traduce a la llamada `holobit([...])` en Python, `new Holobit([...])` en JavaScript, `holobit(vec![...])` en Rust o `holobit({ ... })` en C++. En Go se genera `fmt.Println`, en Kotlin `println`, en Swift `print`, en R se usa `print` y en Julia `println`; en Java se usa `System.out.println`, en COBOL `DISPLAY`, en Fortran `print *` y en Pascal `writeln`, en VisualBasic `Console.WriteLine`, en Ruby `puts`, en PHP `echo`, en Matlab `disp`, en Mojo `print` y en LaTeX `\\texttt{}`.\r\n\r\n## Integraci\u00f3n con holobit-sdk\r\n\r\nEl proyecto instala autom\u00e1ticamente la librer\u00eda `holobit-sdk`, utilizada para visualizar y manipular holobits. Las funciones `graficar`, `proyectar`, `transformar`, `escalar` y `mover` de `src.core.holobits` delegan en esta API. Desde la versi\u00f3n ``1.0.8`` del SDK se incluyen las operaciones ``escalar`` y ``mover``; en versiones anteriores Cobra calcula estos efectos manualmente.\r\n\r\n```python\r\nfrom core.holobits import Holobit, graficar, proyectar, transformar, escalar, mover\r\n\r\nh = Holobit([0.8, -0.5, 1.2, 0.0, 0.0, 0.0])\r\nproyectar(h, \"2D\")\r\ngraficar(h)\r\ntransformar(h, \"rotar\", \"z\", 90)\r\nescalar(h, 2.0)\r\nmover(h, 1.0, 0.0, -1.0)\r\n```\r\n\r\n## Ejemplo de carga de m\u00f3dulos\r\n\r\nPuedes dividir el c\u00f3digo en varios archivos y cargarlos con `import`:\r\n\r\n````cobra\r\n# modulo.co\r\nvar saludo = 'Hola desde m\u00f3dulo'\r\n\r\n# programa.co\r\nimport 'modulo.co'\r\nimprimir(saludo)\r\n````\r\n\r\nAl ejecutar `programa.co`, se procesar\u00e1 primero `modulo.co` y luego se imprimir\u00e1 `Hola desde m\u00f3dulo`.\r\n\r\n## Instrucci\u00f3n `usar` para dependencias din\u00e1micas\r\n\r\nLa sentencia `usar \"paquete\"` intenta importar un m\u00f3dulo de Python. Si el\r\npaquete no est\u00e1 disponible, Cobra ejecutar\u00e1 `pip install paquete` para\r\ninstalarlo y luego lo cargar\u00e1 en tiempo de ejecuci\u00f3n. El m\u00f3dulo queda\r\nregistrado en el entorno bajo el mismo nombre para su uso posterior.\r\nPara restringir qu\u00e9 dependencias pueden instalarse se emplea la variable\r\n`USAR_WHITELIST` definida en `src/pcobra/cobra/usar_loader.py`. Basta con\r\na\u00f1adir o quitar nombres de paquetes en dicho conjunto para modificar la lista\r\nautorizada. Si la lista se deja vac\u00eda la funci\u00f3n `obtener_modulo` lanzar\u00e1\r\n`PermissionError`, por lo que es necesario poblarla antes de permitir\r\ninstalaciones din\u00e1micas.\r\n\r\nPara habilitar la instalaci\u00f3n autom\u00e1tica define la variable de entorno\r\n`COBRA_USAR_INSTALL=1`. Cuando esta variable no est\u00e9 establecida,\r\n`obtener_modulo()` rechazar\u00e1 instalar dependencias y lanzar\u00e1 un\r\n`RuntimeError` si el paquete no se encuentra.\r\n\r\n## Archivo de mapeo de m\u00f3dulos\r\n\r\nLos transpiladores consultan `cobra.mod` para resolver las importaciones.\r\nEste archivo sigue un esquema YAML sencillo donde cada clave es la ruta del\r\nm\u00f3dulo Cobra y sus valores indican las rutas de los archivos generados.\r\n\r\nEjemplo de formato:\r\n\r\n```yaml\r\nmodulo.co:\r\n  version: \"1.0.0\"\r\n  python: modulo.py\r\n  js: modulo.js\r\n```\r\n\r\nSi una entrada no se encuentra, el transpilador cargar\u00e1 directamente el archivo\r\nindicado en la instrucci\u00f3n `import`. Para a\u00f1adir o modificar rutas basta con\r\neditar `cobra.mod` y volver a ejecutar las pruebas.\r\n\r\n## Invocar el transpilador\r\n\r\nLa carpeta [`src/pcobra/cobra/transpilers/transpiler`](src/pcobra/cobra/transpilers/transpiler)\r\ncontiene la implementaci\u00f3n de los transpiladores a Python, JavaScript, ensamblador, Rust, C++, Go, Kotlin, Swift, R, Julia, Java, COBOL, Fortran, Pascal, Ruby, PHP, Perl, VisualBasic, Matlab, Mojo, LaTeX, C y WebAssembly. Una vez\r\ninstaladas las dependencias, puedes llamar al transpilador desde tu propio\r\nscript de la siguiente manera:\r\n\r\n```python\r\nfrom cobra.transpilers.transpiler.to_python import TranspiladorPython\r\nfrom cobra.core import Parser\r\n\r\ncodigo = \"imprimir('hola')\"\r\nparser = Parser(codigo)\r\narbol = parser.parsear()\r\ntranspiler = TranspiladorPython()\r\nresultado = transpiler.generate_code(arbol)\r\nprint(resultado)\r\n```\r\n\r\nPara otros lenguajes puedes invocar los nuevos transpiladores as\u00ed:\r\n\r\n```python\r\nfrom cobra.transpilers.transpiler.to_cobol import TranspiladorCOBOL\r\nfrom cobra.transpilers.transpiler.to_fortran import TranspiladorFortran\r\nfrom cobra.transpilers.transpiler.to_pascal import TranspiladorPascal\r\nfrom cobra.transpilers.transpiler.to_ruby import TranspiladorRuby\r\nfrom cobra.transpilers.transpiler.to_php import TranspiladorPHP\r\nfrom cobra.transpilers.transpiler.to_perl import TranspiladorPerl\r\nfrom cobra.transpilers.transpiler.to_visualbasic import TranspiladorVisualBasic\r\nfrom cobra.transpilers.transpiler.to_kotlin import TranspiladorKotlin\r\nfrom cobra.transpilers.transpiler.to_swift import TranspiladorSwift\r\nfrom cobra.transpilers.transpiler.to_matlab import TranspiladorMatlab\r\nfrom cobra.transpilers.transpiler.to_mojo import TranspiladorMojo\r\nfrom cobra.transpilers.transpiler.to_latex import TranspiladorLatex\r\n\r\ncodigo_cobol = TranspiladorCOBOL().generate_code(arbol)\r\ncodigo_fortran = TranspiladorFortran().generate_code(arbol)\r\ncodigo_pascal = TranspiladorPascal().generate_code(arbol)\r\ncodigo_ruby = TranspiladorRuby().generate_code(arbol)\r\ncodigo_php = TranspiladorPHP().generate_code(arbol)\r\ncodigo_perl = TranspiladorPerl().generate_code(arbol)\r\ncodigo_visualbasic = TranspiladorVisualBasic().generate_code(arbol)\r\ncodigo_kotlin = TranspiladorKotlin().generate_code(arbol)\r\ncodigo_swift = TranspiladorSwift().generate_code(arbol)\r\ncodigo_matlab = TranspiladorMatlab().generate_code(arbol)\r\ncodigo_mojo = TranspiladorMojo().generate_code(arbol)\r\ncodigo_latex = TranspiladorLatex().generate_code(arbol)\r\n```\r\n\r\nTras obtener el c\u00f3digo con ``generate_code`` puedes guardarlo usando ``save_file``:\r\n\r\n```python\r\ntranspiler.save_file(\"salida.py\")\r\n```\r\n\r\nRequiere tener instalado el paquete en modo editable y todas las dependencias\r\nde `requirements.txt`. Si necesitas generar archivos a partir de m\u00f3dulos Cobra,\r\nconsulta el mapeo definido en `cobra.mod`.\r\n\r\n## Ejemplo de concurrencia\r\n\r\nEs posible lanzar funciones en hilos con la palabra clave `hilo`:\r\n\r\n````cobra\r\nfunc tarea():\r\n    imprimir('trabajo')\r\nfin\r\n\r\nhilo tarea()\r\nimprimir('principal')\r\n````\r\n\r\nAl generar c\u00f3digo para estas funciones, se crean llamadas `asyncio.create_task` en Python y `Promise.resolve().then` en JavaScript.\r\n\r\n## Uso desde la CLI\r\n\r\nUna vez instalado el paquete, la herramienta `cobra` ofrece varios subcomandos:\r\n\r\n### Autocompletado\r\n\r\nLa CLI soporta autocompletado de argumentos mediante\r\n[argcomplete](https://kislyuk.github.io/argcomplete/). Para habilitarlo en tu\r\nterminal ejecuta uno de los siguientes comandos seg\u00fan tu *shell*:\r\n\r\n- **bash**:\r\n\r\n  ```bash\r\n  eval \"$(register-python-argcomplete cobra)\"\r\n  ```\r\n\r\n- **zsh**:\r\n\r\n  ```bash\r\n  autoload -U bashcompinit\r\n  bashcompinit\r\n  eval \"$(register-python-argcomplete cobra)\"\r\n  ```\r\n\r\n- **fish**:\r\n\r\n  ```bash\r\n  register-python-argcomplete --shell fish cobra | source\r\n  ```\r\n\r\n```bash\r\n# Compilar un archivo a Python, JavaScript, ensamblador, Rust, C++, Go, Kotlin, Swift, R, Julia, Java, COBOL, Fortran, Pascal, Ruby, PHP, Perl, VisualBasic, Matlab, Mojo, LaTeX, C o WebAssembly\r\ncobra compilar programa.co --tipo python\r\n\r\n# Transpilar inverso de Python a JavaScript\r\ncobra transpilar-inverso script.py --origen=python --destino=js\r\n\r\n# Ejemplo de mensaje de error al compilar un archivo inexistente\r\ncobra compilar noexiste.co\r\n# Salida:\r\n# Error: El archivo 'noexiste.co' no existe\r\n\r\n\r\n# Gestionar m\u00f3dulos instalados\r\ncobra modulos listar\r\ncobra modulos instalar ruta/al/modulo.co\r\ncobra modulos remover modulo.co\r\n# Crear e instalar paquetes Cobra\r\ncobra paquete crear src demo.cobra\r\ncobra paquete instalar demo.cobra\r\n# Generar documentaci\u00f3n HTML y API\r\ncobra docs\r\n# Crear un ejecutable independiente\r\ncobra empaquetar --output dist\r\n# Perfilar un programa y guardar los resultados\r\ncobra profile programa.co --output salida.prof\r\n# O mostrar el perfil directamente en pantalla\r\ncobra profile programa.co\r\n# Verificar la salida en Python y JavaScript\r\ncobra verificar ejemplo.co --lenguajes=python,js\r\n# Iniciar el iddle gr\u00e1fico (requiere Flet)\r\ncobra gui\r\n```\r\n\r\nSi deseas desactivar los colores usa `--no-color`:\r\n\r\n```bash\r\ncobra --no-color ejecutar programa.co\r\n```\r\n\r\nPara aumentar el nivel de detalle de los mensajes a\u00f1ade `-v` o `--verbose`.\r\nPor defecto el nivel de registro es `INFO`; con `-v` o m\u00e1s se cambia a `DEBUG`:\r\n\r\n```bash\r\ncobra -v ejecutar programa.co\r\n```\r\n\r\nLos archivos con extensi\u00f3n ``.cobra`` representan paquetes completos, mientras que los scripts individuales se guardan como ``.co``.\r\n\r\nEl subcomando `docs` ejecuta `sphinx-apidoc` para generar la documentaci\u00f3n de la API antes de compilar el HTML.\r\nEl subcomando `gui` abre el iddle integrado y requiere tener instalado Flet.\r\n\r\n## Conversi\u00f3n desde otros lenguajes a Cobra\r\n\r\nPuedes usar `cobra transpilar-inverso` para leer un archivo en otro lenguaje,\r\nconvertirlo al AST de Cobra y luego generarlo en cualquier backend soportado.\r\n\r\n```bash\r\ncobra transpilar-inverso script.py --origen=python --destino=cobra\r\n```\r\n\r\nEl proceso intenta mapear instrucciones b\u00e1sicas, pero caracter\u00edsticas muy espec\u00edficas pueden requerir ajustes manuales. Actualmente la cobertura var\u00eda seg\u00fan el lenguaje y puede que ciertas construcciones no est\u00e9n implementadas.\r\n\r\nActualmente es posible convertir a Cobra c\u00f3digo escrito en ensamblador, C, C++, COBOL, Fortran, Go, Java, JavaScript, Julia, Kotlin, LaTeX, Matlab, Mojo, Pascal, Perl, PHP, Python, R, Ruby, Rust, Swift, VisualBasic y WebAssembly.\r\n\r\n### Dise\u00f1o extensible de la CLI\r\n\r\nLa CLI est\u00e1 organizada en clases dentro de `src/pcobra/cli/commands`. Cada subcomando\r\nhereda de `BaseCommand` y define su nombre, los argumentos que acepta y la acci\u00f3n\r\na ejecutar. En `src/pcobra/cli/cli.py` se instancian autom\u00e1ticamente y se registran en\r\n`argparse`, por lo que para a\u00f1adir un nuevo comando solo es necesario crear un\r\narchivo con la nueva clase y llamar a `register_subparser` y `run`.\r\nPara un tutorial completo de creaci\u00f3n de plugins revisa\r\n[`docs/frontend/plugins.rst`](docs/frontend/plugins.rst).\r\n\r\n## Modo seguro\r\n\r\nEl int\u00e9rprete y la CLI ejecutan el c\u00f3digo en modo seguro de forma predeterminada. Este modo valida el AST y proh\u00edbe primitivas como `leer_archivo`, `escribir_archivo`, `obtener_url`, `hilo`, `leer`, `escribir`, `existe`, `eliminar` y `enviar_post`. El validador `ValidadorProhibirReflexion` tambi\u00e9n bloquea llamadas a `eval`, `exec` y otras funciones de reflexi\u00f3n, adem\u00e1s de impedir el acceso a atributos internos. Asimismo, las instrucciones `import` solo est\u00e1n permitidas para m\u00f3dulos instalados o incluidos en `IMPORT_WHITELIST`. Antes de cargar el c\u00f3digo las rutas se normalizan con `os.path.realpath` y se comparan con `os.path.commonpath`, por lo que un enlace simb\u00f3lico o un directorio como `modules_fake` no pueden evadir el filtro. Si el programa intenta utilizar estas funciones o importar otros archivos se lanzar\u00e1 `PrimitivaPeligrosaError`.\r\nLa validaci\u00f3n se realiza mediante una cadena de validadores configurada por la\r\nfunci\u00f3n `construir_cadena`, lo que facilita a\u00f1adir nuevas comprobaciones en el\r\nfuturo.\r\n\r\n## Ejecuci\u00f3n en sandbox (--sandbox)\r\n\r\nAlgunos comandos permiten ejecutar c\u00f3digo Python dentro de una \"sandbox\" gracias\r\na la biblioteca `RestrictedPython`. Esto limita las operaciones disponibles y\r\nevita acciones potencialmente peligrosas como leer archivos o importar m\u00f3dulos\r\nexternos. Para activar esta opci\u00f3n utiliza `--sandbox` en los subcomandos\r\n`ejecutar` e `interactive`.\r\n\r\nEl c\u00f3digo se compila con `compile_restricted` y luego se ejecuta mediante\r\n`exec`. **No** se recurre a `compile()` cuando la compilaci\u00f3n segura falla,\r\nsino que se propaga la excepci\u00f3n. El uso de `exec` sigue siendo peligroso,\r\npor lo que se recomienda mantener el entorno de ejecuci\u00f3n lo m\u00e1s peque\u00f1o\r\nposible para reducir riesgos.\r\n\r\n# Pruebas\r\n\r\nLas pruebas est\u00e1n ubicadas en la carpeta `tests/` y utilizan pytest para la\r\nejecuci\u00f3n. **Antes de correr cualquier prueba instala el paquete en modo\r\neditable junto con las dependencias de desarrollo:**\r\n\r\n```bash\r\npip install -e .[dev]\r\n```\r\n\r\nAdem\u00e1s, cada cambio en los workflows de GitHub Actions se valida con\r\n[`actionlint`](https://github.com/rhysd/actionlint) mediante el workflow\r\n[Validar workflows](.github/workflows/validate-workflows.yml). Este proceso se\r\nejecuta autom\u00e1ticamente en los eventos `push` y `pull_request` cuando se\r\nmodifican archivos dentro de `.github/workflows/`, evitando que se integren\r\ndefiniciones inv\u00e1lidas en la canalizaci\u00f3n de CI.\r\n\r\nEsta instrucci\u00f3n a\u00f1ade el proyecto al `PYTHONPATH` e instala todas las\r\ndependencias listadas en `requirements-dev.txt`, las cuales est\u00e1n incluidas en\r\nel extra `dev` de `pyproject.toml`. Sin estas bibliotecas las pruebas fallar\u00e1n\r\ndebido a m\u00f3dulos no encontrados.\r\n\r\nSi prefieres ejecutar las pruebas directamente desde el repositorio sin\r\ninstalar el paquete, utiliza el script `scripts/test.sh`:\r\n\r\n```bash\r\n./scripts/test.sh\r\n```\r\n\r\nEste comando exporta `PYTHONPATH=$PWD` e invoca `pytest` con los argumentos\r\ndefinidos en `pyproject.toml`.\r\n\r\n````bash\r\nPYTHONPATH=$PWD pytest tests --cov=pcobra --cov-report=term-missing \\\r\n  --cov-fail-under=95\r\n````\r\n\r\n Algunas pruebas generan c\u00f3digo en distintos lenguajes (por ejemplo C++, JavaScript o Go) y verifican que la sintaxis sea correcta. Para que estas pruebas se ejecuten con \u00e9xito es necesario contar con los compiladores o int\u00e9rpretes correspondientes instalados en el sistema. En particular se requiere:\r\n\r\n- Node.js\r\n- gcc y g++\r\n- Go (`golang-go`)\r\n- Ruby (`ruby`)\r\n- Rust (`rustc`)\r\n- Java (`default-jdk`)\r\n\r\nCon estas herramientas disponibles puedes ejecutar todo el conjunto con:\r\n\r\n```bash\r\nPYTHONPATH=$PWD pytest\r\n```\r\n\r\nEn la integraci\u00f3n continua se emplea:\r\n\r\n```bash\r\npytest --cov=pcobra tests/\r\n```\r\n\r\nEl reporte se guarda como `coverage.xml` y se utiliza en el CI.\r\n\r\n### Ejemplos de prueba\r\n\r\nEn `tests/data` se incluyen programas m\u00ednimos utilizados en las\r\npruebas de entrada y salida de la CLI:\r\n\r\n- `hola.cobra`: imprime el saludo \u00abHola Cobra\u00bb.\r\n- `suma.cobra`: define la funci\u00f3n `sumar` y muestra la suma de dos\r\n  n\u00fameros.\r\n\r\nEl archivo `tests/test_ejemplos_io.py` ejecuta estos ejemplos y compara\r\nla salida con los archivos `.out` correspondientes. Para probarlos\r\nmanualmente:\r\n\r\n```bash\r\ncobra ejecutar tests/data/hola.cobra\r\ncobra ejecutar tests/data/suma.cobra\r\n```\r\n\r\nTambi\u00e9n puedes transpilar los ejemplos para ver el c\u00f3digo Python generado:\r\n\r\n```bash\r\ncobra transpilar tests/data/hola.cobra\r\ncobra transpilar tests/data/suma.cobra\r\n```\r\n\r\n### Pruebas de rendimiento\r\n\r\nEl archivo `cobra.toml` incluye una secci\u00f3n `[rendimiento]` con el par\u00e1metro\r\n`tiempo_max_transpilacion_seg`, que define en segundos el tiempo m\u00e1ximo\r\npermitido para transpilar un archivo.\r\n\r\nPara ejecutar \u00fanicamente las pruebas de rendimiento utiliza:\r\n\r\n```bash\r\npytest -m performance\r\n```\r\n\r\nSi tu entorno es m\u00e1s lento o m\u00e1s r\u00e1pido, ajusta el valor de\r\n`tiempo_max_transpilacion_seg` en `cobra.toml` seg\u00fan tus necesidades.\r\n\r\nSe han incluido pruebas que verifican los c\u00f3digos de salida de la CLI. Los\r\nsubcomandos devuelven `0` al finalizar correctamente y un valor distinto en caso\r\nde error.\r\n\r\n### Ejemplos de subcomandos\r\n\r\n````bash\r\ncobra compilar programa.co --tipo=python\r\ncobra compilar programa.co --tipo=asm\r\ncobra compilar programa.co --tipo=cpp\r\ncobra compilar programa.co --tipo=go\r\ncobra compilar programa.co --tipo=ruby\r\ncobra compilar programa.co --tipo=r\r\ncobra compilar programa.co --tipo=julia\r\ncobra compilar programa.co --tipo=java\r\ncobra compilar programa.co --tipo=cobol\r\ncobra compilar programa.co --tipo=fortran\r\ncobra compilar programa.co --tipo=pascal\r\ncobra compilar programa.co --tipo=php\r\necho $?  # 0 al compilar sin problemas\r\n\r\ncobra ejecutar inexistente.co\r\n# El archivo 'inexistente.co' no existe\r\necho $?  # 1\r\n````\r\n\r\n### Errores comunes\r\n\r\n- `El archivo '<archivo>' no existe`: la ruta es incorrecta o el archivo no est\u00e1 disponible.\r\n- `El m\u00f3dulo <nombre> no existe`: se intenta eliminar un m\u00f3dulo no instalado.\r\n- `Primitiva peligrosa: <nombre>`: se us\u00f3 una funci\u00f3n restringida en modo seguro.\r\n- `Acci\u00f3n de m\u00f3dulos no reconocida`: el subcomando indicado es inv\u00e1lido.\r\n\r\n## Selecci\u00f3n de idioma\r\n\r\nLa CLI utiliza `gettext` para mostrar los mensajes en distintos idiomas.\r\nPuedes definir el idioma estableciendo la variable de entorno `COBRA_LANG`\r\no pasando el argumento `--lang` al ejecutar `cobra`.\r\n\r\n```bash\r\nCOBRA_LANG=en cobra --ayuda\r\ncobra --lang en compilar archivo.co\r\n```\r\n\r\nSi deseas a\u00f1adir otro idioma, crea una carpeta `docs/frontend/locale/<cod>/LC_MESSAGES`\r\ncon los archivos `.po` de traducci\u00f3n y env\u00eda un pull request.\r\n\r\nPara obtener un reporte de cobertura en la terminal ejecuta:\r\n\r\n````bash\r\npytest --cov=src --cov-report=term-missing --cov-fail-under=95\r\n````\r\n\r\n## Cach\u00e9 del AST y SQLitePlus\r\n\r\nA partir de la migraci\u00f3n a **SQLitePlus**, la cach\u00e9 incremental de AST y tokens\r\nse almacena en una base de datos `SQLite` cifrada en lugar de archivos sueltos.\r\nLa ruta por defecto es `~/.cobra/sqliteplus/core.db`, que se crea\r\nautom\u00e1ticamente al primer acceso. Para inicializar la conexi\u00f3n es obligatoria la\r\nvariable de entorno `SQLITE_DB_KEY`, cuyo valor act\u00faa como clave de cifrado.\r\nSi necesitas una ubicaci\u00f3n distinta configura `COBRA_DB_PATH`; cuando se\r\nproporciona, el valor de `SQLITE_DB_KEY` se mantiene como clave incluso si\r\ncontiene `/` u otros separadores.\r\n\r\n```bash\r\nexport SQLITE_DB_KEY=\"clave-local\"          # Obligatorio para abrir la base\r\nexport COBRA_DB_PATH=\"$HOME/.cobra/sqliteplus/core.db\"  # Opcional; usa el\r\n                                                        # valor por defecto\r\n# Para despliegues sin cifrado puedes usar un prefijo expl\u00edcito:\r\nexport SQLITE_DB_KEY=\"path:/var/cache/pcobra/core.db\"\r\n```\r\n\r\nSi necesitas ubicar la base de datos en otro sitio, ajusta `COBRA_DB_PATH` a la\r\nubicaci\u00f3n deseada antes de ejecutar `cobra`. Como compatibilidad adicional, un\r\nvalor de `SQLITE_DB_KEY` que empiece por `path:` o `file:` se interpreta como\r\nruta expl\u00edcita y desactiva el cifrado; en cualquier otro caso el valor se trata\r\ncomo clave aunque contenga separadores y se emitir\u00e1 una advertencia si parece\r\nuna ruta. La antigua variable\r\n`COBRA_AST_CACHE` contin\u00faa disponible \u00fanicamente como alias de compatibilidad:\r\nsi la defines, el sistema derivar\u00e1 autom\u00e1ticamente una ruta `cache.db` en ese\r\ndirectorio y mostrar\u00e1 una advertencia de depreciaci\u00f3n.\r\n\r\n### Limpieza y mantenimiento\r\n\r\nEl comando `cobra cache` sigue siendo el m\u00e9todo soportado para borrar la cach\u00e9 y\r\nahora opera directamente sobre la base de datos. Incluye la opci\u00f3n `--vacuum`\r\npara recompac tar la base tras la limpieza:\r\n\r\n```bash\r\ncobra cache --vacuum\r\n```\r\n\r\n### Migraci\u00f3n de cach\u00e9s JSON anteriores\r\n\r\nSi conservas el directorio `cache/` con los archivos `.ast`/`.tok` utilizados en\r\nversiones anteriores, puedes importarlos a SQLitePlus con el siguiente flujo:\r\n\r\n1. Define `SQLITE_DB_KEY` (y `COBRA_DB_PATH` si deseas una ruta distinta).\r\n2. Ejecuta el script auxiliar desde la ra\u00edz del proyecto, indicando la carpeta\r\n   donde se encuentran los archivos heredados:\r\n\r\n   ```bash\r\n   python scripts/migrar_cache_sqliteplus.py --origen /ruta/al/cache\r\n   ```\r\n\r\n   El script convierte cada hash almacenado en JSON y recrea los fragmentos en\r\n   la tabla SQLite. Las ejecuciones posteriores reutilizar\u00e1n esa informaci\u00f3n sin\r\n   necesidad de reanalizar tus fuentes.\r\n\r\n3. Verifica la migraci\u00f3n listando el contenido con cualquier visor SQLite o\r\n   ejecutando nuevamente `cobra cache --vacuum` para comprobar que la conexi\u00f3n se\r\n   inicializa correctamente.\r\n\r\nTras la migraci\u00f3n, los ficheros JSON pueden eliminarse si ya no son necesarios.\r\n\r\n## Generar documentaci\u00f3n\r\n\r\nPara obtener la documentaci\u00f3n HTML puedes usar `cobra docs` o\r\n`make html` desde la ra\u00edz del proyecto. El subcomando `docs` ejecuta\r\n`sphinx-apidoc` y luego compila el HTML en la carpeta de salida configurada.\r\n\r\nPuedes compilar la documentaci\u00f3n de dos maneras:\r\n\r\n1. **Con la CLI de Cobra**. Ejecuta `cobra docs`.\r\n\r\n2. **Con Make**. Ejecuta `make html` para compilar los archivos ubicados en\r\n   `docs/frontend`.\r\n\r\n3. **Con pdoc**. Para generar documentaci\u00f3n de la API con [pdoc](https://pdoc.dev),\r\n   ejecuta `python scripts/generar_pdoc.py`. El resultado se guardar\u00e1 en\r\n   la carpeta de salida configurada para la API.\r\n\r\nA partir de esta versi\u00f3n, la API se genera de forma autom\u00e1tica antes de\r\ncada compilaci\u00f3n para mantener la documentaci\u00f3n actualizada.\r\nPara aprender a desarrollar plugins revisa\r\n[`docs/frontend/plugin_dev.rst`](docs/frontend/plugin_dev.rst).\r\nPara conocer en detalle la interfaz disponible consulta\r\n[`docs/frontend/plugin_sdk.rst`](docs/frontend/plugin_sdk.rst).\r\n\r\n## An\u00e1lisis con CodeQL\r\n\r\nEste proyecto cuenta con un workflow de GitHub Actions definido en\r\n`.github/workflows/codeql.yml`. Dicho flujo se ejecuta en cada *push* y\r\n*pull request*, inicializando CodeQL para el lenguaje Python y aplicando\r\nreglas personalizadas ubicadas en `.github/codeql/custom/`.\r\n\r\nLas reglas proporcionan comprobaciones adicionales sobre el AST y los\r\ntranspiladores:\r\n\r\n- **ast-no-type-validation.ql** verifica que las clases de nodos cuyo\r\n  nombre empieza por `Nodo` incluyan validaciones de tipo en\r\n  `__post_init__`.\r\n- **missing-codegen-exception.ql** detecta m\u00e9todos `generate_code` sin\r\n  manejo de excepciones.\r\n- **unsafe-eval-exec.ql** avisa cuando se usa `eval` o `exec` fuera del sandbox.\r\n\r\nPara ejecutar el an\u00e1lisis de CodeQL de forma local puedes usar la CLI:\r\n\r\n```bash\r\ncurl -L -o codeql.zip \\\r\n  https://github.com/github/codeql-cli-binaries/releases/latest/download/codeql-linux64.zip\r\nunzip codeql.zip\r\n./codeql/codeql database create db-python --language=python --source-root=.\r\n./codeql/codeql database analyze db-python \\\r\n  .github/codeql/custom/codeql-config.yml\r\n```\r\n\r\nEsto te permitir\u00e1 validar los cambios antes de subirlos al repositorio.\r\n## Hitos y Roadmap\r\n\r\nEl proyecto avanza en versiones incrementales. Puedes consultar las tareas planeadas en [ROADMAP.md](docs/ROADMAP.md).\r\n\r\n\r\n# Contribuciones\r\n\r\nLas contribuciones son bienvenidas. Si deseas contribuir, sigue estos pasos:\r\n\r\n- Haz un fork del proyecto.\r\n- Crea una nueva rama (`git checkout -b feature/nueva-caracteristica`).\r\n- Las ramas que comiencen con `feature/`, `bugfix/` o `doc/` recibir\u00e1n etiquetas\r\n  autom\u00e1ticas al abrir un pull request.\r\n- Sigue las convenciones de estilo indicadas en `CONTRIBUTING.md`\r\n  (formateo con `black`, longitud m\u00e1xima de l\u00ednea 88 y uso de `ruff`, `mypy`\r\n  y `bandit`).\r\n- Realiza tus cambios y haz commit (`git commit -m 'A\u00f1adir nueva caracter\u00edstica'`).\r\n- Ejecuta `make lint` para verificar el c\u00f3digo con *ruff*, *mypy* y *bandit*. `bandit` analizar\u00e1 el directorio `src`.\r\n- Ejecuta `make typecheck` para la verificaci\u00f3n est\u00e1tica con *mypy* (y\r\n  opcionalmente *pyright* si est\u00e1 instalado).\r\n- Ejecuta `make secrets` para buscar credenciales expuestas usando *gitleaks*.\r\n- Para lanzar todas las validaciones en un solo paso ejecuta `python scripts/check.py`.\r\n  Este script corre *ruff*, *mypy*, *bandit*, *pytest* y *pyright*.\r\n- El CI de GitHub Actions ejecuta autom\u00e1ticamente estas herramientas en cada pull request.\r\n- Env\u00eda un pull request.\r\n- Consulta [CONTRIBUTING.md](CONTRIBUTING.md) para m\u00e1s detalles sobre c\u00f3mo abrir\r\n  issues y preparar pull requests.\r\n- Para proponer nuevas extensiones consulta [docs/frontend/rfc_plugins.rst](docs/frontend/rfc_plugins.rst).\r\n\r\n## Dependabot y seguridad\r\n\r\nEste repositorio cuenta con [Dependabot](.github/dependabot.yml) para mantener\r\nactualizadas las dependencias de Python y las acciones de GitHub. Cada semana se\r\ncrean PR autom\u00e1ticos contra la rama `work` con las versiones m\u00e1s recientes.\r\n\r\nAdem\u00e1s, en el flujo de CI se incluye un paso de **safety check** que revisa la\r\nlista de paquetes instalados en busca de vulnerabilidades conocidas. Si se\r\ndetecta alguna, la acci\u00f3n devolver\u00e1 un reporte detallado y el trabajo fallar\u00e1.\r\nConsulta el log del paso \"Seguridad de dependencias\" para ver los paquetes\r\nafectados y las recomendaciones de actualizaci\u00f3n.\r\nDe igual forma, se ejecuta *gitleaks* para asegurarse de que no existan\r\ncredenciales accidentales en el repositorio.\r\n\r\nEl repositorio tambi\u00e9n ejecuta CodeQL con reglas personalizadas para detectar\r\npatrones de c\u00f3digo riesgosos, como el uso de `eval` o `exec` fuera del sandbox.\r\n\r\n## Comunidad\r\n\r\n\u00danete a nuestro servidor de Discord para recibir anuncios, resolver dudas y colaborar en el desarrollo en [https://discord.gg/cobra](https://discord.gg/cobra).\r\nTambi\u00e9n contamos con un canal de **Telegram** y una cuenta de **Twitter** donde difundimos eventos y actualizaciones.\r\n\r\n## Desarrollo\r\n\r\nPara verificar el tipado de forma local ejecuta:\r\n\r\n```bash\r\nmypy src\r\npyright\r\n```\r\n\r\nTanto `mypy` como `pyright` utilizan la configuraci\u00f3n presente en `pyproject.toml`.\r\n\r\nPara ejecutar los linters puedes usar el comando de Make:\r\n\r\n```bash\r\nmake lint\r\nmake secrets\r\n```\r\nEl segundo comando ejecuta *gitleaks* para detectar posibles secretos en el repositorio.\r\n\r\nEsto ejecutar\u00e1 `ruff` y `mypy` sobre `src`, y `bandit` revisar\u00e1 el directorio `src`. Si prefieres lanzar las herramientas de\r\nmanera individual utiliza:\r\n\r\n```bash\r\nruff check src\r\nmypy src\r\n```\r\n\r\n## Desarrollo de plugins\r\n\r\nLa CLI puede ampliarse mediante plugins externos. Desde esta versi\u00f3n todo el SDK\r\nde plugins se encuentra en ``src.cobra.cli.plugin``. Para crear uno, define una clase\r\nque herede de ``PluginCommand`` y declara el ``entry point`` en la secci\u00f3n\r\n``[project.entry-points.\"cobra.plugins\"]`` de tu ``pyproject.toml``. Tambi\u00e9n es\r\nnecesario configurar un ``[build-system]`` moderno, como el basado en\r\n``setuptools``:\r\n\r\n```toml\r\n[build-system]\r\nrequires = [\"setuptools>=61.0\"]\r\nbuild-backend = \"setuptools.build_meta\"\r\n\r\n[project.entry-points.\"cobra.plugins\"]\r\nsaludo = \"mi_paquete.mi_modulo:SaludoCommand\"\r\n```\r\n\r\nTras instalar el paquete con `pip install -e .`, Cobra detectar\u00e1 autom\u00e1ticamente\r\nel nuevo comando.\r\n\r\n### Ejemplo de plugin\r\n\r\n```python\r\nfrom cobra.cli.plugin import PluginCommand\r\n\r\n\r\nclass HolaCommand(PluginCommand):\r\n    name = \"hola\"\r\n    version = \"1.0\"\r\n    author = \"Tu Nombre\"\r\n    description = \"Dice hola desde un plugin\"\r\n\r\n    def register_subparser(self, subparsers):\r\n        parser = subparsers.add_parser(self.name, help=\"Muestra un saludo\")\r\n        parser.set_defaults(cmd=self)\r\n\r\n    def run(self, args):\r\n        print(\"\u00a1Hola desde un plugin!\")\r\n```\r\n## Extensi\u00f3n para VS Code\r\n\r\nLa extensi\u00f3n para Visual Studio Code se encuentra en [`extensions/vscode`](extensions/vscode). Instala las dependencias con `npm install`. Desde VS Code puedes pulsar `F5` para probarla o ejecutar `vsce package` para generar el paquete `.vsix`. Consulta [extensions/vscode/README.md](extensions/vscode/README.md) para m\u00e1s detalles.\r\n\r\n## Versionado Sem\u00e1ntico\r\n\r\nEste proyecto sigue el esquema [SemVer](https://semver.org/lang/es/). Los numeros se interpretan como Mayor.Menor.Parche. Cada incremento de version refleja cambios compatibles o rupturas segun esta norma.\r\n\r\n## Historial de Cambios\r\n\r\n - Versi\u00f3n 10.0.9: ajustes en `SafeUnpickler`, restricciones en `corelibs.sistema.ejecutar`, cach\u00e9 incremental en formato JSON para AST y tokens, y actualizaci\u00f3n a Agix 1.4.0.\r\n\r\n## Publicar una nueva versi\u00f3n\r\n\r\nAl crear y subir una etiqueta `vX.Y.Z` se ejecuta el workflow [`release.yml`](.github/workflows/release.yml), que construye el paquete, los ejecutables y la imagen Docker.\r\n\r\nEl workflow [`Deploy Docs`](.github/workflows/pages.yml) generar\u00e1 la documentaci\u00f3n cuando haya un push en `main` o al etiquetar una nueva versi\u00f3n.\r\n\r\nConsulta la [gu\u00eda de lanzamiento](docs/release.md) para m\u00e1s detalles sobre el etiquetado, secretos y el flujo de la pipeline.\r\n\r\n```bash\r\ngit tag v10.0.9\r\ngit push origin v10.0.9\r\n```\r\n\r\nPara m\u00e1s informaci\u00f3n consulta el [CHANGELOG](CHANGELOG.md) y la [configuraci\u00f3n de GitHub Actions](.github/workflows).\r\n\r\n## Lenguajes soportados\r\n\r\n- Python\r\n- JavaScript\r\n- ensamblador\r\n- Rust\r\n- C++\r\n- Go\r\n- Kotlin\r\n- Swift\r\n- R\r\n- Julia\r\n- Java\r\n- COBOL\r\n- Fortran\r\n- Pascal\r\n- Ruby\r\n- PHP\r\n- Perl\r\n- Visual Basic\r\n- Matlab\r\n- Mojo\r\n- LaTeX\r\n- C\r\n- WebAssembly\r\n\r\nEsta lista debe mantenerse sincronizada con la documentaci\u00f3n en ingl\u00e9s. Consulta la [traducci\u00f3n al ingl\u00e9s](docs/README.en.md) para m\u00e1s detalles.\r\n\r\n# Licencia\r\n\r\nEste proyecto est\u00e1 bajo la [Licencia MIT](LICENSE).\r\n\r\n\r\n### Notas\r\n\r\n- **Documentaci\u00f3n y Ejemplos Actualizados**: El README ha sido actualizado para reflejar las capacidades de transpilaci\u00f3n. Consulta la secci\u00f3n [Lenguajes soportados](#lenguajes-soportados) para ver la lista de lenguajes compatibles.\r\n- **Ejemplos de C\u00f3digo y Nuevas Estructuras**: Incluye ejemplos con el uso de estructuras avanzadas como clases y diccionarios en el lenguaje Cobra.\r\n\r\nSi deseas agregar o modificar algo, h\u00e1zmelo saber.\r\n",
    "bugtrack_url": null,
    "license": "MIT License\r\n        \r\n        Copyright (c) 2024 Adolfo Gonz\u00e1lez Hern\u00e1ndez\r\n        \r\n        Permission is hereby granted, free of charge, to any person obtaining a copy\r\n        of this software and associated documentation files (the \"Software\"), to deal\r\n        in the Software without restriction, including without limitation the rights\r\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n        copies of the Software, and to permit persons to whom the Software is\r\n        furnished to do so, subject to the following conditions:\r\n        \r\n        The above copyright notice and this permission notice shall be included in all\r\n        copies or substantial portions of the Software.\r\n        \r\n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n        SOFTWARE.\r\n        ",
    "summary": "Un lenguaje de programaci\u00f3n en espa\u00f1ol para simulaciones y m\u00e1s.",
    "version": "10.0.12",
    "project_urls": {
        "Documentation": "https://github.com/Alphonsus411/pCobra#readme",
        "Source": "https://github.com/Alphonsus411/pCobra"
    },
    "split_keywords": [
        "cobra",
        " lenguaje",
        " cli"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "78b856d4f57b67dcb5da07d5900708226de2623ee9db4191bb0fdbc9042cb512",
                "md5": "59490ee2f73731b8968c21f4523b0e1d",
                "sha256": "867b5cd85a0937a8f5a90e962b45a4437b96b12cf6a0d84c746c7815ebc55180"
            },
            "downloads": -1,
            "filename": "pcobra-10.0.12-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "59490ee2f73731b8968c21f4523b0e1d",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 484053,
            "upload_time": "2025-11-01T11:26:52",
            "upload_time_iso_8601": "2025-11-01T11:26:52.913026Z",
            "url": "https://files.pythonhosted.org/packages/78/b8/56d4f57b67dcb5da07d5900708226de2623ee9db4191bb0fdbc9042cb512/pcobra-10.0.12-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "e4af6bb2c3c47adbb977f52a72d31ae21caf63095878788fac8f50791e926bbd",
                "md5": "8f284153bde91f2e2391092849ca8128",
                "sha256": "7a72acbe5356a706a13eda6287072f1c728e88a1f250cbf7d6e4323287d3aacf"
            },
            "downloads": -1,
            "filename": "pcobra-10.0.12.tar.gz",
            "has_sig": false,
            "md5_digest": "8f284153bde91f2e2391092849ca8128",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 403007,
            "upload_time": "2025-11-01T11:26:54",
            "upload_time_iso_8601": "2025-11-01T11:26:54.588612Z",
            "url": "https://files.pythonhosted.org/packages/e4/af/6bb2c3c47adbb977f52a72d31ae21caf63095878788fac8f50791e926bbd/pcobra-10.0.12.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-11-01 11:26:54",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Alphonsus411",
    "github_project": "pCobra#readme",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "requirements": [],
    "lcname": "pcobra"
}
        
Elapsed time: 1.03250s