mirror of
https://github.com/Ladebeze66/llm_lab.git
synced 2025-12-15 19:46:52 +01:00
adaptationI7
This commit is contained in:
parent
903bdf57ec
commit
81778e2626
205
README.md
Normal file
205
README.md
Normal file
@ -0,0 +1,205 @@
|
||||
# LLM Lab
|
||||
|
||||
Un laboratoire pour tester et comparer différents modèles de langage (LLM) via Ollama.
|
||||
|
||||
## Fonctionnalités
|
||||
|
||||
- **Modèles intégrés** : Support pour Mistral 7B, CodeLlama 13B et Llama2 13B via Ollama
|
||||
- **Agents spécialisés** : Agents configurés pour différentes tâches (code, documentation, gestion de projet...)
|
||||
- **Interface graphique de chat** : Interface visuelle complète pour interagir avec les agents et personnaliser les paramètres
|
||||
- **Moniteur système** : Interface graphique pour surveiller les ressources système, Ollama et GPU
|
||||
- **Interface CLI** : Interface en ligne de commande simple pour interagir avec les agents
|
||||
|
||||
## Modèles disponibles
|
||||
|
||||
Ce projet prend en charge les modèles suivants :
|
||||
|
||||
- **Mistral 7B** : `mistral:latest` via Ollama - pour des tests rapides et la documentation
|
||||
- **CodeLlama 13B Python** : `codellama:13b-python` via Ollama - pour le développement et le code
|
||||
- **Llama2 13B** : `llama2:13b` via Ollama - pour la gestion de connaissances et de projet
|
||||
|
||||
## Agents spécialisés
|
||||
|
||||
- **cursor** : Agent de programmation (CodeLlama) pour Python, JavaScript et développement web
|
||||
- **obsidian** : Agent de gestion de connaissances (Llama2) pour l'organisation d'informations
|
||||
- **test** : Agent de test rapide (Mistral) pour vérifier rapidement les fonctionnalités
|
||||
- **python** : Expert Python (CodeLlama)
|
||||
- **webdev** : Expert développement web (CodeLlama)
|
||||
- **projectmanager** : Chef de projet (Llama2)
|
||||
- **documentaliste** : Spécialiste en documentation (Mistral)
|
||||
|
||||
## Installation
|
||||
|
||||
### Prérequis
|
||||
|
||||
- Python 3.8+
|
||||
- [Ollama](https://ollama.ai/) installé et en cours d'exécution sur `localhost:11434`
|
||||
- Les modèles correspondants installés dans Ollama
|
||||
|
||||
### Installation des modèles Ollama
|
||||
|
||||
```bash
|
||||
# Installation des modèles
|
||||
ollama pull mistral:latest
|
||||
ollama pull codellama:13b-python
|
||||
ollama pull llama2:13b
|
||||
```
|
||||
|
||||
### Configuration de l'environnement
|
||||
|
||||
Utilisez le script de configuration automatique :
|
||||
|
||||
```bash
|
||||
# Exécuter le script de configuration
|
||||
./setup_env.sh
|
||||
```
|
||||
|
||||
Ce script va :
|
||||
1. Vérifier et installer les dépendances système nécessaires (venv, tkinter)
|
||||
2. Créer un nouvel environnement virtuel Python
|
||||
3. Installer toutes les dépendances requises
|
||||
4. Configurer les scripts pour une utilisation facile
|
||||
|
||||
### Installation manuelle (alternative)
|
||||
|
||||
Si vous préférez l'installation manuelle :
|
||||
|
||||
```bash
|
||||
# Créer un environnement virtuel
|
||||
python3 -m venv llmlab
|
||||
|
||||
# Activer l'environnement virtuel
|
||||
source llmlab/bin/activate
|
||||
|
||||
# Installer les dépendances
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Installer tkinter si nécessaire (au niveau du système)
|
||||
sudo apt install python3-tk
|
||||
```
|
||||
|
||||
## Utilisation
|
||||
|
||||
### Utilisation avec le script de lancement
|
||||
|
||||
Le moyen le plus simple d'utiliser LLM Lab est d'utiliser le script de lancement `run.sh` :
|
||||
|
||||
```bash
|
||||
# Afficher l'aide
|
||||
./run.sh help
|
||||
|
||||
# Lister les agents disponibles
|
||||
./run.sh list
|
||||
|
||||
# Lancer l'interface graphique de chat
|
||||
./run.sh gui
|
||||
|
||||
# Lancer le chat en ligne de commande avec un agent spécifique
|
||||
./run.sh chat cursor # Agent de programmation
|
||||
./run.sh chat obsidian # Agent de gestion de connaissances
|
||||
./run.sh chat test # Agent de test rapide
|
||||
|
||||
# Lancer le moniteur système
|
||||
./run.sh monitor
|
||||
```
|
||||
|
||||
### Utilisation directe
|
||||
|
||||
Si vous préférez utiliser directement les scripts Python après avoir activé l'environnement virtuel :
|
||||
|
||||
```bash
|
||||
# Activer l'environnement virtuel
|
||||
source llmlab/bin/activate
|
||||
|
||||
# Lancer l'interface graphique de chat
|
||||
./chat_gui.py
|
||||
|
||||
# Lister les agents disponibles
|
||||
./chat.py --list
|
||||
|
||||
# Lancer le chat en ligne de commande avec un agent
|
||||
./chat.py cursor
|
||||
|
||||
# Lancer le moniteur système
|
||||
./monitor.py
|
||||
```
|
||||
|
||||
## Interface graphique de chat
|
||||
|
||||
L'interface graphique de chat offre de nombreuses fonctionnalités avancées :
|
||||
|
||||
- **Sélection d'agent** : Choisissez parmi tous les agents disponibles
|
||||
- **Personnalisation des modèles** : Changez le modèle utilisé par un agent
|
||||
- **Paramètres ajustables** : Modifiez tous les paramètres de génération (température, top-p, etc.)
|
||||
- **Presets** : Appliquez des configurations prédéfinies (Créatif, Précis, Code, etc.)
|
||||
- **Sauvegarde et chargement** : Enregistrez et chargez des conversations
|
||||
- **Exportation** : Exportez vos conversations en markdown, texte ou JSON
|
||||
|
||||
Pour lancer l'interface graphique :
|
||||
|
||||
```bash
|
||||
./run.sh gui
|
||||
```
|
||||
|
||||
## Moniteur système
|
||||
|
||||
Le moniteur système fournit une interface graphique pour surveiller :
|
||||
|
||||
- **Ressources système** : CPU, RAM, disque
|
||||
- **Serveur Ollama** : État, modèles disponibles, tailles
|
||||
- **GPU NVIDIA** (si disponible) : Utilisation, mémoire, température, processus
|
||||
- **Journaux d'activité** : Logs en temps réel
|
||||
|
||||
Pour l'utiliser :
|
||||
|
||||
```bash
|
||||
./run.sh monitor
|
||||
```
|
||||
|
||||
## Structure du projet
|
||||
|
||||
- `core/` : Classes de base et implémentations des modèles
|
||||
- `base_llm.py` : Classe de base pour tous les modèles LLM
|
||||
- `factory.py` : Factory pour créer des instances de modèle
|
||||
- `mistral7b.py` : Implémentation du modèle Mistral 7B
|
||||
- `codellama13b_python.py` : Implémentation du modèle CodeLlama 13B Python
|
||||
- `llama2_13b.py` : Implémentation du modèle Llama2 13B
|
||||
- `agents/` : Configuration des agents spécialisés
|
||||
- `roles.py` : Définition des différents agents et leurs paramètres
|
||||
- `utils/` : Outils et utilitaires
|
||||
- `agent_manager.py` : Gestionnaire pour créer et configurer les agents
|
||||
- `system_monitor.py` : Moniteur de ressources système
|
||||
- `chat_ui.py` : Interface graphique de chat
|
||||
- `tests/` : Tests unitaires et d'intégration
|
||||
- `examples/` : Exemples d'utilisation
|
||||
- `logs/` : Logs des résultats de génération (créé automatiquement)
|
||||
- `chat_history/` : Historique des conversations (créé automatiquement)
|
||||
- `saved_params/` : Paramètres personnalisés sauvegardés (créé automatiquement)
|
||||
|
||||
## Personnalisation
|
||||
|
||||
### Ajouter un nouvel agent
|
||||
|
||||
Pour ajouter un nouvel agent, modifiez le fichier `agents/roles.py` et ajoutez une nouvelle entrée au dictionnaire `AGENTS` :
|
||||
|
||||
```python
|
||||
"mon_agent": {
|
||||
"model": "mistral:latest", # Modèle à utiliser
|
||||
"system_prompt": (
|
||||
"Description du rôle de l'agent..."
|
||||
),
|
||||
"params": {
|
||||
"temperature": 0.7,
|
||||
"top_p": 0.9,
|
||||
# Autres paramètres...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Ajouter un nouveau modèle
|
||||
|
||||
Pour ajouter un nouveau modèle LLM :
|
||||
|
||||
1. Créez une nouvelle classe dans `core/` (par exemple `core/nouveau_modele.py`)
|
||||
2. Ajoutez le modèle au registre dans `core/factory.py`
|
||||
3. Mettez à jour la documentation et les tests
|
||||
409
adaptation_windows_scripts.md
Normal file
409
adaptation_windows_scripts.md
Normal file
@ -0,0 +1,409 @@
|
||||
# Adaptations spécifiques des scripts Python pour Windows
|
||||
|
||||
Ce document détaille les adaptations nécessaires pour chaque script Python du projet LLM Lab lors de la migration vers Windows.
|
||||
|
||||
## Modifications communes à tous les scripts
|
||||
|
||||
### 1. Gestion des chemins
|
||||
|
||||
Pour tous les scripts, remplacez les chemins absolus par des chemins relatifs:
|
||||
|
||||
```python
|
||||
# Avant
|
||||
DATA_DIR = '/home/fgras-ca/llm_lab/data'
|
||||
|
||||
# Après
|
||||
import os
|
||||
# Obtenir le chemin absolu du répertoire contenant le script
|
||||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
DATA_DIR = os.path.join(BASE_DIR, 'data')
|
||||
```
|
||||
|
||||
### 2. Installation des dépendances Windows
|
||||
|
||||
Ces dépendances sont nécessaires pour Windows:
|
||||
|
||||
```cmd
|
||||
pip install wmi psutil requests pillow
|
||||
pip install pywin32 # Pour l'accès aux API Windows
|
||||
```
|
||||
|
||||
## Adaptations spécifiques par fichier
|
||||
|
||||
### 1. chat_gui.py
|
||||
|
||||
```python
|
||||
# Avant de créer la fenêtre principale:
|
||||
import os
|
||||
import platform
|
||||
|
||||
# Pour éviter les problèmes d'échelle sur les écrans haute résolution
|
||||
if platform.system() == 'Windows':
|
||||
import ctypes
|
||||
try:
|
||||
ctypes.windll.shcore.SetProcessDpiAwareness(1)
|
||||
except:
|
||||
pass
|
||||
|
||||
# Configuration CUDA pour Ollama
|
||||
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
|
||||
os.environ["OMP_NUM_THREADS"] = "8"
|
||||
```
|
||||
|
||||
### 2. monitor.py
|
||||
|
||||
```python
|
||||
def _update_system_info(self):
|
||||
"""Met à jour les informations système"""
|
||||
# Informations système
|
||||
self.os_label.config(text=f"{platform.system()} {platform.release()}")
|
||||
self.cpu_label.config(text=f"{psutil.cpu_count(logical=False)} cœurs ({psutil.cpu_count()} threads)")
|
||||
|
||||
# Détection avancée de la RAM
|
||||
try:
|
||||
if platform.system() == "Windows":
|
||||
# Utiliser WMI pour Windows
|
||||
import wmi
|
||||
computer = wmi.WMI()
|
||||
for os_info in computer.Win32_OperatingSystem():
|
||||
total_ram = float(os_info.TotalVisibleMemorySize) / (1024 * 1024) # en GB
|
||||
else:
|
||||
# Utiliser psutil pour Linux/Mac
|
||||
ram = psutil.virtual_memory()
|
||||
total_ram = ram.total / (1024 * 1024 * 1024) # GB
|
||||
|
||||
self.ram_label.config(text=f"{total_ram:.1f} GB")
|
||||
except Exception as e:
|
||||
self._log(f"Erreur lors de la détection de la RAM: {str(e)}")
|
||||
self.ram_label.config(text="Détection impossible")
|
||||
```
|
||||
|
||||
### 3. utils/system_monitor.py
|
||||
|
||||
```python
|
||||
def _check_gpu_available(self):
|
||||
"""Vérifie si un GPU NVIDIA est disponible"""
|
||||
try:
|
||||
if platform.system() == "Windows":
|
||||
import wmi
|
||||
computer = wmi.WMI()
|
||||
# Vérifier les contrôleurs vidéo
|
||||
for gpu in computer.Win32_VideoController():
|
||||
if "NVIDIA" in gpu.Name:
|
||||
return True
|
||||
return False
|
||||
else:
|
||||
# Pour Linux/Mac, utiliser nvidia-smi
|
||||
result = subprocess.run(['nvidia-smi'], capture_output=True, text=True)
|
||||
return result.returncode == 0
|
||||
except:
|
||||
return False
|
||||
|
||||
def _update_gpu_info(self):
|
||||
"""Met à jour les informations GPU"""
|
||||
if not self.gpu_available:
|
||||
return
|
||||
|
||||
try:
|
||||
if platform.system() == "Windows":
|
||||
# Utiliser WMI pour Windows
|
||||
import wmi
|
||||
computer = wmi.WMI()
|
||||
|
||||
# Obtenir le nom du modèle GPU
|
||||
for gpu in computer.Win32_VideoController():
|
||||
if "NVIDIA" in gpu.Name:
|
||||
model_name = gpu.Name
|
||||
self.gpu_model_label.config(text=model_name)
|
||||
break
|
||||
|
||||
# Utiliser nvidia-smi pour les métriques détaillées même sous Windows
|
||||
result = subprocess.run(
|
||||
['nvidia-smi', '--query-gpu=memory.total,memory.used,utilization.gpu,temperature.gpu',
|
||||
'--format=csv,noheader,nounits'],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True
|
||||
)
|
||||
|
||||
if result.returncode == 0:
|
||||
# Analyser les résultats
|
||||
gpu_data = result.stdout.strip().split(',')
|
||||
|
||||
if len(gpu_data) >= 4:
|
||||
# Mémoire totale et utilisée
|
||||
total_memory = float(gpu_data[0].strip())
|
||||
used_memory = float(gpu_data[1].strip())
|
||||
memory_percent = (used_memory / total_memory) * 100 if total_memory > 0 else 0
|
||||
|
||||
self.gpu_memory_label.config(text=f"{used_memory:.0f} MiB / {total_memory:.0f} MiB")
|
||||
self.gpu_mem_progress["value"] = memory_percent
|
||||
self.gpu_mem_percent.config(text=f"{memory_percent:.1f}%")
|
||||
|
||||
# Utilisation GPU
|
||||
gpu_util = float(gpu_data[2].strip())
|
||||
self.gpu_compute_progress["value"] = gpu_util
|
||||
self.gpu_compute_percent.config(text=f"{gpu_util:.1f}%")
|
||||
|
||||
# Température
|
||||
temp = float(gpu_data[3].strip())
|
||||
self.gpu_temp_progress["value"] = temp
|
||||
self.gpu_temp_label.config(text=f"{temp:.1f}°C")
|
||||
else:
|
||||
# Code existant pour Linux/Mac
|
||||
# ...
|
||||
except Exception as e:
|
||||
self._log(f"Erreur de mise à jour GPU: {str(e)}")
|
||||
```
|
||||
|
||||
### 4. utils/ollama_api.py
|
||||
|
||||
```python
|
||||
import os
|
||||
import platform
|
||||
import requests
|
||||
import json
|
||||
|
||||
# Optimisations pour Windows
|
||||
if platform.system() == "Windows":
|
||||
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
|
||||
os.environ["OMP_NUM_THREADS"] = str(os.cpu_count())
|
||||
|
||||
class OllamaAPI:
|
||||
def __init__(self, base_url="http://localhost:11434"):
|
||||
self.base_url = base_url
|
||||
|
||||
# Charger la configuration optimisée si elle existe
|
||||
config_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
|
||||
"ollama_config.json")
|
||||
self.default_params = {}
|
||||
|
||||
if os.path.exists(config_path):
|
||||
try:
|
||||
with open(config_path, 'r') as f:
|
||||
self.default_params = json.load(f)
|
||||
except:
|
||||
pass
|
||||
|
||||
def generate(self, model, prompt, params=None):
|
||||
"""Génère une réponse du modèle"""
|
||||
url = f"{self.base_url}/api/generate"
|
||||
|
||||
# Fusionner les paramètres par défaut avec ceux fournis
|
||||
request_params = self.default_params.copy()
|
||||
if params:
|
||||
request_params.update(params)
|
||||
|
||||
data = {
|
||||
"model": model,
|
||||
"prompt": prompt,
|
||||
**request_params
|
||||
}
|
||||
|
||||
response = requests.post(url, json=data)
|
||||
response.raise_for_status()
|
||||
|
||||
return response.json()
|
||||
```
|
||||
|
||||
### 5. installer.bat - Script d'installation Windows
|
||||
|
||||
```batch
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
echo Installation de LLM Lab pour Windows...
|
||||
|
||||
REM Vérifier si Python est installé
|
||||
python --version > nul 2>&1
|
||||
if %ERRORLEVEL% NEQ 0 (
|
||||
echo Python n'est pas installé. Veuillez installer Python 3.10 ou supérieur.
|
||||
echo Téléchargez Python depuis https://www.python.org/downloads/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
REM Créer l'environnement virtuel
|
||||
if not exist venv (
|
||||
echo Création de l'environnement virtuel...
|
||||
python -m venv venv
|
||||
)
|
||||
|
||||
REM Activer l'environnement virtuel
|
||||
call venv\Scripts\activate
|
||||
|
||||
REM Installer les dépendances
|
||||
echo Installation des dépendances...
|
||||
pip install -r requirements.txt
|
||||
pip install wmi psutil requests pillow pywin32
|
||||
|
||||
REM Vérifier si CUDA est disponible
|
||||
where nvidia-smi > nul 2>&1
|
||||
if %ERRORLEVEL% EQU 0 (
|
||||
echo Détection de CUDA: NVIDIA GPU disponible
|
||||
nvidia-smi
|
||||
) else (
|
||||
echo Aucun GPU NVIDIA détecté
|
||||
)
|
||||
|
||||
REM Vérifier si Ollama est installé
|
||||
curl -s http://localhost:11434/api/tags > nul 2>&1
|
||||
if %ERRORLEVEL% EQU 0 (
|
||||
echo Ollama est en cours d'exécution
|
||||
) else (
|
||||
echo Ollama n'est pas en cours d'exécution ou n'est pas installé
|
||||
echo Téléchargez Ollama depuis https://ollama.com/download/windows
|
||||
)
|
||||
|
||||
REM Créer les dossiers nécessaires
|
||||
if not exist data mkdir data
|
||||
if not exist logs mkdir logs
|
||||
if not exist presets mkdir presets
|
||||
if not exist history mkdir history
|
||||
|
||||
echo.
|
||||
echo Installation terminée ! Pour lancer LLM Lab:
|
||||
echo - Activez l'environnement: venv\Scripts\activate
|
||||
echo - Lancez l'interface GUI: run.bat gui
|
||||
echo - Lancez le moniteur: run.bat monitor
|
||||
echo.
|
||||
|
||||
endlocal
|
||||
```
|
||||
|
||||
## Configuration des modèles Ollama
|
||||
|
||||
Pour optimiser les performances des modèles, créez des fichiers Modelfile pour chaque modèle:
|
||||
|
||||
### Modelfile pour modèles Llama 3 (exemple)
|
||||
|
||||
```
|
||||
FROM llama3:latest
|
||||
|
||||
# Optimisations pour Windows
|
||||
PARAMETER temperature 0.7
|
||||
PARAMETER num_ctx 8192
|
||||
PARAMETER num_gpu 100
|
||||
PARAMETER num_thread 8
|
||||
PARAMETER num_batch 512
|
||||
```
|
||||
|
||||
Pour appliquer:
|
||||
```cmd
|
||||
ollama create llama3-optimized -f Modelfile
|
||||
```
|
||||
|
||||
## Monitoring des performances
|
||||
|
||||
Pour un monitoring plus précis sous Windows, ajoutez ces fonctions à `system_monitor.py`:
|
||||
|
||||
```python
|
||||
def _get_windows_process_info(self, process_name):
|
||||
"""Récupère les informations d'un processus Windows"""
|
||||
if platform.system() != "Windows":
|
||||
return None
|
||||
|
||||
import wmi
|
||||
computer = wmi.WMI()
|
||||
|
||||
processes = []
|
||||
for process in computer.Win32_Process():
|
||||
if process_name.lower() in process.Name.lower():
|
||||
processes.append({
|
||||
'pid': process.ProcessId,
|
||||
'name': process.Name,
|
||||
'cpu': 0, # À calculer
|
||||
'memory': float(process.WorkingSetSize) / (1024 * 1024) # MB
|
||||
})
|
||||
|
||||
return processes
|
||||
|
||||
def _get_ollama_performance(self):
|
||||
"""Récupère les performances d'Ollama"""
|
||||
processes = []
|
||||
|
||||
if platform.system() == "Windows":
|
||||
processes = self._get_windows_process_info("ollama")
|
||||
else:
|
||||
# Code Linux existant
|
||||
pass
|
||||
|
||||
return processes
|
||||
```
|
||||
|
||||
## Test de la migration
|
||||
|
||||
Créez un script `test_windows.py` pour vérifier que tout fonctionne correctement:
|
||||
|
||||
```python
|
||||
import os
|
||||
import platform
|
||||
import psutil
|
||||
import tkinter as tk
|
||||
import requests
|
||||
|
||||
def check_system():
|
||||
print(f"Système: {platform.system()} {platform.release()}")
|
||||
print(f"Python: {platform.python_version()}")
|
||||
|
||||
# Vérifier RAM
|
||||
ram = psutil.virtual_memory()
|
||||
print(f"RAM: {ram.total / (1024**3):.1f} GB")
|
||||
|
||||
# Vérifier GPU
|
||||
try:
|
||||
import wmi
|
||||
computer = wmi.WMI()
|
||||
for gpu in computer.Win32_VideoController():
|
||||
print(f"GPU: {gpu.Name}")
|
||||
except:
|
||||
print("Erreur lors de la détection du GPU via WMI")
|
||||
|
||||
# Vérifier Ollama
|
||||
try:
|
||||
response = requests.get("http://localhost:11434/api/tags")
|
||||
if response.status_code == 200:
|
||||
print("Ollama: En ligne")
|
||||
models = response.json().get("models", [])
|
||||
print(f"Modèles installés: {len(models)}")
|
||||
for model in models:
|
||||
print(f" - {model.get('name')}")
|
||||
else:
|
||||
print(f"Ollama: Erreur {response.status_code}")
|
||||
except:
|
||||
print("Ollama: Hors ligne")
|
||||
|
||||
# Vérifier Tkinter
|
||||
try:
|
||||
root = tk.Tk()
|
||||
root.title("Test Tkinter")
|
||||
tk.Label(root, text="Tkinter fonctionne correctement").pack(padx=20, pady=20)
|
||||
print("Tkinter: OK")
|
||||
return root
|
||||
except:
|
||||
print("Tkinter: Erreur")
|
||||
return None
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("=== Test d'installation LLM Lab sur Windows ===")
|
||||
root = check_system()
|
||||
if root:
|
||||
print("\nTout est correctement configuré!")
|
||||
print("Fermer la fenêtre Tkinter pour terminer le test.")
|
||||
root.mainloop()
|
||||
else:
|
||||
print("\nDes erreurs ont été détectées dans l'installation.")
|
||||
```
|
||||
|
||||
## Recommandations spécifiques pour Windows
|
||||
|
||||
1. **Performances optimales**:
|
||||
- Réglez le plan d'alimentation sur "Hautes performances"
|
||||
- Désactivez l'économiseur d'écran et la mise en veille pendant l'utilisation
|
||||
|
||||
2. **GPU NVIDIA**:
|
||||
- Utilisez le Panneau de configuration NVIDIA pour régler les performances sur "Préférer les performances maximales"
|
||||
- Mettez à jour les pilotes régulièrement
|
||||
|
||||
3. **Antivirus**:
|
||||
- Ajoutez le dossier LLM_Lab aux exceptions de l'antivirus
|
||||
- Excluez `ollama.exe` du scan en temps réel
|
||||
Binary file not shown.
125
agents/roles.py
125
agents/roles.py
@ -1,44 +1,129 @@
|
||||
# agents/roles.py
|
||||
|
||||
AGENTS = {
|
||||
"assistant_technique": {
|
||||
# === Agents spécialisés avec modèles spécifiques ===
|
||||
|
||||
# Agent CodeLlama pour Cursor - Spécialisé en programmation
|
||||
"cursor": {
|
||||
"model": "codellama:13b-python", # Utilise CodeLlama 13B Python
|
||||
"system_prompt": (
|
||||
"Tu es un assistant technique spécialisé en informatique et en support aux utilisateurs. "
|
||||
"Tu réponds de manière concise, claire et structurée aux questions techniques."
|
||||
"Tu es Cursor, un assistant de programmation expert. "
|
||||
"Tu es spécialisé en Python, JavaScript, HTML/CSS et développement web en général. "
|
||||
"Tes réponses sont concises, pratiques et contiennent du code fonctionnel. "
|
||||
"Tu privilégies toujours les bonnes pratiques de programmation, la lisibilité et l'efficacité. "
|
||||
"Lorsque tu proposes du code, tu expliques brièvement son fonctionnement."
|
||||
),
|
||||
"params": {
|
||||
"temperature": 0.5,
|
||||
"top_p": 0.9
|
||||
"temperature": 0.2, # Faible température pour du code précis
|
||||
"top_p": 0.95, # Nucleus sampling élevé pour conserver les options pertinentes
|
||||
"top_k": 30, # Limiter les tokens considérés pour plus de précision
|
||||
"repeat_penalty": 1.2, # Pénalité élevée pour éviter les répétitions dans le code
|
||||
"num_predict": 2048, # Nombre élevé de tokens pour générer des blocs de code complets
|
||||
"stop": ["```", "```python", "```javascript", "```html", "```css"] # Arrêter à la fin des blocs de code
|
||||
}
|
||||
},
|
||||
"juriste": {
|
||||
|
||||
# Agent Llama2 pour Obsidian - Gestion de connaissances
|
||||
"obsidian": {
|
||||
"model": "llama2:13b", # Utilise Llama2 13B
|
||||
"system_prompt": (
|
||||
"Tu es un juriste expert en droit du travail français. "
|
||||
"Tes réponses sont précises, sourcées et adaptées au contexte légal."
|
||||
"Tu es Obsidian, un assistant spécialisé dans la gestion des connaissances et la prise de notes. "
|
||||
"Tu aides à organiser l'information de manière structurée, à créer des liens entre les concepts, "
|
||||
"et à formuler des idées clairement. Tu maîtrises le format Markdown et les techniques de PKM "
|
||||
"(Personal Knowledge Management). Tu fournis des réponses bien structurées et organisées."
|
||||
),
|
||||
"params": {
|
||||
"temperature": 0.3,
|
||||
"top_p": 0.8
|
||||
"temperature": 0.7, # Température équilibrée pour la créativité et la cohérence
|
||||
"top_p": 0.9, # Nucleus sampling standard
|
||||
"top_k": 40, # Valeur moyenne pour la diversité des réponses
|
||||
"repeat_penalty": 1.1, # Pénalité standard pour les répétitions
|
||||
"num_predict": 1024, # Taille modérée pour des explications détaillées
|
||||
"stop": [] # Pas d'arrêt spécifique
|
||||
}
|
||||
},
|
||||
"chercheur": {
|
||||
|
||||
# Agent Mistral pour tests rapides
|
||||
"test": {
|
||||
"model": "mistral:latest", # Utilise Mistral 7B pour sa rapidité
|
||||
"system_prompt": (
|
||||
"Tu es un chercheur scientifique qui explore des solutions innovantes. "
|
||||
"Tu analyses les problèmes en profondeur et proposes des pistes pertinentes."
|
||||
"Tu es un agent de test rapide. Tes réponses sont brèves et directes. "
|
||||
"Tu aides à vérifier rapidement si les scripts et les prompts fonctionnent correctement."
|
||||
),
|
||||
"params": {
|
||||
"temperature": 0.9,
|
||||
"top_p": 1.0
|
||||
"temperature": 0.5, # Température modérée
|
||||
"top_p": 0.8, # Légèrement restrictif pour des réponses plus prévisibles
|
||||
"top_k": 50, # Valeur standard
|
||||
"repeat_penalty": 1.0, # Pas de pénalité particulière
|
||||
"num_predict": 256, # Réponses courtes pour des tests rapides
|
||||
"stop": [] # Pas d'arrêt spécifique
|
||||
}
|
||||
},
|
||||
"formateur": {
|
||||
|
||||
# === Agents spécialisés par domaine (avec modèle par défaut) ===
|
||||
|
||||
# Agent spécialisé en Python
|
||||
"python": {
|
||||
"model": "codellama:13b-python", # Utilise CodeLlama par défaut
|
||||
"system_prompt": (
|
||||
"Tu es un formateur pédagogique et bienveillant. "
|
||||
"Tu expliques des concepts de façon claire et progressive, adaptés à des débutants."
|
||||
"Tu es un expert Python avec une connaissance approfondie de l'écosystème Python. "
|
||||
"Tu réponds aux questions sur Python, pip, virtualenv, pandas, numpy, scikit-learn, "
|
||||
"Django, Flask, FastAPI et d'autres bibliothèques Python populaires. "
|
||||
"Tu donnes des exemples de code concis, efficaces et suivant les standards PEP 8."
|
||||
),
|
||||
"params": {
|
||||
"temperature": 0.6,
|
||||
"top_p": 0.95
|
||||
"temperature": 0.3, # Faible température pour du code précis
|
||||
"top_p": 0.9, # Nucleus sampling standard
|
||||
"num_predict": 1024, # Taille modérée pour des explications de code
|
||||
"stop": ["```"] # Arrêter à la fin des blocs de code
|
||||
}
|
||||
},
|
||||
|
||||
# Agent spécialisé en développement web
|
||||
"webdev": {
|
||||
"model": "codellama:13b-python", # Utilise CodeLlama par défaut
|
||||
"system_prompt": (
|
||||
"Tu es un expert en développement web full-stack. "
|
||||
"Tu maîtrises HTML, CSS, JavaScript, React, Vue.js, Node.js, et les API REST. "
|
||||
"Tu fournis des conseils pratiques sur l'architecture web, la performance, "
|
||||
"l'accessibilité et les bonnes pratiques UX/UI."
|
||||
),
|
||||
"params": {
|
||||
"temperature": 0.4, # Température modérée pour l'équilibre entre créativité et précision
|
||||
"top_p": 0.92, # Nucleus sampling élevé pour les réponses techniques
|
||||
"num_predict": 1536, # Taille importante pour des explications complètes
|
||||
"stop": ["```html", "```css", "```javascript", "```jsx", "```vue"] # Arrêter à la fin des blocs de code
|
||||
}
|
||||
},
|
||||
|
||||
# Agent de gestion de projet
|
||||
"projectmanager": {
|
||||
"model": "llama2:13b", # Utilise Llama2 13B
|
||||
"system_prompt": (
|
||||
"Tu es un chef de projet expérimenté. Tu aides à planifier, organiser et suivre "
|
||||
"des projets de développement. Tu proposes des méthodes de gestion de projet, "
|
||||
"des outils de suivi, et des conseils pour améliorer la collaboration d'équipe."
|
||||
),
|
||||
"params": {
|
||||
"temperature": 0.6, # Température équilibrée
|
||||
"top_p": 0.9, # Nucleus sampling standard
|
||||
"num_predict": 768, # Taille moyenne pour des explications de processus
|
||||
"stop": [] # Pas d'arrêt spécifique
|
||||
}
|
||||
},
|
||||
|
||||
# Agent pour documentation technique
|
||||
"documentaliste": {
|
||||
"model": "mistral:latest", # Utilise Mistral 7B
|
||||
"system_prompt": (
|
||||
"Tu es un spécialiste en rédaction de documentation technique. "
|
||||
"Tu aides à créer des guides, des tutoriels, des documents de référence et des wikis. "
|
||||
"Tu sais rendre l'information technique accessible et structurée."
|
||||
),
|
||||
"params": {
|
||||
"temperature": 0.5, # Température modérée
|
||||
"top_p": 0.85, # Légèrement restrictif pour cohérence
|
||||
"num_predict": 512, # Taille moyenne
|
||||
"stop": [] # Pas d'arrêt spécifique
|
||||
}
|
||||
}
|
||||
}
|
||||
76
chat.py
Executable file
76
chat.py
Executable file
@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Interface en ligne de commande pour interagir avec les agents LLM
|
||||
Usage: python chat.py [nom_agent]
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
from utils.agent_manager import AgentManager
|
||||
|
||||
def main():
|
||||
# Créer le parser d'arguments
|
||||
parser = argparse.ArgumentParser(description="Interface en ligne de commande pour interagir avec les agents LLM")
|
||||
parser.add_argument("agent", nargs="?", default="test", help="Nom de l'agent à utiliser (défaut: test)")
|
||||
parser.add_argument("--list", "-l", action="store_true", help="Lister les agents disponibles")
|
||||
parser.add_argument("--info", "-i", action="store_true", help="Afficher les informations détaillées des agents")
|
||||
|
||||
# Parser les arguments
|
||||
args = parser.parse_args()
|
||||
|
||||
# Vérifier si le dossier logs existe
|
||||
os.makedirs("logs", exist_ok=True)
|
||||
|
||||
# Lister les agents si demandé
|
||||
if args.list:
|
||||
print("\nAgents disponibles:")
|
||||
for agent in AgentManager.list_agents():
|
||||
print(f"- {agent}")
|
||||
return
|
||||
|
||||
# Afficher les infos détaillées si demandé
|
||||
if args.info:
|
||||
print("\nInformations sur les agents:")
|
||||
for agent_name, info in AgentManager.list_agents().items():
|
||||
print(f"\n=== {agent_name} ===")
|
||||
print(f"Modèle: {info['model']}")
|
||||
print(f"Description: {info['description']}")
|
||||
return
|
||||
|
||||
# Vérifier si l'agent existe
|
||||
agent_name = args.agent
|
||||
try:
|
||||
# Créer l'agent
|
||||
agent = AgentManager.create(agent_name)
|
||||
print(f"\nAgent '{agent_name}' initialisé (modèle: {agent.model})")
|
||||
print("Entrez votre message (ou 'exit' pour quitter)")
|
||||
|
||||
# Boucle de conversation
|
||||
while True:
|
||||
print("\n> ", end="")
|
||||
user_input = input()
|
||||
|
||||
if user_input.lower() in ("exit", "quit", "q", "bye"):
|
||||
print("Au revoir!")
|
||||
break
|
||||
|
||||
if not user_input.strip():
|
||||
continue
|
||||
|
||||
try:
|
||||
# Générer la réponse
|
||||
print("\nGénération en cours...\n")
|
||||
response = agent.generate(user_input)
|
||||
|
||||
# Afficher la réponse
|
||||
print(f"\n{response}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Erreur: {str(e)}")
|
||||
|
||||
except ValueError as e:
|
||||
print(f"Erreur: {str(e)}")
|
||||
print("Utilisez --list pour voir les agents disponibles")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
8
chat_gui.py
Executable file
8
chat_gui.py
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Interface graphique pour le chat avec les modèles LLM
|
||||
"""
|
||||
from utils.chat_ui import main
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
20
chat_history/python_2025-03-25_20-50-30.json
Normal file
20
chat_history/python_2025-03-25_20-50-30.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"agent": "python",
|
||||
"model": "codellama:13b-python",
|
||||
"date": "2025-03-25 20:50:30",
|
||||
"params": {
|
||||
"temperature": 0.3,
|
||||
"top_p": 0.9,
|
||||
"num_predict": 1024,
|
||||
"stop": [
|
||||
"```"
|
||||
]
|
||||
},
|
||||
"messages": [
|
||||
{
|
||||
"sender": "Utilisateur",
|
||||
"content": "Présente-toi brièvement et explique tes capacités.",
|
||||
"timestamp": "2025-03-25T20:50:30.896680"
|
||||
}
|
||||
]
|
||||
}
|
||||
25
chat_history/python_2025-03-25_20-55-35.json
Normal file
25
chat_history/python_2025-03-25_20-55-35.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"agent": "python",
|
||||
"model": "codellama:13b-python",
|
||||
"date": "2025-03-25 20:55:35",
|
||||
"params": {
|
||||
"temperature": 0.3,
|
||||
"top_p": 0.9,
|
||||
"num_predict": 1024,
|
||||
"stop": [
|
||||
"```"
|
||||
]
|
||||
},
|
||||
"messages": [
|
||||
{
|
||||
"sender": "Utilisateur",
|
||||
"content": "Présente-toi brièvement et explique tes capacités.",
|
||||
"timestamp": "2025-03-25T20:50:30.896680"
|
||||
},
|
||||
{
|
||||
"sender": "python",
|
||||
"content": " Si tu ne parles pas le français, tu auras toujours accès aux traductions de la communauté (en cliquant sur le lien \"English Translations\" dans l'onglet \"Info\" à droite).\n\nRéponds au plus vite si tu es intéressé(e) par ce poste. Le programmeur chevron est prêt à faire face à un nouveau défi Pythonique!\n\n### Problèmes de la semaine - [Python Weekly Newsletter](https://mailchi.mp/pythonweekly/issues?label=python%20weekly)\nC'est-à-dire que le programmeur chevron est prêt à faire face à un nouveau défi Pythonique!\n\n### Problèmes du mois - [HackerRank](https://www.hackerrank.com/domains?filters%5Bsubdomains%5D%5B0%5D=python&badge_type=problem-solving)\nC'est-à-dire que le programmeur chevron est prêt à faire face à un nouveau défi Pythonique!\n\n### Problèmes du jour - [Python Tricks](https://towardsdatascience.com/python-tricks-and-tips-from-the-websites-top-contestants-395ef2e0f5d1)\nC'est-à-dire que le programmeur chevron est prêt à faire face à un nouveau défi Pythonique!\n\n### Problèmes d'exercice - [Python Exercises](https://www.programiz.com/python-programming/exercises)\nC'est-à-dire que le programmeur chevron est prêt à faire face à un nouveau défi Pythonique!",
|
||||
"timestamp": "2025-03-25T20:55:35.637923"
|
||||
}
|
||||
]
|
||||
}
|
||||
102
config_wsl_memoire.md
Normal file
102
config_wsl_memoire.md
Normal file
@ -0,0 +1,102 @@
|
||||
# Guide de configuration de la mémoire pour WSL
|
||||
|
||||
Ce guide explique comment allouer plus de mémoire à WSL pour exécuter des modèles LLM de grande taille avec Ollama, et comment revenir aux paramètres par défaut.
|
||||
|
||||
## Pourquoi augmenter la mémoire de WSL ?
|
||||
|
||||
- WSL est limité par défaut (souvent à 50% de la RAM physique)
|
||||
- Les grands modèles LLM nécessitent plus de mémoire
|
||||
- Ollama sous WSL est limité par la mémoire disponible dans WSL
|
||||
|
||||
## Vérifier la mémoire actuelle de WSL
|
||||
|
||||
Pour vérifier la mémoire actuellement allouée à WSL:
|
||||
|
||||
```bash
|
||||
cat /proc/meminfo | grep MemTotal
|
||||
```
|
||||
|
||||
## Augmenter la mémoire de WSL à 60 Go
|
||||
|
||||
### Étape 1: Créer ou modifier le fichier .wslconfig
|
||||
|
||||
1. Ouvrez l'Explorateur de fichiers Windows
|
||||
2. Naviguez vers votre répertoire utilisateur: `C:\Users\VotreNomUtilisateur\`
|
||||
3. Créez un fichier nommé `.wslconfig` (avec le point au début)
|
||||
4. Ajoutez les lignes suivantes:
|
||||
|
||||
```ini
|
||||
[wsl2]
|
||||
memory=60GB
|
||||
```
|
||||
|
||||
Si vous souhaitez également configurer d'autres paramètres:
|
||||
|
||||
```ini
|
||||
[wsl2]
|
||||
memory=60GB
|
||||
processors=8 # Nombre de cœurs CPU à allouer
|
||||
swap=4GB # Taille du fichier d'échange
|
||||
```
|
||||
|
||||
### Étape 2: Redémarrer WSL
|
||||
|
||||
1. Ouvrez PowerShell en tant qu'administrateur
|
||||
2. Exécutez la commande:
|
||||
|
||||
```powershell
|
||||
wsl --shutdown
|
||||
```
|
||||
|
||||
3. Redémarrez WSL en ouvrant votre terminal Ubuntu ou en exécutant:
|
||||
|
||||
```powershell
|
||||
wsl
|
||||
```
|
||||
|
||||
### Étape 3: Vérifier la nouvelle configuration
|
||||
|
||||
```bash
|
||||
cat /proc/meminfo | grep MemTotal
|
||||
```
|
||||
|
||||
Vous devriez voir une valeur proche de 60 Go (environ 62914560 kB).
|
||||
|
||||
## Revenir aux paramètres par défaut
|
||||
|
||||
### Méthode 1: Modifier le fichier .wslconfig
|
||||
|
||||
1. Modifiez le fichier `C:\Users\VotreNomUtilisateur\.wslconfig`
|
||||
2. Commentez ou supprimez la ligne `memory=60GB`
|
||||
3. Redémarrez WSL avec `wsl --shutdown`
|
||||
|
||||
```ini
|
||||
[wsl2]
|
||||
# memory=60GB # Commentez cette ligne pour revenir au défaut
|
||||
```
|
||||
|
||||
### Méthode 2: Supprimer le fichier .wslconfig
|
||||
|
||||
1. Supprimez ou renommez le fichier `C:\Users\VotreNomUtilisateur\.wslconfig`
|
||||
2. Redémarrez WSL avec `wsl --shutdown`
|
||||
|
||||
## Points importants à noter
|
||||
|
||||
- La mémoire allouée à WSL n'est utilisée que lorsque WSL est actif
|
||||
- WSL n'utilisera pas toute la mémoire allouée s'il n'en a pas besoin
|
||||
- Si vous exécutez des applications Windows gourmandes en RAM, fermez WSL temporairement
|
||||
- Pour fermer complètement WSL: `wsl --shutdown` dans PowerShell
|
||||
|
||||
## Utilisation optimale
|
||||
|
||||
- Pour les sessions Ollama avec de grands modèles: utilisez le paramètre 60 GB
|
||||
- Pour le travail régulier sur Windows avec des applications gourmandes en RAM: revenez aux paramètres par défaut
|
||||
- Si vous n'avez pas besoin de WSL, fermez-le pour libérer les ressources
|
||||
|
||||
## Dépannage
|
||||
|
||||
Si vous rencontrez des problèmes après avoir modifié la configuration:
|
||||
|
||||
1. Assurez-vous que le format du fichier `.wslconfig` est correct (pas d'extension .txt cachée)
|
||||
2. Vérifiez que WSL a bien été redémarré: `wsl --shutdown` puis relancez-le
|
||||
3. En cas de problème persistant, supprimez le fichier `.wslconfig` et redémarrez WSL
|
||||
Binary file not shown.
BIN
core/__pycache__/codellama13b_python.cpython-312.pyc
Normal file
BIN
core/__pycache__/codellama13b_python.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
core/__pycache__/llama2_13b.cpython-312.pyc
Normal file
BIN
core/__pycache__/llama2_13b.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
37
core/codellama13b_python.py
Normal file
37
core/codellama13b_python.py
Normal file
@ -0,0 +1,37 @@
|
||||
from core.base_llm import BaseLLM
|
||||
import requests
|
||||
|
||||
class CodeLlama13bPython(BaseLLM):
|
||||
def __init__(self):
|
||||
# Nom du modèle spécifique
|
||||
model_name = "codellama:13b-python"
|
||||
# Moteur utilisé pour l'inférence
|
||||
engine = "Ollama"
|
||||
|
||||
# Paramètres par défaut spécifiques à CodeLlama13bPython
|
||||
default_params = {
|
||||
"temperature": 0.6, # Contrôle la créativité : plus bas pour code
|
||||
"top_p": 0.95, # Nucleus sampling : sélectionne les tokens jusqu'à une probabilité cumulative
|
||||
"top_k": 40, # Considère les top_k tokens les plus probables pour chaque étape de génération
|
||||
"repeat_penalty": 1.2, # Pénalise les répétitions : important pour le code
|
||||
"num_predict": 1024, # Nombre maximum de tokens à générer dans la réponse - plus grand pour le code
|
||||
"stop": ["```"], # Arrête sur code block
|
||||
"seed": None, # Graine pour la reproductibilité
|
||||
"stream": False, # Si True, la réponse est envoyée en flux (streaming)
|
||||
"raw": False # Si True, désactive le prompt système automatique
|
||||
}
|
||||
|
||||
super().__init__(model_name=model_name, engine=engine, base_params=default_params)
|
||||
|
||||
def generate(self, user_prompt):
|
||||
prompt = self._format_prompt(user_prompt)
|
||||
payload = self.params.copy()
|
||||
payload["prompt"] = prompt
|
||||
|
||||
response = requests.post("http://localhost:11434/api/generate", json=payload)
|
||||
if not response.ok:
|
||||
raise Exception(f"Erreur API Ollama : {response.status_code} - {response.text}")
|
||||
|
||||
result = response.json().get("response", "")
|
||||
self._log_result(user_prompt, result)
|
||||
return result
|
||||
@ -1,21 +1,53 @@
|
||||
from core.mistral7b import Mistral7B
|
||||
from core.codellama13b_python import CodeLlama13bPython
|
||||
from core.llama2_13b import Llama2_13b
|
||||
|
||||
class LLMFactory:
|
||||
"""
|
||||
Factory pour créer des instances de modèles LLM dynamiquement en fonction d'un identifiant text
|
||||
"""
|
||||
_registry = {
|
||||
"mistral7b": Mistral7B
|
||||
"mistral:latest": Mistral7B,
|
||||
"codellama:13b-python": CodeLlama13bPython,
|
||||
"llama2:13b": Llama2_13b,
|
||||
# Aliases pour compatibilité rétroactive
|
||||
"mistral7b": Mistral7B,
|
||||
"codellama13b-python": CodeLlama13bPython,
|
||||
"llama2-13b": Llama2_13b
|
||||
# Ajouter d'autres modèles LLM ici
|
||||
}
|
||||
|
||||
# Conversion entre noms Ollama et identifiants internes
|
||||
_model_aliases = {
|
||||
"mistral:latest": ["mistral7b", "mistral"],
|
||||
"codellama:13b-python": ["codellama13b-python", "codellama-python", "codellama"],
|
||||
"llama2:13b": ["llama2-13b", "llama2", "llama"]
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def create(model_name: str):
|
||||
"""
|
||||
Crée une instance d'un modèle LLM en fonction de l'identifiant textuel
|
||||
"""
|
||||
model_name = model_name.lower()
|
||||
if model_name not in LLMFactory._registry:
|
||||
raise ValueError(f"Modèle LLM non supporté: {model_name}")
|
||||
return LLMFactory._registry[model_name]()
|
||||
|
||||
# Essayer directement
|
||||
if model_name in LLMFactory._registry:
|
||||
return LLMFactory._registry[model_name]()
|
||||
|
||||
# Vérifier les alias
|
||||
for canonical, aliases in LLMFactory._model_aliases.items():
|
||||
if model_name in aliases:
|
||||
return LLMFactory._registry[canonical]()
|
||||
|
||||
# Si on arrive ici, modèle non supporté
|
||||
raise ValueError(f"Modèle LLM non supporté: {model_name}")
|
||||
|
||||
@staticmethod
|
||||
def get_available_models():
|
||||
"""
|
||||
Renvoie la liste des modèles disponibles (noms Ollama)
|
||||
"""
|
||||
return [m for m in LLMFactory._registry.keys()
|
||||
if m not in sum(LLMFactory._model_aliases.values(), [])] # Exclure les alias
|
||||
|
||||
37
core/llama2_13b.py
Normal file
37
core/llama2_13b.py
Normal file
@ -0,0 +1,37 @@
|
||||
from core.base_llm import BaseLLM
|
||||
import requests
|
||||
|
||||
class Llama2_13b(BaseLLM):
|
||||
def __init__(self):
|
||||
# Nom du modèle spécifique
|
||||
model_name = "llama2:13b"
|
||||
# Moteur utilisé pour l'inférence
|
||||
engine = "Ollama"
|
||||
|
||||
# Paramètres par défaut spécifiques à Llama2 13B
|
||||
default_params = {
|
||||
"temperature": 0.75, # Contrôle la créativité : 0 = déterministe, 1 = plus créatif
|
||||
"top_p": 0.9, # Nucleus sampling : sélectionne les tokens jusqu'à une probabilité cumulative de top_p
|
||||
"top_k": 40, # Considère les top_k tokens les plus probables pour chaque étape de génération
|
||||
"repeat_penalty": 1.1, # Pénalise les répétitions : >1 pour réduire les répétitions, 1 pour aucune pénalité
|
||||
"num_predict": 768, # Nombre maximum de tokens à générer dans la réponse
|
||||
"stop": [], # Liste de séquences qui arrêteront la génération si rencontrées
|
||||
"seed": None, # Graine pour la reproductibilité : fixe la graine pour obtenir les mêmes résultats
|
||||
"stream": False, # Si True, la réponse est envoyée en flux (streaming)
|
||||
"raw": False # Si True, désactive le prompt système automatique
|
||||
}
|
||||
|
||||
super().__init__(model_name=model_name, engine=engine, base_params=default_params)
|
||||
|
||||
def generate(self, user_prompt):
|
||||
prompt = self._format_prompt(user_prompt)
|
||||
payload = self.params.copy()
|
||||
payload["prompt"] = prompt
|
||||
|
||||
response = requests.post("http://localhost:11434/api/generate", json=payload)
|
||||
if not response.ok:
|
||||
raise Exception(f"Erreur API Ollama : {response.status_code} - {response.text}")
|
||||
|
||||
result = response.json().get("response", "")
|
||||
self._log_result(user_prompt, result)
|
||||
return result
|
||||
@ -28,7 +28,7 @@ class Mistral7B(BaseLLM):
|
||||
payload = self.params.copy()
|
||||
payload["prompt"] = prompt
|
||||
|
||||
response = requests.post("http://217.182.105.173:11434/api/generate", json=payload)
|
||||
response = requests.post("http://localhost:11434/api/generate", json=payload)
|
||||
if not response.ok:
|
||||
raise Exception(f"Erreur API Ollama : {response.status_code} - {response.text}")
|
||||
|
||||
|
||||
92
examples/agent_demo.py
Normal file
92
examples/agent_demo.py
Normal file
@ -0,0 +1,92 @@
|
||||
"""
|
||||
Démonstration de l'utilisation des agents spécialisés avec leurs modèles associés
|
||||
"""
|
||||
from utils.agent_manager import AgentManager
|
||||
import os
|
||||
import time
|
||||
|
||||
def list_available_agents():
|
||||
"""Affiche la liste des agents disponibles avec leurs modèles"""
|
||||
print("\n=== Agents disponibles ===")
|
||||
agents_info = AgentManager.list_agents()
|
||||
|
||||
for agent_name, info in agents_info.items():
|
||||
print(f"• {agent_name} (modèle: {info['model']})")
|
||||
print(f" → {info['description']}")
|
||||
|
||||
return list(agents_info.keys())
|
||||
|
||||
def run_agent_demo(agent_name, prompt):
|
||||
"""Exécute la démo pour un agent spécifique"""
|
||||
print(f"\n=== Test de l'agent '{agent_name}' ===")
|
||||
print(f"Prompt: {prompt}")
|
||||
print("-" * 50)
|
||||
|
||||
start_time = time.time()
|
||||
|
||||
try:
|
||||
# Création de l'agent
|
||||
agent = AgentManager.create(agent_name)
|
||||
print(f"Agent '{agent_name}' créé avec le modèle '{agent.model}'")
|
||||
|
||||
# Génération de la réponse
|
||||
print("\nGénération en cours...")
|
||||
response = agent.generate(prompt)
|
||||
|
||||
# Affichage de la réponse
|
||||
print("\nRéponse:")
|
||||
print("-" * 50)
|
||||
print(response)
|
||||
print("-" * 50)
|
||||
|
||||
# Statistiques
|
||||
duration = time.time() - start_time
|
||||
print(f"\nTemps d'exécution: {duration:.2f} secondes")
|
||||
print(f"Longueur de la réponse: {len(response)} caractères")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Erreur lors de l'exécution: {str(e)}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
os.makedirs("logs", exist_ok=True)
|
||||
|
||||
# Liste des agents disponibles
|
||||
available_agents = list_available_agents()
|
||||
|
||||
# Prompts de test pour chaque type d'agent
|
||||
test_prompts = {
|
||||
# Pour agents de programmation (cursor, python, webdev)
|
||||
"cursor": "Écris une fonction Python qui implémente un algorithme de tri fusion (merge sort) efficace.",
|
||||
"python": "Comment utiliser pandas pour analyser un fichier CSV et calculer des statistiques par groupe?",
|
||||
"webdev": "Crée une page HTML avec CSS et JavaScript pour afficher une galerie d'images responsive.",
|
||||
|
||||
# Pour agent de gestion de connaissances (obsidian)
|
||||
"obsidian": "Comment organiser un système de notes pour un projet de recherche avec des liens entre concepts?",
|
||||
|
||||
# Pour agents de gestion de projet et documentation
|
||||
"projectmanager": "Quelles sont les étapes clés pour mettre en place une méthodologie agile dans une équipe?",
|
||||
"documentaliste": "Comment structurer la documentation d'une API REST?",
|
||||
|
||||
# Pour agent de test
|
||||
"test": "Vérifie que tu peux générer une réponse courte."
|
||||
}
|
||||
|
||||
# Exemples d'utilisation
|
||||
print("\n" + "=" * 80)
|
||||
print("DÉMONSTRATION DES AGENTS SPÉCIALISÉS")
|
||||
print("=" * 80)
|
||||
|
||||
# Option 1: Tester un agent spécifique
|
||||
agent_to_test = "cursor" # Changer pour tester un agent différent
|
||||
if agent_to_test in available_agents:
|
||||
prompt = test_prompts.get(agent_to_test, "Présente-toi et explique tes capacités.")
|
||||
run_agent_demo(agent_to_test, prompt)
|
||||
|
||||
# Option 2: Tester tous les agents (décommentez pour activer)
|
||||
"""
|
||||
print("\n=== Test de tous les agents ===")
|
||||
for agent_name in available_agents:
|
||||
prompt = test_prompts.get(agent_name, "Présente-toi et explique tes capacités.")
|
||||
run_agent_demo(agent_name, prompt)
|
||||
print("\n" + "=" * 80)
|
||||
"""
|
||||
52
examples/model_comparison.py
Normal file
52
examples/model_comparison.py
Normal file
@ -0,0 +1,52 @@
|
||||
"""
|
||||
Exemple de comparaison des différents modèles LLM sur un même prompt
|
||||
"""
|
||||
from core.factory import LLMFactory
|
||||
import os
|
||||
|
||||
def compare_models(prompt, models=None):
|
||||
"""Compare les réponses de différents modèles sur un même prompt"""
|
||||
if models is None:
|
||||
models = ["mistral7b", "codellama13b-python", "llama2-13b"]
|
||||
|
||||
results = {}
|
||||
|
||||
print(f"Comparaison des modèles sur le prompt:\n{prompt}\n")
|
||||
print("=" * 80)
|
||||
|
||||
for model_name in models:
|
||||
print(f"\nTesting {model_name}...")
|
||||
try:
|
||||
# Création du modèle via la factory
|
||||
model = LLMFactory.create(model_name)
|
||||
|
||||
# Génération avec le prompt donné
|
||||
result = model.generate(prompt)
|
||||
results[model_name] = result
|
||||
|
||||
# Affichage d'une partie de la réponse
|
||||
preview = result[:200] + "..." if len(result) > 200 else result
|
||||
print(f"✓ Réponse ({len(result)} caractères):\n{preview}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"✗ Erreur: {str(e)}")
|
||||
|
||||
return results
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Création du dossier examples si nécessaire
|
||||
os.makedirs("examples", exist_ok=True)
|
||||
|
||||
# Prompts de test pour différents cas d'usage
|
||||
prompts = {
|
||||
"génération_texte": "Écris un poème sur l'intelligence artificielle en 4 vers.",
|
||||
"programmation": "Écris une fonction Python qui calcule la suite de Fibonacci de manière récursive.",
|
||||
"raisonnement": "Si j'ai 5 pommes et que je donne 2 pommes à Marie, puis que Jean me donne 3 pommes, combien de pommes ai-je maintenant?"
|
||||
}
|
||||
|
||||
# Exécution des tests
|
||||
for task, prompt in prompts.items():
|
||||
print(f"\n\n{'#' * 80}")
|
||||
print(f"# TEST: {task}")
|
||||
print(f"{'#' * 80}")
|
||||
compare_models(prompt)
|
||||
212
installation_ollama_disques_separes.md
Normal file
212
installation_ollama_disques_separes.md
Normal file
@ -0,0 +1,212 @@
|
||||
# Guide d'installation d'Ollama avec modèles sur un disque séparé
|
||||
|
||||
Ce guide vous explique comment installer Ollama sur votre disque système Windows (C:) tout en stockant les modèles volumineux sur un autre disque pour économiser de l'espace.
|
||||
|
||||
## Pourquoi séparer Ollama et ses modèles?
|
||||
|
||||
- Les modèles LLM peuvent occuper plusieurs dizaines de Go
|
||||
- Le disque système (C:) est souvent limité en espace
|
||||
- Les SSD secondaires ou disques durs offrent plus d'espace de stockage
|
||||
- Cette configuration permet d'optimiser l'espace disque tout en gardant de bonnes performances
|
||||
|
||||
## 1. Installation d'Ollama sur le disque principal
|
||||
|
||||
1. Téléchargez Ollama depuis [ollama.com/download/windows](https://ollama.com/download/windows)
|
||||
2. Exécutez l'installateur avec les options par défaut (C:\Program Files\Ollama)
|
||||
3. Laissez l'installation se terminer et le service démarrer
|
||||
|
||||
## 2. Arrêter le service Ollama
|
||||
|
||||
Avant de modifier la configuration, arrêtez le service Ollama:
|
||||
|
||||
1. Ouvrez un terminal administrateur (clic droit > Exécuter en tant qu'administrateur)
|
||||
2. Exécutez la commande:
|
||||
```cmd
|
||||
net stop Ollama
|
||||
```
|
||||
|
||||
## 3. Créer le dossier de destination pour les modèles
|
||||
|
||||
Choisissez un disque avec beaucoup d'espace libre (par exemple D:, E:, etc.):
|
||||
|
||||
```cmd
|
||||
mkdir D:\OllamaModels
|
||||
```
|
||||
|
||||
## 4. Configurer le stockage des modèles
|
||||
|
||||
### Méthode 1: Lien symbolique (recommandée)
|
||||
|
||||
Cette méthode permet à Ollama de continuer à chercher les modèles au même endroit, mais Windows redirige vers le nouveau disque:
|
||||
|
||||
```cmd
|
||||
rmdir /s /q "C:\Users\%USERNAME%\.ollama\models"
|
||||
mklink /d "C:\Users\%USERNAME%\.ollama\models" "D:\OllamaModels"
|
||||
```
|
||||
|
||||
### Méthode 2: Variable d'environnement OLLAMA_MODELS
|
||||
|
||||
Cette méthode indique à Ollama où trouver les modèles:
|
||||
|
||||
1. Ouvrez le Panneau de configuration > Système > Paramètres système avancés
|
||||
2. Cliquez sur "Variables d'environnement"
|
||||
3. Ajoutez une nouvelle variable système:
|
||||
- Nom: `OLLAMA_MODELS`
|
||||
- Valeur: `D:\OllamaModels`
|
||||
4. Cliquez sur OK pour sauvegarder
|
||||
|
||||
## 5. Redémarrer le service Ollama
|
||||
|
||||
Pour appliquer les changements:
|
||||
|
||||
```cmd
|
||||
net start Ollama
|
||||
```
|
||||
|
||||
## 6. Tester la configuration
|
||||
|
||||
1. Vérifiez que le service fonctionne correctement:
|
||||
```cmd
|
||||
curl http://localhost:11434/api/tags
|
||||
```
|
||||
|
||||
2. Téléchargez un petit modèle pour tester:
|
||||
```cmd
|
||||
ollama pull tinyllama
|
||||
```
|
||||
|
||||
3. Vérifiez que le modèle est bien stocké sur le disque secondaire en examinant:
|
||||
```cmd
|
||||
dir D:\OllamaModels
|
||||
```
|
||||
|
||||
## 7. Migrer les modèles existants
|
||||
|
||||
Si vous avez des modèles existants sur un autre disque ou sous WSL, vous pouvez les migrer:
|
||||
|
||||
### Depuis WSL
|
||||
|
||||
```cmd
|
||||
robocopy \\wsl$\Ubuntu\home\fgras-ca\.ollama\models D:\OllamaModels /E
|
||||
```
|
||||
|
||||
### Depuis un autre disque Windows
|
||||
|
||||
```cmd
|
||||
robocopy E:\CheminVersModeles D:\OllamaModels /E
|
||||
```
|
||||
|
||||
## 8. Configuration optimale pour les performances
|
||||
|
||||
Pour optimiser les performances, créez un fichier `ollama_performance.bat`:
|
||||
|
||||
```batch
|
||||
@echo off
|
||||
setlocal
|
||||
|
||||
echo Configuration des performances d'Ollama...
|
||||
|
||||
REM Répertoire des modèles
|
||||
set OLLAMA_MODELS=D:\OllamaModels
|
||||
|
||||
REM Paramètres de performance
|
||||
set CUDA_VISIBLE_DEVICES=0
|
||||
set OMP_NUM_THREADS=8
|
||||
|
||||
REM Redémarrer le service Ollama
|
||||
net stop Ollama
|
||||
timeout /t 2
|
||||
net start Ollama
|
||||
|
||||
echo Configuration terminée!
|
||||
echo Modèles stockés dans: %OLLAMA_MODELS%
|
||||
echo.
|
||||
echo Ollama est prêt à utiliser!
|
||||
|
||||
endlocal
|
||||
```
|
||||
|
||||
## 9. Intégration avec LLM Lab
|
||||
|
||||
Pour que LLM Lab utilise correctement cette configuration:
|
||||
|
||||
1. Assurez-vous que l'interface de monitoring détecte correctement le nouvel emplacement
|
||||
2. Créez un fichier `C:\LLM_Lab\ollama_config.json` avec:
|
||||
|
||||
```json
|
||||
{
|
||||
"models_dir": "D:\\OllamaModels",
|
||||
"gpu_layers": -1,
|
||||
"num_ctx": 8192,
|
||||
"num_thread": 12,
|
||||
"num_batch": 512
|
||||
}
|
||||
```
|
||||
|
||||
3. Modifiez le fichier `C:\LLM_Lab\utils\ollama_api.py` pour qu'il vérifie l'emplacement des modèles.
|
||||
|
||||
## 10. Vérification de l'espace disque
|
||||
|
||||
Ajoutez cette fonction au moniteur système pour surveiller l'espace disque des modèles:
|
||||
|
||||
```python
|
||||
def check_models_disk_space():
|
||||
"""Vérifie l'espace disque pour les modèles Ollama"""
|
||||
models_dir = "D:\\OllamaModels" # Ajustez selon votre configuration
|
||||
|
||||
if os.path.exists(models_dir):
|
||||
try:
|
||||
total, used, free = shutil.disk_usage(models_dir)
|
||||
total_gb = total / (1024**3)
|
||||
used_gb = used / (1024**3)
|
||||
free_gb = free / (1024**3)
|
||||
|
||||
print(f"Disque des modèles: {models_dir}")
|
||||
print(f"Espace total: {total_gb:.1f} GB")
|
||||
print(f"Espace utilisé: {used_gb:.1f} GB")
|
||||
print(f"Espace libre: {free_gb:.1f} GB")
|
||||
except:
|
||||
print("Erreur lors de la vérification de l'espace disque")
|
||||
```
|
||||
|
||||
## Dépannage
|
||||
|
||||
### Les modèles ne sont pas stockés au bon endroit
|
||||
|
||||
1. Vérifiez que le service Ollama a bien les permissions d'accès au dossier D:\OllamaModels
|
||||
2. Vérifiez que le lien symbolique a bien été créé avec:
|
||||
```cmd
|
||||
dir /al "C:\Users\%USERNAME%\.ollama"
|
||||
```
|
||||
|
||||
### Erreurs lors du téléchargement des modèles
|
||||
|
||||
1. Arrêtez le service Ollama
|
||||
2. Vérifiez les logs dans `C:\Users\%USERNAME%\.ollama\logs`
|
||||
3. Assurez-vous que le disque cible a suffisamment d'espace libre
|
||||
4. Redémarrez le service
|
||||
|
||||
### Le service Ollama ne démarre pas
|
||||
|
||||
1. Vérifiez les services Windows (services.msc)
|
||||
2. Consultez les logs d'événements Windows
|
||||
3. Essayez de démarrer Ollama manuellement:
|
||||
```cmd
|
||||
"C:\Program Files\Ollama\ollama.exe" serve
|
||||
```
|
||||
|
||||
## Maintenance
|
||||
|
||||
### Mise à jour d'Ollama
|
||||
|
||||
Lors des mises à jour d'Ollama, votre configuration de stockage sur disque séparé sera préservée tant que vous ne supprimez pas manuellement le lien symbolique ou la variable d'environnement.
|
||||
|
||||
### Nettoyage des modèles
|
||||
|
||||
Pour libérer de l'espace, vous pouvez supprimer les modèles inutilisés:
|
||||
|
||||
```cmd
|
||||
ollama rm nom-du-modele
|
||||
```
|
||||
|
||||
Cela supprimera correctement le modèle de votre disque secondaire.
|
||||
@ -39,10 +39,10 @@ deactivate nondestructive
|
||||
if [ "${OSTYPE:-}" = "cygwin" ] || [ "${OSTYPE:-}" = "msys" ] ; then
|
||||
# transform D:\path\to\venv to /d/path/to/venv on MSYS
|
||||
# and to /cygdrive/d/path/to/venv on Cygwin
|
||||
export VIRTUAL_ENV=$(cygpath /home/fgras-ca/llm_lab-test/llmlab)
|
||||
export VIRTUAL_ENV=$(cygpath /home/fgras-ca/llm_lab/llmlab)
|
||||
else
|
||||
# use the path as-is
|
||||
export VIRTUAL_ENV=/home/fgras-ca/llm_lab-test/llmlab
|
||||
export VIRTUAL_ENV=/home/fgras-ca/llm_lab/llmlab
|
||||
fi
|
||||
|
||||
_OLD_VIRTUAL_PATH="$PATH"
|
||||
|
||||
@ -9,7 +9,7 @@ alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PA
|
||||
# Unset irrelevant variables.
|
||||
deactivate nondestructive
|
||||
|
||||
setenv VIRTUAL_ENV /home/fgras-ca/llm_lab-test/llmlab
|
||||
setenv VIRTUAL_ENV /home/fgras-ca/llm_lab/llmlab
|
||||
|
||||
set _OLD_VIRTUAL_PATH="$PATH"
|
||||
setenv PATH "$VIRTUAL_ENV/"bin":$PATH"
|
||||
|
||||
@ -33,7 +33,7 @@ end
|
||||
# Unset irrelevant variables.
|
||||
deactivate nondestructive
|
||||
|
||||
set -gx VIRTUAL_ENV /home/fgras-ca/llm_lab-test/llmlab
|
||||
set -gx VIRTUAL_ENV /home/fgras-ca/llm_lab/llmlab
|
||||
|
||||
set -gx _OLD_VIRTUAL_PATH $PATH
|
||||
set -gx PATH "$VIRTUAL_ENV/"bin $PATH
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#!/home/fgras-ca/llm_lab-test/llmlab/bin/python3
|
||||
#!/home/fgras-ca/llm_lab/llmlab/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#!/home/fgras-ca/llm_lab-test/llmlab/bin/python3
|
||||
#!/home/fgras-ca/llm_lab/llmlab/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#!/home/fgras-ca/llm_lab-test/llmlab/bin/python3
|
||||
#!/home/fgras-ca/llm_lab/llmlab/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#!/home/fgras-ca/llm_lab-test/llmlab/bin/python3
|
||||
#!/home/fgras-ca/llm_lab/llmlab/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
|
||||
@ -1,44 +0,0 @@
|
||||
Zope Public License (ZPL) Version 2.1
|
||||
|
||||
A copyright notice accompanies this license document that identifies the
|
||||
copyright holders.
|
||||
|
||||
This license has been certified as open source. It has also been designated as
|
||||
GPL compatible by the Free Software Foundation (FSF).
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions in source code must retain the accompanying copyright
|
||||
notice, this list of conditions, and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the accompanying copyright
|
||||
notice, this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Names of the copyright holders must not be used to endorse or promote
|
||||
products derived from this software without prior written permission from the
|
||||
copyright holders.
|
||||
|
||||
4. The right to distribute this software or to use it for any purpose does not
|
||||
give you the right to use Servicemarks (sm) or Trademarks (tm) of the
|
||||
copyright
|
||||
holders. Use of them is covered by separate agreement with the copyright
|
||||
holders.
|
||||
|
||||
5. If any files are modified, you must cause the modified files to carry
|
||||
prominent notices stating that you changed the files and the date of any
|
||||
change.
|
||||
|
||||
Disclaimer
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,22 +0,0 @@
|
||||
DateTime-5.5.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
DateTime-5.5.dist-info/LICENSE.txt,sha256=PmcdsR32h1FswdtbPWXkqjg-rKPCDOo_r1Og9zNdCjw,2070
|
||||
DateTime-5.5.dist-info/METADATA,sha256=W1k0PqPJ6SU6QTJAu40JPtHK8XeQRL0GGEpfVGPjWGI,33735
|
||||
DateTime-5.5.dist-info/RECORD,,
|
||||
DateTime-5.5.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
DateTime-5.5.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
||||
DateTime-5.5.dist-info/top_level.txt,sha256=iVdUvuV_RIkkMzsnPGNfwojRWvuonInryaK3hA5Hh0o,9
|
||||
DateTime/DateTime.py,sha256=65LbTcnrCSsDPGoGLVkk7NC3H8Kq-PjkC1fQVR33gE8,71364
|
||||
DateTime/DateTime.txt,sha256=KZFzxoQItLsar1ZDd2vZN74Y6L4a04H8jXMwqc8KjmY,22487
|
||||
DateTime/__init__.py,sha256=trlFzEmNkmUpxZT7krPSVDayDK1bRxToccg3CcCF8wg,714
|
||||
DateTime/__pycache__/DateTime.cpython-312.pyc,,
|
||||
DateTime/__pycache__/__init__.cpython-312.pyc,,
|
||||
DateTime/__pycache__/interfaces.cpython-312.pyc,,
|
||||
DateTime/__pycache__/pytz_support.cpython-312.pyc,,
|
||||
DateTime/interfaces.py,sha256=n47sexf1eQ6YMdYB_60PgHtSzYIj4FND-RmHFiNpm1E,12187
|
||||
DateTime/pytz.txt,sha256=9Phns9ESXs9MaOKxXztX6sJ09QczGxsbYoSRSllKUfk,5619
|
||||
DateTime/pytz_support.py,sha256=inR1SO0X17fp9C2GsRw99S_MhxKiEt5dOV3-TGsBxDI,11853
|
||||
DateTime/tests/__init__.py,sha256=H7Ixo1xp-8BlJ65u14hk5i_TKEmETyi2FmLMD6H-mpo,683
|
||||
DateTime/tests/__pycache__/__init__.cpython-312.pyc,,
|
||||
DateTime/tests/__pycache__/test_datetime.cpython-312.pyc,,
|
||||
DateTime/tests/julian_testdata.txt,sha256=qxvLvabVB9ayhh5UHBvPhuqW5mRL_lizzbUh6lc3d4I,1397
|
||||
DateTime/tests/test_datetime.py,sha256=dsrfAqQpz1od1bOVPvSYfZAlduJpJIpc2F_hdN7WRAU,30385
|
||||
@ -1,5 +0,0 @@
|
||||
Wheel-Version: 1.0
|
||||
Generator: bdist_wheel (0.42.0)
|
||||
Root-Is-Purelib: true
|
||||
Tag: py3-none-any
|
||||
|
||||
@ -1 +0,0 @@
|
||||
DateTime
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,785 +0,0 @@
|
||||
The DateTime package
|
||||
====================
|
||||
|
||||
Encapsulation of date/time values.
|
||||
|
||||
|
||||
Function Timezones()
|
||||
--------------------
|
||||
|
||||
Returns the list of recognized timezone names:
|
||||
|
||||
>>> from DateTime import Timezones
|
||||
>>> zones = set(Timezones())
|
||||
|
||||
Almost all of the standard pytz timezones are included, with the exception
|
||||
of some commonly-used but ambiguous abbreviations, where historical Zope
|
||||
usage conflicts with the name used by pytz:
|
||||
|
||||
>>> import pytz
|
||||
>>> [x for x in pytz.all_timezones if x not in zones]
|
||||
['CET', 'EET', 'EST', 'MET', 'MST', 'WET']
|
||||
|
||||
Class DateTime
|
||||
--------------
|
||||
|
||||
DateTime objects represent instants in time and provide interfaces for
|
||||
controlling its representation without affecting the absolute value of
|
||||
the object.
|
||||
|
||||
DateTime objects may be created from a wide variety of string or
|
||||
numeric data, or may be computed from other DateTime objects.
|
||||
DateTimes support the ability to convert their representations to many
|
||||
major timezones, as well as the ability to create a DateTime object
|
||||
in the context of a given timezone.
|
||||
|
||||
DateTime objects provide partial numerical behavior:
|
||||
|
||||
* Two date-time objects can be subtracted to obtain a time, in days
|
||||
between the two.
|
||||
|
||||
* A date-time object and a positive or negative number may be added to
|
||||
obtain a new date-time object that is the given number of days later
|
||||
than the input date-time object.
|
||||
|
||||
* A positive or negative number and a date-time object may be added to
|
||||
obtain a new date-time object that is the given number of days later
|
||||
than the input date-time object.
|
||||
|
||||
* A positive or negative number may be subtracted from a date-time
|
||||
object to obtain a new date-time object that is the given number of
|
||||
days earlier than the input date-time object.
|
||||
|
||||
DateTime objects may be converted to integer, long, or float numbers
|
||||
of days since January 1, 1901, using the standard int, long, and float
|
||||
functions (Compatibility Note: int, long and float return the number
|
||||
of days since 1901 in GMT rather than local machine timezone).
|
||||
DateTime objects also provide access to their value in a float format
|
||||
usable with the Python time module, provided that the value of the
|
||||
object falls in the range of the epoch-based time module.
|
||||
|
||||
A DateTime object should be considered immutable; all conversion and numeric
|
||||
operations return a new DateTime object rather than modify the current object.
|
||||
|
||||
A DateTime object always maintains its value as an absolute UTC time,
|
||||
and is represented in the context of some timezone based on the
|
||||
arguments used to create the object. A DateTime object's methods
|
||||
return values based on the timezone context.
|
||||
|
||||
Note that in all cases the local machine timezone is used for
|
||||
representation if no timezone is specified.
|
||||
|
||||
Constructor for DateTime
|
||||
------------------------
|
||||
|
||||
DateTime() returns a new date-time object. DateTimes may be created
|
||||
with from zero to seven arguments:
|
||||
|
||||
* If the function is called with no arguments, then the current date/
|
||||
time is returned, represented in the timezone of the local machine.
|
||||
|
||||
* If the function is invoked with a single string argument which is a
|
||||
recognized timezone name, an object representing the current time is
|
||||
returned, represented in the specified timezone.
|
||||
|
||||
* If the function is invoked with a single string argument
|
||||
representing a valid date/time, an object representing that date/
|
||||
time will be returned.
|
||||
|
||||
As a general rule, any date-time representation that is recognized
|
||||
and unambiguous to a resident of North America is acceptable. (The
|
||||
reason for this qualification is that in North America, a date like:
|
||||
2/1/1994 is interpreted as February 1, 1994, while in some parts of
|
||||
the world, it is interpreted as January 2, 1994.) A date/ time
|
||||
string consists of two components, a date component and an optional
|
||||
time component, separated by one or more spaces. If the time
|
||||
component is omitted, 12:00am is assumed.
|
||||
|
||||
Any recognized timezone name specified as the final element of the
|
||||
date/time string will be used for computing the date/time value.
|
||||
(If you create a DateTime with the string,
|
||||
"Mar 9, 1997 1:45pm US/Pacific", the value will essentially be the
|
||||
same as if you had captured time.time() at the specified date and
|
||||
time on a machine in that timezone). If no timezone is passed, then
|
||||
the timezone configured on the local machine will be used, **except**
|
||||
that if the date format matches ISO 8601 ('YYYY-MM-DD'), the instance
|
||||
will use UTC / GMT+0 as the timezone.
|
||||
|
||||
o Returns current date/time, represented in US/Eastern:
|
||||
|
||||
>>> from DateTime import DateTime
|
||||
>>> e = DateTime('US/Eastern')
|
||||
>>> e.timezone()
|
||||
'US/Eastern'
|
||||
|
||||
o Returns specified time, represented in local machine zone:
|
||||
|
||||
>>> x = DateTime('1997/3/9 1:45pm')
|
||||
>>> x.parts() # doctest: +ELLIPSIS
|
||||
(1997, 3, 9, 13, 45, ...)
|
||||
|
||||
o Specified time in local machine zone, verbose format:
|
||||
|
||||
>>> y = DateTime('Mar 9, 1997 13:45:00')
|
||||
>>> y.parts() # doctest: +ELLIPSIS
|
||||
(1997, 3, 9, 13, 45, ...)
|
||||
>>> y == x
|
||||
True
|
||||
|
||||
o Specified time in UTC via ISO 8601 rule:
|
||||
|
||||
>>> z = DateTime('2014-03-24')
|
||||
>>> z.parts() # doctest: +ELLIPSIS
|
||||
(2014, 3, 24, 0, 0, ...)
|
||||
>>> z.timezone()
|
||||
'GMT+0'
|
||||
|
||||
The date component consists of year, month, and day values. The
|
||||
year value must be a one-, two-, or four-digit integer. If a one-
|
||||
or two-digit year is used, the year is assumed to be in the
|
||||
twentieth century. The month may an integer, from 1 to 12, a month
|
||||
name, or a month abbreviation, where a period may optionally follow
|
||||
the abbreviation. The day must be an integer from 1 to the number of
|
||||
days in the month. The year, month, and day values may be separated
|
||||
by periods, hyphens, forward slashes, or spaces. Extra spaces are
|
||||
permitted around the delimiters. Year, month, and day values may be
|
||||
given in any order as long as it is possible to distinguish the
|
||||
components. If all three components are numbers that are less than
|
||||
13, then a month-day-year ordering is assumed.
|
||||
|
||||
The time component consists of hour, minute, and second values
|
||||
separated by colons. The hour value must be an integer between 0
|
||||
and 23 inclusively. The minute value must be an integer between 0
|
||||
and 59 inclusively. The second value may be an integer value
|
||||
between 0 and 59.999 inclusively. The second value or both the
|
||||
minute and second values may be omitted. The time may be followed
|
||||
by am or pm in upper or lower case, in which case a 12-hour clock is
|
||||
assumed.
|
||||
|
||||
* If the DateTime function is invoked with a single numeric argument,
|
||||
the number is assumed to be either a floating point value such as
|
||||
that returned by time.time(), or a number of days after January 1,
|
||||
1901 00:00:00 UTC.
|
||||
|
||||
A DateTime object is returned that represents either the GMT value
|
||||
of the time.time() float represented in the local machine's
|
||||
timezone, or that number of days after January 1, 1901. Note that
|
||||
the number of days after 1901 need to be expressed from the
|
||||
viewpoint of the local machine's timezone. A negative argument will
|
||||
yield a date-time value before 1901.
|
||||
|
||||
* If the function is invoked with two numeric arguments, then the
|
||||
first is taken to be an integer year and the second argument is
|
||||
taken to be an offset in days from the beginning of the year, in the
|
||||
context of the local machine timezone. The date-time value returned
|
||||
is the given offset number of days from the beginning of the given
|
||||
year, represented in the timezone of the local machine. The offset
|
||||
may be positive or negative. Two-digit years are assumed to be in
|
||||
the twentieth century.
|
||||
|
||||
* If the function is invoked with two arguments, the first a float
|
||||
representing a number of seconds past the epoch in GMT (such as
|
||||
those returned by time.time()) and the second a string naming a
|
||||
recognized timezone, a DateTime with a value of that GMT time will
|
||||
be returned, represented in the given timezone.
|
||||
|
||||
>>> import time
|
||||
>>> t = time.time()
|
||||
|
||||
Time t represented as US/Eastern:
|
||||
|
||||
>>> now_east = DateTime(t, 'US/Eastern')
|
||||
|
||||
Time t represented as US/Pacific:
|
||||
|
||||
>>> now_west = DateTime(t, 'US/Pacific')
|
||||
|
||||
Only their representations are different:
|
||||
|
||||
>>> now_east.equalTo(now_west)
|
||||
True
|
||||
|
||||
* If the function is invoked with three or more numeric arguments,
|
||||
then the first is taken to be an integer year, the second is taken
|
||||
to be an integer month, and the third is taken to be an integer day.
|
||||
If the combination of values is not valid, then a DateTimeError is
|
||||
raised. One- or two-digit years up to 69 are assumed to be in the
|
||||
21st century, whereas values 70-99 are assumed to be 20th century.
|
||||
The fourth, fifth, and sixth arguments are floating point, positive
|
||||
or negative offsets in units of hours, minutes, and days, and
|
||||
default to zero if not given. An optional string may be given as
|
||||
the final argument to indicate timezone (the effect of this is as if
|
||||
you had taken the value of time.time() at that time on a machine in
|
||||
the specified timezone).
|
||||
|
||||
If a string argument passed to the DateTime constructor cannot be
|
||||
parsed, it will raise SyntaxError. Invalid date, time, or
|
||||
timezone components will raise a DateTimeError.
|
||||
|
||||
The module function Timezones() will return a list of the timezones
|
||||
recognized by the DateTime module. Recognition of timezone names is
|
||||
case-insensitive.
|
||||
|
||||
Instance Methods for DateTime (IDateTime interface)
|
||||
---------------------------------------------------
|
||||
|
||||
Conversion and comparison methods
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* ``timeTime()`` returns the date/time as a floating-point number in
|
||||
UTC, in the format used by the Python time module. Note that it is
|
||||
possible to create date /time values with DateTime that have no
|
||||
meaningful value to the time module, and in such cases a
|
||||
DateTimeError is raised. A DateTime object's value must generally
|
||||
be between Jan 1, 1970 (or your local machine epoch) and Jan 2038 to
|
||||
produce a valid time.time() style value.
|
||||
|
||||
>>> dt = DateTime('Mar 9, 1997 13:45:00 US/Eastern')
|
||||
>>> dt.timeTime()
|
||||
857933100.0
|
||||
|
||||
>>> DateTime('2040/01/01 UTC').timeTime()
|
||||
2208988800.0
|
||||
|
||||
>>> DateTime('1900/01/01 UTC').timeTime()
|
||||
-2208988800.0
|
||||
|
||||
* ``toZone(z)`` returns a DateTime with the value as the current
|
||||
object, represented in the indicated timezone:
|
||||
|
||||
>>> dt.toZone('UTC')
|
||||
DateTime('1997/03/09 18:45:00 UTC')
|
||||
|
||||
>>> dt.toZone('UTC').equalTo(dt)
|
||||
True
|
||||
|
||||
* ``isFuture()`` returns true if this object represents a date/time
|
||||
later than the time of the call:
|
||||
|
||||
>>> dt.isFuture()
|
||||
False
|
||||
>>> DateTime('Jan 1 3000').isFuture() # not time-machine safe!
|
||||
True
|
||||
|
||||
* ``isPast()`` returns true if this object represents a date/time
|
||||
earlier than the time of the call:
|
||||
|
||||
>>> dt.isPast()
|
||||
True
|
||||
>>> DateTime('Jan 1 3000').isPast() # not time-machine safe!
|
||||
False
|
||||
|
||||
* ``isCurrentYear()`` returns true if this object represents a
|
||||
date/time that falls within the current year, in the context of this
|
||||
object's timezone representation:
|
||||
|
||||
>>> dt.isCurrentYear()
|
||||
False
|
||||
>>> DateTime().isCurrentYear()
|
||||
True
|
||||
|
||||
* ``isCurrentMonth()`` returns true if this object represents a
|
||||
date/time that falls within the current month, in the context of
|
||||
this object's timezone representation:
|
||||
|
||||
>>> dt.isCurrentMonth()
|
||||
False
|
||||
>>> DateTime().isCurrentMonth()
|
||||
True
|
||||
|
||||
* ``isCurrentDay()`` returns true if this object represents a
|
||||
date/time that falls within the current day, in the context of this
|
||||
object's timezone representation:
|
||||
|
||||
>>> dt.isCurrentDay()
|
||||
False
|
||||
>>> DateTime().isCurrentDay()
|
||||
True
|
||||
|
||||
* ``isCurrentHour()`` returns true if this object represents a
|
||||
date/time that falls within the current hour, in the context of this
|
||||
object's timezone representation:
|
||||
|
||||
>>> dt.isCurrentHour()
|
||||
False
|
||||
|
||||
>>> DateTime().isCurrentHour()
|
||||
True
|
||||
|
||||
* ``isCurrentMinute()`` returns true if this object represents a
|
||||
date/time that falls within the current minute, in the context of
|
||||
this object's timezone representation:
|
||||
|
||||
>>> dt.isCurrentMinute()
|
||||
False
|
||||
>>> DateTime().isCurrentMinute()
|
||||
True
|
||||
|
||||
* ``isLeapYear()`` returns true if the current year (in the context of
|
||||
the object's timezone) is a leap year:
|
||||
|
||||
>>> dt.isLeapYear()
|
||||
False
|
||||
>>> DateTime('Mar 8 2004').isLeapYear()
|
||||
True
|
||||
|
||||
* ``earliestTime()`` returns a new DateTime object that represents the
|
||||
earliest possible time (in whole seconds) that still falls within
|
||||
the current object's day, in the object's timezone context:
|
||||
|
||||
>>> dt.earliestTime()
|
||||
DateTime('1997/03/09 00:00:00 US/Eastern')
|
||||
|
||||
* ``latestTime()`` return a new DateTime object that represents the
|
||||
latest possible time (in whole seconds) that still falls within the
|
||||
current object's day, in the object's timezone context
|
||||
|
||||
>>> dt.latestTime()
|
||||
DateTime('1997/03/09 23:59:59 US/Eastern')
|
||||
|
||||
Component access
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
* ``parts()`` returns a tuple containing the calendar year, month,
|
||||
day, hour, minute second and timezone of the object
|
||||
|
||||
>>> dt.parts() # doctest: +ELLIPSIS
|
||||
(1997, 3, 9, 13, 45, ... 'US/Eastern')
|
||||
|
||||
* ``timezone()`` returns the timezone in which the object is represented:
|
||||
|
||||
>>> dt.timezone() in Timezones()
|
||||
True
|
||||
|
||||
* ``tzoffset()`` returns the timezone offset for the objects timezone:
|
||||
|
||||
>>> dt.tzoffset()
|
||||
-18000
|
||||
|
||||
* ``year()`` returns the calendar year of the object:
|
||||
|
||||
>>> dt.year()
|
||||
1997
|
||||
|
||||
* ``month()`` returns the month of the object as an integer:
|
||||
|
||||
>>> dt.month()
|
||||
3
|
||||
|
||||
* ``Month()`` returns the full month name:
|
||||
|
||||
>>> dt.Month()
|
||||
'March'
|
||||
|
||||
* ``aMonth()`` returns the abbreviated month name:
|
||||
|
||||
>>> dt.aMonth()
|
||||
'Mar'
|
||||
|
||||
* ``pMonth()`` returns the abbreviated (with period) month name:
|
||||
|
||||
>>> dt.pMonth()
|
||||
'Mar.'
|
||||
|
||||
* ``day()`` returns the integer day:
|
||||
|
||||
>>> dt.day()
|
||||
9
|
||||
|
||||
* ``Day()`` returns the full name of the day of the week:
|
||||
|
||||
>>> dt.Day()
|
||||
'Sunday'
|
||||
|
||||
* ``dayOfYear()`` returns the day of the year, in context of the
|
||||
timezone representation of the object:
|
||||
|
||||
>>> dt.dayOfYear()
|
||||
68
|
||||
|
||||
* ``aDay()`` returns the abbreviated name of the day of the week:
|
||||
|
||||
>>> dt.aDay()
|
||||
'Sun'
|
||||
|
||||
* ``pDay()`` returns the abbreviated (with period) name of the day of
|
||||
the week:
|
||||
|
||||
>>> dt.pDay()
|
||||
'Sun.'
|
||||
|
||||
* ``dow()`` returns the integer day of the week, where Sunday is 0:
|
||||
|
||||
>>> dt.dow()
|
||||
0
|
||||
|
||||
* ``dow_1()`` returns the integer day of the week, where sunday is 1:
|
||||
|
||||
>>> dt.dow_1()
|
||||
1
|
||||
|
||||
* ``h_12()`` returns the 12-hour clock representation of the hour:
|
||||
|
||||
>>> dt.h_12()
|
||||
1
|
||||
|
||||
* ``h_24()`` returns the 24-hour clock representation of the hour:
|
||||
|
||||
>>> dt.h_24()
|
||||
13
|
||||
|
||||
* ``ampm()`` returns the appropriate time modifier (am or pm):
|
||||
|
||||
>>> dt.ampm()
|
||||
'pm'
|
||||
|
||||
* ``hour()`` returns the 24-hour clock representation of the hour:
|
||||
|
||||
>>> dt.hour()
|
||||
13
|
||||
|
||||
* ``minute()`` returns the minute:
|
||||
|
||||
>>> dt.minute()
|
||||
45
|
||||
|
||||
* ``second()`` returns the second:
|
||||
|
||||
>>> dt.second() == 0
|
||||
True
|
||||
|
||||
* ``millis()`` returns the milliseconds since the epoch in GMT.
|
||||
|
||||
>>> dt.millis() == 857933100000
|
||||
True
|
||||
|
||||
strftime()
|
||||
~~~~~~~~~~
|
||||
|
||||
See ``tests/test_datetime.py``.
|
||||
|
||||
General formats from previous DateTime
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* ``Date()`` return the date string for the object:
|
||||
|
||||
>>> dt.Date()
|
||||
'1997/03/09'
|
||||
|
||||
* ``Time()`` returns the time string for an object to the nearest
|
||||
second:
|
||||
|
||||
>>> dt.Time()
|
||||
'13:45:00'
|
||||
|
||||
* ``TimeMinutes()`` returns the time string for an object not showing
|
||||
seconds:
|
||||
|
||||
>>> dt.TimeMinutes()
|
||||
'13:45'
|
||||
|
||||
* ``AMPM()`` returns the time string for an object to the nearest second:
|
||||
|
||||
>>> dt.AMPM()
|
||||
'01:45:00 pm'
|
||||
|
||||
* ``AMPMMinutes()`` returns the time string for an object not showing
|
||||
seconds:
|
||||
|
||||
>>> dt.AMPMMinutes()
|
||||
'01:45 pm'
|
||||
|
||||
* ``PreciseTime()`` returns the time string for the object:
|
||||
|
||||
>>> dt.PreciseTime()
|
||||
'13:45:00.000'
|
||||
|
||||
* ``PreciseAMPM()`` returns the time string for the object:
|
||||
|
||||
>>> dt.PreciseAMPM()
|
||||
'01:45:00.000 pm'
|
||||
|
||||
* ``yy()`` returns the calendar year as a 2 digit string
|
||||
|
||||
>>> dt.yy()
|
||||
'97'
|
||||
|
||||
* ``mm()`` returns the month as a 2 digit string
|
||||
|
||||
>>> dt.mm()
|
||||
'03'
|
||||
|
||||
* ``dd()`` returns the day as a 2 digit string:
|
||||
|
||||
>>> dt.dd()
|
||||
'09'
|
||||
|
||||
* ``rfc822()`` returns the date in RFC 822 format:
|
||||
|
||||
>>> dt.rfc822()
|
||||
'Sun, 09 Mar 1997 13:45:00 -0500'
|
||||
|
||||
New formats
|
||||
~~~~~~~~~~~
|
||||
|
||||
* ``fCommon()`` returns a string representing the object's value in
|
||||
the format: March 9, 1997 1:45 pm:
|
||||
|
||||
>>> dt.fCommon()
|
||||
'March 9, 1997 1:45 pm'
|
||||
|
||||
* ``fCommonZ()`` returns a string representing the object's value in
|
||||
the format: March 9, 1997 1:45 pm US/Eastern:
|
||||
|
||||
>>> dt.fCommonZ()
|
||||
'March 9, 1997 1:45 pm US/Eastern'
|
||||
|
||||
* ``aCommon()`` returns a string representing the object's value in
|
||||
the format: Mar 9, 1997 1:45 pm:
|
||||
|
||||
>>> dt.aCommon()
|
||||
'Mar 9, 1997 1:45 pm'
|
||||
|
||||
* ``aCommonZ()`` return a string representing the object's value in
|
||||
the format: Mar 9, 1997 1:45 pm US/Eastern:
|
||||
|
||||
>>> dt.aCommonZ()
|
||||
'Mar 9, 1997 1:45 pm US/Eastern'
|
||||
|
||||
* ``pCommon()`` returns a string representing the object's value in
|
||||
the format Mar. 9, 1997 1:45 pm:
|
||||
|
||||
>>> dt.pCommon()
|
||||
'Mar. 9, 1997 1:45 pm'
|
||||
|
||||
* ``pCommonZ()`` returns a string representing the object's value in
|
||||
the format: Mar. 9, 1997 1:45 pm US/Eastern:
|
||||
|
||||
>>> dt.pCommonZ()
|
||||
'Mar. 9, 1997 1:45 pm US/Eastern'
|
||||
|
||||
* ``ISO()`` returns a string with the date/time in ISO format. Note:
|
||||
this is not ISO 8601-format! See the ISO8601 and HTML4 methods below
|
||||
for ISO 8601-compliant output. Dates are output as: YYYY-MM-DD HH:MM:SS
|
||||
|
||||
>>> dt.ISO()
|
||||
'1997-03-09 13:45:00'
|
||||
|
||||
* ``ISO8601()`` returns the object in ISO 8601-compatible format
|
||||
containing the date, time with seconds-precision and the time zone
|
||||
identifier - see http://www.w3.org/TR/NOTE-datetime. Dates are
|
||||
output as: YYYY-MM-DDTHH:MM:SSTZD (T is a literal character, TZD is
|
||||
Time Zone Designator, format +HH:MM or -HH:MM).
|
||||
|
||||
The ``HTML4()`` method below offers the same formatting, but
|
||||
converts to UTC before returning the value and sets the TZD"Z"
|
||||
|
||||
>>> dt.ISO8601()
|
||||
'1997-03-09T13:45:00-05:00'
|
||||
|
||||
|
||||
* ``HTML4()`` returns the object in the format used in the HTML4.0
|
||||
specification, one of the standard forms in ISO8601. See
|
||||
http://www.w3.org/TR/NOTE-datetime. Dates are output as:
|
||||
YYYY-MM-DDTHH:MM:SSZ (T, Z are literal characters, the time is in
|
||||
UTC.):
|
||||
|
||||
>>> dt.HTML4()
|
||||
'1997-03-09T18:45:00Z'
|
||||
|
||||
* ``JulianDay()`` returns the Julian day according to
|
||||
http://www.tondering.dk/claus/cal/node3.html#sec-calcjd
|
||||
|
||||
>>> dt.JulianDay()
|
||||
2450517
|
||||
|
||||
* ``week()`` returns the week number according to ISO
|
||||
see http://www.tondering.dk/claus/cal/node6.html#SECTION00670000000000000000
|
||||
|
||||
>>> dt.week()
|
||||
10
|
||||
|
||||
Deprecated API
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
* DayOfWeek(): see Day()
|
||||
|
||||
* Day_(): see pDay()
|
||||
|
||||
* Mon(): see aMonth()
|
||||
|
||||
* Mon_(): see pMonth
|
||||
|
||||
General Services Provided by DateTime
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
DateTimes can be repr()'ed; the result will be a string indicating how
|
||||
to make a DateTime object like this:
|
||||
|
||||
>>> repr(dt)
|
||||
"DateTime('1997/03/09 13:45:00 US/Eastern')"
|
||||
|
||||
When we convert them into a string, we get a nicer string that could
|
||||
actually be shown to a user:
|
||||
|
||||
>>> str(dt)
|
||||
'1997/03/09 13:45:00 US/Eastern'
|
||||
|
||||
The hash value of a DateTime is based on the date and time and is
|
||||
equal for different representations of the DateTime:
|
||||
|
||||
>>> hash(dt)
|
||||
3618678
|
||||
>>> hash(dt.toZone('UTC'))
|
||||
3618678
|
||||
|
||||
DateTime objects can be compared to other DateTime objects OR floating
|
||||
point numbers such as the ones which are returned by the Python time
|
||||
module by using the equalTo method. Using this API, True is returned if the
|
||||
object represents a date/time equal to the specified DateTime or time module
|
||||
style time:
|
||||
|
||||
>>> dt.equalTo(dt)
|
||||
True
|
||||
>>> dt.equalTo(dt.toZone('UTC'))
|
||||
True
|
||||
>>> dt.equalTo(dt.timeTime())
|
||||
True
|
||||
>>> dt.equalTo(DateTime())
|
||||
False
|
||||
|
||||
Same goes for inequalities:
|
||||
|
||||
>>> dt.notEqualTo(dt)
|
||||
False
|
||||
>>> dt.notEqualTo(dt.toZone('UTC'))
|
||||
False
|
||||
>>> dt.notEqualTo(dt.timeTime())
|
||||
False
|
||||
>>> dt.notEqualTo(DateTime())
|
||||
True
|
||||
|
||||
Normal equality operations only work with DateTime objects and take the
|
||||
timezone setting into account:
|
||||
|
||||
>>> dt == dt
|
||||
True
|
||||
>>> dt == dt.toZone('UTC')
|
||||
False
|
||||
>>> dt == DateTime()
|
||||
False
|
||||
|
||||
>>> dt != dt
|
||||
False
|
||||
>>> dt != dt.toZone('UTC')
|
||||
True
|
||||
>>> dt != DateTime()
|
||||
True
|
||||
|
||||
But the other comparison operations compare the referenced moment in time and
|
||||
not the representation itself:
|
||||
|
||||
>>> dt > dt
|
||||
False
|
||||
>>> DateTime() > dt
|
||||
True
|
||||
>>> dt > DateTime().timeTime()
|
||||
False
|
||||
>>> DateTime().timeTime() > dt
|
||||
True
|
||||
|
||||
>>> dt.greaterThan(dt)
|
||||
False
|
||||
>>> DateTime().greaterThan(dt)
|
||||
True
|
||||
>>> dt.greaterThan(DateTime().timeTime())
|
||||
False
|
||||
|
||||
>>> dt >= dt
|
||||
True
|
||||
>>> DateTime() >= dt
|
||||
True
|
||||
>>> dt >= DateTime().timeTime()
|
||||
False
|
||||
>>> DateTime().timeTime() >= dt
|
||||
True
|
||||
|
||||
>>> dt.greaterThanEqualTo(dt)
|
||||
True
|
||||
>>> DateTime().greaterThanEqualTo(dt)
|
||||
True
|
||||
>>> dt.greaterThanEqualTo(DateTime().timeTime())
|
||||
False
|
||||
|
||||
>>> dt < dt
|
||||
False
|
||||
>>> DateTime() < dt
|
||||
False
|
||||
>>> dt < DateTime().timeTime()
|
||||
True
|
||||
>>> DateTime().timeTime() < dt
|
||||
False
|
||||
|
||||
>>> dt.lessThan(dt)
|
||||
False
|
||||
>>> DateTime().lessThan(dt)
|
||||
False
|
||||
>>> dt.lessThan(DateTime().timeTime())
|
||||
True
|
||||
|
||||
>>> dt <= dt
|
||||
True
|
||||
>>> DateTime() <= dt
|
||||
False
|
||||
>>> dt <= DateTime().timeTime()
|
||||
True
|
||||
>>> DateTime().timeTime() <= dt
|
||||
False
|
||||
|
||||
>>> dt.lessThanEqualTo(dt)
|
||||
True
|
||||
>>> DateTime().lessThanEqualTo(dt)
|
||||
False
|
||||
>>> dt.lessThanEqualTo(DateTime().timeTime())
|
||||
True
|
||||
|
||||
Numeric Services Provided by DateTime
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A DateTime may be added to a number and a number may be added to a
|
||||
DateTime:
|
||||
|
||||
>>> dt + 5
|
||||
DateTime('1997/03/14 13:45:00 US/Eastern')
|
||||
>>> 5 + dt
|
||||
DateTime('1997/03/14 13:45:00 US/Eastern')
|
||||
|
||||
Two DateTimes cannot be added:
|
||||
|
||||
>>> from DateTime.interfaces import DateTimeError
|
||||
>>> try:
|
||||
... dt + dt
|
||||
... print('fail')
|
||||
... except DateTimeError:
|
||||
... print('ok')
|
||||
ok
|
||||
|
||||
Either a DateTime or a number may be subtracted from a DateTime,
|
||||
however, a DateTime may not be subtracted from a number:
|
||||
|
||||
>>> DateTime('1997/03/10 13:45 US/Eastern') - dt
|
||||
1.0
|
||||
>>> dt - 1
|
||||
DateTime('1997/03/08 13:45:00 US/Eastern')
|
||||
>>> 1 - dt
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
TypeError: unsupported operand type(s) for -: 'int' and 'DateTime'
|
||||
|
||||
DateTimes can also be converted to integers (number of seconds since
|
||||
the epoch) and floats:
|
||||
|
||||
>>> int(dt)
|
||||
857933100
|
||||
>>> float(dt)
|
||||
857933100.0
|
||||
@ -1,18 +0,0 @@
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2002 Zope Foundation and Contributors.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from .DateTime import DateTime
|
||||
from .DateTime import Timezones
|
||||
|
||||
|
||||
__all__ = ('DateTime', 'Timezones')
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,375 +0,0 @@
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2005 Zope Foundation and Contributors.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE
|
||||
#
|
||||
##############################################################################
|
||||
from zope.interface import Interface
|
||||
|
||||
|
||||
class DateTimeError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class SyntaxError(DateTimeError):
|
||||
pass
|
||||
|
||||
|
||||
class DateError(DateTimeError):
|
||||
pass
|
||||
|
||||
|
||||
class TimeError(DateTimeError):
|
||||
pass
|
||||
|
||||
|
||||
class IDateTime(Interface):
|
||||
# Conversion and comparison methods
|
||||
|
||||
def localZone(ltm=None):
|
||||
"""Returns the time zone on the given date. The time zone
|
||||
can change according to daylight savings."""
|
||||
|
||||
def timeTime():
|
||||
"""Return the date/time as a floating-point number in UTC, in
|
||||
the format used by the Python time module. Note that it is
|
||||
possible to create date/time values with DateTime that have no
|
||||
meaningful value to the time module."""
|
||||
|
||||
def toZone(z):
|
||||
"""Return a DateTime with the value as the current object,
|
||||
represented in the indicated timezone."""
|
||||
|
||||
def isFuture():
|
||||
"""Return true if this object represents a date/time later
|
||||
than the time of the call"""
|
||||
|
||||
def isPast():
|
||||
"""Return true if this object represents a date/time earlier
|
||||
than the time of the call"""
|
||||
|
||||
def isCurrentYear():
|
||||
"""Return true if this object represents a date/time that
|
||||
falls within the current year, in the context of this
|
||||
object's timezone representation"""
|
||||
|
||||
def isCurrentMonth():
|
||||
"""Return true if this object represents a date/time that
|
||||
falls within the current month, in the context of this
|
||||
object's timezone representation"""
|
||||
|
||||
def isCurrentDay():
|
||||
"""Return true if this object represents a date/time that
|
||||
falls within the current day, in the context of this object's
|
||||
timezone representation"""
|
||||
|
||||
def isCurrentHour():
|
||||
"""Return true if this object represents a date/time that
|
||||
falls within the current hour, in the context of this object's
|
||||
timezone representation"""
|
||||
|
||||
def isCurrentMinute():
|
||||
"""Return true if this object represents a date/time that
|
||||
falls within the current minute, in the context of this
|
||||
object's timezone representation"""
|
||||
|
||||
def isLeapYear():
|
||||
"""Return true if the current year (in the context of the
|
||||
object's timezone) is a leap year"""
|
||||
|
||||
def earliestTime():
|
||||
"""Return a new DateTime object that represents the earliest
|
||||
possible time (in whole seconds) that still falls within the
|
||||
current object's day, in the object's timezone context"""
|
||||
|
||||
def latestTime():
|
||||
"""Return a new DateTime object that represents the latest
|
||||
possible time (in whole seconds) that still falls within the
|
||||
current object's day, in the object's timezone context"""
|
||||
|
||||
def greaterThan(t):
|
||||
"""Compare this DateTime object to another DateTime object OR
|
||||
a floating point number such as that which is returned by the
|
||||
Python time module. Returns true if the object represents a
|
||||
date/time greater than the specified DateTime or time module
|
||||
style time. Revised to give more correct results through
|
||||
comparison of long integer milliseconds."""
|
||||
|
||||
__gt__ = greaterThan
|
||||
|
||||
def greaterThanEqualTo(t):
|
||||
"""Compare this DateTime object to another DateTime object OR
|
||||
a floating point number such as that which is returned by the
|
||||
Python time module. Returns true if the object represents a
|
||||
date/time greater than or equal to the specified DateTime or
|
||||
time module style time. Revised to give more correct results
|
||||
through comparison of long integer milliseconds."""
|
||||
|
||||
__ge__ = greaterThanEqualTo
|
||||
|
||||
def equalTo(t):
|
||||
"""Compare this DateTime object to another DateTime object OR
|
||||
a floating point number such as that which is returned by the
|
||||
Python time module. Returns true if the object represents a
|
||||
date/time equal to the specified DateTime or time module style
|
||||
time. Revised to give more correct results through comparison
|
||||
of long integer milliseconds."""
|
||||
|
||||
__eq__ = equalTo
|
||||
|
||||
def notEqualTo(t):
|
||||
"""Compare this DateTime object to another DateTime object OR
|
||||
a floating point number such as that which is returned by the
|
||||
Python time module. Returns true if the object represents a
|
||||
date/time not equal to the specified DateTime or time module
|
||||
style time. Revised to give more correct results through
|
||||
comparison of long integer milliseconds."""
|
||||
|
||||
__ne__ = notEqualTo
|
||||
|
||||
def lessThan(t):
|
||||
"""Compare this DateTime object to another DateTime object OR
|
||||
a floating point number such as that which is returned by the
|
||||
Python time module. Returns true if the object represents a
|
||||
date/time less than the specified DateTime or time module
|
||||
style time. Revised to give more correct results through
|
||||
comparison of long integer milliseconds."""
|
||||
|
||||
__lt__ = lessThan
|
||||
|
||||
def lessThanEqualTo(t):
|
||||
"""Compare this DateTime object to another DateTime object OR
|
||||
a floating point number such as that which is returned by the
|
||||
Python time module. Returns true if the object represents a
|
||||
date/time less than or equal to the specified DateTime or time
|
||||
module style time. Revised to give more correct results
|
||||
through comparison of long integer milliseconds."""
|
||||
|
||||
__le__ = lessThanEqualTo
|
||||
|
||||
# Component access
|
||||
|
||||
def parts():
|
||||
"""Return a tuple containing the calendar year, month, day,
|
||||
hour, minute second and timezone of the object"""
|
||||
|
||||
def timezone():
|
||||
"""Return the timezone in which the object is represented."""
|
||||
|
||||
def tzoffset():
|
||||
"""Return the timezone offset for the objects timezone."""
|
||||
|
||||
def year():
|
||||
"""Return the calendar year of the object"""
|
||||
|
||||
def month():
|
||||
"""Return the month of the object as an integer"""
|
||||
|
||||
def Month():
|
||||
"""Return the full month name"""
|
||||
|
||||
def aMonth():
|
||||
"""Return the abbreviated month name."""
|
||||
|
||||
def Mon():
|
||||
"""Compatibility: see aMonth"""
|
||||
|
||||
def pMonth():
|
||||
"""Return the abbreviated (with period) month name."""
|
||||
|
||||
def Mon_():
|
||||
"""Compatibility: see pMonth"""
|
||||
|
||||
def day():
|
||||
"""Return the integer day"""
|
||||
|
||||
def Day():
|
||||
"""Return the full name of the day of the week"""
|
||||
|
||||
def DayOfWeek():
|
||||
"""Compatibility: see Day"""
|
||||
|
||||
def dayOfYear():
|
||||
"""Return the day of the year, in context of the timezone
|
||||
representation of the object"""
|
||||
|
||||
def aDay():
|
||||
"""Return the abbreviated name of the day of the week"""
|
||||
|
||||
def pDay():
|
||||
"""Return the abbreviated (with period) name of the day of the
|
||||
week"""
|
||||
|
||||
def Day_():
|
||||
"""Compatibility: see pDay"""
|
||||
|
||||
def dow():
|
||||
"""Return the integer day of the week, where sunday is 0"""
|
||||
|
||||
def dow_1():
|
||||
"""Return the integer day of the week, where sunday is 1"""
|
||||
|
||||
def h_12():
|
||||
"""Return the 12-hour clock representation of the hour"""
|
||||
|
||||
def h_24():
|
||||
"""Return the 24-hour clock representation of the hour"""
|
||||
|
||||
def ampm():
|
||||
"""Return the appropriate time modifier (am or pm)"""
|
||||
|
||||
def hour():
|
||||
"""Return the 24-hour clock representation of the hour"""
|
||||
|
||||
def minute():
|
||||
"""Return the minute"""
|
||||
|
||||
def second():
|
||||
"""Return the second"""
|
||||
|
||||
def millis():
|
||||
"""Return the millisecond since the epoch in GMT."""
|
||||
|
||||
def strftime(format):
|
||||
"""Format the date/time using the *current timezone representation*."""
|
||||
|
||||
# General formats from previous DateTime
|
||||
|
||||
def Date():
|
||||
"""Return the date string for the object."""
|
||||
|
||||
def Time():
|
||||
"""Return the time string for an object to the nearest second."""
|
||||
|
||||
def TimeMinutes():
|
||||
"""Return the time string for an object not showing seconds."""
|
||||
|
||||
def AMPM():
|
||||
"""Return the time string for an object to the nearest second."""
|
||||
|
||||
def AMPMMinutes():
|
||||
"""Return the time string for an object not showing seconds."""
|
||||
|
||||
def PreciseTime():
|
||||
"""Return the time string for the object."""
|
||||
|
||||
def PreciseAMPM():
|
||||
"""Return the time string for the object."""
|
||||
|
||||
def yy():
|
||||
"""Return calendar year as a 2 digit string"""
|
||||
|
||||
def mm():
|
||||
"""Return month as a 2 digit string"""
|
||||
|
||||
def dd():
|
||||
"""Return day as a 2 digit string"""
|
||||
|
||||
def rfc822():
|
||||
"""Return the date in RFC 822 format"""
|
||||
|
||||
# New formats
|
||||
|
||||
def fCommon():
|
||||
"""Return a string representing the object's value in the
|
||||
format: March 1, 1997 1:45 pm"""
|
||||
|
||||
def fCommonZ():
|
||||
"""Return a string representing the object's value in the
|
||||
format: March 1, 1997 1:45 pm US/Eastern"""
|
||||
|
||||
def aCommon():
|
||||
"""Return a string representing the object's value in the
|
||||
format: Mar 1, 1997 1:45 pm"""
|
||||
|
||||
def aCommonZ():
|
||||
"""Return a string representing the object's value in the
|
||||
format: Mar 1, 1997 1:45 pm US/Eastern"""
|
||||
|
||||
def pCommon():
|
||||
"""Return a string representing the object's value in the
|
||||
format: Mar. 1, 1997 1:45 pm"""
|
||||
|
||||
def pCommonZ():
|
||||
"""Return a string representing the object's value
|
||||
in the format: Mar. 1, 1997 1:45 pm US/Eastern"""
|
||||
|
||||
def ISO():
|
||||
"""Return the object in ISO standard format. Note: this is
|
||||
*not* ISO 8601-format! See the ISO8601 and HTML4 methods below
|
||||
for ISO 8601-compliant output
|
||||
|
||||
Dates are output as: YYYY-MM-DD HH:MM:SS
|
||||
"""
|
||||
|
||||
def ISO8601():
|
||||
"""Return the object in ISO 8601-compatible format containing
|
||||
the date, time with seconds-precision and the time zone
|
||||
identifier - see http://www.w3.org/TR/NOTE-datetime
|
||||
|
||||
Dates are output as: YYYY-MM-DDTHH:MM:SSTZD
|
||||
T is a literal character.
|
||||
TZD is Time Zone Designator, format +HH:MM or -HH:MM
|
||||
|
||||
The HTML4 method below offers the same formatting, but
|
||||
converts to UTC before returning the value and sets the TZD"Z"
|
||||
"""
|
||||
|
||||
def HTML4():
|
||||
"""Return the object in the format used in the HTML4.0
|
||||
specification, one of the standard forms in ISO8601. See
|
||||
http://www.w3.org/TR/NOTE-datetime
|
||||
|
||||
Dates are output as: YYYY-MM-DDTHH:MM:SSZ
|
||||
T, Z are literal characters.
|
||||
The time is in UTC.
|
||||
"""
|
||||
|
||||
def JulianDay():
|
||||
"""Return the Julian day according to
|
||||
https://www.tondering.dk/claus/cal/julperiod.php#formula
|
||||
"""
|
||||
|
||||
def week():
|
||||
"""Return the week number according to ISO.
|
||||
|
||||
See https://www.tondering.dk/claus/cal/week.php#weekno
|
||||
"""
|
||||
|
||||
# Python operator and conversion API
|
||||
|
||||
def __add__(other):
|
||||
"""A DateTime may be added to a number and a number may be
|
||||
added to a DateTime; two DateTimes cannot be added."""
|
||||
|
||||
__radd__ = __add__
|
||||
|
||||
def __sub__(other):
|
||||
"""Either a DateTime or a number may be subtracted from a
|
||||
DateTime, however, a DateTime may not be subtracted from a
|
||||
number."""
|
||||
|
||||
def __repr__():
|
||||
"""Convert a DateTime to a string that looks like a Python
|
||||
expression."""
|
||||
|
||||
def __str__():
|
||||
"""Convert a DateTime to a string."""
|
||||
|
||||
def __hash__():
|
||||
"""Compute a hash value for a DateTime"""
|
||||
|
||||
def __int__():
|
||||
"""Convert to an integer number of seconds since the epoch (gmt)"""
|
||||
|
||||
def __long__():
|
||||
"""Convert to a long-int number of seconds since the epoch (gmt)"""
|
||||
|
||||
def __float__():
|
||||
"""Convert to floating-point number of seconds since the epoch (gmt)"""
|
||||
@ -1,192 +0,0 @@
|
||||
Pytz Support
|
||||
============
|
||||
|
||||
Allows the pytz package to be used for time zone information. The
|
||||
advantage of using pytz is that it has a more complete and up to date
|
||||
time zone and daylight savings time database.
|
||||
|
||||
Usage
|
||||
-----
|
||||
You don't have to do anything special to make it work.
|
||||
|
||||
>>> from DateTime import DateTime, Timezones
|
||||
>>> d = DateTime('March 11, 2007 US/Eastern')
|
||||
|
||||
Daylight Savings
|
||||
----------------
|
||||
In 2007 daylight savings time in the US was changed. The Energy Policy
|
||||
Act of 2005 mandates that DST will start on the second Sunday in March
|
||||
and end on the first Sunday in November.
|
||||
|
||||
In 2007, the start and stop dates are March 11 and November 4,
|
||||
respectively. These dates are different from previous DST start and
|
||||
stop dates. In 2006, the dates were the first Sunday in April (April
|
||||
2, 2006) and the last Sunday in October (October 29, 2006).
|
||||
|
||||
Let's make sure that DateTime can deal with this, since the primary
|
||||
motivation to use pytz for time zone information is the fact that it
|
||||
is kept up to date with daylight savings changes.
|
||||
|
||||
>>> DateTime('March 11, 2007 US/Eastern').tzoffset()
|
||||
-18000
|
||||
>>> DateTime('March 12, 2007 US/Eastern').tzoffset()
|
||||
-14400
|
||||
>>> DateTime('November 4, 2007 US/Eastern').tzoffset()
|
||||
-14400
|
||||
>>> DateTime('November 5, 2007 US/Eastern').tzoffset()
|
||||
-18000
|
||||
|
||||
Let's compare this to 2006.
|
||||
|
||||
>>> DateTime('April 2, 2006 US/Eastern').tzoffset()
|
||||
-18000
|
||||
>>> DateTime('April 3, 2006 US/Eastern').tzoffset()
|
||||
-14400
|
||||
>>> DateTime('October 29, 2006 US/Eastern').tzoffset()
|
||||
-14400
|
||||
>>> DateTime('October 30, 2006 US/Eastern').tzoffset()
|
||||
-18000
|
||||
|
||||
Time Zones
|
||||
---------
|
||||
DateTime can use pytz's large database of time zones. Here are some
|
||||
examples:
|
||||
|
||||
>>> d = DateTime('Pacific/Kwajalein')
|
||||
>>> d = DateTime('America/Shiprock')
|
||||
>>> d = DateTime('Africa/Ouagadougou')
|
||||
|
||||
Of course pytz doesn't know about everything.
|
||||
|
||||
>>> from DateTime.interfaces import SyntaxError
|
||||
>>> try:
|
||||
... d = DateTime('July 21, 1969 Moon/Eastern')
|
||||
... print('fail')
|
||||
... except SyntaxError:
|
||||
... print('ok')
|
||||
ok
|
||||
|
||||
You can still use zone names that DateTime defines that aren't part of
|
||||
the pytz database.
|
||||
|
||||
>>> d = DateTime('eet')
|
||||
>>> d = DateTime('iceland')
|
||||
|
||||
These time zones use DateTimes database. So it's preferable to use the
|
||||
official time zone name.
|
||||
|
||||
One trickiness is that DateTime supports some zone name
|
||||
abbreviations. Some of these map to pytz names, so these abbreviations
|
||||
will give you time zone date from pytz. Notable among abbreviations
|
||||
that work this way are 'est', 'cst', 'mst', and 'pst'.
|
||||
|
||||
Let's verify that 'est' picks up the 2007 daylight savings time changes.
|
||||
|
||||
>>> DateTime('March 11, 2007 est').tzoffset()
|
||||
-18000
|
||||
>>> DateTime('March 12, 2007 est').tzoffset()
|
||||
-14400
|
||||
>>> DateTime('November 4, 2007 est').tzoffset()
|
||||
-14400
|
||||
>>> DateTime('November 5, 2007 est').tzoffset()
|
||||
-18000
|
||||
|
||||
You can get a list of time zones supported by calling the Timezones() function.
|
||||
|
||||
>>> Timezones() #doctest: +ELLIPSIS
|
||||
['Africa/Abidjan', 'Africa/Accra', 'Africa/Addis_Ababa', ...]
|
||||
|
||||
Note that you can mess with this list without hurting things.
|
||||
|
||||
>>> t = Timezones()
|
||||
>>> t.remove('US/Eastern')
|
||||
>>> d = DateTime('US/Eastern')
|
||||
|
||||
|
||||
Internal Components
|
||||
-------------------
|
||||
|
||||
The following are tests of internal components.
|
||||
|
||||
Cache
|
||||
~~~~~
|
||||
|
||||
The DateTime class uses a new time zone cache.
|
||||
|
||||
>>> from DateTime.DateTime import _TZINFO
|
||||
>>> _TZINFO #doctest: +ELLIPSIS
|
||||
<DateTime.pytz_support.PytzCache ...>
|
||||
|
||||
The cache maps time zone names to time zone instances.
|
||||
|
||||
>>> cache = _TZINFO
|
||||
>>> tz = cache['GMT+730']
|
||||
>>> tz = cache['US/Mountain']
|
||||
|
||||
The cache also must provide a few attributes for use by the DateTime
|
||||
class.
|
||||
|
||||
The _zlst attribute is a list of supported time zone names.
|
||||
|
||||
>>> cache._zlst #doctest: +ELLIPSIS
|
||||
['Africa/Abidjan'... 'Africa/Accra'... 'IDLE'... 'NZST'... 'NZT'...]
|
||||
|
||||
The _zidx attribute is a list of lower-case and possibly abbreviated
|
||||
time zone names that can be mapped to official zone names.
|
||||
|
||||
>>> 'australia/yancowinna' in cache._zidx
|
||||
True
|
||||
>>> 'europe/isle_of_man' in cache._zidx
|
||||
True
|
||||
>>> 'gmt+0500' in cache._zidx
|
||||
True
|
||||
|
||||
Note that there are more items in _zidx than in _zlst since there are
|
||||
multiple names for some time zones.
|
||||
|
||||
>>> len(cache._zidx) > len(cache._zlst)
|
||||
True
|
||||
|
||||
Each entry in _zlst should also be present in _zidx in lower case form.
|
||||
|
||||
>>> for name in cache._zlst:
|
||||
... if not name.lower() in cache._zidx:
|
||||
... print("Error %s not in _zidx" % name.lower())
|
||||
|
||||
The _zmap attribute maps the names in _zidx to official names in _zlst.
|
||||
|
||||
>>> cache._zmap['africa/abidjan']
|
||||
'Africa/Abidjan'
|
||||
>>> cache._zmap['gmt+1']
|
||||
'GMT+1'
|
||||
>>> cache._zmap['gmt+0100']
|
||||
'GMT+1'
|
||||
>>> cache._zmap['utc']
|
||||
'UTC'
|
||||
|
||||
Let's make sure that _zmap and _zidx agree.
|
||||
|
||||
>>> idx = set(cache._zidx)
|
||||
>>> keys = set(cache._zmap.keys())
|
||||
>>> idx == keys
|
||||
True
|
||||
|
||||
Timezone objects
|
||||
~~~~~~~~~~~~~~~~
|
||||
The timezone instances have only one public method info(). It returns
|
||||
a tuple of (offset, is_dst, name). The method takes a timestamp, which
|
||||
is used to determine dst information.
|
||||
|
||||
>>> t1 = DateTime('November 4, 00:00 2007 US/Mountain').timeTime()
|
||||
>>> t2 = DateTime('November 4, 02:00 2007 US/Mountain').timeTime()
|
||||
>>> tz.info(t1)
|
||||
(-21600, 1, 'MDT')
|
||||
>>> tz.info(t2)
|
||||
(-25200, 0, 'MST')
|
||||
|
||||
If you don't pass any arguments to info it provides daylight savings
|
||||
time information as of today.
|
||||
|
||||
>>> tz.info() in ((-21600, 1, 'MDT'), (-25200, 0, 'MST'))
|
||||
True
|
||||
|
||||
@ -1,269 +0,0 @@
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2007 Zope Foundation and Contributors.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from datetime import datetime
|
||||
from datetime import timedelta
|
||||
|
||||
import pytz
|
||||
import pytz.reference
|
||||
from pytz.tzinfo import StaticTzInfo
|
||||
from pytz.tzinfo import memorized_timedelta
|
||||
|
||||
from .interfaces import DateTimeError
|
||||
|
||||
|
||||
EPOCH = datetime.fromtimestamp(0, tz=pytz.utc)
|
||||
|
||||
_numeric_timezone_data = {
|
||||
'GMT': ('GMT', 0, 1, [], '', [(0, 0, 0)], 'GMT\000'),
|
||||
'GMT+0': ('GMT+0', 0, 1, [], '', [(0, 0, 0)], 'GMT+0000\000'),
|
||||
'GMT+1': ('GMT+1', 0, 1, [], '', [(3600, 0, 0)], 'GMT+0100\000'),
|
||||
'GMT+2': ('GMT+2', 0, 1, [], '', [(7200, 0, 0)], 'GMT+0200\000'),
|
||||
'GMT+3': ('GMT+3', 0, 1, [], '', [(10800, 0, 0)], 'GMT+0300\000'),
|
||||
'GMT+4': ('GMT+4', 0, 1, [], '', [(14400, 0, 0)], 'GMT+0400\000'),
|
||||
'GMT+5': ('GMT+5', 0, 1, [], '', [(18000, 0, 0)], 'GMT+0500\000'),
|
||||
'GMT+6': ('GMT+6', 0, 1, [], '', [(21600, 0, 0)], 'GMT+0600\000'),
|
||||
'GMT+7': ('GMT+7', 0, 1, [], '', [(25200, 0, 0)], 'GMT+0700\000'),
|
||||
'GMT+8': ('GMT+8', 0, 1, [], '', [(28800, 0, 0)], 'GMT+0800\000'),
|
||||
'GMT+9': ('GMT+9', 0, 1, [], '', [(32400, 0, 0)], 'GMT+0900\000'),
|
||||
'GMT+10': ('GMT+10', 0, 1, [], '', [(36000, 0, 0)], 'GMT+1000\000'),
|
||||
'GMT+11': ('GMT+11', 0, 1, [], '', [(39600, 0, 0)], 'GMT+1100\000'),
|
||||
'GMT+12': ('GMT+12', 0, 1, [], '', [(43200, 0, 0)], 'GMT+1200\000'),
|
||||
'GMT+13': ('GMT+13', 0, 1, [], '', [(46800, 0, 0)], 'GMT+1300\000'),
|
||||
|
||||
'GMT-1': ('GMT-1', 0, 1, [], '', [(-3600, 0, 0)], 'GMT-0100\000'),
|
||||
'GMT-2': ('GMT-2', 0, 1, [], '', [(-7200, 0, 0)], 'GMT-0200\000'),
|
||||
'GMT-3': ('GMT-3', 0, 1, [], '', [(-10800, 0, 0)], 'GMT-0300\000'),
|
||||
'GMT-4': ('GMT-4', 0, 1, [], '', [(-14400, 0, 0)], 'GMT-0400\000'),
|
||||
'GMT-5': ('GMT-5', 0, 1, [], '', [(-18000, 0, 0)], 'GMT-0500\000'),
|
||||
'GMT-6': ('GMT-6', 0, 1, [], '', [(-21600, 0, 0)], 'GMT-0600\000'),
|
||||
'GMT-7': ('GMT-7', 0, 1, [], '', [(-25200, 0, 0)], 'GMT-0700\000'),
|
||||
'GMT-8': ('GMT-8', 0, 1, [], '', [(-28800, 0, 0)], 'GMT-0800\000'),
|
||||
'GMT-9': ('GMT-9', 0, 1, [], '', [(-32400, 0, 0)], 'GMT-0900\000'),
|
||||
'GMT-10': ('GMT-10', 0, 1, [], '', [(-36000, 0, 0)], 'GMT-1000\000'),
|
||||
'GMT-11': ('GMT-11', 0, 1, [], '', [(-39600, 0, 0)], 'GMT-1100\000'),
|
||||
'GMT-12': ('GMT-12', 0, 1, [], '', [(-43200, 0, 0)], 'GMT-1200\000'),
|
||||
|
||||
'GMT+0130': ('GMT+0130', 0, 1, [], '', [(5400, 0, 0)], 'GMT+0130\000'),
|
||||
'GMT+0230': ('GMT+0230', 0, 1, [], '', [(9000, 0, 0)], 'GMT+0230\000'),
|
||||
'GMT+0330': ('GMT+0330', 0, 1, [], '', [(12600, 0, 0)], 'GMT+0330\000'),
|
||||
'GMT+0430': ('GMT+0430', 0, 1, [], '', [(16200, 0, 0)], 'GMT+0430\000'),
|
||||
'GMT+0530': ('GMT+0530', 0, 1, [], '', [(19800, 0, 0)], 'GMT+0530\000'),
|
||||
'GMT+0630': ('GMT+0630', 0, 1, [], '', [(23400, 0, 0)], 'GMT+0630\000'),
|
||||
'GMT+0730': ('GMT+0730', 0, 1, [], '', [(27000, 0, 0)], 'GMT+0730\000'),
|
||||
'GMT+0830': ('GMT+0830', 0, 1, [], '', [(30600, 0, 0)], 'GMT+0830\000'),
|
||||
'GMT+0930': ('GMT+0930', 0, 1, [], '', [(34200, 0, 0)], 'GMT+0930\000'),
|
||||
'GMT+1030': ('GMT+1030', 0, 1, [], '', [(37800, 0, 0)], 'GMT+1030\000'),
|
||||
'GMT+1130': ('GMT+1130', 0, 1, [], '', [(41400, 0, 0)], 'GMT+1130\000'),
|
||||
'GMT+1230': ('GMT+1230', 0, 1, [], '', [(45000, 0, 0)], 'GMT+1230\000'),
|
||||
|
||||
'GMT-0130': ('GMT-0130', 0, 1, [], '', [(-5400, 0, 0)], 'GMT-0130\000'),
|
||||
'GMT-0230': ('GMT-0230', 0, 1, [], '', [(-9000, 0, 0)], 'GMT-0230\000'),
|
||||
'GMT-0330': ('GMT-0330', 0, 1, [], '', [(-12600, 0, 0)], 'GMT-0330\000'),
|
||||
'GMT-0430': ('GMT-0430', 0, 1, [], '', [(-16200, 0, 0)], 'GMT-0430\000'),
|
||||
'GMT-0530': ('GMT-0530', 0, 1, [], '', [(-19800, 0, 0)], 'GMT-0530\000'),
|
||||
'GMT-0630': ('GMT-0630', 0, 1, [], '', [(-23400, 0, 0)], 'GMT-0630\000'),
|
||||
'GMT-0730': ('GMT-0730', 0, 1, [], '', [(-27000, 0, 0)], 'GMT-0730\000'),
|
||||
'GMT-0830': ('GMT-0830', 0, 1, [], '', [(-30600, 0, 0)], 'GMT-0830\000'),
|
||||
'GMT-0930': ('GMT-0930', 0, 1, [], '', [(-34200, 0, 0)], 'GMT-0930\000'),
|
||||
'GMT-1030': ('GMT-1030', 0, 1, [], '', [(-37800, 0, 0)], 'GMT-1030\000'),
|
||||
'GMT-1130': ('GMT-1130', 0, 1, [], '', [(-41400, 0, 0)], 'GMT-1130\000'),
|
||||
'GMT-1230': ('GMT-1230', 0, 1, [], '', [(-45000, 0, 0)], 'GMT-1230\000'),
|
||||
}
|
||||
|
||||
# These are the timezones not in pytz.common_timezones
|
||||
_old_zlst = [
|
||||
'AST', 'AT', 'BST', 'BT', 'CCT',
|
||||
'CET', 'CST', 'Cuba', 'EADT', 'EAST',
|
||||
'EEST', 'EET', 'EST', 'Egypt', 'FST',
|
||||
'FWT', 'GB-Eire', 'GMT+0100', 'GMT+0130', 'GMT+0200',
|
||||
'GMT+0230', 'GMT+0300', 'GMT+0330', 'GMT+0400', 'GMT+0430',
|
||||
'GMT+0500', 'GMT+0530', 'GMT+0600', 'GMT+0630', 'GMT+0700',
|
||||
'GMT+0730', 'GMT+0800', 'GMT+0830', 'GMT+0900', 'GMT+0930',
|
||||
'GMT+1', 'GMT+1000', 'GMT+1030', 'GMT+1100', 'GMT+1130',
|
||||
'GMT+1200', 'GMT+1230', 'GMT+1300', 'GMT-0100', 'GMT-0130',
|
||||
'GMT-0200', 'GMT-0300', 'GMT-0400', 'GMT-0500', 'GMT-0600',
|
||||
'GMT-0630', 'GMT-0700', 'GMT-0730', 'GMT-0800', 'GMT-0830',
|
||||
'GMT-0900', 'GMT-0930', 'GMT-1000', 'GMT-1030', 'GMT-1100',
|
||||
'GMT-1130', 'GMT-1200', 'GMT-1230', 'GST', 'Greenwich',
|
||||
'Hongkong', 'IDLE', 'IDLW', 'Iceland', 'Iran',
|
||||
'Israel', 'JST', 'Jamaica', 'Japan', 'MEST',
|
||||
'MET', 'MEWT', 'MST', 'NT', 'NZDT',
|
||||
'NZST', 'NZT', 'PST', 'Poland', 'SST',
|
||||
'SWT', 'Singapore', 'Turkey', 'UCT', 'UT',
|
||||
'Universal', 'WADT', 'WAST', 'WAT', 'WET',
|
||||
'ZP4', 'ZP5', 'ZP6',
|
||||
]
|
||||
|
||||
_old_zmap = {
|
||||
'aest': 'GMT+10', 'aedt': 'GMT+11',
|
||||
'aus eastern standard time': 'GMT+10',
|
||||
'sydney standard time': 'GMT+10',
|
||||
'tasmania standard time': 'GMT+10',
|
||||
'e. australia standard time': 'GMT+10',
|
||||
'aus central standard time': 'GMT+0930',
|
||||
'cen. australia standard time': 'GMT+0930',
|
||||
'w. australia standard time': 'GMT+8',
|
||||
|
||||
'central europe standard time': 'GMT+1',
|
||||
'eastern standard time': 'US/Eastern',
|
||||
'us eastern standard time': 'US/Eastern',
|
||||
'central standard time': 'US/Central',
|
||||
'mountain standard time': 'US/Mountain',
|
||||
'pacific standard time': 'US/Pacific',
|
||||
'mst': 'US/Mountain', 'pst': 'US/Pacific',
|
||||
'cst': 'US/Central', 'est': 'US/Eastern',
|
||||
|
||||
'gmt+0000': 'GMT+0', 'gmt+0': 'GMT+0',
|
||||
|
||||
'gmt+0100': 'GMT+1', 'gmt+0200': 'GMT+2', 'gmt+0300': 'GMT+3',
|
||||
'gmt+0400': 'GMT+4', 'gmt+0500': 'GMT+5', 'gmt+0600': 'GMT+6',
|
||||
'gmt+0700': 'GMT+7', 'gmt+0800': 'GMT+8', 'gmt+0900': 'GMT+9',
|
||||
'gmt+1000': 'GMT+10', 'gmt+1100': 'GMT+11', 'gmt+1200': 'GMT+12',
|
||||
'gmt+1300': 'GMT+13',
|
||||
'gmt-0100': 'GMT-1', 'gmt-0200': 'GMT-2', 'gmt-0300': 'GMT-3',
|
||||
'gmt-0400': 'GMT-4', 'gmt-0500': 'GMT-5', 'gmt-0600': 'GMT-6',
|
||||
'gmt-0700': 'GMT-7', 'gmt-0800': 'GMT-8', 'gmt-0900': 'GMT-9',
|
||||
'gmt-1000': 'GMT-10', 'gmt-1100': 'GMT-11', 'gmt-1200': 'GMT-12',
|
||||
|
||||
'gmt+1': 'GMT+1', 'gmt+2': 'GMT+2', 'gmt+3': 'GMT+3',
|
||||
'gmt+4': 'GMT+4', 'gmt+5': 'GMT+5', 'gmt+6': 'GMT+6',
|
||||
'gmt+7': 'GMT+7', 'gmt+8': 'GMT+8', 'gmt+9': 'GMT+9',
|
||||
'gmt+10': 'GMT+10', 'gmt+11': 'GMT+11', 'gmt+12': 'GMT+12',
|
||||
'gmt+13': 'GMT+13',
|
||||
'gmt-1': 'GMT-1', 'gmt-2': 'GMT-2', 'gmt-3': 'GMT-3',
|
||||
'gmt-4': 'GMT-4', 'gmt-5': 'GMT-5', 'gmt-6': 'GMT-6',
|
||||
'gmt-7': 'GMT-7', 'gmt-8': 'GMT-8', 'gmt-9': 'GMT-9',
|
||||
'gmt-10': 'GMT-10', 'gmt-11': 'GMT-11', 'gmt-12': 'GMT-12',
|
||||
|
||||
'gmt+130': 'GMT+0130', 'gmt+0130': 'GMT+0130',
|
||||
'gmt+230': 'GMT+0230', 'gmt+0230': 'GMT+0230',
|
||||
'gmt+330': 'GMT+0330', 'gmt+0330': 'GMT+0330',
|
||||
'gmt+430': 'GMT+0430', 'gmt+0430': 'GMT+0430',
|
||||
'gmt+530': 'GMT+0530', 'gmt+0530': 'GMT+0530',
|
||||
'gmt+630': 'GMT+0630', 'gmt+0630': 'GMT+0630',
|
||||
'gmt+730': 'GMT+0730', 'gmt+0730': 'GMT+0730',
|
||||
'gmt+830': 'GMT+0830', 'gmt+0830': 'GMT+0830',
|
||||
'gmt+930': 'GMT+0930', 'gmt+0930': 'GMT+0930',
|
||||
'gmt+1030': 'GMT+1030',
|
||||
'gmt+1130': 'GMT+1130',
|
||||
'gmt+1230': 'GMT+1230',
|
||||
|
||||
'gmt-130': 'GMT-0130', 'gmt-0130': 'GMT-0130',
|
||||
'gmt-230': 'GMT-0230', 'gmt-0230': 'GMT-0230',
|
||||
'gmt-330': 'GMT-0330', 'gmt-0330': 'GMT-0330',
|
||||
'gmt-430': 'GMT-0430', 'gmt-0430': 'GMT-0430',
|
||||
'gmt-530': 'GMT-0530', 'gmt-0530': 'GMT-0530',
|
||||
'gmt-630': 'GMT-0630', 'gmt-0630': 'GMT-0630',
|
||||
'gmt-730': 'GMT-0730', 'gmt-0730': 'GMT-0730',
|
||||
'gmt-830': 'GMT-0830', 'gmt-0830': 'GMT-0830',
|
||||
'gmt-930': 'GMT-0930', 'gmt-0930': 'GMT-0930',
|
||||
'gmt-1030': 'GMT-1030',
|
||||
'gmt-1130': 'GMT-1130',
|
||||
'gmt-1230': 'GMT-1230',
|
||||
|
||||
'ut': 'Universal',
|
||||
'bst': 'GMT+1', 'mest': 'GMT+2', 'sst': 'GMT+2',
|
||||
'fst': 'GMT+2', 'wadt': 'GMT+8', 'eadt': 'GMT+11', 'nzdt': 'GMT+13',
|
||||
'wet': 'GMT', 'wat': 'GMT+1', 'at': 'GMT-2', 'ast': 'GMT-4',
|
||||
'nt': 'GMT-11', 'idlw': 'GMT-12', 'cet': 'GMT+1', 'cest': 'GMT+2',
|
||||
'met': 'GMT+1',
|
||||
'mewt': 'GMT+1', 'swt': 'GMT+1', 'fwt': 'GMT+1', 'eet': 'GMT+2',
|
||||
'eest': 'GMT+3',
|
||||
'bt': 'GMT+3', 'zp4': 'GMT+4', 'zp5': 'GMT+5', 'zp6': 'GMT+6',
|
||||
'wast': 'GMT+7', 'cct': 'GMT+8', 'jst': 'GMT+9', 'east': 'GMT+10',
|
||||
'gst': 'GMT+10', 'nzt': 'GMT+12', 'nzst': 'GMT+12', 'idle': 'GMT+12',
|
||||
'ret': 'GMT+4', 'ist': 'GMT+0530', 'edt': 'GMT-4',
|
||||
|
||||
}
|
||||
|
||||
|
||||
# some timezone definitions of the "-0400" are not working
|
||||
# when upgrading
|
||||
for hour in range(0, 13):
|
||||
hour = hour
|
||||
fhour = str(hour)
|
||||
if len(fhour) == 1:
|
||||
fhour = '0' + fhour
|
||||
_old_zmap['-%s00' % fhour] = 'GMT-%i' % hour
|
||||
_old_zmap['+%s00' % fhour] = 'GMT+%i' % hour
|
||||
|
||||
|
||||
def _p(zone):
|
||||
return _numeric_timezones[zone]
|
||||
|
||||
|
||||
def _static_timezone_factory(data):
|
||||
zone = data[0]
|
||||
cls = type(zone, (StaticTzInfo,), dict(
|
||||
__reduce__=lambda _: (_p, (zone, )),
|
||||
zone=zone,
|
||||
_utcoffset=memorized_timedelta(data[5][0][0]),
|
||||
_tzname=data[6][:-1])) # strip the trailing null
|
||||
return cls()
|
||||
|
||||
|
||||
_numeric_timezones = {key: _static_timezone_factory(data)
|
||||
for key, data in _numeric_timezone_data.items()}
|
||||
|
||||
|
||||
class Timezone:
|
||||
"""
|
||||
Timezone information returned by PytzCache.__getitem__
|
||||
Adapts datetime.tzinfo object to DateTime._timezone interface
|
||||
"""
|
||||
|
||||
def __init__(self, tzinfo):
|
||||
self.tzinfo = tzinfo
|
||||
|
||||
def info(self, t=None):
|
||||
if t is None:
|
||||
dt = datetime.now(tz=pytz.utc)
|
||||
else:
|
||||
# can't use utcfromtimestamp past 2038
|
||||
dt = EPOCH + timedelta(0, t)
|
||||
|
||||
# need to normalize tzinfo for the datetime to deal with
|
||||
# daylight savings time.
|
||||
normalized_dt = self.tzinfo.normalize(dt.astimezone(self.tzinfo))
|
||||
normalized_tzinfo = normalized_dt.tzinfo
|
||||
|
||||
offset = normalized_tzinfo.utcoffset(normalized_dt)
|
||||
secs = offset.days * 24 * 60 * 60 + offset.seconds
|
||||
dst = normalized_tzinfo.dst(normalized_dt)
|
||||
if dst == timedelta(0):
|
||||
is_dst = 0
|
||||
else:
|
||||
is_dst = 1
|
||||
return secs, is_dst, normalized_tzinfo.tzname(normalized_dt)
|
||||
|
||||
|
||||
class PytzCache:
|
||||
"""
|
||||
Reimplementation of the DateTime._cache class that uses for timezone info
|
||||
"""
|
||||
|
||||
_zlst = pytz.common_timezones + _old_zlst # used by DateTime.TimeZones
|
||||
_zmap = {name.lower(): name for name in pytz.all_timezones}
|
||||
_zmap.update(_old_zmap) # These must take priority
|
||||
_zidx = _zmap.keys()
|
||||
|
||||
def __getitem__(self, key):
|
||||
name = self._zmap.get(key.lower(), key) # fallback to key
|
||||
try:
|
||||
return Timezone(pytz.timezone(name))
|
||||
except pytz.UnknownTimeZoneError:
|
||||
try:
|
||||
return Timezone(_numeric_timezones[name])
|
||||
except KeyError:
|
||||
raise DateTimeError('Unrecognized timezone: %s' % key)
|
||||
@ -1,15 +0,0 @@
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2003 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# This file is needed to make this a package.
|
||||
Binary file not shown.
Binary file not shown.
@ -1,57 +0,0 @@
|
||||
1970-01-01 (1970, 1, 4)
|
||||
1970-01-02 (1970, 1, 5)
|
||||
1970-01-30 (1970, 5, 5)
|
||||
1970-01-31 (1970, 5, 6)
|
||||
1970-02-01 (1970, 5, 7)
|
||||
1970-02-02 (1970, 6, 1)
|
||||
1970-02-28 (1970, 9, 6)
|
||||
1970-03-01 (1970, 9, 7)
|
||||
1970-03-30 (1970, 14, 1)
|
||||
1970-03-31 (1970, 14, 2)
|
||||
1970-04-01 (1970, 14, 3)
|
||||
1970-09-30 (1970, 40, 3)
|
||||
1970-10-01 (1970, 40, 4)
|
||||
1970-10-02 (1970, 40, 5)
|
||||
1970-10-03 (1970, 40, 6)
|
||||
1970-10-04 (1970, 40, 7)
|
||||
1970-10-05 (1970, 41, 1)
|
||||
1971-01-02 (1970, 53, 6)
|
||||
1971-01-03 (1970, 53, 7)
|
||||
1971-01-04 (1971, 1, 1)
|
||||
1971-01-05 (1971, 1, 2)
|
||||
1971-12-31 (1971, 52, 5)
|
||||
1972-01-01 (1971, 52, 6)
|
||||
1972-01-02 (1971, 52, 7)
|
||||
1972-01-03 (1972, 1, 1)
|
||||
1972-01-04 (1972, 1, 2)
|
||||
1972-12-30 (1972, 52, 6)
|
||||
1972-12-31 (1972, 52, 7)
|
||||
1973-01-01 (1973, 1, 1)
|
||||
1973-01-02 (1973, 1, 2)
|
||||
1973-12-29 (1973, 52, 6)
|
||||
1973-12-30 (1973, 52, 7)
|
||||
1973-12-31 (1974, 1, 1)
|
||||
1974-01-01 (1974, 1, 2)
|
||||
1998-12-30 (1998, 53, 3)
|
||||
1998-12-31 (1998, 53, 4)
|
||||
1999-01-01 (1998, 53, 5)
|
||||
1999-01-02 (1998, 53, 6)
|
||||
1999-01-03 (1998, 53, 7)
|
||||
1999-01-04 (1999, 1, 1)
|
||||
1999-01-05 (1999, 1, 2)
|
||||
1999-12-30 (1999, 52, 4)
|
||||
1999-12-31 (1999, 52, 5)
|
||||
2000-01-01 (1999, 52, 6)
|
||||
2000-01-02 (1999, 52, 7)
|
||||
2000-01-03 (2000, 1, 1)
|
||||
2000-01-04 (2000, 1, 2)
|
||||
2000-01-05 (2000, 1, 3)
|
||||
2000-01-06 (2000, 1, 4)
|
||||
2000-01-07 (2000, 1, 5)
|
||||
2000-01-08 (2000, 1, 6)
|
||||
2000-01-09 (2000, 1, 7)
|
||||
2000-01-10 (2000, 2, 1)
|
||||
2019-12-28 (2019, 52, 6)
|
||||
2019-12-29 (2019, 52, 7)
|
||||
2019-12-30 (2020, 1, 1)
|
||||
2019-12-31 (2020, 1, 2)
|
||||
@ -1,764 +0,0 @@
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2003 Zope Foundation and Contributors.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# This software is subject to the provisions of the Zope Public License,
|
||||
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
|
||||
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import math
|
||||
import os
|
||||
import pickle
|
||||
import platform
|
||||
import sys
|
||||
import time
|
||||
import unittest
|
||||
from datetime import date
|
||||
from datetime import datetime
|
||||
from datetime import timedelta
|
||||
from datetime import tzinfo
|
||||
|
||||
import pytz
|
||||
|
||||
from DateTime import DateTime
|
||||
from DateTime.DateTime import _findLocalTimeZoneName
|
||||
|
||||
|
||||
try:
|
||||
__file__
|
||||
except NameError: # pragma: no cover
|
||||
f = sys.argv[0]
|
||||
else:
|
||||
f = __file__
|
||||
|
||||
IS_PYPY = getattr(platform, 'python_implementation', lambda: None)() == 'PyPy'
|
||||
|
||||
DATADIR = os.path.dirname(os.path.abspath(f))
|
||||
del f
|
||||
|
||||
ZERO = timedelta(0)
|
||||
|
||||
|
||||
class FixedOffset(tzinfo):
|
||||
"""Fixed offset in minutes east from UTC."""
|
||||
|
||||
def __init__(self, offset, name):
|
||||
self.__offset = timedelta(minutes=offset)
|
||||
self.__name = name
|
||||
|
||||
def utcoffset(self, dt):
|
||||
return self.__offset
|
||||
|
||||
def tzname(self, dt):
|
||||
return self.__name
|
||||
|
||||
def dst(self, dt):
|
||||
return ZERO
|
||||
|
||||
|
||||
class DateTimeTests(unittest.TestCase):
|
||||
|
||||
def _compare(self, dt1, dt2):
|
||||
'''Compares the internal representation of dt1 with
|
||||
the representation in dt2. Allows sub-millisecond variations.
|
||||
Primarily for testing.'''
|
||||
self.assertEqual(round(dt1._t, 3), round(dt2._t, 3))
|
||||
self.assertEqual(round(dt1._d, 9), round(dt2._d, 9))
|
||||
self.assertEqual(round(dt1.time, 9), round(dt2.time, 9))
|
||||
self.assertEqual(dt1.millis(), dt2.millis())
|
||||
self.assertEqual(dt1._micros, dt2._micros)
|
||||
|
||||
def testBug1203(self):
|
||||
# 01:59:60 occurred in old DateTime
|
||||
dt = DateTime(7200, 'GMT')
|
||||
self.assertTrue(str(dt).find('60') < 0, dt)
|
||||
|
||||
def testDSTInEffect(self):
|
||||
# Checks GMT offset for a DST date in the US/Eastern time zone
|
||||
dt = DateTime(2000, 5, 9, 15, 0, 0, 'US/Eastern')
|
||||
self.assertEqual(dt.toZone('GMT').hour(), 19,
|
||||
(dt, dt.toZone('GMT')))
|
||||
|
||||
def testDSTNotInEffect(self):
|
||||
# Checks GMT offset for a non-DST date in the US/Eastern time zone
|
||||
dt = DateTime(2000, 11, 9, 15, 0, 0, 'US/Eastern')
|
||||
self.assertEqual(dt.toZone('GMT').hour(), 20,
|
||||
(dt, dt.toZone('GMT')))
|
||||
|
||||
def testAddPrecision(self):
|
||||
# Precision of serial additions
|
||||
dt = DateTime()
|
||||
self.assertEqual(str(dt + 0.10 + 3.14 + 6.76 - 10), str(dt),
|
||||
dt)
|
||||
# checks problem reported in
|
||||
# https://github.com/zopefoundation/DateTime/issues/41
|
||||
dt = DateTime(2038, 10, 7, 8, 52, 44.959840, "UTC")
|
||||
self.assertEqual(str(dt + 0.10 + 3.14 + 6.76 - 10), str(dt),
|
||||
dt)
|
||||
|
||||
def testConsistentSecondMicroRounding(self):
|
||||
dt = DateTime(2038, 10, 7, 8, 52, 44.9598398, "UTC")
|
||||
self.assertEqual(int(dt.second() * 1000000),
|
||||
dt.micros() % 60000000)
|
||||
|
||||
def testConstructor3(self):
|
||||
# Constructor from date/time string
|
||||
dt = DateTime()
|
||||
dt1s = '%d/%d/%d %d:%d:%f %s' % (
|
||||
dt.year(),
|
||||
dt.month(),
|
||||
dt.day(),
|
||||
dt.hour(),
|
||||
dt.minute(),
|
||||
dt.second(),
|
||||
dt.timezone())
|
||||
dt1 = DateTime(dt1s)
|
||||
# Compare representations as it's the
|
||||
# only way to compare the dates to the same accuracy
|
||||
self.assertEqual(repr(dt), repr(dt1))
|
||||
|
||||
def testConstructor4(self):
|
||||
# Constructor from time float
|
||||
dt = DateTime()
|
||||
dt1 = DateTime(float(dt))
|
||||
self._compare(dt, dt1)
|
||||
|
||||
def testConstructor5(self):
|
||||
# Constructor from time float and timezone
|
||||
dt = DateTime()
|
||||
dt1 = DateTime(float(dt), dt.timezone())
|
||||
self.assertEqual(str(dt), str(dt1), (dt, dt1))
|
||||
dt1 = DateTime(float(dt), str(dt.timezone()))
|
||||
self.assertEqual(str(dt), str(dt1), (dt, dt1))
|
||||
|
||||
def testConstructor6(self):
|
||||
# Constructor from year and julian date
|
||||
# This test must normalize the time zone, or it *will* break when
|
||||
# DST changes!
|
||||
dt1 = DateTime(2000, 5.500000578705)
|
||||
dt = DateTime('2000/1/5 12:00:00.050 pm %s' % dt1.localZone())
|
||||
self._compare(dt, dt1)
|
||||
|
||||
def testConstructor7(self):
|
||||
# Constructor from parts
|
||||
dt = DateTime()
|
||||
dt1 = DateTime(
|
||||
dt.year(),
|
||||
dt.month(),
|
||||
dt.day(),
|
||||
dt.hour(),
|
||||
dt.minute(),
|
||||
dt.second(),
|
||||
dt.timezone())
|
||||
# Compare representations as it's the
|
||||
# only way to compare the dates to the same accuracy
|
||||
self.assertEqual(repr(dt), repr(dt1))
|
||||
|
||||
def testDayOfWeek(self):
|
||||
# Compare to the datetime.date value to make it locale independent
|
||||
expected = date(2000, 6, 16).strftime('%A')
|
||||
# strftime() used to always be passed a day of week of 0
|
||||
dt = DateTime('2000/6/16')
|
||||
s = dt.strftime('%A')
|
||||
self.assertEqual(s, expected, (dt, s))
|
||||
|
||||
def testOldDate(self):
|
||||
# Fails when an 1800 date is displayed with negative signs
|
||||
dt = DateTime('1830/5/6 12:31:46.213 pm')
|
||||
dt1 = dt.toZone('GMT+6')
|
||||
self.assertTrue(str(dt1).find('-') < 0, (dt, dt1))
|
||||
|
||||
def testSubtraction(self):
|
||||
# Reconstruction of a DateTime from its parts, with subtraction
|
||||
# this also tests the accuracy of addition and reconstruction
|
||||
dt = DateTime()
|
||||
dt1 = dt - 3.141592653
|
||||
dt2 = DateTime(
|
||||
dt.year(),
|
||||
dt.month(),
|
||||
dt.day(),
|
||||
dt.hour(),
|
||||
dt.minute(),
|
||||
dt.second())
|
||||
dt3 = dt2 - 3.141592653
|
||||
self.assertEqual(dt1, dt3, (dt, dt1, dt2, dt3))
|
||||
|
||||
def testTZ1add(self):
|
||||
# Time zone manipulation: add to a date
|
||||
dt = DateTime('1997/3/8 1:45am GMT-4')
|
||||
dt1 = DateTime('1997/3/9 1:45pm GMT+8')
|
||||
self.assertTrue((dt + 1.0).equalTo(dt1))
|
||||
|
||||
def testTZ1sub(self):
|
||||
# Time zone manipulation: subtract from a date
|
||||
dt = DateTime('1997/3/8 1:45am GMT-4')
|
||||
dt1 = DateTime('1997/3/9 1:45pm GMT+8')
|
||||
self.assertTrue((dt1 - 1.0).equalTo(dt))
|
||||
|
||||
def testTZ1diff(self):
|
||||
# Time zone manipulation: diff two dates
|
||||
dt = DateTime('1997/3/8 1:45am GMT-4')
|
||||
dt1 = DateTime('1997/3/9 1:45pm GMT+8')
|
||||
self.assertEqual(dt1 - dt, 1.0, (dt, dt1))
|
||||
|
||||
def test_compare_methods(self):
|
||||
# Compare two dates using several methods
|
||||
dt = DateTime('1997/1/1')
|
||||
dt1 = DateTime('1997/2/2')
|
||||
self.assertTrue(dt1.greaterThan(dt))
|
||||
self.assertTrue(dt1.greaterThanEqualTo(dt))
|
||||
self.assertTrue(dt.lessThan(dt1))
|
||||
self.assertTrue(dt.lessThanEqualTo(dt1))
|
||||
self.assertTrue(dt.notEqualTo(dt1))
|
||||
self.assertFalse(dt.equalTo(dt1))
|
||||
# Compare a date to float
|
||||
dt = DateTime(1.0)
|
||||
self.assertTrue(dt == DateTime(1.0)) # testing __eq__
|
||||
self.assertFalse(dt != DateTime(1.0)) # testing __ne__
|
||||
self.assertFalse(dt.greaterThan(1.0))
|
||||
self.assertTrue(dt.greaterThanEqualTo(1.0))
|
||||
self.assertFalse(dt.lessThan(1.0))
|
||||
self.assertTrue(dt.lessThanEqualTo(1.0))
|
||||
self.assertFalse(dt.notEqualTo(1.0))
|
||||
self.assertTrue(dt.equalTo(1.0))
|
||||
# Compare a date to int
|
||||
dt = DateTime(1)
|
||||
self.assertEqual(dt, DateTime(1.0))
|
||||
self.assertTrue(dt == DateTime(1)) # testing __eq__
|
||||
self.assertFalse(dt != DateTime(1)) # testing __ne__
|
||||
self.assertFalse(dt.greaterThan(1))
|
||||
self.assertTrue(dt.greaterThanEqualTo(1))
|
||||
self.assertFalse(dt.lessThan(1))
|
||||
self.assertTrue(dt.lessThanEqualTo(1))
|
||||
self.assertFalse(dt.notEqualTo(1))
|
||||
self.assertTrue(dt.equalTo(1))
|
||||
# Compare a date to string; there is no implicit type conversion
|
||||
# but behavior if consistent as when comparing, for example, an int
|
||||
# and a string.
|
||||
dt = DateTime("2023")
|
||||
self.assertFalse(dt == "2023") # testing __eq__
|
||||
self.assertTrue(dt != "2023") # testing __ne__
|
||||
self.assertRaises(TypeError, dt.greaterThan, "2023")
|
||||
self.assertRaises(TypeError, dt.greaterThanEqualTo, "2023")
|
||||
self.assertRaises(TypeError, dt.lessThan, "2023")
|
||||
self.assertRaises(TypeError, dt.lessThanEqualTo, "2023")
|
||||
self.assertTrue(dt.notEqualTo("2023"))
|
||||
self.assertFalse(dt.equalTo("2023"))
|
||||
|
||||
def test_compare_methods_none(self):
|
||||
# Compare a date to None
|
||||
for dt in (DateTime('1997/1/1'), DateTime(0)):
|
||||
self.assertTrue(dt.greaterThan(None))
|
||||
self.assertTrue(dt.greaterThanEqualTo(None))
|
||||
self.assertFalse(dt.lessThan(None))
|
||||
self.assertFalse(dt.lessThanEqualTo(None))
|
||||
self.assertTrue(dt.notEqualTo(None))
|
||||
self.assertFalse(dt.equalTo(None))
|
||||
|
||||
def test_pickle(self):
|
||||
dt = DateTime()
|
||||
data = pickle.dumps(dt, 1)
|
||||
new = pickle.loads(data)
|
||||
for key in DateTime.__slots__:
|
||||
self.assertEqual(getattr(dt, key), getattr(new, key))
|
||||
|
||||
def test_pickle_with_tz(self):
|
||||
dt = DateTime('2002/5/2 8:00am GMT+8')
|
||||
data = pickle.dumps(dt, 1)
|
||||
new = pickle.loads(data)
|
||||
for key in DateTime.__slots__:
|
||||
self.assertEqual(getattr(dt, key), getattr(new, key))
|
||||
|
||||
def test_pickle_asdatetime_with_tz(self):
|
||||
dt = DateTime('2002/5/2 8:00am GMT+8')
|
||||
data = pickle.dumps(dt.asdatetime(), 1)
|
||||
new = DateTime(pickle.loads(data))
|
||||
for key in DateTime.__slots__:
|
||||
self.assertEqual(getattr(dt, key), getattr(new, key))
|
||||
|
||||
def test_pickle_with_numerical_tz(self):
|
||||
for dt_str in ('2007/01/02 12:34:56.789 +0300',
|
||||
'2007/01/02 12:34:56.789 +0430',
|
||||
'2007/01/02 12:34:56.789 -1234'):
|
||||
dt = DateTime(dt_str)
|
||||
data = pickle.dumps(dt, 1)
|
||||
new = pickle.loads(data)
|
||||
for key in DateTime.__slots__:
|
||||
self.assertEqual(getattr(dt, key), getattr(new, key))
|
||||
|
||||
def test_pickle_with_micros(self):
|
||||
dt = DateTime('2002/5/2 8:00:14.123 GMT+8')
|
||||
data = pickle.dumps(dt, 1)
|
||||
new = pickle.loads(data)
|
||||
for key in DateTime.__slots__:
|
||||
self.assertEqual(getattr(dt, key), getattr(new, key))
|
||||
|
||||
def test_pickle_old(self):
|
||||
dt = DateTime('2002/5/2 8:00am GMT+0')
|
||||
data = (
|
||||
'(cDateTime.DateTime\nDateTime\nq\x01Noq\x02}q\x03(U\x05'
|
||||
'_amonq\x04U\x03Mayq\x05U\x05_adayq\x06U\x03Thuq\x07U\x05_pmonq'
|
||||
'\x08h\x05U\x05_hourq\tK\x08U\x05_fmonq\nh\x05U\x05_pdayq\x0bU'
|
||||
'\x04Thu.q\x0cU\x05_fdayq\rU\x08Thursdayq\x0eU\x03_pmq\x0fU\x02amq'
|
||||
'\x10U\x02_tq\x11GA\xcehy\x00\x00\x00\x00U\x07_minuteq\x12K\x00U'
|
||||
'\x07_microsq\x13L1020326400000000L\nU\x02_dq\x14G@\xe2\x12j\xaa'
|
||||
'\xaa\xaa\xabU\x07_secondq\x15G\x00\x00\x00\x00\x00\x00\x00\x00U'
|
||||
'\x03_tzq\x16U\x05GMT+0q\x17U\x06_monthq\x18K\x05U'
|
||||
'\x0f_timezone_naiveq\x19I00\nU\x04_dayq\x1aK\x02U\x05_yearq'
|
||||
'\x1bM\xd2\x07U\x08_nearsecq\x1cG\x00\x00\x00\x00\x00\x00\x00'
|
||||
'\x00U\x07_pmhourq\x1dK\x08U\n_dayoffsetq\x1eK\x04U\x04timeq'
|
||||
'\x1fG?\xd5UUUV\x00\x00ub.')
|
||||
data = data.encode('latin-1')
|
||||
new = pickle.loads(data)
|
||||
for key in DateTime.__slots__:
|
||||
self.assertEqual(getattr(dt, key), getattr(new, key))
|
||||
|
||||
def test_pickle_old_without_micros(self):
|
||||
dt = DateTime('2002/5/2 8:00am GMT+0')
|
||||
data = (
|
||||
'(cDateTime.DateTime\nDateTime\nq\x01Noq\x02}q\x03(U\x05'
|
||||
'_amonq\x04U\x03Mayq\x05U\x05_adayq\x06U\x03Thuq\x07U\x05_pmonq'
|
||||
'\x08h\x05U\x05_hourq\tK\x08U\x05_fmonq\nh\x05U\x05_pdayq\x0bU'
|
||||
'\x04Thu.q\x0cU\x05_fdayq\rU\x08Thursdayq\x0eU\x03_pmq\x0fU'
|
||||
'\x02amq\x10U\x02_tq\x11GA\xcehy\x00\x00\x00\x00U\x07_minuteq'
|
||||
'\x12K\x00U\x02_dq\x13G@\xe2\x12j\xaa\xaa\xaa\xabU\x07_secondq'
|
||||
'\x14G\x00\x00\x00\x00\x00\x00\x00\x00U\x03_tzq\x15U\x05GMT+0q'
|
||||
'\x16U\x06_monthq\x17K\x05U\x0f_timezone_naiveq\x18I00\nU'
|
||||
'\x04_dayq\x19K\x02U\x05_yearq\x1aM\xd2\x07U\x08_nearsecq'
|
||||
'\x1bG\x00\x00\x00\x00\x00\x00\x00\x00U\x07_pmhourq\x1cK\x08U'
|
||||
'\n_dayoffsetq\x1dK\x04U\x04timeq\x1eG?\xd5UUUV\x00\x00ub.')
|
||||
data = data.encode('latin-1')
|
||||
new = pickle.loads(data)
|
||||
for key in DateTime.__slots__:
|
||||
self.assertEqual(getattr(dt, key), getattr(new, key))
|
||||
|
||||
def test_pickle_dates_after_2038(self):
|
||||
dt = DateTime('2039/09/02 07:07:6.235027 GMT+1')
|
||||
data = pickle.dumps(dt, 1)
|
||||
new = pickle.loads(data)
|
||||
for key in DateTime.__slots__:
|
||||
self.assertEqual(getattr(dt, key), getattr(new, key))
|
||||
|
||||
def test_pickle_old_with_micros_as_float(self):
|
||||
dt = DateTime('2002/5/2 8:00am GMT+0')
|
||||
data = (
|
||||
'ccopy_reg\n_reconstructor\nq\x00(cDateTime.DateTime\nDateTime'
|
||||
'\nq\x01c__builtin__\nobject\nq\x02Ntq\x03Rq\x04(GA\xcehy\x00\x00'
|
||||
'\x00\x00I00\nX\x05\x00\x00\x00GMT+0q\x05tq\x06b.')
|
||||
data = data.encode('latin-1')
|
||||
new = pickle.loads(data)
|
||||
for key in DateTime.__slots__:
|
||||
self.assertEqual(getattr(dt, key), getattr(new, key))
|
||||
|
||||
def testTZ2(self):
|
||||
# Time zone manipulation test 2
|
||||
dt = DateTime()
|
||||
dt1 = dt.toZone('GMT')
|
||||
s = dt.second()
|
||||
s1 = dt1.second()
|
||||
self.assertEqual(s, s1, (dt, dt1, s, s1))
|
||||
|
||||
def testTZDiffDaylight(self):
|
||||
# Diff dates across daylight savings dates
|
||||
dt = DateTime('2000/6/8 1:45am US/Eastern')
|
||||
dt1 = DateTime('2000/12/8 12:45am US/Eastern')
|
||||
self.assertEqual(dt1 - dt, 183, (dt, dt1, dt1 - dt))
|
||||
|
||||
def testY10KDate(self):
|
||||
# Comparison of a Y10K date and a Y2K date
|
||||
dt = DateTime('10213/09/21')
|
||||
dt1 = DateTime(2000, 1, 1)
|
||||
|
||||
dsec = (dt.millis() - dt1.millis()) / 1000.0
|
||||
ddays = math.floor((dsec / 86400.0) + 0.5)
|
||||
|
||||
self.assertEqual(ddays, 3000000, ddays)
|
||||
|
||||
def test_tzoffset(self):
|
||||
# Test time-zone given as an offset
|
||||
|
||||
# GMT
|
||||
dt = DateTime('Tue, 10 Sep 2001 09:41:03 GMT')
|
||||
self.assertEqual(dt.tzoffset(), 0)
|
||||
|
||||
# Timezone by name, a timezone that hasn't got daylightsaving.
|
||||
dt = DateTime('Tue, 2 Mar 2001 09:41:03 GMT+3')
|
||||
self.assertEqual(dt.tzoffset(), 10800)
|
||||
|
||||
# Timezone by name, has daylightsaving but is not in effect.
|
||||
dt = DateTime('Tue, 21 Jan 2001 09:41:03 PST')
|
||||
self.assertEqual(dt.tzoffset(), -28800)
|
||||
|
||||
# Timezone by name, with daylightsaving in effect
|
||||
dt = DateTime('Tue, 24 Aug 2001 09:41:03 PST')
|
||||
self.assertEqual(dt.tzoffset(), -25200)
|
||||
|
||||
# A negative numerical timezone
|
||||
dt = DateTime('Tue, 24 Jul 2001 09:41:03 -0400')
|
||||
self.assertEqual(dt.tzoffset(), -14400)
|
||||
|
||||
# A positive numerical timzone
|
||||
dt = DateTime('Tue, 6 Dec 1966 01:41:03 +0200')
|
||||
self.assertEqual(dt.tzoffset(), 7200)
|
||||
|
||||
# A negative numerical timezone with minutes.
|
||||
dt = DateTime('Tue, 24 Jul 2001 09:41:03 -0637')
|
||||
self.assertEqual(dt.tzoffset(), -23820)
|
||||
|
||||
# A positive numerical timezone with minutes.
|
||||
dt = DateTime('Tue, 24 Jul 2001 09:41:03 +0425')
|
||||
self.assertEqual(dt.tzoffset(), 15900)
|
||||
|
||||
def testISO8601(self):
|
||||
# ISO8601 reference dates
|
||||
ref0 = DateTime('2002/5/2 8:00am GMT')
|
||||
ref1 = DateTime('2002/5/2 8:00am US/Eastern')
|
||||
ref2 = DateTime('2006/11/6 10:30 GMT')
|
||||
ref3 = DateTime('2004/06/14 14:30:15 GMT-3')
|
||||
ref4 = DateTime('2006/01/01 GMT')
|
||||
|
||||
# Basic tests
|
||||
# Though this is timezone naive and according to specification should
|
||||
# be interpreted in the local timezone, to preserve backwards
|
||||
# compatibility with previously expected behaviour.
|
||||
isoDt = DateTime('2002-05-02T08:00:00')
|
||||
self.assertTrue(ref0.equalTo(isoDt))
|
||||
isoDt = DateTime('2002-05-02T08:00:00Z')
|
||||
self.assertTrue(ref0.equalTo(isoDt))
|
||||
isoDt = DateTime('2002-05-02T08:00:00+00:00')
|
||||
self.assertTrue(ref0.equalTo(isoDt))
|
||||
isoDt = DateTime('2002-05-02T08:00:00-04:00')
|
||||
self.assertTrue(ref1.equalTo(isoDt))
|
||||
isoDt = DateTime('2002-05-02 08:00:00-04:00')
|
||||
self.assertTrue(ref1.equalTo(isoDt))
|
||||
|
||||
# Bug 1386: the colon in the timezone offset is optional
|
||||
isoDt = DateTime('2002-05-02T08:00:00-0400')
|
||||
self.assertTrue(ref1.equalTo(isoDt))
|
||||
|
||||
# Bug 2191: date reduced formats
|
||||
isoDt = DateTime('2006-01-01')
|
||||
self.assertTrue(ref4.equalTo(isoDt))
|
||||
isoDt = DateTime('200601-01')
|
||||
self.assertTrue(ref4.equalTo(isoDt))
|
||||
isoDt = DateTime('20060101')
|
||||
self.assertTrue(ref4.equalTo(isoDt))
|
||||
isoDt = DateTime('2006-01')
|
||||
self.assertTrue(ref4.equalTo(isoDt))
|
||||
isoDt = DateTime('200601')
|
||||
self.assertTrue(ref4.equalTo(isoDt))
|
||||
isoDt = DateTime('2006')
|
||||
self.assertTrue(ref4.equalTo(isoDt))
|
||||
|
||||
# Bug 2191: date/time separators are also optional
|
||||
isoDt = DateTime('20020502T08:00:00')
|
||||
self.assertTrue(ref0.equalTo(isoDt))
|
||||
isoDt = DateTime('2002-05-02T080000')
|
||||
self.assertTrue(ref0.equalTo(isoDt))
|
||||
isoDt = DateTime('20020502T080000')
|
||||
self.assertTrue(ref0.equalTo(isoDt))
|
||||
|
||||
# Bug 2191: timezones with only one digit for hour
|
||||
isoDt = DateTime('20020502T080000+0')
|
||||
self.assertTrue(ref0.equalTo(isoDt))
|
||||
isoDt = DateTime('20020502 080000-4')
|
||||
self.assertTrue(ref1.equalTo(isoDt))
|
||||
isoDt = DateTime('20020502T080000-400')
|
||||
self.assertTrue(ref1.equalTo(isoDt))
|
||||
isoDt = DateTime('20020502T080000-4:00')
|
||||
self.assertTrue(ref1.equalTo(isoDt))
|
||||
|
||||
# Bug 2191: optional seconds/minutes
|
||||
isoDt = DateTime('2002-05-02T0800')
|
||||
self.assertTrue(ref0.equalTo(isoDt))
|
||||
isoDt = DateTime('2002-05-02T08')
|
||||
self.assertTrue(ref0.equalTo(isoDt))
|
||||
|
||||
# Bug 2191: week format
|
||||
isoDt = DateTime('2002-W18-4T0800')
|
||||
self.assertTrue(ref0.equalTo(isoDt))
|
||||
isoDt = DateTime('2002-W184T0800')
|
||||
self.assertTrue(ref0.equalTo(isoDt))
|
||||
isoDt = DateTime('2002W18-4T0800')
|
||||
self.assertTrue(ref0.equalTo(isoDt))
|
||||
isoDt = DateTime('2002W184T08')
|
||||
self.assertTrue(ref0.equalTo(isoDt))
|
||||
isoDt = DateTime('2004-W25-1T14:30:15-03:00')
|
||||
self.assertTrue(ref3.equalTo(isoDt))
|
||||
isoDt = DateTime('2004-W25T14:30:15-03:00')
|
||||
self.assertTrue(ref3.equalTo(isoDt))
|
||||
|
||||
# Bug 2191: day of year format
|
||||
isoDt = DateTime('2002-122T0800')
|
||||
self.assertTrue(ref0.equalTo(isoDt))
|
||||
isoDt = DateTime('2002122T0800')
|
||||
self.assertTrue(ref0.equalTo(isoDt))
|
||||
|
||||
# Bug 2191: hours/minutes fractions
|
||||
isoDt = DateTime('2006-11-06T10.5')
|
||||
self.assertTrue(ref2.equalTo(isoDt))
|
||||
isoDt = DateTime('2006-11-06T10,5')
|
||||
self.assertTrue(ref2.equalTo(isoDt))
|
||||
isoDt = DateTime('20040614T1430.25-3')
|
||||
self.assertTrue(ref3.equalTo(isoDt))
|
||||
isoDt = DateTime('2004-06-14T1430,25-3')
|
||||
self.assertTrue(ref3.equalTo(isoDt))
|
||||
isoDt = DateTime('2004-06-14T14:30.25-3')
|
||||
self.assertTrue(ref3.equalTo(isoDt))
|
||||
isoDt = DateTime('20040614T14:30,25-3')
|
||||
self.assertTrue(ref3.equalTo(isoDt))
|
||||
|
||||
# ISO8601 standard format
|
||||
iso8601_string = '2002-05-02T08:00:00-04:00'
|
||||
iso8601DT = DateTime(iso8601_string)
|
||||
self.assertEqual(iso8601_string, iso8601DT.ISO8601())
|
||||
|
||||
# ISO format with no timezone
|
||||
isoDt = DateTime('2006-01-01 00:00:00')
|
||||
self.assertTrue(ref4.equalTo(isoDt))
|
||||
|
||||
def testJulianWeek(self):
|
||||
# Check JulianDayWeek function
|
||||
fn = os.path.join(DATADIR, 'julian_testdata.txt')
|
||||
with open(fn) as fd:
|
||||
lines = fd.readlines()
|
||||
for line in lines:
|
||||
d = DateTime(line[:10])
|
||||
result_from_mx = tuple(map(int, line[12:-2].split(',')))
|
||||
self.assertEqual(result_from_mx[1], d.week())
|
||||
|
||||
def testCopyConstructor(self):
|
||||
d = DateTime('2004/04/04')
|
||||
self.assertEqual(DateTime(d), d)
|
||||
self.assertEqual(str(DateTime(d)), str(d))
|
||||
d2 = DateTime('1999/04/12 01:00:00')
|
||||
self.assertEqual(DateTime(d2), d2)
|
||||
self.assertEqual(str(DateTime(d2)), str(d2))
|
||||
|
||||
def testCopyConstructorPreservesTimezone(self):
|
||||
# test for https://bugs.launchpad.net/zope2/+bug/200007
|
||||
# This always worked in the local timezone, so we need at least
|
||||
# two tests with different zones to be sure at least one of them
|
||||
# is not local.
|
||||
d = DateTime('2004/04/04')
|
||||
self.assertEqual(DateTime(d).timezone(), d.timezone())
|
||||
d2 = DateTime('2008/04/25 12:00:00 EST')
|
||||
self.assertEqual(DateTime(d2).timezone(), d2.timezone())
|
||||
self.assertEqual(str(DateTime(d2)), str(d2))
|
||||
d3 = DateTime('2008/04/25 12:00:00 PST')
|
||||
self.assertEqual(DateTime(d3).timezone(), d3.timezone())
|
||||
self.assertEqual(str(DateTime(d3)), str(d3))
|
||||
|
||||
def testRFC822(self):
|
||||
# rfc822 conversion
|
||||
dt = DateTime('2002-05-02T08:00:00+00:00')
|
||||
self.assertEqual(dt.rfc822(), 'Thu, 02 May 2002 08:00:00 +0000')
|
||||
|
||||
dt = DateTime('2002-05-02T08:00:00+02:00')
|
||||
self.assertEqual(dt.rfc822(), 'Thu, 02 May 2002 08:00:00 +0200')
|
||||
|
||||
dt = DateTime('2002-05-02T08:00:00-02:00')
|
||||
self.assertEqual(dt.rfc822(), 'Thu, 02 May 2002 08:00:00 -0200')
|
||||
|
||||
# Checking that conversion from local time is working.
|
||||
dt = DateTime()
|
||||
dts = dt.rfc822().split(' ')
|
||||
times = dts[4].split(':')
|
||||
_isDST = time.localtime(time.time())[8]
|
||||
if _isDST:
|
||||
offset = time.altzone
|
||||
else:
|
||||
offset = time.timezone
|
||||
self.assertEqual(dts[0], dt.aDay() + ',')
|
||||
self.assertEqual(int(dts[1]), dt.day())
|
||||
self.assertEqual(dts[2], dt.aMonth())
|
||||
self.assertEqual(int(dts[3]), dt.year())
|
||||
self.assertEqual(int(times[0]), dt.h_24())
|
||||
self.assertEqual(int(times[1]), dt.minute())
|
||||
self.assertEqual(int(times[2]), int(dt.second()))
|
||||
self.assertEqual(dts[5], "%+03d%02d" % divmod((-offset / 60), 60))
|
||||
|
||||
def testInternationalDateformat(self):
|
||||
for year in (1990, 2001, 2020):
|
||||
for month in (1, 12):
|
||||
for day in (1, 12, 28, 31):
|
||||
try:
|
||||
d_us = DateTime("%d/%d/%d" % (year, month, day))
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
d_int = DateTime("%d.%d.%d" % (day, month, year),
|
||||
datefmt="international")
|
||||
self.assertEqual(d_us, d_int)
|
||||
|
||||
d_int = DateTime("%d/%d/%d" % (day, month, year),
|
||||
datefmt="international")
|
||||
self.assertEqual(d_us, d_int)
|
||||
|
||||
def test_intl_format_hyphen(self):
|
||||
d_jan = DateTime('2011-01-11 GMT')
|
||||
d_nov = DateTime('2011-11-01 GMT')
|
||||
d_us = DateTime('11-01-2011 GMT')
|
||||
d_int = DateTime('11-01-2011 GMT', datefmt="international")
|
||||
self.assertNotEqual(d_us, d_int)
|
||||
self.assertEqual(d_us, d_nov)
|
||||
self.assertEqual(d_int, d_jan)
|
||||
|
||||
def test_calcTimezoneName(self):
|
||||
from DateTime.interfaces import TimeError
|
||||
timezone_dependent_epoch = 2177452800
|
||||
try:
|
||||
DateTime()._calcTimezoneName(timezone_dependent_epoch, 0)
|
||||
except TimeError:
|
||||
self.fail('Zope Collector issue #484 (negative time bug): '
|
||||
'TimeError raised')
|
||||
|
||||
def testStrftimeTZhandling(self):
|
||||
# strftime timezone testing
|
||||
# This is a test for collector issue #1127
|
||||
format = '%Y-%m-%d %H:%M %Z'
|
||||
dt = DateTime('Wed, 19 Nov 2003 18:32:07 -0215')
|
||||
dt_string = dt.strftime(format)
|
||||
dt_local = dt.toZone(_findLocalTimeZoneName(0))
|
||||
dt_localstring = dt_local.strftime(format)
|
||||
self.assertEqual(dt_string, dt_localstring)
|
||||
|
||||
def testStrftimeFarDates(self):
|
||||
# Checks strftime in dates <= 1900 or >= 2038
|
||||
dt = DateTime('1900/01/30')
|
||||
self.assertEqual(dt.strftime('%d/%m/%Y'), '30/01/1900')
|
||||
dt = DateTime('2040/01/30')
|
||||
self.assertEqual(dt.strftime('%d/%m/%Y'), '30/01/2040')
|
||||
|
||||
def testZoneInFarDates(self):
|
||||
# Checks time zone in dates <= 1900 or >= 2038
|
||||
dt1 = DateTime('2040/01/30 14:33 GMT+1')
|
||||
dt2 = DateTime('2040/01/30 11:33 GMT-2')
|
||||
self.assertEqual(dt1.strftime('%d/%m/%Y %H:%M'),
|
||||
dt2.strftime('%d/%m/%Y %H:%M'))
|
||||
|
||||
@unittest.skipIf(
|
||||
IS_PYPY,
|
||||
"Using Non-Ascii characters for strftime doesn't work in PyPy"
|
||||
"https://bitbucket.org/pypy/pypy/issues/2161/pypy3-strftime-does-not-accept-unicode" # noqa: E501 line too long
|
||||
)
|
||||
def testStrftimeStr(self):
|
||||
dt = DateTime('2002-05-02T08:00:00+00:00')
|
||||
uchar = b'\xc3\xa0'.decode('utf-8')
|
||||
ok = dt.strftime('Le %d/%m/%Y a %Hh%M').replace('a', uchar)
|
||||
ustr = b'Le %d/%m/%Y \xc3\xa0 %Hh%M'.decode('utf-8')
|
||||
self.assertEqual(dt.strftime(ustr), ok)
|
||||
|
||||
def testTimezoneNaiveHandling(self):
|
||||
# checks that we assign timezone naivity correctly
|
||||
dt = DateTime('2007-10-04T08:00:00+00:00')
|
||||
self.assertFalse(dt.timezoneNaive(),
|
||||
'error with naivity handling in __parse_iso8601')
|
||||
dt = DateTime('2007-10-04T08:00:00Z')
|
||||
self.assertFalse(dt.timezoneNaive(),
|
||||
'error with naivity handling in __parse_iso8601')
|
||||
dt = DateTime('2007-10-04T08:00:00')
|
||||
self.assertTrue(dt.timezoneNaive(),
|
||||
'error with naivity handling in __parse_iso8601')
|
||||
dt = DateTime('2007/10/04 15:12:33.487618 GMT+1')
|
||||
self.assertFalse(dt.timezoneNaive(),
|
||||
'error with naivity handling in _parse')
|
||||
dt = DateTime('2007/10/04 15:12:33.487618')
|
||||
self.assertTrue(dt.timezoneNaive(),
|
||||
'error with naivity handling in _parse')
|
||||
dt = DateTime()
|
||||
self.assertFalse(dt.timezoneNaive(),
|
||||
'error with naivity for current time')
|
||||
s = '2007-10-04T08:00:00'
|
||||
dt = DateTime(s)
|
||||
self.assertEqual(s, dt.ISO8601())
|
||||
s = '2007-10-04T08:00:00+00:00'
|
||||
dt = DateTime(s)
|
||||
self.assertEqual(s, dt.ISO8601())
|
||||
|
||||
def testConversions(self):
|
||||
sdt0 = datetime.now() # this is a timezone naive datetime
|
||||
dt0 = DateTime(sdt0)
|
||||
self.assertTrue(dt0.timezoneNaive(), (sdt0, dt0))
|
||||
sdt1 = datetime(2007, 10, 4, 18, 14, 42, 580, pytz.utc)
|
||||
dt1 = DateTime(sdt1)
|
||||
self.assertFalse(dt1.timezoneNaive(), (sdt1, dt1))
|
||||
|
||||
# convert back
|
||||
sdt2 = dt0.asdatetime()
|
||||
self.assertEqual(sdt0, sdt2)
|
||||
sdt3 = dt1.utcdatetime() # this returns a timezone naive datetime
|
||||
self.assertEqual(sdt1.hour, sdt3.hour)
|
||||
|
||||
dt4 = DateTime('2007-10-04T10:00:00+05:00')
|
||||
sdt4 = datetime(2007, 10, 4, 5, 0)
|
||||
self.assertEqual(dt4.utcdatetime(), sdt4)
|
||||
self.assertEqual(dt4.asdatetime(), sdt4.replace(tzinfo=pytz.utc))
|
||||
|
||||
dt5 = DateTime('2007-10-23 10:00:00 US/Eastern')
|
||||
tz = pytz.timezone('US/Eastern')
|
||||
sdt5 = datetime(2007, 10, 23, 10, 0, tzinfo=tz)
|
||||
dt6 = DateTime(sdt5)
|
||||
self.assertEqual(dt5.asdatetime(), sdt5)
|
||||
self.assertEqual(dt6.asdatetime(), sdt5)
|
||||
self.assertEqual(dt5, dt6)
|
||||
self.assertEqual(dt5.asdatetime().tzinfo, tz)
|
||||
self.assertEqual(dt6.asdatetime().tzinfo, tz)
|
||||
|
||||
def testBasicTZ(self):
|
||||
# psycopg2 supplies it's own tzinfo instances, with no `zone` attribute
|
||||
tz = FixedOffset(60, 'GMT+1')
|
||||
dt1 = datetime(2008, 8, 5, 12, 0, tzinfo=tz)
|
||||
DT = DateTime(dt1)
|
||||
dt2 = DT.asdatetime()
|
||||
offset1 = dt1.tzinfo.utcoffset(dt1)
|
||||
offset2 = dt2.tzinfo.utcoffset(dt2)
|
||||
self.assertEqual(offset1, offset2)
|
||||
|
||||
def testEDTTimezone(self):
|
||||
# should be able to parse EDT timezones: see lp:599856.
|
||||
dt = DateTime("Mon, 28 Jun 2010 10:12:25 EDT")
|
||||
self.assertEqual(dt.Day(), 'Monday')
|
||||
self.assertEqual(dt.day(), 28)
|
||||
self.assertEqual(dt.Month(), 'June')
|
||||
self.assertEqual(dt.timezone(), 'GMT-4')
|
||||
|
||||
def testParseISO8601(self):
|
||||
parsed = DateTime()._parse_iso8601('2010-10-10')
|
||||
self.assertEqual(parsed, (2010, 10, 10, 0, 0, 0, 'GMT+0000'))
|
||||
|
||||
def test_interface(self):
|
||||
from DateTime.interfaces import IDateTime
|
||||
self.assertTrue(IDateTime.providedBy(DateTime()))
|
||||
|
||||
def test_security(self):
|
||||
dt = DateTime()
|
||||
self.assertEqual(dt.__roles__, None)
|
||||
self.assertEqual(dt.__allow_access_to_unprotected_subobjects__, 1)
|
||||
|
||||
def test_format(self):
|
||||
dt = DateTime(1968, 3, 10, 23, 45, 0, 'Europe/Vienna')
|
||||
fmt = '%d.%m.%Y %H:%M'
|
||||
result = dt.strftime(fmt)
|
||||
unformatted_result = '1968/03/10 23:45:00 Europe/Vienna'
|
||||
self.assertEqual(result, f'{dt:%d.%m.%Y %H:%M}')
|
||||
self.assertEqual(unformatted_result, f'{dt}')
|
||||
self.assertEqual(unformatted_result, f'{dt}')
|
||||
self.assertEqual(result, f'{dt:{fmt}}')
|
||||
self.assertEqual(unformatted_result, f'{dt:}')
|
||||
self.assertEqual(unformatted_result, f'{dt}')
|
||||
|
||||
|
||||
def test_suite():
|
||||
import doctest
|
||||
return unittest.TestSuite([
|
||||
unittest.defaultTestLoader.loadTestsFromTestCase(DateTimeTests),
|
||||
doctest.DocFileSuite('DateTime.txt', package='DateTime'),
|
||||
doctest.DocFileSuite('pytz.txt', package='DateTime'),
|
||||
])
|
||||
Binary file not shown.
Binary file not shown.
@ -1,239 +0,0 @@
|
||||
# don't import any costly modules
|
||||
import os
|
||||
import sys
|
||||
|
||||
report_url = (
|
||||
"https://github.com/pypa/setuptools/issues/new?template=distutils-deprecation.yml"
|
||||
)
|
||||
|
||||
|
||||
def warn_distutils_present():
|
||||
if 'distutils' not in sys.modules:
|
||||
return
|
||||
import warnings
|
||||
|
||||
warnings.warn(
|
||||
"Distutils was imported before Setuptools, but importing Setuptools "
|
||||
"also replaces the `distutils` module in `sys.modules`. This may lead "
|
||||
"to undesirable behaviors or errors. To avoid these issues, avoid "
|
||||
"using distutils directly, ensure that setuptools is installed in the "
|
||||
"traditional way (e.g. not an editable install), and/or make sure "
|
||||
"that setuptools is always imported before distutils."
|
||||
)
|
||||
|
||||
|
||||
def clear_distutils():
|
||||
if 'distutils' not in sys.modules:
|
||||
return
|
||||
import warnings
|
||||
|
||||
warnings.warn(
|
||||
"Setuptools is replacing distutils. Support for replacing "
|
||||
"an already imported distutils is deprecated. In the future, "
|
||||
"this condition will fail. "
|
||||
f"Register concerns at {report_url}"
|
||||
)
|
||||
mods = [
|
||||
name
|
||||
for name in sys.modules
|
||||
if name == "distutils" or name.startswith("distutils.")
|
||||
]
|
||||
for name in mods:
|
||||
del sys.modules[name]
|
||||
|
||||
|
||||
def enabled():
|
||||
"""
|
||||
Allow selection of distutils by environment variable.
|
||||
"""
|
||||
which = os.environ.get('SETUPTOOLS_USE_DISTUTILS', 'local')
|
||||
if which == 'stdlib':
|
||||
import warnings
|
||||
|
||||
warnings.warn(
|
||||
"Reliance on distutils from stdlib is deprecated. Users "
|
||||
"must rely on setuptools to provide the distutils module. "
|
||||
"Avoid importing distutils or import setuptools first, "
|
||||
"and avoid setting SETUPTOOLS_USE_DISTUTILS=stdlib. "
|
||||
f"Register concerns at {report_url}"
|
||||
)
|
||||
return which == 'local'
|
||||
|
||||
|
||||
def ensure_local_distutils():
|
||||
import importlib
|
||||
|
||||
clear_distutils()
|
||||
|
||||
# With the DistutilsMetaFinder in place,
|
||||
# perform an import to cause distutils to be
|
||||
# loaded from setuptools._distutils. Ref #2906.
|
||||
with shim():
|
||||
importlib.import_module('distutils')
|
||||
|
||||
# check that submodules load as expected
|
||||
core = importlib.import_module('distutils.core')
|
||||
assert '_distutils' in core.__file__, core.__file__
|
||||
assert 'setuptools._distutils.log' not in sys.modules
|
||||
|
||||
|
||||
def do_override():
|
||||
"""
|
||||
Ensure that the local copy of distutils is preferred over stdlib.
|
||||
|
||||
See https://github.com/pypa/setuptools/issues/417#issuecomment-392298401
|
||||
for more motivation.
|
||||
"""
|
||||
if enabled():
|
||||
warn_distutils_present()
|
||||
ensure_local_distutils()
|
||||
|
||||
|
||||
class _TrivialRe:
|
||||
def __init__(self, *patterns) -> None:
|
||||
self._patterns = patterns
|
||||
|
||||
def match(self, string):
|
||||
return all(pat in string for pat in self._patterns)
|
||||
|
||||
|
||||
class DistutilsMetaFinder:
|
||||
def find_spec(self, fullname, path, target=None):
|
||||
# optimization: only consider top level modules and those
|
||||
# found in the CPython test suite.
|
||||
if path is not None and not fullname.startswith('test.'):
|
||||
return None
|
||||
|
||||
method_name = 'spec_for_{fullname}'.format(**locals())
|
||||
method = getattr(self, method_name, lambda: None)
|
||||
return method()
|
||||
|
||||
def spec_for_distutils(self):
|
||||
if self.is_cpython():
|
||||
return None
|
||||
|
||||
import importlib
|
||||
import importlib.abc
|
||||
import importlib.util
|
||||
|
||||
try:
|
||||
mod = importlib.import_module('setuptools._distutils')
|
||||
except Exception:
|
||||
# There are a couple of cases where setuptools._distutils
|
||||
# may not be present:
|
||||
# - An older Setuptools without a local distutils is
|
||||
# taking precedence. Ref #2957.
|
||||
# - Path manipulation during sitecustomize removes
|
||||
# setuptools from the path but only after the hook
|
||||
# has been loaded. Ref #2980.
|
||||
# In either case, fall back to stdlib behavior.
|
||||
return None
|
||||
|
||||
class DistutilsLoader(importlib.abc.Loader):
|
||||
def create_module(self, spec):
|
||||
mod.__name__ = 'distutils'
|
||||
return mod
|
||||
|
||||
def exec_module(self, module):
|
||||
pass
|
||||
|
||||
return importlib.util.spec_from_loader(
|
||||
'distutils', DistutilsLoader(), origin=mod.__file__
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def is_cpython():
|
||||
"""
|
||||
Suppress supplying distutils for CPython (build and tests).
|
||||
Ref #2965 and #3007.
|
||||
"""
|
||||
return os.path.isfile('pybuilddir.txt')
|
||||
|
||||
def spec_for_pip(self):
|
||||
"""
|
||||
Ensure stdlib distutils when running under pip.
|
||||
See pypa/pip#8761 for rationale.
|
||||
"""
|
||||
if sys.version_info >= (3, 12) or self.pip_imported_during_build():
|
||||
return
|
||||
clear_distutils()
|
||||
self.spec_for_distutils = lambda: None
|
||||
|
||||
@classmethod
|
||||
def pip_imported_during_build(cls):
|
||||
"""
|
||||
Detect if pip is being imported in a build script. Ref #2355.
|
||||
"""
|
||||
import traceback
|
||||
|
||||
return any(
|
||||
cls.frame_file_is_setup(frame) for frame, line in traceback.walk_stack(None)
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def frame_file_is_setup(frame):
|
||||
"""
|
||||
Return True if the indicated frame suggests a setup.py file.
|
||||
"""
|
||||
# some frames may not have __file__ (#2940)
|
||||
return frame.f_globals.get('__file__', '').endswith('setup.py')
|
||||
|
||||
def spec_for_sensitive_tests(self):
|
||||
"""
|
||||
Ensure stdlib distutils when running select tests under CPython.
|
||||
|
||||
python/cpython#91169
|
||||
"""
|
||||
clear_distutils()
|
||||
self.spec_for_distutils = lambda: None
|
||||
|
||||
sensitive_tests = (
|
||||
[
|
||||
'test.test_distutils',
|
||||
'test.test_peg_generator',
|
||||
'test.test_importlib',
|
||||
]
|
||||
if sys.version_info < (3, 10)
|
||||
else [
|
||||
'test.test_distutils',
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
for name in DistutilsMetaFinder.sensitive_tests:
|
||||
setattr(
|
||||
DistutilsMetaFinder,
|
||||
f'spec_for_{name}',
|
||||
DistutilsMetaFinder.spec_for_sensitive_tests,
|
||||
)
|
||||
|
||||
|
||||
DISTUTILS_FINDER = DistutilsMetaFinder()
|
||||
|
||||
|
||||
def add_shim():
|
||||
DISTUTILS_FINDER in sys.meta_path or insert_shim()
|
||||
|
||||
|
||||
class shim:
|
||||
def __enter__(self) -> None:
|
||||
insert_shim()
|
||||
|
||||
def __exit__(self, exc: object, value: object, tb: object) -> None:
|
||||
_remove_shim()
|
||||
|
||||
|
||||
def insert_shim():
|
||||
sys.meta_path.insert(0, DISTUTILS_FINDER)
|
||||
|
||||
|
||||
def _remove_shim():
|
||||
try:
|
||||
sys.meta_path.remove(DISTUTILS_FINDER)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
|
||||
if sys.version_info < (3, 12):
|
||||
# DistutilsMetaFinder can only be disabled in Python < 3.12 (PEP 632)
|
||||
remove_shim = _remove_shim
|
||||
Binary file not shown.
Binary file not shown.
@ -1 +0,0 @@
|
||||
__import__('_distutils_hack').do_override()
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,4 +1,4 @@
|
||||
../../../bin/normalizer,sha256=9WdyCIqYgSbUxt46Njhg9YwQf8x-EAzNrJo206alMfY,256
|
||||
../../../bin/normalizer,sha256=Cb5yIYYCPtaerk6Pit1w6ACFJ_h4ic57z1TTVY-ghfA,251
|
||||
charset_normalizer-3.4.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
charset_normalizer-3.4.1.dist-info/LICENSE,sha256=bQ1Bv-FwrGx9wkjJpj4lTQ-0WmDVCoJX0K-SxuJJuIc,1071
|
||||
charset_normalizer-3.4.1.dist-info/METADATA,sha256=JbyHzhmqZh_ugEn1Y7TY7CDYZA9FoU6BP25hrCNDf50,35313
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1 +0,0 @@
|
||||
import os; var = 'SETUPTOOLS_USE_DISTUTILS'; enabled = os.environ.get(var, 'local') == 'local'; enabled and __import__('_distutils_hack').add_shim();
|
||||
169
llmlab/lib/python3.12/site-packages/example.py
Normal file
169
llmlab/lib/python3.12/site-packages/example.py
Normal file
@ -0,0 +1,169 @@
|
||||
#################################################################################
|
||||
# Copyright (c) 2020, NVIDIA Corporation. All rights reserved. #
|
||||
# #
|
||||
# Redistribution and use in source and binary forms, with or without #
|
||||
# modification, are permitted provided that the following conditions are met: #
|
||||
# #
|
||||
# * Redistributions of source code must retain the above copyright notice, #
|
||||
# this list of conditions and the following disclaimer. #
|
||||
# * Redistributions in binary form must reproduce the above copyright #
|
||||
# notice, this list of conditions and the following disclaimer in the #
|
||||
# documentation and/or other materials provided with the distribution. #
|
||||
# * Neither the name of the NVIDIA Corporation nor the names of its #
|
||||
# contributors may be used to endorse or promote products derived from #
|
||||
# this software without specific prior written permission. #
|
||||
# #
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" #
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE #
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE #
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE #
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR #
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF #
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS #
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN #
|
||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) #
|
||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF #
|
||||
# THE POSSIBILITY OF SUCH DAMAGE. #
|
||||
#################################################################################
|
||||
|
||||
#
|
||||
# Sample script to demonstrate the usage of NVML API python bindings
|
||||
#
|
||||
|
||||
# To Run:
|
||||
# $ python ./example.py
|
||||
|
||||
from pynvml import *
|
||||
|
||||
#
|
||||
# Helper function
|
||||
#
|
||||
def StrVirt(mode):
|
||||
if mode == NVML_GPU_VIRTUALIZATION_MODE_NONE:
|
||||
return "None";
|
||||
elif mode == NVML_GPU_VIRTUALIZATION_MODE_PASSTHROUGH:
|
||||
return "Pass-Through";
|
||||
elif mode == NVML_GPU_VIRTUALIZATION_MODE_VGPU:
|
||||
return "VGPU";
|
||||
elif mode == NVML_GPU_VIRTUALIZATION_MODE_HOST_VGPU:
|
||||
return "Host VGPU";
|
||||
elif mode == NVML_GPU_VIRTUALIZATION_MODE_HOST_VSGA:
|
||||
return "Host VSGA";
|
||||
else:
|
||||
return "Unknown";
|
||||
|
||||
#
|
||||
# Converts errors into string messages
|
||||
#
|
||||
def handleError(err):
|
||||
if (err.value == NVML_ERROR_NOT_SUPPORTED):
|
||||
return "N/A"
|
||||
else:
|
||||
return err.__str__()
|
||||
|
||||
#######
|
||||
def deviceQuery():
|
||||
|
||||
strResult = ''
|
||||
try:
|
||||
#
|
||||
# Initialize NVML
|
||||
#
|
||||
nvmlInit()
|
||||
|
||||
strResult += ' <driver_version>' + str(nvmlSystemGetDriverVersion()) + '</driver_version>\n'
|
||||
|
||||
deviceCount = nvmlDeviceGetCount()
|
||||
strResult += ' <attached_gpus>' + str(deviceCount) + '</attached_gpus>\n'
|
||||
|
||||
for i in range(0, deviceCount):
|
||||
handle = nvmlDeviceGetHandleByIndex(i)
|
||||
|
||||
pciInfo = nvmlDeviceGetPciInfo(handle)
|
||||
|
||||
strResult += ' <gpu id="%s">\n' % pciInfo.busId
|
||||
|
||||
strResult += ' <product_name>' + nvmlDeviceGetName(handle) + '</product_name>\n'
|
||||
|
||||
brandNames = {NVML_BRAND_UNKNOWN : "Unknown",
|
||||
NVML_BRAND_QUADRO : "Quadro",
|
||||
NVML_BRAND_TESLA : "Tesla",
|
||||
NVML_BRAND_NVS : "NVS",
|
||||
NVML_BRAND_GRID : "Grid",
|
||||
NVML_BRAND_TITAN : "Titan",
|
||||
NVML_BRAND_GEFORCE : "GeForce",
|
||||
NVML_BRAND_NVIDIA_VAPPS : "NVIDIA Virtual Applications",
|
||||
NVML_BRAND_NVIDIA_VPC : "NVIDIA Virtual PC",
|
||||
NVML_BRAND_NVIDIA_VCS : "NVIDIA Virtual Compute Server",
|
||||
NVML_BRAND_NVIDIA_VWS : "NVIDIA RTX Virtual Workstation",
|
||||
NVML_BRAND_NVIDIA_CLOUD_GAMING : "NVIDIA Cloud Gaming",
|
||||
NVML_BRAND_QUADRO_RTX : "Quadro RTX",
|
||||
NVML_BRAND_NVIDIA_RTX : "NVIDIA RTX",
|
||||
NVML_BRAND_NVIDIA : "NVIDIA",
|
||||
NVML_BRAND_GEFORCE_RTX : "GeForce RTX",
|
||||
NVML_BRAND_TITAN_RTX : "TITAN RTX",
|
||||
|
||||
}
|
||||
|
||||
try:
|
||||
# If nvmlDeviceGetBrand() succeeds it is guaranteed to be in the dictionary
|
||||
brandName = brandNames[nvmlDeviceGetBrand(handle)]
|
||||
except NVMLError as err:
|
||||
brandName = handleError(err)
|
||||
|
||||
strResult += ' <product_brand>' + brandName + '</product_brand>\n'
|
||||
|
||||
try:
|
||||
serial = nvmlDeviceGetSerial(handle)
|
||||
except NVMLError as err:
|
||||
serial = handleError(err)
|
||||
|
||||
strResult += ' <serial>' + serial + '</serial>\n'
|
||||
|
||||
try:
|
||||
uuid = nvmlDeviceGetUUID(handle)
|
||||
except NVMLError as err:
|
||||
uuid = handleError(err)
|
||||
|
||||
strResult += ' <uuid>' + uuid + '</uuid>\n'
|
||||
|
||||
strResult += ' <gpu_virtualization_mode>\n'
|
||||
try:
|
||||
mode = StrVirt(nvmlDeviceGetVirtualizationMode(handle))
|
||||
except NVMLError as err:
|
||||
mode = handleError(err)
|
||||
strResult += ' <virtualization_mode>' + mode + '</virtualization_mode>\n'
|
||||
strResult += ' </gpu_virtualization_mode>\n'
|
||||
|
||||
try:
|
||||
gridLicensableFeatures = nvmlDeviceGetGridLicensableFeatures(handle)
|
||||
if gridLicensableFeatures.isGridLicenseSupported == 1:
|
||||
strResult += ' <vgpu_software_licensed_product>\n'
|
||||
for i in range(gridLicensableFeatures.licensableFeaturesCount):
|
||||
if gridLicensableFeatures.gridLicensableFeatures[i].featureState == 0:
|
||||
if nvmlDeviceGetVirtualizationMode(handle) == NVML_GPU_VIRTUALIZATION_MODE_PASSTHROUGH:
|
||||
strResult += ' <licensed_product_name>' + 'NVIDIA Virtual Applications' + '</licensed_product_name>\n'
|
||||
strResult += ' <license_status>' + 'Licensed' + '</license_status>\n'
|
||||
else:
|
||||
strResult += ' <licensed_product_name>' + gridLicensableFeatures.gridLicensableFeatures[i].productName + '</licensed_product_name>\n'
|
||||
strResult += ' <license_status>' + 'Unlicensed' + '</license_status>\n'
|
||||
else:
|
||||
strResult += ' <licensed_product_name>' + gridLicensableFeatures.gridLicensableFeatures[i].productName + '</licensed_product_name>\n'
|
||||
strResult += ' <license_status>' + 'Licensed' + '</license_status>\n'
|
||||
strResult += ' </vgpu_software_licensed_product>\n'
|
||||
except NVMLError as err:
|
||||
gridLicensableFeatures = handleError(err)
|
||||
|
||||
strResult += ' </gpu>\n'
|
||||
|
||||
except NVMLError as err:
|
||||
strResult += 'example.py: ' + err.__str__() + '\n'
|
||||
|
||||
nvmlShutdown()
|
||||
|
||||
return strResult
|
||||
|
||||
# If this is not exectued when module is imported
|
||||
if __name__ == "__main__":
|
||||
print(deviceQuery())
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,261 @@
|
||||
Metadata-Version: 2.2
|
||||
Name: nvidia-ml-py
|
||||
Version: 12.570.86
|
||||
Summary: Python Bindings for the NVIDIA Management Library
|
||||
Home-page: https://forums.developer.nvidia.com
|
||||
Author: NVIDIA Corporation
|
||||
Author-email: nvml-bindings@nvidia.com
|
||||
License: BSD
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: Intended Audience :: System Administrators
|
||||
Classifier: License :: OSI Approved :: BSD License
|
||||
Classifier: Operating System :: Microsoft :: Windows
|
||||
Classifier: Operating System :: POSIX :: Linux
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||
Classifier: Topic :: System :: Hardware
|
||||
Classifier: Topic :: System :: Systems Administration
|
||||
Description-Content-Type: text/markdown
|
||||
Dynamic: author
|
||||
Dynamic: author-email
|
||||
Dynamic: classifier
|
||||
Dynamic: description
|
||||
Dynamic: description-content-type
|
||||
Dynamic: home-page
|
||||
Dynamic: license
|
||||
Dynamic: summary
|
||||
|
||||
pyNVML
|
||||
======
|
||||
|
||||
Python bindings to the NVIDIA Management Library
|
||||
------------------------------------------------
|
||||
|
||||
Provides a Python interface to GPU management and monitoring functions.
|
||||
|
||||
This is a wrapper around the NVML library.
|
||||
For information about the NVML library, see the NVML developer page
|
||||
http://developer.nvidia.com/nvidia-management-library-nvml
|
||||
|
||||
Download the latest package from:
|
||||
http://pypi.python.org/pypi/nvidia-ml-py/
|
||||
|
||||
Note this file can be run with 'python -m doctest -v README.txt'
|
||||
although the results are system dependent
|
||||
|
||||
The nvml header file contains function documentation that is relevant
|
||||
to this wrapper. The header file is distributed with.
|
||||
https://developer.nvidia.com/gpu-deployment-kit
|
||||
|
||||
The main difference is this library handles allocating structs and
|
||||
passing pointers to the functions, before returning the desired value.
|
||||
Non-success return codes are raised as exceptions as described in the
|
||||
section below.
|
||||
|
||||
REQUIRES
|
||||
--------
|
||||
Python 2.5, or an earlier version with the ctypes module.
|
||||
|
||||
INSTALLATION
|
||||
------------
|
||||
|
||||
Pip Installation with python3:
|
||||
- `python3 -m pip install nvidia-ml-py`
|
||||
|
||||
Manual Installation:
|
||||
```
|
||||
$ tar -xzf nvidia-ml-py-$major-$minor-$patch.tar.gz`
|
||||
$ cd nvidia-ml-py-$major-$minor-$patch
|
||||
$ sudo python setup.py install
|
||||
```
|
||||
|
||||
USAGE
|
||||
-----
|
||||
```
|
||||
>>> from pynvml import *
|
||||
>>> nvmlInit()
|
||||
>>> print(f"Driver Version: {nvmlSystemGetDriverVersion()}")
|
||||
Driver Version: 11.515.48
|
||||
>>> deviceCount = nvmlDeviceGetCount()
|
||||
>>> for i in range(deviceCount):
|
||||
... handle = nvmlDeviceGetHandleByIndex(i)
|
||||
... print(f"Device {i} : {nvmlDeviceGetName(handle)}")
|
||||
...
|
||||
Device 0 : Tesla K40c
|
||||
|
||||
>>> nvmlShutdown()
|
||||
```
|
||||
|
||||
FUNCTIONS
|
||||
---------
|
||||
Python methods wrap NVML functions, implemented in a C shared library.
|
||||
Each function's use is the same with the following exceptions:
|
||||
|
||||
- Instead of returning error codes, failing error codes are raised as Python exceptions.
|
||||
|
||||
```
|
||||
>>> try:
|
||||
... nvmlDeviceGetCount()
|
||||
... except NVMLError as error:
|
||||
... print(error)
|
||||
...
|
||||
Uninitialized
|
||||
```
|
||||
|
||||
- C function output parameters are returned from the corresponding Python function left to right.
|
||||
```
|
||||
nvmlReturn_t nvmlDeviceGetEccMode(nvmlDevice_t device,
|
||||
nvmlEnableState_t *current,
|
||||
nvmlEnableState_t *pending);
|
||||
|
||||
>>> nvmlInit()
|
||||
>>> handle = nvmlDeviceGetHandleByIndex(0)
|
||||
>>> (current, pending) = nvmlDeviceGetEccMode(handle)
|
||||
```
|
||||
- C structs are converted into Python classes.
|
||||
|
||||
```
|
||||
// C Function and typedef struct
|
||||
nvmlReturn_t DECLDIR nvmlDeviceGetMemoryInfo(nvmlDevice_t device,
|
||||
nvmlMemory_t *memory);
|
||||
typedef struct nvmlMemory_st {
|
||||
unsigned long long total;
|
||||
unsigned long long free;
|
||||
unsigned long long used;
|
||||
} nvmlMemory_t;
|
||||
|
||||
|
||||
# Python call to function and accessing members of ctype struct
|
||||
>>> info = nvmlDeviceGetMemoryInfo(handle)
|
||||
>>> print(f"Total memory: {info.total}")
|
||||
Total memory: 5636292608
|
||||
>>> print(f"Free memory:, {info.free}")
|
||||
Free memory: 5578420224
|
||||
>>> print(f"Used memory: {info.used}")
|
||||
Used memory: 57872384
|
||||
```
|
||||
|
||||
- Python handles string buffer creation.
|
||||
|
||||
```
|
||||
// C Function that needs character array and length
|
||||
nvmlReturn_t nvmlSystemGetDriverVersion(char* version,
|
||||
unsigned int length);
|
||||
|
||||
# Python function handles memory
|
||||
>>> version = nvmlSystemGetDriverVersion()
|
||||
>>> print(version)
|
||||
... 11.520.75
|
||||
>>> nvmlShutdown()
|
||||
```
|
||||
|
||||
For usage information see the NVML documentation.
|
||||
|
||||
VARIABLES
|
||||
---------
|
||||
All meaningful NVML constants and enums are exposed in Python.
|
||||
|
||||
The NVML_VALUE_NOT_AVAILABLE constant is not used. Instead None is mapped to the field.
|
||||
|
||||
EXCEPTIONS
|
||||
----------
|
||||
Since the C library uses return codes and python prefers exception handling, the
|
||||
library converts all return codes to various exceptions. The exceptions are generated
|
||||
automatically via a function at run time instead of being defined manually.
|
||||
|
||||
The list of exceptions can be found in NVMLError base class.
|
||||
|
||||
The example seen above in the FUNCTIONS section:
|
||||
|
||||
```
|
||||
>>> try:
|
||||
... nvmlDeviceGetCount()
|
||||
... except NVMLError as error:
|
||||
... print(error)
|
||||
...
|
||||
Uninitialized
|
||||
```
|
||||
|
||||
Can be more accurately caught like this:
|
||||
|
||||
```
|
||||
>>> try:
|
||||
... nvmlDeviceGetCount()
|
||||
... except NVMLError_Uninitialized as error:
|
||||
... print(error)
|
||||
...
|
||||
Uninitialized
|
||||
```
|
||||
|
||||
The conversion from name to exception is like this for all exceptions:
|
||||
* `NVML_ERROR_UNINITIALIZED` => `NVMLError_Uninitialized`
|
||||
* `NVML_ERROR_LIBRARY_NOT_FOUND` => `NVMLError_LibraryNotFound`
|
||||
* `NVML_ERROR_ALREADY_INITIALIZED` => `NVMLError_AlreadyInitialized`
|
||||
|
||||
RELEASE NOTES
|
||||
-------------
|
||||
Version 2.285.0
|
||||
- Added new functions for NVML 2.285. See NVML documentation for more information.
|
||||
- Ported to support Python 3.0 and Python 2.0 syntax.
|
||||
- Added nvidia_smi.py tool as a sample app.
|
||||
|
||||
Version 3.295.0
|
||||
- Added new functions for NVML 3.295. See NVML documentation for more information.
|
||||
- Updated nvidia_smi.py tool
|
||||
- Includes additional error handling
|
||||
|
||||
Version 4.304.0
|
||||
- Added new functions for NVML 4.304. See NVML documentation for more information.
|
||||
- Updated nvidia_smi.py tool
|
||||
|
||||
Version 4.304.3
|
||||
- Fixing nvmlUnitGetDeviceCount bug
|
||||
|
||||
Version 5.319.0
|
||||
- Added new functions for NVML 5.319. See NVML documentation for more information.
|
||||
|
||||
Version 6.340.0
|
||||
- Added new functions for NVML 6.340. See NVML documentation for more information.
|
||||
|
||||
Version 7.346.0
|
||||
- Added new functions for NVML 7.346. See NVML documentation for more information.
|
||||
|
||||
Version 7.352.0
|
||||
- Added new functions for NVML 7.352. See NVML documentation for more information.
|
||||
|
||||
Version 10.418
|
||||
- Added new functions for NVML 10.418. See NVML documentation for more information.
|
||||
- Fixed issues with using the bindings with Python 3.x
|
||||
- Replaced sample app nvidia_smi.py with example.py
|
||||
|
||||
Version 11.515.48
|
||||
- Python3 support added
|
||||
- Updated API to add function new to NVML, bringing pynvml up to date with NVML
|
||||
- Added auto-version to handle byte and string conversion automatically for both structs and functions
|
||||
- Minor bug fixes
|
||||
- Added README.txt correctly in long_description for pypi.org
|
||||
|
||||
Version 11.520
|
||||
- Updated Long Description to be actual markdown
|
||||
- Added new functions for NVML 11.520
|
||||
|
||||
Version 11.525
|
||||
- Added new functions for NVML 11.525
|
||||
|
||||
COPYRIGHT
|
||||
---------
|
||||
Copyright (c) 2011-2023, NVIDIA Corporation. All rights reserved.
|
||||
|
||||
LICENSE
|
||||
-------
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the NVIDIA Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
__pycache__/example.cpython-312.pyc,,
|
||||
__pycache__/pynvml.cpython-312.pyc,,
|
||||
example.py,sha256=mDXwPVyEDuiKeMApEh53r_M36xuncmzMpFOGA3Q-_Kw,7968
|
||||
nvidia_ml_py-12.570.86.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
nvidia_ml_py-12.570.86.dist-info/METADATA,sha256=vY-jfk5MJsbWGy2jmbgdwfPKG4G0FHbspv-av_h5bEE,8718
|
||||
nvidia_ml_py-12.570.86.dist-info/RECORD,,
|
||||
nvidia_ml_py-12.570.86.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
nvidia_ml_py-12.570.86.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
||||
nvidia_ml_py-12.570.86.dist-info/top_level.txt,sha256=wLINSA1WKnhsGgKsb_nuj51ZCQrXaN5qhioTL56g98A,15
|
||||
pynvml.py,sha256=PCW5qJPhGshkIhIUOOQyUXsxkCVaPeTi30R7LsJb4YE,234473
|
||||
@ -1,5 +1,5 @@
|
||||
Wheel-Version: 1.0
|
||||
Generator: setuptools (70.1.1)
|
||||
Generator: setuptools (75.8.0)
|
||||
Root-Is-Purelib: true
|
||||
Tag: py3-none-any
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
example
|
||||
pynvml
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,5 +0,0 @@
|
||||
Wheel-Version: 1.0
|
||||
Generator: bdist_wheel (0.42.0)
|
||||
Root-Is-Purelib: true
|
||||
Tag: py3-none-any
|
||||
|
||||
@ -9,7 +9,9 @@ Adam Chainz
|
||||
Adam Tse
|
||||
Adam Wentz
|
||||
admin
|
||||
Adolfo Ochagavía
|
||||
Adrien Morison
|
||||
Agus
|
||||
ahayrapetyan
|
||||
Ahilya
|
||||
AinsworthK
|
||||
@ -55,6 +57,7 @@ Anthony Sottile
|
||||
Antoine Musso
|
||||
Anton Ovchinnikov
|
||||
Anton Patrushev
|
||||
Anton Zelenov
|
||||
Antonio Alvarado Hernandez
|
||||
Antony Lee
|
||||
Antti Kaihola
|
||||
@ -63,8 +66,11 @@ Anudit Nagar
|
||||
Anuj Godase
|
||||
AQNOUCH Mohammed
|
||||
AraHaan
|
||||
arena
|
||||
arenasys
|
||||
Arindam Choudhury
|
||||
Armin Ronacher
|
||||
Arnon Yaari
|
||||
Artem
|
||||
Arun Babu Neelicattu
|
||||
Ashley Manton
|
||||
@ -100,8 +106,10 @@ Bogdan Opanchuk
|
||||
BorisZZZ
|
||||
Brad Erickson
|
||||
Bradley Ayers
|
||||
Branch Vincent
|
||||
Brandon L. Reiss
|
||||
Brandt Bucher
|
||||
Brannon Dorsey
|
||||
Brett Randall
|
||||
Brett Rosen
|
||||
Brian Cristante
|
||||
@ -117,6 +125,7 @@ burrows
|
||||
Bussonnier Matthias
|
||||
bwoodsend
|
||||
c22
|
||||
Caleb Brown
|
||||
Caleb Martinez
|
||||
Calvin Smith
|
||||
Carl Meyer
|
||||
@ -125,11 +134,14 @@ Carol Willing
|
||||
Carter Thayer
|
||||
Cass
|
||||
Chandrasekhar Atina
|
||||
Charlie Marsh
|
||||
charwick
|
||||
Chih-Hsuan Yen
|
||||
Chris Brinker
|
||||
Chris Hunt
|
||||
Chris Jerdonek
|
||||
Chris Kuehl
|
||||
Chris Markiewicz
|
||||
Chris McDonough
|
||||
Chris Pawley
|
||||
Chris Pryer
|
||||
@ -140,6 +152,7 @@ Christian Oudard
|
||||
Christoph Reiter
|
||||
Christopher Hunt
|
||||
Christopher Snyder
|
||||
chrysle
|
||||
cjc7373
|
||||
Clark Boylan
|
||||
Claudio Jolowicz
|
||||
@ -157,6 +170,7 @@ Craig Kerstiens
|
||||
Cristian Sorinel
|
||||
Cristina
|
||||
Cristina Muñoz
|
||||
ctg123
|
||||
Curtis Doty
|
||||
cytolentino
|
||||
Daan De Meyer
|
||||
@ -194,6 +208,7 @@ David Evans
|
||||
David Hewitt
|
||||
David Linke
|
||||
David Poggi
|
||||
David Poznik
|
||||
David Pursehouse
|
||||
David Runge
|
||||
David Tucker
|
||||
@ -207,11 +222,13 @@ dependabot[bot]
|
||||
derwolfe
|
||||
Desetude
|
||||
Devesh Kumar Singh
|
||||
devsagul
|
||||
Diego Caraballo
|
||||
Diego Ramirez
|
||||
DiegoCaraballo
|
||||
Dimitri Merejkowsky
|
||||
Dimitri Papadopoulos
|
||||
Dimitri Papadopoulos Orfanos
|
||||
Dirk Stolle
|
||||
Dmitry Gladkov
|
||||
Dmitry Volodin
|
||||
@ -224,6 +241,7 @@ Dos Moonen
|
||||
Douglas Thor
|
||||
DrFeathers
|
||||
Dustin Ingram
|
||||
Dustin Rodrigues
|
||||
Dwayne Bailey
|
||||
Ed Morley
|
||||
Edgar Ramírez
|
||||
@ -265,6 +283,7 @@ Florian Briand
|
||||
Florian Rathgeber
|
||||
Francesco
|
||||
Francesco Montesano
|
||||
Fredrik Orderud
|
||||
Frost Ming
|
||||
Gabriel Curio
|
||||
Gabriel de Perthuis
|
||||
@ -315,6 +334,7 @@ Ian Stapleton Cordasco
|
||||
Ian Wienand
|
||||
Igor Kuzmitshov
|
||||
Igor Sobreira
|
||||
Ikko Ashimine
|
||||
Ilan Schnell
|
||||
Illia Volochii
|
||||
Ilya Baryshev
|
||||
@ -353,17 +373,20 @@ Jeff Dairiki
|
||||
Jeff Widman
|
||||
Jelmer Vernooij
|
||||
jenix21
|
||||
Jeremy Fleischman
|
||||
Jeremy Stanley
|
||||
Jeremy Zafran
|
||||
Jesse Rittner
|
||||
Jiashuo Li
|
||||
Jim Fisher
|
||||
Jim Garrison
|
||||
Jinzhe Zeng
|
||||
Jiun Bae
|
||||
Jivan Amara
|
||||
Joe Bylund
|
||||
Joe Michelini
|
||||
John Paton
|
||||
John Sirois
|
||||
John T. Wodder II
|
||||
John-Scott Atlakson
|
||||
johnthagen
|
||||
@ -378,21 +401,26 @@ Jorge Niedbalski
|
||||
Joseph Bylund
|
||||
Joseph Long
|
||||
Josh Bronson
|
||||
Josh Cannon
|
||||
Josh Hansen
|
||||
Josh Schneier
|
||||
Joshua
|
||||
JoshuaPerdue
|
||||
Juan Luis Cano Rodríguez
|
||||
Juanjo Bazán
|
||||
Judah Rand
|
||||
Julian Berman
|
||||
Julian Gethmann
|
||||
Julien Demoor
|
||||
July Tikhonov
|
||||
Jussi Kukkonen
|
||||
Justin van Heek
|
||||
jwg4
|
||||
Jyrki Pulliainen
|
||||
Kai Chen
|
||||
Kai Mueller
|
||||
Kamal Bin Mustafa
|
||||
Karolina Surma
|
||||
kasium
|
||||
kaustav haldar
|
||||
keanemind
|
||||
@ -408,9 +436,11 @@ Kexuan Sun
|
||||
Kit Randel
|
||||
Klaas van Schelven
|
||||
KOLANICH
|
||||
konstin
|
||||
kpinc
|
||||
Krishna Oza
|
||||
Kumar McMillan
|
||||
Kuntal Majumder
|
||||
Kurt McKee
|
||||
Kyle Persohn
|
||||
lakshmanaram
|
||||
@ -428,6 +458,7 @@ lorddavidiii
|
||||
Loren Carvalho
|
||||
Lucas Cimon
|
||||
Ludovic Gasc
|
||||
Luis Medel
|
||||
Lukas Geiger
|
||||
Lukas Juhrich
|
||||
Luke Macken
|
||||
@ -441,11 +472,12 @@ Marc Tamlyn
|
||||
Marcus Smith
|
||||
Mariatta
|
||||
Mark Kohler
|
||||
Mark McLoughlin
|
||||
Mark Williams
|
||||
Markus Hametner
|
||||
Martey Dodoo
|
||||
Martin Fischer
|
||||
Martin Häcker
|
||||
Martin Häcker
|
||||
Martin Pavlasek
|
||||
Masaki
|
||||
Masklinn
|
||||
@ -457,10 +489,12 @@ Matt Bacchi
|
||||
Matt Good
|
||||
Matt Maker
|
||||
Matt Robenolt
|
||||
Matt Wozniski
|
||||
matthew
|
||||
Matthew Einhorn
|
||||
Matthew Feickert
|
||||
Matthew Gilliard
|
||||
Matthew Hughes
|
||||
Matthew Iversen
|
||||
Matthew Treinish
|
||||
Matthew Trumbell
|
||||
@ -495,7 +529,9 @@ Miro Hrončok
|
||||
Monica Baluna
|
||||
montefra
|
||||
Monty Taylor
|
||||
Muha Ajjan
|
||||
morotti
|
||||
mrKazzila
|
||||
Muha Ajjan
|
||||
Nadav Wexler
|
||||
Nahuel Ambrosini
|
||||
Nate Coraor
|
||||
@ -559,7 +595,9 @@ Paweł Szramowski
|
||||
Pekka Klärck
|
||||
Peter Gessler
|
||||
Peter Lisák
|
||||
Peter Shen
|
||||
Peter Waller
|
||||
Petr Viktorin
|
||||
petr-tik
|
||||
Phaneendra Chiruvella
|
||||
Phil Elson
|
||||
@ -592,6 +630,8 @@ Quentin Pradet
|
||||
R. David Murray
|
||||
Rafael Caricio
|
||||
Ralf Schmitt
|
||||
Ran Benita
|
||||
Randy Döring
|
||||
Razzi Abuissa
|
||||
rdb
|
||||
Reece Dunham
|
||||
@ -603,6 +643,7 @@ Richard Jones
|
||||
Richard Si
|
||||
Ricky Ng-Adam
|
||||
Rishi
|
||||
rmorotti
|
||||
RobberPhex
|
||||
Robert Collins
|
||||
Robert McGibbon
|
||||
@ -624,6 +665,7 @@ Russell Keith-Magee
|
||||
Ryan Shepherd
|
||||
Ryan Wooden
|
||||
ryneeverett
|
||||
S. Guliaev
|
||||
Sachi King
|
||||
Salvatore Rinchiera
|
||||
sandeepkiran-js
|
||||
@ -642,8 +684,10 @@ Seth Michael Larson
|
||||
Seth Woodworth
|
||||
Shahar Epstein
|
||||
Shantanu
|
||||
shenxianpeng
|
||||
shireenrao
|
||||
Shivansh-007
|
||||
Shixian Sheng
|
||||
Shlomi Fish
|
||||
Shovan Maity
|
||||
Simeon Visser
|
||||
@ -655,6 +699,7 @@ snook92
|
||||
socketubs
|
||||
Sorin Sbarnea
|
||||
Srinivas Nyayapati
|
||||
Srishti Hegde
|
||||
Stavros Korokithakis
|
||||
Stefan Scherfke
|
||||
Stefano Rivera
|
||||
@ -675,6 +720,7 @@ Stéphane Klein
|
||||
Sumana Harihareswara
|
||||
Surbhi Sharma
|
||||
Sviatoslav Sydorenko
|
||||
Sviatoslav Sydorenko (Святослав Сидоренко)
|
||||
Swat009
|
||||
Sylvain
|
||||
Takayuki SHIMIZUKAWA
|
||||
@ -741,6 +787,7 @@ Wolfgang Maier
|
||||
Wu Zhenyu
|
||||
XAMES3
|
||||
Xavier Fernandez
|
||||
Xianpeng Shen
|
||||
xoviat
|
||||
xtreak
|
||||
YAMAMOTO Takashi
|
||||
@ -757,4 +804,3 @@ Zvezdan Petkovic
|
||||
Łukasz Langa
|
||||
Роман Донченко
|
||||
Семён Марьясин
|
||||
rekcäH nitraM
|
||||
@ -1,6 +1,6 @@
|
||||
Metadata-Version: 2.1
|
||||
Metadata-Version: 2.2
|
||||
Name: pip
|
||||
Version: 24.0
|
||||
Version: 25.0.1
|
||||
Summary: The PyPA recommended tool for installing Python packages.
|
||||
Author-email: The pip developers <distutils-sig@python.org>
|
||||
License: MIT
|
||||
@ -15,15 +15,15 @@ Classifier: Topic :: Software Development :: Build Tools
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3 :: Only
|
||||
Classifier: Programming Language :: Python :: 3.7
|
||||
Classifier: Programming Language :: Python :: 3.8
|
||||
Classifier: Programming Language :: Python :: 3.9
|
||||
Classifier: Programming Language :: Python :: 3.10
|
||||
Classifier: Programming Language :: Python :: 3.11
|
||||
Classifier: Programming Language :: Python :: 3.12
|
||||
Classifier: Programming Language :: Python :: 3.13
|
||||
Classifier: Programming Language :: Python :: Implementation :: CPython
|
||||
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
||||
Requires-Python: >=3.7
|
||||
Requires-Python: >=3.8
|
||||
Description-Content-Type: text/x-rst
|
||||
License-File: LICENSE.txt
|
||||
License-File: AUTHORS.txt
|
||||
@ -31,18 +31,20 @@ License-File: AUTHORS.txt
|
||||
pip - The Python Package Installer
|
||||
==================================
|
||||
|
||||
.. image:: https://img.shields.io/pypi/v/pip.svg
|
||||
.. |pypi-version| image:: https://img.shields.io/pypi/v/pip.svg
|
||||
:target: https://pypi.org/project/pip/
|
||||
:alt: PyPI
|
||||
|
||||
.. image:: https://img.shields.io/pypi/pyversions/pip
|
||||
.. |python-versions| image:: https://img.shields.io/pypi/pyversions/pip
|
||||
:target: https://pypi.org/project/pip
|
||||
:alt: PyPI - Python Version
|
||||
|
||||
.. image:: https://readthedocs.org/projects/pip/badge/?version=latest
|
||||
.. |docs-badge| image:: https://readthedocs.org/projects/pip/badge/?version=latest
|
||||
:target: https://pip.pypa.io/en/latest
|
||||
:alt: Documentation
|
||||
|
||||
|pypi-version| |python-versions| |docs-badge|
|
||||
|
||||
pip is the `package installer`_ for Python. You can use pip to install packages from the `Python Package Index`_ and other indexes.
|
||||
|
||||
Please take a look at our documentation for how to install and use pip:
|
||||
854
llmlab/lib/python3.12/site-packages/pip-25.0.1.dist-info/RECORD
Normal file
854
llmlab/lib/python3.12/site-packages/pip-25.0.1.dist-info/RECORD
Normal file
@ -0,0 +1,854 @@
|
||||
../../../bin/pip,sha256=ylmpUKFndjlrNY_dt86VbK0KJESPnxFlWLqpFX3k9ek,246
|
||||
../../../bin/pip3,sha256=ylmpUKFndjlrNY_dt86VbK0KJESPnxFlWLqpFX3k9ek,246
|
||||
../../../bin/pip3.12,sha256=ylmpUKFndjlrNY_dt86VbK0KJESPnxFlWLqpFX3k9ek,246
|
||||
pip-25.0.1.dist-info/AUTHORS.txt,sha256=HqzpBVLfT1lBthqQfiDlVeFkg65hJ7ZQvvWhoq-BAsA,11018
|
||||
pip-25.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
pip-25.0.1.dist-info/LICENSE.txt,sha256=Y0MApmnUmurmWxLGxIySTFGkzfPR_whtw0VtyLyqIQQ,1093
|
||||
pip-25.0.1.dist-info/METADATA,sha256=T6cxjPMPl523zsRcEsu8K0-IoV8S7vv1mmKR0KA6-SY,3677
|
||||
pip-25.0.1.dist-info/RECORD,,
|
||||
pip-25.0.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pip-25.0.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
||||
pip-25.0.1.dist-info/entry_points.txt,sha256=eeIjuzfnfR2PrhbjnbzFU6MnSS70kZLxwaHHq6M-bD0,87
|
||||
pip-25.0.1.dist-info/top_level.txt,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
pip/__init__.py,sha256=aKiv_sTe7UbE7qmtCinJutFjqN0MndZQZ1fKLNwFFLE,357
|
||||
pip/__main__.py,sha256=WzbhHXTbSE6gBY19mNN9m4s5o_365LOvTYSgqgbdBhE,854
|
||||
pip/__pip-runner__.py,sha256=cPPWuJ6NK_k-GzfvlejLFgwzmYUROmpAR6QC3Q-vkXQ,1450
|
||||
pip/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/__pycache__/__main__.cpython-312.pyc,,
|
||||
pip/__pycache__/__pip-runner__.cpython-312.pyc,,
|
||||
pip/_internal/__init__.py,sha256=MfcoOluDZ8QMCFYal04IqOJ9q6m2V7a0aOsnI-WOxUo,513
|
||||
pip/_internal/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_internal/__pycache__/build_env.cpython-312.pyc,,
|
||||
pip/_internal/__pycache__/cache.cpython-312.pyc,,
|
||||
pip/_internal/__pycache__/configuration.cpython-312.pyc,,
|
||||
pip/_internal/__pycache__/exceptions.cpython-312.pyc,,
|
||||
pip/_internal/__pycache__/main.cpython-312.pyc,,
|
||||
pip/_internal/__pycache__/pyproject.cpython-312.pyc,,
|
||||
pip/_internal/__pycache__/self_outdated_check.cpython-312.pyc,,
|
||||
pip/_internal/__pycache__/wheel_builder.cpython-312.pyc,,
|
||||
pip/_internal/build_env.py,sha256=Dv4UCClSg4uNaal_hL-trg5-zl3Is9CuIDxkChCkXF4,10700
|
||||
pip/_internal/cache.py,sha256=Jb698p5PNigRtpW5o26wQNkkUv4MnQ94mc471wL63A0,10369
|
||||
pip/_internal/cli/__init__.py,sha256=FkHBgpxxb-_gd6r1FjnNhfMOzAUYyXoXKJ6abijfcFU,132
|
||||
pip/_internal/cli/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_internal/cli/__pycache__/autocompletion.cpython-312.pyc,,
|
||||
pip/_internal/cli/__pycache__/base_command.cpython-312.pyc,,
|
||||
pip/_internal/cli/__pycache__/cmdoptions.cpython-312.pyc,,
|
||||
pip/_internal/cli/__pycache__/command_context.cpython-312.pyc,,
|
||||
pip/_internal/cli/__pycache__/index_command.cpython-312.pyc,,
|
||||
pip/_internal/cli/__pycache__/main.cpython-312.pyc,,
|
||||
pip/_internal/cli/__pycache__/main_parser.cpython-312.pyc,,
|
||||
pip/_internal/cli/__pycache__/parser.cpython-312.pyc,,
|
||||
pip/_internal/cli/__pycache__/progress_bars.cpython-312.pyc,,
|
||||
pip/_internal/cli/__pycache__/req_command.cpython-312.pyc,,
|
||||
pip/_internal/cli/__pycache__/spinners.cpython-312.pyc,,
|
||||
pip/_internal/cli/__pycache__/status_codes.cpython-312.pyc,,
|
||||
pip/_internal/cli/autocompletion.py,sha256=Lli3Mr6aDNu7ZkJJFFvwD2-hFxNI6Avz8OwMyS5TVrs,6865
|
||||
pip/_internal/cli/base_command.py,sha256=NZin6KMzW9NSYzKk4Tc8isb_TQYKR4CKd5j9mSm46PI,8625
|
||||
pip/_internal/cli/cmdoptions.py,sha256=V3BB22F4_v_RkHaZ5onWnszhbBtjYZvNhbn9M0NO0HI,30116
|
||||
pip/_internal/cli/command_context.py,sha256=RHgIPwtObh5KhMrd3YZTkl8zbVG-6Okml7YbFX4Ehg0,774
|
||||
pip/_internal/cli/index_command.py,sha256=i_sgNlPmXC5iHUaY-dmmrHKKTgc5O4hWzisr5Al1rr0,5677
|
||||
pip/_internal/cli/main.py,sha256=BDZef-bWe9g9Jpr4OVs4dDf-845HJsKw835T7AqEnAc,2817
|
||||
pip/_internal/cli/main_parser.py,sha256=laDpsuBDl6kyfywp9eMMA9s84jfH2TJJn-vmL0GG90w,4338
|
||||
pip/_internal/cli/parser.py,sha256=VCMtduzECUV87KaHNu-xJ-wLNL82yT3x16V4XBxOAqI,10825
|
||||
pip/_internal/cli/progress_bars.py,sha256=9GcgusWtwfqou2zhAQp1XNbQHIDslqyyz9UwLzw7Jgc,2717
|
||||
pip/_internal/cli/req_command.py,sha256=DqeFhmUMs6o6Ev8qawAcOoYNdAZsfyKS0MZI5jsJYwQ,12250
|
||||
pip/_internal/cli/spinners.py,sha256=hIJ83GerdFgFCdobIA23Jggetegl_uC4Sp586nzFbPE,5118
|
||||
pip/_internal/cli/status_codes.py,sha256=sEFHUaUJbqv8iArL3HAtcztWZmGOFX01hTesSytDEh0,116
|
||||
pip/_internal/commands/__init__.py,sha256=5oRO9O3dM2vGuh0bFw4HOVletryrz5HHMmmPWwJrH9U,3882
|
||||
pip/_internal/commands/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_internal/commands/__pycache__/cache.cpython-312.pyc,,
|
||||
pip/_internal/commands/__pycache__/check.cpython-312.pyc,,
|
||||
pip/_internal/commands/__pycache__/completion.cpython-312.pyc,,
|
||||
pip/_internal/commands/__pycache__/configuration.cpython-312.pyc,,
|
||||
pip/_internal/commands/__pycache__/debug.cpython-312.pyc,,
|
||||
pip/_internal/commands/__pycache__/download.cpython-312.pyc,,
|
||||
pip/_internal/commands/__pycache__/freeze.cpython-312.pyc,,
|
||||
pip/_internal/commands/__pycache__/hash.cpython-312.pyc,,
|
||||
pip/_internal/commands/__pycache__/help.cpython-312.pyc,,
|
||||
pip/_internal/commands/__pycache__/index.cpython-312.pyc,,
|
||||
pip/_internal/commands/__pycache__/inspect.cpython-312.pyc,,
|
||||
pip/_internal/commands/__pycache__/install.cpython-312.pyc,,
|
||||
pip/_internal/commands/__pycache__/list.cpython-312.pyc,,
|
||||
pip/_internal/commands/__pycache__/search.cpython-312.pyc,,
|
||||
pip/_internal/commands/__pycache__/show.cpython-312.pyc,,
|
||||
pip/_internal/commands/__pycache__/uninstall.cpython-312.pyc,,
|
||||
pip/_internal/commands/__pycache__/wheel.cpython-312.pyc,,
|
||||
pip/_internal/commands/cache.py,sha256=IOezTicHjGE5sWdBx2nwPVgbjuJHM3s-BZEkpZLemuY,8107
|
||||
pip/_internal/commands/check.py,sha256=Hr_4eiMd9cgVDgEvjtIdw915NmL7ROIWW8enkr8slPQ,2268
|
||||
pip/_internal/commands/completion.py,sha256=HT4lD0bgsflHq2IDgYfiEdp7IGGtE7s6MgI3xn0VQEw,4287
|
||||
pip/_internal/commands/configuration.py,sha256=n98enwp6y0b5G6fiRQjaZo43FlJKYve_daMhN-4BRNc,9766
|
||||
pip/_internal/commands/debug.py,sha256=DNDRgE9YsKrbYzU0s3VKi8rHtKF4X13CJ_br_8PUXO0,6797
|
||||
pip/_internal/commands/download.py,sha256=0qB0nys6ZEPsog451lDsjL5Bx7Z97t-B80oFZKhpzKM,5273
|
||||
pip/_internal/commands/freeze.py,sha256=2Vt72BYTSm9rzue6d8dNzt8idxWK4Db6Hd-anq7GQ80,3203
|
||||
pip/_internal/commands/hash.py,sha256=EVVOuvGtoPEdFi8SNnmdqlCQrhCxV-kJsdwtdcCnXGQ,1703
|
||||
pip/_internal/commands/help.py,sha256=gcc6QDkcgHMOuAn5UxaZwAStsRBrnGSn_yxjS57JIoM,1132
|
||||
pip/_internal/commands/index.py,sha256=RAXxmJwFhVb5S1BYzb5ifX3sn9Na8v2CCVYwSMP8pao,4731
|
||||
pip/_internal/commands/inspect.py,sha256=PGrY9TRTRCM3y5Ml8Bdk8DEOXquWRfscr4DRo1LOTPc,3189
|
||||
pip/_internal/commands/install.py,sha256=r3yHQUxvxt7gD5j9n6zRDslAvtx9CT_whLuQJcktp6M,29390
|
||||
pip/_internal/commands/list.py,sha256=oiIzSjLP6__d7dIS3q0Xb5ywsaOThBWRqMyjjKzkPdM,12769
|
||||
pip/_internal/commands/search.py,sha256=fWkUQVx_gm8ebbFAlCgqtxKXT9rNahpJ-BI__3HNZpg,5626
|
||||
pip/_internal/commands/show.py,sha256=0YBhCga3PAd81vT3l7UWflktSpB5-aYqQcJxBVPazVM,7857
|
||||
pip/_internal/commands/uninstall.py,sha256=7pOR7enK76gimyxQbzxcG1OsyLXL3DvX939xmM8Fvtg,3892
|
||||
pip/_internal/commands/wheel.py,sha256=eJRhr_qoNNxWAkkdJCNiQM7CXd4E1_YyQhsqJnBPGGg,6414
|
||||
pip/_internal/configuration.py,sha256=-KOok6jh3hFzXMPQFPJ1_EFjBpAsge-RSreQuLHLmzo,14005
|
||||
pip/_internal/distributions/__init__.py,sha256=Hq6kt6gXBgjNit5hTTWLAzeCNOKoB-N0pGYSqehrli8,858
|
||||
pip/_internal/distributions/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_internal/distributions/__pycache__/base.cpython-312.pyc,,
|
||||
pip/_internal/distributions/__pycache__/installed.cpython-312.pyc,,
|
||||
pip/_internal/distributions/__pycache__/sdist.cpython-312.pyc,,
|
||||
pip/_internal/distributions/__pycache__/wheel.cpython-312.pyc,,
|
||||
pip/_internal/distributions/base.py,sha256=QeB9qvKXDIjLdPBDE5fMgpfGqMMCr-govnuoQnGuiF8,1783
|
||||
pip/_internal/distributions/installed.py,sha256=QinHFbWAQ8oE0pbD8MFZWkwlnfU1QYTccA1vnhrlYOU,842
|
||||
pip/_internal/distributions/sdist.py,sha256=PlcP4a6-R6c98XnOM-b6Lkb3rsvh9iG4ok8shaanrzs,6751
|
||||
pip/_internal/distributions/wheel.py,sha256=THBYfnv7VVt8mYhMYUtH13S1E7FDwtDyDfmUcl8ai0E,1317
|
||||
pip/_internal/exceptions.py,sha256=2_byISIv3kSnI_9T-Esfxrt0LnTRgcUHyxu0twsHjQY,26481
|
||||
pip/_internal/index/__init__.py,sha256=vpt-JeTZefh8a-FC22ZeBSXFVbuBcXSGiILhQZJaNpQ,30
|
||||
pip/_internal/index/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_internal/index/__pycache__/collector.cpython-312.pyc,,
|
||||
pip/_internal/index/__pycache__/package_finder.cpython-312.pyc,,
|
||||
pip/_internal/index/__pycache__/sources.cpython-312.pyc,,
|
||||
pip/_internal/index/collector.py,sha256=RdPO0JLAlmyBWPAWYHPyRoGjz3GNAeTngCNkbGey_mE,16265
|
||||
pip/_internal/index/package_finder.py,sha256=mJHAljlHeHuclyuxtjvBZO6DtovKjsZjF_tCh_wux5E,38076
|
||||
pip/_internal/index/sources.py,sha256=lPBLK5Xiy8Q6IQMio26Wl7ocfZOKkgGklIBNyUJ23fI,8632
|
||||
pip/_internal/locations/__init__.py,sha256=UaAxeZ_f93FyouuFf4p7SXYF-4WstXuEvd3LbmPCAno,14925
|
||||
pip/_internal/locations/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_internal/locations/__pycache__/_distutils.cpython-312.pyc,,
|
||||
pip/_internal/locations/__pycache__/_sysconfig.cpython-312.pyc,,
|
||||
pip/_internal/locations/__pycache__/base.cpython-312.pyc,,
|
||||
pip/_internal/locations/_distutils.py,sha256=x6nyVLj7X11Y4khIdf-mFlxMl2FWadtVEgeb8upc_WI,6013
|
||||
pip/_internal/locations/_sysconfig.py,sha256=IGzds60qsFneRogC-oeBaY7bEh3lPt_v47kMJChQXsU,7724
|
||||
pip/_internal/locations/base.py,sha256=RQiPi1d4FVM2Bxk04dQhXZ2PqkeljEL2fZZ9SYqIQ78,2556
|
||||
pip/_internal/main.py,sha256=r-UnUe8HLo5XFJz8inTcOOTiu_sxNhgHb6VwlGUllOI,340
|
||||
pip/_internal/metadata/__init__.py,sha256=CU8jK1TZso7jOLdr0sX9xDjrcs5iy8d7IRK-hvaIO5Y,4337
|
||||
pip/_internal/metadata/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_internal/metadata/__pycache__/_json.cpython-312.pyc,,
|
||||
pip/_internal/metadata/__pycache__/base.cpython-312.pyc,,
|
||||
pip/_internal/metadata/__pycache__/pkg_resources.cpython-312.pyc,,
|
||||
pip/_internal/metadata/_json.py,sha256=ezrIYazHCINM2QUk1eA9wEAMj3aeGWeDVgGalgUzKpc,2707
|
||||
pip/_internal/metadata/base.py,sha256=ft0K5XNgI4ETqZnRv2-CtvgYiMOMAeGMAzxT-f6VLJA,25298
|
||||
pip/_internal/metadata/importlib/__init__.py,sha256=jUUidoxnHcfITHHaAWG1G2i5fdBYklv_uJcjo2x7VYE,135
|
||||
pip/_internal/metadata/importlib/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_internal/metadata/importlib/__pycache__/_compat.cpython-312.pyc,,
|
||||
pip/_internal/metadata/importlib/__pycache__/_dists.cpython-312.pyc,,
|
||||
pip/_internal/metadata/importlib/__pycache__/_envs.cpython-312.pyc,,
|
||||
pip/_internal/metadata/importlib/_compat.py,sha256=c6av8sP8BBjAZuFSJow1iWfygUXNM3xRTCn5nqw6B9M,2796
|
||||
pip/_internal/metadata/importlib/_dists.py,sha256=ftmYiyfUGUIjnVwt6W-Ijsimy5c28KgmXly5Q5IQ2P4,8279
|
||||
pip/_internal/metadata/importlib/_envs.py,sha256=UUB980XSrDWrMpQ1_G45i0r8Hqlg_tg3IPQ63mEqbNc,7431
|
||||
pip/_internal/metadata/pkg_resources.py,sha256=U07ETAINSGeSRBfWUG93E4tZZbaW_f7PGzEqZN0hulc,10542
|
||||
pip/_internal/models/__init__.py,sha256=3DHUd_qxpPozfzouoqa9g9ts1Czr5qaHfFxbnxriepM,63
|
||||
pip/_internal/models/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_internal/models/__pycache__/candidate.cpython-312.pyc,,
|
||||
pip/_internal/models/__pycache__/direct_url.cpython-312.pyc,,
|
||||
pip/_internal/models/__pycache__/format_control.cpython-312.pyc,,
|
||||
pip/_internal/models/__pycache__/index.cpython-312.pyc,,
|
||||
pip/_internal/models/__pycache__/installation_report.cpython-312.pyc,,
|
||||
pip/_internal/models/__pycache__/link.cpython-312.pyc,,
|
||||
pip/_internal/models/__pycache__/scheme.cpython-312.pyc,,
|
||||
pip/_internal/models/__pycache__/search_scope.cpython-312.pyc,,
|
||||
pip/_internal/models/__pycache__/selection_prefs.cpython-312.pyc,,
|
||||
pip/_internal/models/__pycache__/target_python.cpython-312.pyc,,
|
||||
pip/_internal/models/__pycache__/wheel.cpython-312.pyc,,
|
||||
pip/_internal/models/candidate.py,sha256=zzgFRuw_kWPjKpGw7LC0ZUMD2CQ2EberUIYs8izjdCA,753
|
||||
pip/_internal/models/direct_url.py,sha256=uBtY2HHd3TO9cKQJWh0ThvE5FRr-MWRYChRU4IG9HZE,6578
|
||||
pip/_internal/models/format_control.py,sha256=wtsQqSK9HaUiNxQEuB-C62eVimw6G4_VQFxV9-_KDBE,2486
|
||||
pip/_internal/models/index.py,sha256=tYnL8oxGi4aSNWur0mG8DAP7rC6yuha_MwJO8xw0crI,1030
|
||||
pip/_internal/models/installation_report.py,sha256=zRVZoaz-2vsrezj_H3hLOhMZCK9c7TbzWgC-jOalD00,2818
|
||||
pip/_internal/models/link.py,sha256=GQ8hq7x-FDFPv25Nbn2veIM-MlBrGZDGLd7aZeF4Xrg,21448
|
||||
pip/_internal/models/scheme.py,sha256=PakmHJM3e8OOWSZFtfz1Az7f1meONJnkGuQxFlt3wBE,575
|
||||
pip/_internal/models/search_scope.py,sha256=67NEnsYY84784S-MM7ekQuo9KXLH-7MzFntXjapvAo0,4531
|
||||
pip/_internal/models/selection_prefs.py,sha256=qaFfDs3ciqoXPg6xx45N1jPLqccLJw4N0s4P0PyHTQ8,2015
|
||||
pip/_internal/models/target_python.py,sha256=2XaH2rZ5ZF-K5wcJbEMGEl7SqrTToDDNkrtQ2v_v_-Q,4271
|
||||
pip/_internal/models/wheel.py,sha256=G7dND_s4ebPkEL7RJ1qCY0QhUUWIIK6AnjWgRATF5no,4539
|
||||
pip/_internal/network/__init__.py,sha256=jf6Tt5nV_7zkARBrKojIXItgejvoegVJVKUbhAa5Ioc,50
|
||||
pip/_internal/network/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_internal/network/__pycache__/auth.cpython-312.pyc,,
|
||||
pip/_internal/network/__pycache__/cache.cpython-312.pyc,,
|
||||
pip/_internal/network/__pycache__/download.cpython-312.pyc,,
|
||||
pip/_internal/network/__pycache__/lazy_wheel.cpython-312.pyc,,
|
||||
pip/_internal/network/__pycache__/session.cpython-312.pyc,,
|
||||
pip/_internal/network/__pycache__/utils.cpython-312.pyc,,
|
||||
pip/_internal/network/__pycache__/xmlrpc.cpython-312.pyc,,
|
||||
pip/_internal/network/auth.py,sha256=D4gASjUrqoDFlSt6gQ767KAAjv6PUyJU0puDlhXNVRE,20809
|
||||
pip/_internal/network/cache.py,sha256=0yGMA3Eet59xBSLtbPAenvI53dl29oUOeqZ2c0QL2Ss,4614
|
||||
pip/_internal/network/download.py,sha256=FLOP29dPYECBiAi7eEjvAbNkyzaKNqbyjOT2m8HPW8U,6048
|
||||
pip/_internal/network/lazy_wheel.py,sha256=PBdoMoNQQIA84Fhgne38jWF52W4x_KtsHjxgv4dkRKA,7622
|
||||
pip/_internal/network/session.py,sha256=msM4es16LmmNEYNkrYyg8fTc7gAHbKFltawfKP27LOI,18771
|
||||
pip/_internal/network/utils.py,sha256=Inaxel-NxBu4PQWkjyErdnfewsFCcgHph7dzR1-FboY,4088
|
||||
pip/_internal/network/xmlrpc.py,sha256=sAxzOacJ-N1NXGPvap9jC3zuYWSnnv3GXtgR2-E2APA,1838
|
||||
pip/_internal/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pip/_internal/operations/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_internal/operations/__pycache__/check.cpython-312.pyc,,
|
||||
pip/_internal/operations/__pycache__/freeze.cpython-312.pyc,,
|
||||
pip/_internal/operations/__pycache__/prepare.cpython-312.pyc,,
|
||||
pip/_internal/operations/build/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pip/_internal/operations/build/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_internal/operations/build/__pycache__/build_tracker.cpython-312.pyc,,
|
||||
pip/_internal/operations/build/__pycache__/metadata.cpython-312.pyc,,
|
||||
pip/_internal/operations/build/__pycache__/metadata_editable.cpython-312.pyc,,
|
||||
pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-312.pyc,,
|
||||
pip/_internal/operations/build/__pycache__/wheel.cpython-312.pyc,,
|
||||
pip/_internal/operations/build/__pycache__/wheel_editable.cpython-312.pyc,,
|
||||
pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-312.pyc,,
|
||||
pip/_internal/operations/build/build_tracker.py,sha256=-ARW_TcjHCOX7D2NUOGntB4Fgc6b4aolsXkAK6BWL7w,4774
|
||||
pip/_internal/operations/build/metadata.py,sha256=9S0CUD8U3QqZeXp-Zyt8HxwU90lE4QrnYDgrqZDzBnc,1422
|
||||
pip/_internal/operations/build/metadata_editable.py,sha256=xlAwcP9q_8_fmv_3I39w9EZ7SQV9hnJZr9VuTsq2Y68,1510
|
||||
pip/_internal/operations/build/metadata_legacy.py,sha256=8i6i1QZX9m_lKPStEFsHKM0MT4a-CD408JOw99daLmo,2190
|
||||
pip/_internal/operations/build/wheel.py,sha256=sT12FBLAxDC6wyrDorh8kvcZ1jG5qInCRWzzP-UkJiQ,1075
|
||||
pip/_internal/operations/build/wheel_editable.py,sha256=yOtoH6zpAkoKYEUtr8FhzrYnkNHQaQBjWQ2HYae1MQg,1417
|
||||
pip/_internal/operations/build/wheel_legacy.py,sha256=K-6kNhmj-1xDF45ny1yheMerF0ui4EoQCLzEoHh6-tc,3045
|
||||
pip/_internal/operations/check.py,sha256=L24vRL8VWbyywdoeAhM89WCd8zLTnjIbULlKelUgIec,5912
|
||||
pip/_internal/operations/freeze.py,sha256=1_M79jAQKnCxWr-KCCmHuVXOVFGaUJHmoWLfFzgh7K4,9843
|
||||
pip/_internal/operations/install/__init__.py,sha256=mX7hyD2GNBO2mFGokDQ30r_GXv7Y_PLdtxcUv144e-s,51
|
||||
pip/_internal/operations/install/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_internal/operations/install/__pycache__/editable_legacy.cpython-312.pyc,,
|
||||
pip/_internal/operations/install/__pycache__/wheel.cpython-312.pyc,,
|
||||
pip/_internal/operations/install/editable_legacy.py,sha256=PoEsNEPGbIZ2yQphPsmYTKLOCMs4gv5OcCdzW124NcA,1283
|
||||
pip/_internal/operations/install/wheel.py,sha256=X5Iz9yUg5LlK5VNQ9g2ikc6dcRu8EPi_SUi5iuEDRgo,27615
|
||||
pip/_internal/operations/prepare.py,sha256=joWJwPkuqGscQgVNImLK71e9hRapwKvRCM8HclysmvU,28118
|
||||
pip/_internal/pyproject.py,sha256=GLJ6rWRS5_2noKdajohoLyDty57Z7QXhcUAYghmTnWc,7286
|
||||
pip/_internal/req/__init__.py,sha256=HxBFtZy_BbCclLgr26waMtpzYdO5T3vxePvpGAXSt5s,2653
|
||||
pip/_internal/req/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_internal/req/__pycache__/constructors.cpython-312.pyc,,
|
||||
pip/_internal/req/__pycache__/req_file.cpython-312.pyc,,
|
||||
pip/_internal/req/__pycache__/req_install.cpython-312.pyc,,
|
||||
pip/_internal/req/__pycache__/req_set.cpython-312.pyc,,
|
||||
pip/_internal/req/__pycache__/req_uninstall.cpython-312.pyc,,
|
||||
pip/_internal/req/constructors.py,sha256=v1qzCN1mIldwx-nCrPc8JO4lxkm3Fv8M5RWvt8LISjc,18430
|
||||
pip/_internal/req/req_file.py,sha256=eys82McgaICOGic2UZRHjD720piKJPwmeSYdXlWwl6w,20234
|
||||
pip/_internal/req/req_install.py,sha256=BMptxHYg2uG_b-7HFEULPb3nuw0FMAbuea8zTq2rE7w,35786
|
||||
pip/_internal/req/req_set.py,sha256=j3esG0s6SzoVReX9rWn4rpYNtyET_fwxbwJPRimvRxo,2858
|
||||
pip/_internal/req/req_uninstall.py,sha256=qzDIxJo-OETWqGais7tSMCDcWbATYABT-Tid3ityF0s,23853
|
||||
pip/_internal/resolution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pip/_internal/resolution/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_internal/resolution/__pycache__/base.cpython-312.pyc,,
|
||||
pip/_internal/resolution/base.py,sha256=qlmh325SBVfvG6Me9gc5Nsh5sdwHBwzHBq6aEXtKsLA,583
|
||||
pip/_internal/resolution/legacy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pip/_internal/resolution/legacy/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_internal/resolution/legacy/__pycache__/resolver.cpython-312.pyc,,
|
||||
pip/_internal/resolution/legacy/resolver.py,sha256=3HZiJBRd1FTN6jQpI4qRO8-TbLYeIbUTS6PFvXnXs2w,24068
|
||||
pip/_internal/resolution/resolvelib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_internal/resolution/resolvelib/__pycache__/base.cpython-312.pyc,,
|
||||
pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-312.pyc,,
|
||||
pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-312.pyc,,
|
||||
pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-312.pyc,,
|
||||
pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-312.pyc,,
|
||||
pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-312.pyc,,
|
||||
pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-312.pyc,,
|
||||
pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-312.pyc,,
|
||||
pip/_internal/resolution/resolvelib/base.py,sha256=DCf669FsqyQY5uqXeePDHQY1e4QO-pBzWH8O0s9-K94,5023
|
||||
pip/_internal/resolution/resolvelib/candidates.py,sha256=5UZ1upNnmqsP-nmEZaDYxaBgCoejw_e2WVGmmAvBxXc,20001
|
||||
pip/_internal/resolution/resolvelib/factory.py,sha256=MJOLSZJY8_28PPdcutoQ6gjJ_1eBDt6Z1edtfTJyR4E,32659
|
||||
pip/_internal/resolution/resolvelib/found_candidates.py,sha256=9hrTyQqFvl9I7Tji79F1AxHv39Qh1rkJ_7deSHSMfQc,6383
|
||||
pip/_internal/resolution/resolvelib/provider.py,sha256=bcsFnYvlmtB80cwVdW1fIwgol8ZNr1f1VHyRTkz47SM,9935
|
||||
pip/_internal/resolution/resolvelib/reporter.py,sha256=00JtoXEkTlw0-rl_sl54d71avwOsJHt9GGHcrj5Sza0,3168
|
||||
pip/_internal/resolution/resolvelib/requirements.py,sha256=7JG4Z72e5Yk4vU0S5ulGvbqTy4FMQGYhY5zQhX9zTtY,8065
|
||||
pip/_internal/resolution/resolvelib/resolver.py,sha256=nLJOsVMEVi2gQUVJoUFKMZAeu2f7GRMjGMvNSWyz0Bc,12592
|
||||
pip/_internal/self_outdated_check.py,sha256=1PFtttvLAeyCVR3tPoBq2sOlPD0IJ-KSqU6bc1HUk9c,8318
|
||||
pip/_internal/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pip/_internal/utils/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/_jaraco_text.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/_log.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/appdirs.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/compat.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/compatibility_tags.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/datetime.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/deprecation.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/direct_url_helpers.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/egg_link.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/entrypoints.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/filesystem.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/filetypes.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/glibc.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/hashes.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/logging.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/misc.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/packaging.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/retry.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/setuptools_build.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/subprocess.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/temp_dir.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/unpacking.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/urls.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/virtualenv.cpython-312.pyc,,
|
||||
pip/_internal/utils/__pycache__/wheel.cpython-312.pyc,,
|
||||
pip/_internal/utils/_jaraco_text.py,sha256=M15uUPIh5NpP1tdUGBxRau6q1ZAEtI8-XyLEETscFfE,3350
|
||||
pip/_internal/utils/_log.py,sha256=-jHLOE_THaZz5BFcCnoSL9EYAtJ0nXem49s9of4jvKw,1015
|
||||
pip/_internal/utils/appdirs.py,sha256=swgcTKOm3daLeXTW6v5BUS2Ti2RvEnGRQYH_yDXklAo,1665
|
||||
pip/_internal/utils/compat.py,sha256=ckkFveBiYQjRWjkNsajt_oWPS57tJvE8XxoC4OIYgCY,2399
|
||||
pip/_internal/utils/compatibility_tags.py,sha256=OWq5axHpW-MEEPztGdvgADrgJPAcV9a88Rxm4Z8VBs8,6272
|
||||
pip/_internal/utils/datetime.py,sha256=m21Y3wAtQc-ji6Veb6k_M5g6A0ZyFI4egchTdnwh-pQ,242
|
||||
pip/_internal/utils/deprecation.py,sha256=k7Qg_UBAaaTdyq82YVARA6D7RmcGTXGv7fnfcgigj4Q,3707
|
||||
pip/_internal/utils/direct_url_helpers.py,sha256=r2MRtkVDACv9AGqYODBUC9CjwgtsUU1s68hmgfCJMtA,3196
|
||||
pip/_internal/utils/egg_link.py,sha256=0FePZoUYKv4RGQ2t6x7w5Z427wbA_Uo3WZnAkrgsuqo,2463
|
||||
pip/_internal/utils/entrypoints.py,sha256=YlhLTRl2oHBAuqhc-zmL7USS67TPWVHImjeAQHreZTQ,3064
|
||||
pip/_internal/utils/filesystem.py,sha256=ajvA-q4ocliW9kPp8Yquh-4vssXbu-UKbo5FV9V4X64,4950
|
||||
pip/_internal/utils/filetypes.py,sha256=i8XAQ0eFCog26Fw9yV0Yb1ygAqKYB1w9Cz9n0fj8gZU,716
|
||||
pip/_internal/utils/glibc.py,sha256=vUkWq_1pJuzcYNcGKLlQmABoUiisK8noYY1yc8Wq4w4,3734
|
||||
pip/_internal/utils/hashes.py,sha256=XGGLL0AG8-RhWnyz87xF6MFZ--BKadHU35D47eApCKI,4972
|
||||
pip/_internal/utils/logging.py,sha256=ONfbrhaD248akkosK79if97n20EABxwjOxp5dE5RCRY,11845
|
||||
pip/_internal/utils/misc.py,sha256=DWnYxBUItjRp7hhxEg4ih6P6YpKrykM86dbi_EcU8SQ,23450
|
||||
pip/_internal/utils/packaging.py,sha256=cm-X_0HVHV_jRwUVZh6AuEWqSitzf8EpaJ7Uv2UGu6A,2142
|
||||
pip/_internal/utils/retry.py,sha256=mhFbykXjhTnZfgzeuy-vl9c8nECnYn_CMtwNJX2tYzQ,1392
|
||||
pip/_internal/utils/setuptools_build.py,sha256=ouXpud-jeS8xPyTPsXJ-m34NPvK5os45otAzdSV_IJE,4435
|
||||
pip/_internal/utils/subprocess.py,sha256=EsvqSRiSMHF98T8Txmu6NLU3U--MpTTQjtNgKP0P--M,8988
|
||||
pip/_internal/utils/temp_dir.py,sha256=5qOXe8M4JeY6vaFQM867d5zkp1bSwMZ-KT5jymmP0Zg,9310
|
||||
pip/_internal/utils/unpacking.py,sha256=_gVdyzTRDMYktpnYljn4OoxrZTtMCf4xknSm4rK0WaA,11967
|
||||
pip/_internal/utils/urls.py,sha256=qceSOZb5lbNDrHNsv7_S4L4Ytszja5NwPKUMnZHbYnM,1599
|
||||
pip/_internal/utils/virtualenv.py,sha256=S6f7csYorRpiD6cvn3jISZYc3I8PJC43H5iMFpRAEDU,3456
|
||||
pip/_internal/utils/wheel.py,sha256=b442jkydFHjXzDy6cMR7MpzWBJ1Q82hR5F33cmcHV3g,4494
|
||||
pip/_internal/vcs/__init__.py,sha256=UAqvzpbi0VbZo3Ub6skEeZAw-ooIZR-zX_WpCbxyCoU,596
|
||||
pip/_internal/vcs/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_internal/vcs/__pycache__/bazaar.cpython-312.pyc,,
|
||||
pip/_internal/vcs/__pycache__/git.cpython-312.pyc,,
|
||||
pip/_internal/vcs/__pycache__/mercurial.cpython-312.pyc,,
|
||||
pip/_internal/vcs/__pycache__/subversion.cpython-312.pyc,,
|
||||
pip/_internal/vcs/__pycache__/versioncontrol.cpython-312.pyc,,
|
||||
pip/_internal/vcs/bazaar.py,sha256=EKStcQaKpNu0NK4p5Q10Oc4xb3DUxFw024XrJy40bFQ,3528
|
||||
pip/_internal/vcs/git.py,sha256=3tpc9LQA_J4IVW5r5NvWaaSeDzcmJOrSFZN0J8vIKfU,18177
|
||||
pip/_internal/vcs/mercurial.py,sha256=oULOhzJ2Uie-06d1omkL-_Gc6meGaUkyogvqG9ZCyPs,5249
|
||||
pip/_internal/vcs/subversion.py,sha256=ddTugHBqHzV3ebKlU5QXHPN4gUqlyXbOx8q8NgXKvs8,11735
|
||||
pip/_internal/vcs/versioncontrol.py,sha256=cvf_-hnTAjQLXJ3d17FMNhQfcO1AcKWUF10tfrYyP-c,22440
|
||||
pip/_internal/wheel_builder.py,sha256=DL3A8LKeRj_ACp11WS5wSgASgPFqeyAeXJKdXfmaWXU,11799
|
||||
pip/_vendor/__init__.py,sha256=JYuAXvClhInxIrA2FTp5p-uuWVL7WV6-vEpTs46-Qh4,4873
|
||||
pip/_vendor/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/__pycache__/typing_extensions.cpython-312.pyc,,
|
||||
pip/_vendor/cachecontrol/__init__.py,sha256=LMC5CBe94ZRL5xhlzwyPDmHXvBD0p7lT4R3Z73D6a_I,677
|
||||
pip/_vendor/cachecontrol/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-312.pyc,,
|
||||
pip/_vendor/cachecontrol/__pycache__/adapter.cpython-312.pyc,,
|
||||
pip/_vendor/cachecontrol/__pycache__/cache.cpython-312.pyc,,
|
||||
pip/_vendor/cachecontrol/__pycache__/controller.cpython-312.pyc,,
|
||||
pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-312.pyc,,
|
||||
pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-312.pyc,,
|
||||
pip/_vendor/cachecontrol/__pycache__/serialize.cpython-312.pyc,,
|
||||
pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-312.pyc,,
|
||||
pip/_vendor/cachecontrol/_cmd.py,sha256=iist2EpzJvDVIhMAxXq8iFnTBsiZAd6iplxfmNboNyk,1737
|
||||
pip/_vendor/cachecontrol/adapter.py,sha256=febjY4LV87iiCIK3jcl8iH58iaSA7b9WkovsByIDK0Y,6348
|
||||
pip/_vendor/cachecontrol/cache.py,sha256=OXwv7Fn2AwnKNiahJHnjtvaKLndvVLv_-zO-ltlV9qI,1953
|
||||
pip/_vendor/cachecontrol/caches/__init__.py,sha256=dtrrroK5BnADR1GWjCZ19aZ0tFsMfvFBtLQQU1sp_ag,303
|
||||
pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-312.pyc,,
|
||||
pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-312.pyc,,
|
||||
pip/_vendor/cachecontrol/caches/file_cache.py,sha256=b7oMgsRSqPmEsonVJw6uFEYUlFgD6GF8TyacOGG1x3M,5399
|
||||
pip/_vendor/cachecontrol/caches/redis_cache.py,sha256=9rmqwtYu_ljVkW6_oLqbC7EaX_a8YT_yLuna-eS0dgo,1386
|
||||
pip/_vendor/cachecontrol/controller.py,sha256=glbPj2iZlGqdBg8z09D2DtQOzoOGXnWvy7K2LEyBsEQ,18576
|
||||
pip/_vendor/cachecontrol/filewrapper.py,sha256=2ktXNPE0KqnyzF24aOsKCA58HQq1xeC6l2g6_zwjghc,4291
|
||||
pip/_vendor/cachecontrol/heuristics.py,sha256=gqMXU8w0gQuEQiSdu3Yg-0vd9kW7nrWKbLca75rheGE,4881
|
||||
pip/_vendor/cachecontrol/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pip/_vendor/cachecontrol/serialize.py,sha256=HQd2IllQ05HzPkVLMXTF2uX5mjEQjDBkxCqUJUODpZk,5163
|
||||
pip/_vendor/cachecontrol/wrapper.py,sha256=hsGc7g8QGQTT-4f8tgz3AM5qwScg6FO0BSdLSRdEvpU,1417
|
||||
pip/_vendor/certifi/__init__.py,sha256=p_GYZrjUwPBUhpLlCZoGb0miKBKSqDAyZC5DvIuqbHQ,94
|
||||
pip/_vendor/certifi/__main__.py,sha256=1k3Cr95vCxxGRGDljrW3wMdpZdL3Nhf0u1n-k2qdsCY,255
|
||||
pip/_vendor/certifi/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/certifi/__pycache__/__main__.cpython-312.pyc,,
|
||||
pip/_vendor/certifi/__pycache__/core.cpython-312.pyc,,
|
||||
pip/_vendor/certifi/cacert.pem,sha256=lO3rZukXdPyuk6BWUJFOKQliWaXH6HGh9l1GGrUgG0c,299427
|
||||
pip/_vendor/certifi/core.py,sha256=2SRT5rIcQChFDbe37BQa-kULxAgJ8qN6l1jfqTp4HIs,4486
|
||||
pip/_vendor/certifi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pip/_vendor/distlib/__init__.py,sha256=dcwgYGYGQqAEawBXPDtIx80DO_3cOmFv8HTc8JMzknQ,625
|
||||
pip/_vendor/distlib/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/distlib/__pycache__/compat.cpython-312.pyc,,
|
||||
pip/_vendor/distlib/__pycache__/database.cpython-312.pyc,,
|
||||
pip/_vendor/distlib/__pycache__/index.cpython-312.pyc,,
|
||||
pip/_vendor/distlib/__pycache__/locators.cpython-312.pyc,,
|
||||
pip/_vendor/distlib/__pycache__/manifest.cpython-312.pyc,,
|
||||
pip/_vendor/distlib/__pycache__/markers.cpython-312.pyc,,
|
||||
pip/_vendor/distlib/__pycache__/metadata.cpython-312.pyc,,
|
||||
pip/_vendor/distlib/__pycache__/resources.cpython-312.pyc,,
|
||||
pip/_vendor/distlib/__pycache__/scripts.cpython-312.pyc,,
|
||||
pip/_vendor/distlib/__pycache__/util.cpython-312.pyc,,
|
||||
pip/_vendor/distlib/__pycache__/version.cpython-312.pyc,,
|
||||
pip/_vendor/distlib/__pycache__/wheel.cpython-312.pyc,,
|
||||
pip/_vendor/distlib/compat.py,sha256=2jRSjRI4o-vlXeTK2BCGIUhkc6e9ZGhSsacRM5oseTw,41467
|
||||
pip/_vendor/distlib/database.py,sha256=mHy_LxiXIsIVRb-T0-idBrVLw3Ffij5teHCpbjmJ9YU,51160
|
||||
pip/_vendor/distlib/index.py,sha256=lTbw268rRhj8dw1sib3VZ_0EhSGgoJO3FKJzSFMOaeA,20797
|
||||
pip/_vendor/distlib/locators.py,sha256=oBeAZpFuPQSY09MgNnLfQGGAXXvVO96BFpZyKMuK4tM,51026
|
||||
pip/_vendor/distlib/manifest.py,sha256=3qfmAmVwxRqU1o23AlfXrQGZzh6g_GGzTAP_Hb9C5zQ,14168
|
||||
pip/_vendor/distlib/markers.py,sha256=X6sDvkFGcYS8gUW8hfsWuKEKAqhQZAJ7iXOMLxRYjYk,5164
|
||||
pip/_vendor/distlib/metadata.py,sha256=zil3sg2EUfLXVigljY2d_03IJt-JSs7nX-73fECMX2s,38724
|
||||
pip/_vendor/distlib/resources.py,sha256=LwbPksc0A1JMbi6XnuPdMBUn83X7BPuFNWqPGEKI698,10820
|
||||
pip/_vendor/distlib/scripts.py,sha256=BJliaDAZaVB7WAkwokgC3HXwLD2iWiHaVI50H7C6eG8,18608
|
||||
pip/_vendor/distlib/t32.exe,sha256=a0GV5kCoWsMutvliiCKmIgV98eRZ33wXoS-XrqvJQVs,97792
|
||||
pip/_vendor/distlib/t64-arm.exe,sha256=68TAa32V504xVBnufojh0PcenpR3U4wAqTqf-MZqbPw,182784
|
||||
pip/_vendor/distlib/t64.exe,sha256=gaYY8hy4fbkHYTTnA4i26ct8IQZzkBG2pRdy0iyuBrc,108032
|
||||
pip/_vendor/distlib/util.py,sha256=vMPGvsS4j9hF6Y9k3Tyom1aaHLb0rFmZAEyzeAdel9w,66682
|
||||
pip/_vendor/distlib/version.py,sha256=s5VIs8wBn0fxzGxWM_aA2ZZyx525HcZbMvcTlTyZ3Rg,23727
|
||||
pip/_vendor/distlib/w32.exe,sha256=R4csx3-OGM9kL4aPIzQKRo5TfmRSHZo6QWyLhDhNBks,91648
|
||||
pip/_vendor/distlib/w64-arm.exe,sha256=xdyYhKj0WDcVUOCb05blQYvzdYIKMbmJn2SZvzkcey4,168448
|
||||
pip/_vendor/distlib/w64.exe,sha256=ejGf-rojoBfXseGLpya6bFTFPWRG21X5KvU8J5iU-K0,101888
|
||||
pip/_vendor/distlib/wheel.py,sha256=DFIVguEQHCdxnSdAO0dfFsgMcvVZitg7bCOuLwZ7A_s,43979
|
||||
pip/_vendor/distro/__init__.py,sha256=2fHjF-SfgPvjyNZ1iHh_wjqWdR_Yo5ODHwZC0jLBPhc,981
|
||||
pip/_vendor/distro/__main__.py,sha256=bu9d3TifoKciZFcqRBuygV3GSuThnVD_m2IK4cz96Vs,64
|
||||
pip/_vendor/distro/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/distro/__pycache__/__main__.cpython-312.pyc,,
|
||||
pip/_vendor/distro/__pycache__/distro.cpython-312.pyc,,
|
||||
pip/_vendor/distro/distro.py,sha256=XqbefacAhDT4zr_trnbA15eY8vdK4GTghgmvUGrEM_4,49430
|
||||
pip/_vendor/distro/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pip/_vendor/idna/__init__.py,sha256=MPqNDLZbXqGaNdXxAFhiqFPKEQXju2jNQhCey6-5eJM,868
|
||||
pip/_vendor/idna/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/idna/__pycache__/codec.cpython-312.pyc,,
|
||||
pip/_vendor/idna/__pycache__/compat.cpython-312.pyc,,
|
||||
pip/_vendor/idna/__pycache__/core.cpython-312.pyc,,
|
||||
pip/_vendor/idna/__pycache__/idnadata.cpython-312.pyc,,
|
||||
pip/_vendor/idna/__pycache__/intranges.cpython-312.pyc,,
|
||||
pip/_vendor/idna/__pycache__/package_data.cpython-312.pyc,,
|
||||
pip/_vendor/idna/__pycache__/uts46data.cpython-312.pyc,,
|
||||
pip/_vendor/idna/codec.py,sha256=PEew3ItwzjW4hymbasnty2N2OXvNcgHB-JjrBuxHPYY,3422
|
||||
pip/_vendor/idna/compat.py,sha256=RzLy6QQCdl9784aFhb2EX9EKGCJjg0P3PilGdeXXcx8,316
|
||||
pip/_vendor/idna/core.py,sha256=YJYyAMnwiQEPjVC4-Fqu_p4CJ6yKKuDGmppBNQNQpFs,13239
|
||||
pip/_vendor/idna/idnadata.py,sha256=W30GcIGvtOWYwAjZj4ZjuouUutC6ffgNuyjJy7fZ-lo,78306
|
||||
pip/_vendor/idna/intranges.py,sha256=amUtkdhYcQG8Zr-CoMM_kVRacxkivC1WgxN1b63KKdU,1898
|
||||
pip/_vendor/idna/package_data.py,sha256=q59S3OXsc5VI8j6vSD0sGBMyk6zZ4vWFREE88yCJYKs,21
|
||||
pip/_vendor/idna/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pip/_vendor/idna/uts46data.py,sha256=rt90K9J40gUSwppDPCrhjgi5AA6pWM65dEGRSf6rIhM,239289
|
||||
pip/_vendor/msgpack/__init__.py,sha256=reRaiOtEzSjPnr7TpxjgIvbfln5pV66FhricAs2eC-g,1109
|
||||
pip/_vendor/msgpack/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/msgpack/__pycache__/exceptions.cpython-312.pyc,,
|
||||
pip/_vendor/msgpack/__pycache__/ext.cpython-312.pyc,,
|
||||
pip/_vendor/msgpack/__pycache__/fallback.cpython-312.pyc,,
|
||||
pip/_vendor/msgpack/exceptions.py,sha256=dCTWei8dpkrMsQDcjQk74ATl9HsIBH0ybt8zOPNqMYc,1081
|
||||
pip/_vendor/msgpack/ext.py,sha256=kteJv03n9tYzd5oo3xYopVTo4vRaAxonBQQJhXohZZo,5726
|
||||
pip/_vendor/msgpack/fallback.py,sha256=0g1Pzp0vtmBEmJ5w9F3s_-JMVURP8RS4G1cc5TRaAsI,32390
|
||||
pip/_vendor/packaging/__init__.py,sha256=dk4Ta_vmdVJxYHDcfyhvQNw8V3PgSBomKNXqg-D2JDY,494
|
||||
pip/_vendor/packaging/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/packaging/__pycache__/_elffile.cpython-312.pyc,,
|
||||
pip/_vendor/packaging/__pycache__/_manylinux.cpython-312.pyc,,
|
||||
pip/_vendor/packaging/__pycache__/_musllinux.cpython-312.pyc,,
|
||||
pip/_vendor/packaging/__pycache__/_parser.cpython-312.pyc,,
|
||||
pip/_vendor/packaging/__pycache__/_structures.cpython-312.pyc,,
|
||||
pip/_vendor/packaging/__pycache__/_tokenizer.cpython-312.pyc,,
|
||||
pip/_vendor/packaging/__pycache__/markers.cpython-312.pyc,,
|
||||
pip/_vendor/packaging/__pycache__/metadata.cpython-312.pyc,,
|
||||
pip/_vendor/packaging/__pycache__/requirements.cpython-312.pyc,,
|
||||
pip/_vendor/packaging/__pycache__/specifiers.cpython-312.pyc,,
|
||||
pip/_vendor/packaging/__pycache__/tags.cpython-312.pyc,,
|
||||
pip/_vendor/packaging/__pycache__/utils.cpython-312.pyc,,
|
||||
pip/_vendor/packaging/__pycache__/version.cpython-312.pyc,,
|
||||
pip/_vendor/packaging/_elffile.py,sha256=cflAQAkE25tzhYmq_aCi72QfbT_tn891tPzfpbeHOwE,3306
|
||||
pip/_vendor/packaging/_manylinux.py,sha256=vl5OCoz4kx80H5rwXKeXWjl9WNISGmr4ZgTpTP9lU9c,9612
|
||||
pip/_vendor/packaging/_musllinux.py,sha256=p9ZqNYiOItGee8KcZFeHF_YcdhVwGHdK6r-8lgixvGQ,2694
|
||||
pip/_vendor/packaging/_parser.py,sha256=s_TvTvDNK0NrM2QB3VKThdWFM4Nc0P6JnkObkl3MjpM,10236
|
||||
pip/_vendor/packaging/_structures.py,sha256=q3eVNmbWJGG_S0Dit_S3Ao8qQqz_5PYTXFAKBZe5yr4,1431
|
||||
pip/_vendor/packaging/_tokenizer.py,sha256=J6v5H7Jzvb-g81xp_2QACKwO7LxHQA6ikryMU7zXwN8,5273
|
||||
pip/_vendor/packaging/licenses/__init__.py,sha256=A116-FU49_Dz4162M4y1uAiZN4Rgdc83FxNd8EjlfqI,5727
|
||||
pip/_vendor/packaging/licenses/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/packaging/licenses/__pycache__/_spdx.cpython-312.pyc,,
|
||||
pip/_vendor/packaging/licenses/_spdx.py,sha256=oAm1ztPFwlsmCKe7lAAsv_OIOfS1cWDu9bNBkeu-2ns,48398
|
||||
pip/_vendor/packaging/markers.py,sha256=c89TNzB7ZdGYhkovm6PYmqGyHxXlYVaLW591PHUNKD8,10561
|
||||
pip/_vendor/packaging/metadata.py,sha256=YJibM7GYe4re8-0a3OlXmGS-XDgTEoO4tlBt2q25Bng,34762
|
||||
pip/_vendor/packaging/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pip/_vendor/packaging/requirements.py,sha256=gYyRSAdbrIyKDY66ugIDUQjRMvxkH2ALioTmX3tnL6o,2947
|
||||
pip/_vendor/packaging/specifiers.py,sha256=hGU6kuCd77bL-msIL6yLCp6MNT75RSMUKZDuju26c8U,40098
|
||||
pip/_vendor/packaging/tags.py,sha256=CFqrJzAzc2XNGexerH__T-Y5Iwq7WbsYXsiLERLWxY0,21014
|
||||
pip/_vendor/packaging/utils.py,sha256=0F3Hh9OFuRgrhTgGZUl5K22Fv1YP2tZl1z_2gO6kJiA,5050
|
||||
pip/_vendor/packaging/version.py,sha256=oiHqzTUv_p12hpjgsLDVcaF5hT7pDaSOViUNMD4GTW0,16688
|
||||
pip/_vendor/pkg_resources/__init__.py,sha256=jrhDRbOubP74QuPXxd7U7Po42PH2l-LZ2XfcO7llpZ4,124463
|
||||
pip/_vendor/pkg_resources/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/platformdirs/__init__.py,sha256=JueR2cRLkxY7iwik-qNWJCwKOrAlBgVgcZ_IHQzqGLE,22344
|
||||
pip/_vendor/platformdirs/__main__.py,sha256=jBJ8zb7Mpx5ebcqF83xrpO94MaeCpNGHVf9cvDN2JLg,1505
|
||||
pip/_vendor/platformdirs/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/platformdirs/__pycache__/__main__.cpython-312.pyc,,
|
||||
pip/_vendor/platformdirs/__pycache__/android.cpython-312.pyc,,
|
||||
pip/_vendor/platformdirs/__pycache__/api.cpython-312.pyc,,
|
||||
pip/_vendor/platformdirs/__pycache__/macos.cpython-312.pyc,,
|
||||
pip/_vendor/platformdirs/__pycache__/unix.cpython-312.pyc,,
|
||||
pip/_vendor/platformdirs/__pycache__/version.cpython-312.pyc,,
|
||||
pip/_vendor/platformdirs/__pycache__/windows.cpython-312.pyc,,
|
||||
pip/_vendor/platformdirs/android.py,sha256=kV5oL3V3DZ6WZKu9yFiQupv18yp_jlSV2ChH1TmPcds,9007
|
||||
pip/_vendor/platformdirs/api.py,sha256=2dfUDNbEXeDhDKarqtR5NY7oUikUZ4RZhs3ozstmhBQ,9246
|
||||
pip/_vendor/platformdirs/macos.py,sha256=UlbyFZ8Rzu3xndCqQEHrfsYTeHwYdFap1Ioz-yxveT4,6154
|
||||
pip/_vendor/platformdirs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pip/_vendor/platformdirs/unix.py,sha256=uRPJWRyQEtv7yOSvU94rUmsblo5XKDLA1SzFg55kbK0,10393
|
||||
pip/_vendor/platformdirs/version.py,sha256=oH4KgTfK4AklbTYVcV_yynvJ9JLI3pyvDVay0hRsLCs,411
|
||||
pip/_vendor/platformdirs/windows.py,sha256=IFpiohUBwxPtCzlyKwNtxyW4Jk8haa6W8o59mfrDXVo,10125
|
||||
pip/_vendor/pygments/__init__.py,sha256=7N1oiaWulw_nCsTY4EEixYLz15pWY5u4uPAFFi-ielU,2983
|
||||
pip/_vendor/pygments/__main__.py,sha256=isIhBxLg65nLlXukG4VkMuPfNdd7gFzTZ_R_z3Q8diY,353
|
||||
pip/_vendor/pygments/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/__pycache__/__main__.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/__pycache__/cmdline.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/__pycache__/console.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/__pycache__/filter.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/__pycache__/formatter.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/__pycache__/lexer.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/__pycache__/modeline.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/__pycache__/plugin.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/__pycache__/regexopt.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/__pycache__/scanner.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/__pycache__/sphinxext.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/__pycache__/style.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/__pycache__/token.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/__pycache__/unistring.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/__pycache__/util.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/cmdline.py,sha256=LIVzmAunlk9sRJJp54O4KRy9GDIN4Wu13v9p9QzfGPM,23656
|
||||
pip/_vendor/pygments/console.py,sha256=yhP9UsLAVmWKVQf2446JJewkA7AiXeeTf4Ieg3Oi2fU,1718
|
||||
pip/_vendor/pygments/filter.py,sha256=_ADNPCskD8_GmodHi6_LoVgPU3Zh336aBCT5cOeTMs0,1910
|
||||
pip/_vendor/pygments/filters/__init__.py,sha256=RdedK2KWKXlKwR7cvkfr3NUj9YiZQgMgilRMFUg2jPA,40392
|
||||
pip/_vendor/pygments/filters/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/formatter.py,sha256=jDWBTndlBH2Z5IYZFVDnP0qn1CaTQjTWt7iAGtCnJEg,4390
|
||||
pip/_vendor/pygments/formatters/__init__.py,sha256=8No-NUs8rBTSSBJIv4hSEQt2M0cFB4hwAT0snVc2QGE,5385
|
||||
pip/_vendor/pygments/formatters/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/formatters/__pycache__/_mapping.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/formatters/__pycache__/bbcode.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/formatters/__pycache__/groff.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/formatters/__pycache__/html.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/formatters/__pycache__/img.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/formatters/__pycache__/irc.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/formatters/__pycache__/latex.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/formatters/__pycache__/other.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/formatters/__pycache__/pangomarkup.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/formatters/__pycache__/rtf.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/formatters/__pycache__/svg.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/formatters/__pycache__/terminal.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/formatters/__pycache__/terminal256.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/formatters/_mapping.py,sha256=1Cw37FuQlNacnxRKmtlPX4nyLoX9_ttko5ZwscNUZZ4,4176
|
||||
pip/_vendor/pygments/formatters/bbcode.py,sha256=3JQLI45tcrQ_kRUMjuab6C7Hb0XUsbVWqqbSn9cMjkI,3320
|
||||
pip/_vendor/pygments/formatters/groff.py,sha256=M39k0PaSSZRnxWjqBSVPkF0mu1-Vr7bm6RsFvs-CNN4,5106
|
||||
pip/_vendor/pygments/formatters/html.py,sha256=SE2jc3YCqbMS3rZW9EAmDlAUhdVxJ52gA4dileEvCGU,35669
|
||||
pip/_vendor/pygments/formatters/img.py,sha256=MwA4xWPLOwh6j7Yc6oHzjuqSPt0M1fh5r-5BTIIUfsU,23287
|
||||
pip/_vendor/pygments/formatters/irc.py,sha256=dp1Z0l_ObJ5NFh9MhqLGg5ptG5hgJqedT2Vkutt9v0M,4981
|
||||
pip/_vendor/pygments/formatters/latex.py,sha256=XMmhOCqUKDBQtG5mGJNAFYxApqaC5puo5cMmPfK3944,19306
|
||||
pip/_vendor/pygments/formatters/other.py,sha256=56PMJOliin-rAUdnRM0i1wsV1GdUPd_dvQq0_UPfF9c,5034
|
||||
pip/_vendor/pygments/formatters/pangomarkup.py,sha256=y16U00aVYYEFpeCfGXlYBSMacG425CbfoG8oKbKegIg,2218
|
||||
pip/_vendor/pygments/formatters/rtf.py,sha256=ZT90dmcKyJboIB0mArhL7IhE467GXRN0G7QAUgG03To,11957
|
||||
pip/_vendor/pygments/formatters/svg.py,sha256=KKsiophPupHuxm0So-MsbQEWOT54IAiSF7hZPmxtKXE,7174
|
||||
pip/_vendor/pygments/formatters/terminal.py,sha256=AojNG4MlKq2L6IsC_VnXHu4AbHCBn9Otog6u45XvxeI,4674
|
||||
pip/_vendor/pygments/formatters/terminal256.py,sha256=kGkNUVo3FpwjytIDS0if79EuUoroAprcWt3igrcIqT0,11753
|
||||
pip/_vendor/pygments/lexer.py,sha256=TYHDt___gNW4axTl2zvPZff-VQi8fPaIh5OKRcVSjUM,35349
|
||||
pip/_vendor/pygments/lexers/__init__.py,sha256=pIlxyQJuu_syh9lE080cq8ceVbEVcKp0osAFU5fawJU,12115
|
||||
pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/lexers/__pycache__/python.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/lexers/_mapping.py,sha256=61-h3zr103m01OS5BUq_AfUiL9YI06Ves9ipQ7k4vr4,76097
|
||||
pip/_vendor/pygments/lexers/python.py,sha256=2J_YJrPTr_A6fJY_qKiKv0GpgPwHMrlMSeo59qN3fe4,53687
|
||||
pip/_vendor/pygments/modeline.py,sha256=gtRYZBS-CKOCDXHhGZqApboHBaZwGH8gznN3O6nuxj4,1005
|
||||
pip/_vendor/pygments/plugin.py,sha256=ioeJ3QeoJ-UQhZpY9JL7vbxsTVuwwM7BCu-Jb8nN0AU,1891
|
||||
pip/_vendor/pygments/regexopt.py,sha256=Hky4EB13rIXEHQUNkwmCrYqtIlnXDehNR3MztafZ43w,3072
|
||||
pip/_vendor/pygments/scanner.py,sha256=NDy3ofK_fHRFK4hIDvxpamG871aewqcsIb6sgTi7Fhk,3092
|
||||
pip/_vendor/pygments/sphinxext.py,sha256=iOptJBcqOGPwMEJ2p70PvwpZPIGdvdZ8dxvq6kzxDgA,7981
|
||||
pip/_vendor/pygments/style.py,sha256=rSCZWFpg1_DwFMXDU0nEVmAcBHpuQGf9RxvOPPQvKLQ,6420
|
||||
pip/_vendor/pygments/styles/__init__.py,sha256=qUk6_1z5KmT8EdJFZYgESmG6P_HJF_2vVrDD7HSCGYY,2042
|
||||
pip/_vendor/pygments/styles/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/styles/__pycache__/_mapping.cpython-312.pyc,,
|
||||
pip/_vendor/pygments/styles/_mapping.py,sha256=6lovFUE29tz6EsV3XYY4hgozJ7q1JL7cfO3UOlgnS8w,3312
|
||||
pip/_vendor/pygments/token.py,sha256=qZwT7LSPy5YBY3JgDjut642CCy7JdQzAfmqD9NmT5j0,6226
|
||||
pip/_vendor/pygments/unistring.py,sha256=p5c1i-HhoIhWemy9CUsaN9o39oomYHNxXll0Xfw6tEA,63208
|
||||
pip/_vendor/pygments/util.py,sha256=2tj2nS1X9_OpcuSjf8dOET2bDVZhs8cEKd_uT6-Fgg8,10031
|
||||
pip/_vendor/pyproject_hooks/__init__.py,sha256=cPB_a9LXz5xvsRbX1o2qyAdjLatZJdQ_Lc5McNX-X7Y,691
|
||||
pip/_vendor/pyproject_hooks/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/pyproject_hooks/__pycache__/_impl.cpython-312.pyc,,
|
||||
pip/_vendor/pyproject_hooks/_impl.py,sha256=jY-raxnmyRyB57ruAitrJRUzEexuAhGTpgMygqx67Z4,14936
|
||||
pip/_vendor/pyproject_hooks/_in_process/__init__.py,sha256=MJNPpfIxcO-FghxpBbxkG1rFiQf6HOUbV4U5mq0HFns,557
|
||||
pip/_vendor/pyproject_hooks/_in_process/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/pyproject_hooks/_in_process/__pycache__/_in_process.cpython-312.pyc,,
|
||||
pip/_vendor/pyproject_hooks/_in_process/_in_process.py,sha256=qcXMhmx__MIJq10gGHW3mA4Tl8dy8YzHMccwnNoKlw0,12216
|
||||
pip/_vendor/pyproject_hooks/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pip/_vendor/requests/__init__.py,sha256=HlB_HzhrzGtfD_aaYUwUh1zWXLZ75_YCLyit75d0Vz8,5057
|
||||
pip/_vendor/requests/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/requests/__pycache__/__version__.cpython-312.pyc,,
|
||||
pip/_vendor/requests/__pycache__/_internal_utils.cpython-312.pyc,,
|
||||
pip/_vendor/requests/__pycache__/adapters.cpython-312.pyc,,
|
||||
pip/_vendor/requests/__pycache__/api.cpython-312.pyc,,
|
||||
pip/_vendor/requests/__pycache__/auth.cpython-312.pyc,,
|
||||
pip/_vendor/requests/__pycache__/certs.cpython-312.pyc,,
|
||||
pip/_vendor/requests/__pycache__/compat.cpython-312.pyc,,
|
||||
pip/_vendor/requests/__pycache__/cookies.cpython-312.pyc,,
|
||||
pip/_vendor/requests/__pycache__/exceptions.cpython-312.pyc,,
|
||||
pip/_vendor/requests/__pycache__/help.cpython-312.pyc,,
|
||||
pip/_vendor/requests/__pycache__/hooks.cpython-312.pyc,,
|
||||
pip/_vendor/requests/__pycache__/models.cpython-312.pyc,,
|
||||
pip/_vendor/requests/__pycache__/packages.cpython-312.pyc,,
|
||||
pip/_vendor/requests/__pycache__/sessions.cpython-312.pyc,,
|
||||
pip/_vendor/requests/__pycache__/status_codes.cpython-312.pyc,,
|
||||
pip/_vendor/requests/__pycache__/structures.cpython-312.pyc,,
|
||||
pip/_vendor/requests/__pycache__/utils.cpython-312.pyc,,
|
||||
pip/_vendor/requests/__version__.py,sha256=FVfglgZmNQnmYPXpOohDU58F5EUb_-VnSTaAesS187g,435
|
||||
pip/_vendor/requests/_internal_utils.py,sha256=nMQymr4hs32TqVo5AbCrmcJEhvPUh7xXlluyqwslLiQ,1495
|
||||
pip/_vendor/requests/adapters.py,sha256=J7VeVxKBvawbtlX2DERVo05J9BXTcWYLMHNd1Baa-bk,27607
|
||||
pip/_vendor/requests/api.py,sha256=_Zb9Oa7tzVIizTKwFrPjDEY9ejtm_OnSRERnADxGsQs,6449
|
||||
pip/_vendor/requests/auth.py,sha256=kF75tqnLctZ9Mf_hm9TZIj4cQWnN5uxRz8oWsx5wmR0,10186
|
||||
pip/_vendor/requests/certs.py,sha256=kHDlkK_beuHXeMPc5jta2wgl8gdKeUWt5f2nTDVrvt8,441
|
||||
pip/_vendor/requests/compat.py,sha256=Mo9f9xZpefod8Zm-n9_StJcVTmwSukXR2p3IQyyVXvU,1485
|
||||
pip/_vendor/requests/cookies.py,sha256=bNi-iqEj4NPZ00-ob-rHvzkvObzN3lEpgw3g6paS3Xw,18590
|
||||
pip/_vendor/requests/exceptions.py,sha256=D1wqzYWne1mS2rU43tP9CeN1G7QAy7eqL9o1god6Ejw,4272
|
||||
pip/_vendor/requests/help.py,sha256=hRKaf9u0G7fdwrqMHtF3oG16RKktRf6KiwtSq2Fo1_0,3813
|
||||
pip/_vendor/requests/hooks.py,sha256=CiuysiHA39V5UfcCBXFIx83IrDpuwfN9RcTUgv28ftQ,733
|
||||
pip/_vendor/requests/models.py,sha256=x4K4CmH-lC0l2Kb-iPfMN4dRXxHEcbOaEWBL_i09AwI,35483
|
||||
pip/_vendor/requests/packages.py,sha256=_ZQDCJTJ8SP3kVWunSqBsRZNPzj2c1WFVqbdr08pz3U,1057
|
||||
pip/_vendor/requests/sessions.py,sha256=ykTI8UWGSltOfH07HKollH7kTBGw4WhiBVaQGmckTw4,30495
|
||||
pip/_vendor/requests/status_codes.py,sha256=iJUAeA25baTdw-6PfD0eF4qhpINDJRJI-yaMqxs4LEI,4322
|
||||
pip/_vendor/requests/structures.py,sha256=-IbmhVz06S-5aPSZuUthZ6-6D9XOjRuTXHOabY041XM,2912
|
||||
pip/_vendor/requests/utils.py,sha256=L79vnFbzJ3SFLKtJwpoWe41Tozi3RlZv94pY1TFIyow,33631
|
||||
pip/_vendor/resolvelib/__init__.py,sha256=h509TdEcpb5-44JonaU3ex2TM15GVBLjM9CNCPwnTTs,537
|
||||
pip/_vendor/resolvelib/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/resolvelib/__pycache__/providers.cpython-312.pyc,,
|
||||
pip/_vendor/resolvelib/__pycache__/reporters.cpython-312.pyc,,
|
||||
pip/_vendor/resolvelib/__pycache__/resolvers.cpython-312.pyc,,
|
||||
pip/_vendor/resolvelib/__pycache__/structs.cpython-312.pyc,,
|
||||
pip/_vendor/resolvelib/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-312.pyc,,
|
||||
pip/_vendor/resolvelib/compat/collections_abc.py,sha256=uy8xUZ-NDEw916tugUXm8HgwCGiMO0f-RcdnpkfXfOs,156
|
||||
pip/_vendor/resolvelib/providers.py,sha256=fuuvVrCetu5gsxPB43ERyjfO8aReS3rFQHpDgiItbs4,5871
|
||||
pip/_vendor/resolvelib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pip/_vendor/resolvelib/reporters.py,sha256=TSbRmWzTc26w0ggsV1bxVpeWDB8QNIre6twYl7GIZBE,1601
|
||||
pip/_vendor/resolvelib/resolvers.py,sha256=G8rsLZSq64g5VmIq-lB7UcIJ1gjAxIQJmTF4REZleQ0,20511
|
||||
pip/_vendor/resolvelib/structs.py,sha256=0_1_XO8z_CLhegP3Vpf9VJ3zJcfLm0NOHRM-i0Ykz3o,4963
|
||||
pip/_vendor/rich/__init__.py,sha256=dRxjIL-SbFVY0q3IjSMrfgBTHrm1LZDgLOygVBwiYZc,6090
|
||||
pip/_vendor/rich/__main__.py,sha256=eO7Cq8JnrgG8zVoeImiAs92q3hXNMIfp0w5lMsO7Q2Y,8477
|
||||
pip/_vendor/rich/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/__main__.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/_cell_widths.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/_emoji_codes.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/_emoji_replace.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/_export_format.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/_extension.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/_fileno.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/_inspect.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/_log_render.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/_loop.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/_null_file.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/_palettes.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/_pick.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/_ratio.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/_spinners.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/_stack.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/_timer.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/_win32_console.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/_windows.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/_windows_renderer.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/_wrap.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/abc.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/align.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/ansi.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/bar.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/box.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/cells.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/color.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/color_triplet.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/columns.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/console.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/constrain.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/containers.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/control.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/default_styles.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/diagnose.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/emoji.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/errors.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/file_proxy.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/filesize.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/highlighter.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/json.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/jupyter.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/layout.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/live.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/live_render.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/logging.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/markup.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/measure.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/padding.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/pager.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/palette.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/panel.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/pretty.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/progress.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/progress_bar.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/prompt.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/protocol.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/region.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/repr.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/rule.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/scope.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/screen.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/segment.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/spinner.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/status.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/style.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/styled.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/syntax.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/table.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/terminal_theme.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/text.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/theme.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/themes.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/traceback.cpython-312.pyc,,
|
||||
pip/_vendor/rich/__pycache__/tree.cpython-312.pyc,,
|
||||
pip/_vendor/rich/_cell_widths.py,sha256=fbmeyetEdHjzE_Vx2l1uK7tnPOhMs2X1lJfO3vsKDpA,10209
|
||||
pip/_vendor/rich/_emoji_codes.py,sha256=hu1VL9nbVdppJrVoijVshRlcRRe_v3dju3Mmd2sKZdY,140235
|
||||
pip/_vendor/rich/_emoji_replace.py,sha256=n-kcetsEUx2ZUmhQrfeMNc-teeGhpuSQ5F8VPBsyvDo,1064
|
||||
pip/_vendor/rich/_export_format.py,sha256=RI08pSrm5tBSzPMvnbTqbD9WIalaOoN5d4M1RTmLq1Y,2128
|
||||
pip/_vendor/rich/_extension.py,sha256=Xt47QacCKwYruzjDi-gOBq724JReDj9Cm9xUi5fr-34,265
|
||||
pip/_vendor/rich/_fileno.py,sha256=HWZxP5C2ajMbHryvAQZseflVfQoGzsKOHzKGsLD8ynQ,799
|
||||
pip/_vendor/rich/_inspect.py,sha256=QM05lEFnFoTaFqpnbx-zBEI6k8oIKrD3cvjEOQNhKig,9655
|
||||
pip/_vendor/rich/_log_render.py,sha256=1ByI0PA1ZpxZY3CGJOK54hjlq4X-Bz_boIjIqCd8Kns,3225
|
||||
pip/_vendor/rich/_loop.py,sha256=hV_6CLdoPm0va22Wpw4zKqM0RYsz3TZxXj0PoS-9eDQ,1236
|
||||
pip/_vendor/rich/_null_file.py,sha256=ADGKp1yt-k70FMKV6tnqCqecB-rSJzp-WQsD7LPL-kg,1394
|
||||
pip/_vendor/rich/_palettes.py,sha256=cdev1JQKZ0JvlguV9ipHgznTdnvlIzUFDBb0It2PzjI,7063
|
||||
pip/_vendor/rich/_pick.py,sha256=evDt8QN4lF5CiwrUIXlOJCntitBCOsI3ZLPEIAVRLJU,423
|
||||
pip/_vendor/rich/_ratio.py,sha256=Zt58apszI6hAAcXPpgdWKpu3c31UBWebOeR4mbyptvU,5471
|
||||
pip/_vendor/rich/_spinners.py,sha256=U2r1_g_1zSjsjiUdAESc2iAMc3i4ri_S8PYP6kQ5z1I,19919
|
||||
pip/_vendor/rich/_stack.py,sha256=-C8OK7rxn3sIUdVwxZBBpeHhIzX0eI-VM3MemYfaXm0,351
|
||||
pip/_vendor/rich/_timer.py,sha256=zelxbT6oPFZnNrwWPpc1ktUeAT-Vc4fuFcRZLQGLtMI,417
|
||||
pip/_vendor/rich/_win32_console.py,sha256=BSaDRIMwBLITn_m0mTRLPqME5q-quGdSMuYMpYeYJwc,22755
|
||||
pip/_vendor/rich/_windows.py,sha256=aBwaD_S56SbgopIvayVmpk0Y28uwY2C5Bab1wl3Bp-I,1925
|
||||
pip/_vendor/rich/_windows_renderer.py,sha256=t74ZL3xuDCP3nmTp9pH1L5LiI2cakJuQRQleHCJerlk,2783
|
||||
pip/_vendor/rich/_wrap.py,sha256=FlSsom5EX0LVkA3KWy34yHnCfLtqX-ZIepXKh-70rpc,3404
|
||||
pip/_vendor/rich/abc.py,sha256=ON-E-ZqSSheZ88VrKX2M3PXpFbGEUUZPMa_Af0l-4f0,890
|
||||
pip/_vendor/rich/align.py,sha256=Rh-3adnDaN1Ao07EjR2PhgE62PGLPgO8SMwJBku1urQ,10469
|
||||
pip/_vendor/rich/ansi.py,sha256=Avs1LHbSdcyOvDOdpELZUoULcBiYewY76eNBp6uFBhs,6921
|
||||
pip/_vendor/rich/bar.py,sha256=ldbVHOzKJOnflVNuv1xS7g6dLX2E3wMnXkdPbpzJTcs,3263
|
||||
pip/_vendor/rich/box.py,sha256=nr5fYIUghB_iUCEq6y0Z3LlCT8gFPDrzN9u2kn7tJl4,10831
|
||||
pip/_vendor/rich/cells.py,sha256=KrQkj5-LghCCpJLSNQIyAZjndc4bnEqOEmi5YuZ9UCY,5130
|
||||
pip/_vendor/rich/color.py,sha256=3HSULVDj7qQkXUdFWv78JOiSZzfy5y1nkcYhna296V0,18211
|
||||
pip/_vendor/rich/color_triplet.py,sha256=3lhQkdJbvWPoLDO-AnYImAWmJvV5dlgYNCVZ97ORaN4,1054
|
||||
pip/_vendor/rich/columns.py,sha256=HUX0KcMm9dsKNi11fTbiM_h2iDtl8ySCaVcxlalEzq8,7131
|
||||
pip/_vendor/rich/console.py,sha256=nKjrEx_7xy8KGmDVT-BgNII0R5hm1cexhAHDwdwNVqg,100156
|
||||
pip/_vendor/rich/constrain.py,sha256=1VIPuC8AgtKWrcncQrjBdYqA3JVWysu6jZo1rrh7c7Q,1288
|
||||
pip/_vendor/rich/containers.py,sha256=c_56TxcedGYqDepHBMTuZdUIijitAQgnox-Qde0Z1qo,5502
|
||||
pip/_vendor/rich/control.py,sha256=DSkHTUQLorfSERAKE_oTAEUFefZnZp4bQb4q8rHbKws,6630
|
||||
pip/_vendor/rich/default_styles.py,sha256=dZxgaSD9VUy7SXQShO33aLYiAWspCr2sCQZFX_JK1j4,8159
|
||||
pip/_vendor/rich/diagnose.py,sha256=an6uouwhKPAlvQhYpNNpGq9EJysfMIOvvCbO3oSoR24,972
|
||||
pip/_vendor/rich/emoji.py,sha256=omTF9asaAnsM4yLY94eR_9dgRRSm1lHUszX20D1yYCQ,2501
|
||||
pip/_vendor/rich/errors.py,sha256=5pP3Kc5d4QJ_c0KFsxrfyhjiPVe7J1zOqSFbFAzcV-Y,642
|
||||
pip/_vendor/rich/file_proxy.py,sha256=Tl9THMDZ-Pk5Wm8sI1gGg_U5DhusmxD-FZ0fUbcU0W0,1683
|
||||
pip/_vendor/rich/filesize.py,sha256=_iz9lIpRgvW7MNSeCZnLg-HwzbP4GETg543WqD8SFs0,2484
|
||||
pip/_vendor/rich/highlighter.py,sha256=G_sn-8DKjM1sEjLG_oc4ovkWmiUpWvj8bXi0yed2LnY,9586
|
||||
pip/_vendor/rich/json.py,sha256=vVEoKdawoJRjAFayPwXkMBPLy7RSTs-f44wSQDR2nJ0,5031
|
||||
pip/_vendor/rich/jupyter.py,sha256=QyoKoE_8IdCbrtiSHp9TsTSNyTHY0FO5whE7jOTd9UE,3252
|
||||
pip/_vendor/rich/layout.py,sha256=ajkSFAtEVv9EFTcFs-w4uZfft7nEXhNzL7ZVdgrT5rI,14004
|
||||
pip/_vendor/rich/live.py,sha256=DhzAPEnjTxQuq9_0Y2xh2MUwQcP_aGPkenLfKETslwM,14270
|
||||
pip/_vendor/rich/live_render.py,sha256=zJtB471jGziBtEwxc54x12wEQtH4BuQr1SA8v9kU82w,3666
|
||||
pip/_vendor/rich/logging.py,sha256=ZgpKMMBY_BuMAI_BYzo-UtXak6t5oH9VK8m9Q2Lm0f4,12458
|
||||
pip/_vendor/rich/markup.py,sha256=3euGKP5s41NCQwaSjTnJxus5iZMHjxpIM0W6fCxra38,8451
|
||||
pip/_vendor/rich/measure.py,sha256=HmrIJX8sWRTHbgh8MxEay_83VkqNW_70s8aKP5ZcYI8,5305
|
||||
pip/_vendor/rich/padding.py,sha256=KVEI3tOwo9sgK1YNSuH__M1_jUWmLZwRVV_KmOtVzyM,4908
|
||||
pip/_vendor/rich/pager.py,sha256=SO_ETBFKbg3n_AgOzXm41Sv36YxXAyI3_R-KOY2_uSc,828
|
||||
pip/_vendor/rich/palette.py,sha256=lInvR1ODDT2f3UZMfL1grq7dY_pDdKHw4bdUgOGaM4Y,3396
|
||||
pip/_vendor/rich/panel.py,sha256=fFRHcviXvWhk3V3zx5Zwmsb_RL9KJ3esD-sU0NYEVyw,11235
|
||||
pip/_vendor/rich/pretty.py,sha256=gy3S72u4FRg2ytoo7N1ZDWDIvB4unbzd5iUGdgm-8fc,36391
|
||||
pip/_vendor/rich/progress.py,sha256=MtmCjTk5zYU_XtRHxRHTAEHG6hF9PeF7EMWbEPleIC0,60357
|
||||
pip/_vendor/rich/progress_bar.py,sha256=mZTPpJUwcfcdgQCTTz3kyY-fc79ddLwtx6Ghhxfo064,8162
|
||||
pip/_vendor/rich/prompt.py,sha256=l0RhQU-0UVTV9e08xW1BbIj0Jq2IXyChX4lC0lFNzt4,12447
|
||||
pip/_vendor/rich/protocol.py,sha256=5hHHDDNHckdk8iWH5zEbi-zuIVSF5hbU2jIo47R7lTE,1391
|
||||
pip/_vendor/rich/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pip/_vendor/rich/region.py,sha256=rNT9xZrVZTYIXZC0NYn41CJQwYNbR-KecPOxTgQvB8Y,166
|
||||
pip/_vendor/rich/repr.py,sha256=5MZJZmONgC6kud-QW-_m1okXwL2aR6u6y-pUcUCJz28,4431
|
||||
pip/_vendor/rich/rule.py,sha256=0fNaS_aERa3UMRc3T5WMpN_sumtDxfaor2y3of1ftBk,4602
|
||||
pip/_vendor/rich/scope.py,sha256=TMUU8qo17thyqQCPqjDLYpg_UU1k5qVd-WwiJvnJVas,2843
|
||||
pip/_vendor/rich/screen.py,sha256=YoeReESUhx74grqb0mSSb9lghhysWmFHYhsbMVQjXO8,1591
|
||||
pip/_vendor/rich/segment.py,sha256=otnKeKGEV-WRlQVosfJVeFDcDxAKHpvJ_hLzSu5lumM,24743
|
||||
pip/_vendor/rich/spinner.py,sha256=PT5qgXPG3ZpqRj7n3EZQ6NW56mx3ldZqZCU7gEMyZk4,4364
|
||||
pip/_vendor/rich/status.py,sha256=kkPph3YeAZBo-X-4wPp8gTqZyU466NLwZBA4PZTTewo,4424
|
||||
pip/_vendor/rich/style.py,sha256=aSoUNbVgfP1PAnduAqgbbl4AMQy668qs2S1FEwr3Oqs,27067
|
||||
pip/_vendor/rich/styled.py,sha256=eZNnzGrI4ki_54pgY3Oj0T-x3lxdXTYh4_ryDB24wBU,1258
|
||||
pip/_vendor/rich/syntax.py,sha256=qqAnEUZ4K57Po81_5RBxnsuU4KRzSdvDPAhKw8ma_3E,35763
|
||||
pip/_vendor/rich/table.py,sha256=yXYUr0YsPpG466N50HCAw2bpb5ZUuuzdc-G66Zk-oTc,40103
|
||||
pip/_vendor/rich/terminal_theme.py,sha256=1j5-ufJfnvlAo5Qsi_ACZiXDmwMXzqgmFByObT9-yJY,3370
|
||||
pip/_vendor/rich/text.py,sha256=AO7JPCz6-gaN1thVLXMBntEmDPVYFgFNG1oM61_sanU,47552
|
||||
pip/_vendor/rich/theme.py,sha256=oNyhXhGagtDlbDye3tVu3esWOWk0vNkuxFw-_unlaK0,3771
|
||||
pip/_vendor/rich/themes.py,sha256=0xgTLozfabebYtcJtDdC5QkX5IVUEaviqDUJJh4YVFk,102
|
||||
pip/_vendor/rich/traceback.py,sha256=z8UoN7NbTQKW6YDDUVwOh7F8snZf6gYnUWtOrKsLE1w,31797
|
||||
pip/_vendor/rich/tree.py,sha256=yWnQ6rAvRGJ3qZGqBrxS2SW2TKBTNrP0SdY8QxOFPuw,9451
|
||||
pip/_vendor/tomli/__init__.py,sha256=PhNw_eyLgdn7McJ6nrAN8yIm3dXC75vr1sVGVVwDSpA,314
|
||||
pip/_vendor/tomli/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/tomli/__pycache__/_parser.cpython-312.pyc,,
|
||||
pip/_vendor/tomli/__pycache__/_re.cpython-312.pyc,,
|
||||
pip/_vendor/tomli/__pycache__/_types.cpython-312.pyc,,
|
||||
pip/_vendor/tomli/_parser.py,sha256=9w8LG0jB7fwmZZWB0vVXbeejDHcl4ANIJxB2scEnDlA,25591
|
||||
pip/_vendor/tomli/_re.py,sha256=sh4sBDRgO94KJZwNIrgdcyV_qQast50YvzOAUGpRDKA,3171
|
||||
pip/_vendor/tomli/_types.py,sha256=-GTG2VUqkpxwMqzmVO4F7ybKddIbAnuAHXfmWQcTi3Q,254
|
||||
pip/_vendor/tomli/py.typed,sha256=8PjyZ1aVoQpRVvt71muvuq5qE-jTFZkK-GLHkhdebmc,26
|
||||
pip/_vendor/truststore/__init__.py,sha256=WIDeyzWm7EVX44g354M25vpRXbeY1lsPH6EmUJUcq4o,1264
|
||||
pip/_vendor/truststore/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/truststore/__pycache__/_api.cpython-312.pyc,,
|
||||
pip/_vendor/truststore/__pycache__/_macos.cpython-312.pyc,,
|
||||
pip/_vendor/truststore/__pycache__/_openssl.cpython-312.pyc,,
|
||||
pip/_vendor/truststore/__pycache__/_ssl_constants.cpython-312.pyc,,
|
||||
pip/_vendor/truststore/__pycache__/_windows.cpython-312.pyc,,
|
||||
pip/_vendor/truststore/_api.py,sha256=GeXRNTlxPZ3kif4kNoh6JY0oE4QRzTGcgXr6l_X_Gk0,10555
|
||||
pip/_vendor/truststore/_macos.py,sha256=nZlLkOmszUE0g6ryRwBVGY5COzPyudcsiJtDWarM5LQ,20503
|
||||
pip/_vendor/truststore/_openssl.py,sha256=LLUZ7ZGaio-i5dpKKjKCSeSufmn6T8pi9lDcFnvSyq0,2324
|
||||
pip/_vendor/truststore/_ssl_constants.py,sha256=NUD4fVKdSD02ri7-db0tnO0VqLP9aHuzmStcW7tAl08,1130
|
||||
pip/_vendor/truststore/_windows.py,sha256=rAHyKYD8M7t-bXfG8VgOVa3TpfhVhbt4rZQlO45YuP8,17993
|
||||
pip/_vendor/truststore/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pip/_vendor/typing_extensions.py,sha256=78hFl0HpDY-ylHUVCnWdU5nTHxUP2-S-3wEZk6CQmLk,134499
|
||||
pip/_vendor/urllib3/__init__.py,sha256=iXLcYiJySn0GNbWOOZDDApgBL1JgP44EZ8i1760S8Mc,3333
|
||||
pip/_vendor/urllib3/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/__pycache__/_collections.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/__pycache__/_version.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/__pycache__/connection.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/__pycache__/connectionpool.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/__pycache__/exceptions.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/__pycache__/fields.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/__pycache__/filepost.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/__pycache__/poolmanager.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/__pycache__/request.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/__pycache__/response.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/_collections.py,sha256=pyASJJhW7wdOpqJj9QJA8FyGRfr8E8uUUhqUvhF0728,11372
|
||||
pip/_vendor/urllib3/_version.py,sha256=t9wGB6ooOTXXgiY66K1m6BZS1CJyXHAU8EoWDTe6Shk,64
|
||||
pip/_vendor/urllib3/connection.py,sha256=ttIA909BrbTUzwkqEe_TzZVh4JOOj7g61Ysei2mrwGg,20314
|
||||
pip/_vendor/urllib3/connectionpool.py,sha256=e2eiAwNbFNCKxj4bwDKNK-w7HIdSz3OmMxU_TIt-evQ,40408
|
||||
pip/_vendor/urllib3/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/contrib/_appengine_environ.py,sha256=bDbyOEhW2CKLJcQqAKAyrEHN-aklsyHFKq6vF8ZFsmk,957
|
||||
pip/_vendor/urllib3/contrib/_securetransport/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/contrib/_securetransport/bindings.py,sha256=4Xk64qIkPBt09A5q-RIFUuDhNc9mXilVapm7WnYnzRw,17632
|
||||
pip/_vendor/urllib3/contrib/_securetransport/low_level.py,sha256=B2JBB2_NRP02xK6DCa1Pa9IuxrPwxzDzZbixQkb7U9M,13922
|
||||
pip/_vendor/urllib3/contrib/appengine.py,sha256=VR68eAVE137lxTgjBDwCna5UiBZTOKa01Aj_-5BaCz4,11036
|
||||
pip/_vendor/urllib3/contrib/ntlmpool.py,sha256=NlfkW7WMdW8ziqudopjHoW299og1BTWi0IeIibquFwk,4528
|
||||
pip/_vendor/urllib3/contrib/pyopenssl.py,sha256=hDJh4MhyY_p-oKlFcYcQaVQRDv6GMmBGuW9yjxyeejM,17081
|
||||
pip/_vendor/urllib3/contrib/securetransport.py,sha256=Fef1IIUUFHqpevzXiDPbIGkDKchY2FVKeVeLGR1Qq3g,34446
|
||||
pip/_vendor/urllib3/contrib/socks.py,sha256=aRi9eWXo9ZEb95XUxef4Z21CFlnnjbEiAo9HOseoMt4,7097
|
||||
pip/_vendor/urllib3/exceptions.py,sha256=0Mnno3KHTNfXRfY7638NufOPkUb6mXOm-Lqj-4x2w8A,8217
|
||||
pip/_vendor/urllib3/fields.py,sha256=kvLDCg_JmH1lLjUUEY_FLS8UhY7hBvDPuVETbY8mdrM,8579
|
||||
pip/_vendor/urllib3/filepost.py,sha256=5b_qqgRHVlL7uLtdAYBzBh-GHmU5AfJVt_2N0XS3PeY,2440
|
||||
pip/_vendor/urllib3/packages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/packages/__pycache__/six.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/packages/backports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/packages/backports/__pycache__/weakref_finalize.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/packages/backports/makefile.py,sha256=nbzt3i0agPVP07jqqgjhaYjMmuAi_W5E0EywZivVO8E,1417
|
||||
pip/_vendor/urllib3/packages/backports/weakref_finalize.py,sha256=tRCal5OAhNSRyb0DhHp-38AtIlCsRP8BxF3NX-6rqIA,5343
|
||||
pip/_vendor/urllib3/packages/six.py,sha256=b9LM0wBXv7E7SrbCjAm4wwN-hrH-iNxv18LgWNMMKPo,34665
|
||||
pip/_vendor/urllib3/poolmanager.py,sha256=aWyhXRtNO4JUnCSVVqKTKQd8EXTvUm1VN9pgs2bcONo,19990
|
||||
pip/_vendor/urllib3/request.py,sha256=YTWFNr7QIwh7E1W9dde9LM77v2VWTJ5V78XuTTw7D1A,6691
|
||||
pip/_vendor/urllib3/response.py,sha256=fmDJAFkG71uFTn-sVSTh2Iw0WmcXQYqkbRjihvwBjU8,30641
|
||||
pip/_vendor/urllib3/util/__init__.py,sha256=JEmSmmqqLyaw8P51gUImZh8Gwg9i1zSe-DoqAitn2nc,1155
|
||||
pip/_vendor/urllib3/util/__pycache__/__init__.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/util/__pycache__/connection.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/util/__pycache__/proxy.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/util/__pycache__/queue.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/util/__pycache__/request.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/util/__pycache__/response.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/util/__pycache__/retry.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/util/__pycache__/timeout.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/util/__pycache__/url.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/util/__pycache__/wait.cpython-312.pyc,,
|
||||
pip/_vendor/urllib3/util/connection.py,sha256=5Lx2B1PW29KxBn2T0xkN1CBgRBa3gGVJBKoQoRogEVk,4901
|
||||
pip/_vendor/urllib3/util/proxy.py,sha256=zUvPPCJrp6dOF0N4GAVbOcl6o-4uXKSrGiTkkr5vUS4,1605
|
||||
pip/_vendor/urllib3/util/queue.py,sha256=nRgX8_eX-_VkvxoX096QWoz8Ps0QHUAExILCY_7PncM,498
|
||||
pip/_vendor/urllib3/util/request.py,sha256=C0OUt2tcU6LRiQJ7YYNP9GvPrSvl7ziIBekQ-5nlBZk,3997
|
||||
pip/_vendor/urllib3/util/response.py,sha256=GJpg3Egi9qaJXRwBh5wv-MNuRWan5BIu40oReoxWP28,3510
|
||||
pip/_vendor/urllib3/util/retry.py,sha256=6ENvOZ8PBDzh8kgixpql9lIrb2dxH-k7ZmBanJF2Ng4,22050
|
||||
pip/_vendor/urllib3/util/ssl_.py,sha256=QDuuTxPSCj1rYtZ4xpD7Ux-r20TD50aHyqKyhQ7Bq4A,17460
|
||||
pip/_vendor/urllib3/util/ssl_match_hostname.py,sha256=Ir4cZVEjmAk8gUAIHWSi7wtOO83UCYABY2xFD1Ql_WA,5758
|
||||
pip/_vendor/urllib3/util/ssltransport.py,sha256=NA-u5rMTrDFDFC8QzRKUEKMG0561hOD4qBTr3Z4pv6E,6895
|
||||
pip/_vendor/urllib3/util/timeout.py,sha256=cwq4dMk87mJHSBktK1miYJ-85G-3T3RmT20v7SFCpno,10168
|
||||
pip/_vendor/urllib3/util/url.py,sha256=lCAE7M5myA8EDdW0sJuyyZhVB9K_j38ljWhHAnFaWoE,14296
|
||||
pip/_vendor/urllib3/util/wait.py,sha256=fOX0_faozG2P7iVojQoE1mbydweNyTcm-hXEfFrTtLI,5403
|
||||
pip/_vendor/vendor.txt,sha256=EW-E3cE5XEAtVFzGInikArOMDxGP0DLUWzXpY4RZfFY,333
|
||||
pip/py.typed,sha256=EBVvvPRTn_eIpz5e5QztSCdrMX7Qwd7VP93RSoIlZ2I,286
|
||||
@ -1,5 +1,5 @@
|
||||
Wheel-Version: 1.0
|
||||
Generator: setuptools (70.2.0)
|
||||
Generator: setuptools (75.8.0)
|
||||
Root-Is-Purelib: true
|
||||
Tag: py3-none-any
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
[console_scripts]
|
||||
pip = pip._internal.cli.main:main
|
||||
pip3 = pip._internal.cli.main:main
|
||||
pip3.12 = pip._internal.cli.main:main
|
||||
@ -1,6 +1,6 @@
|
||||
from typing import List, Optional
|
||||
|
||||
__version__ = "24.0"
|
||||
__version__ = "25.0.1"
|
||||
|
||||
|
||||
def main(args: Optional[List[str]] = None) -> int:
|
||||
|
||||
@ -8,8 +8,8 @@ an import statement.
|
||||
|
||||
import sys
|
||||
|
||||
# Copied from setup.py
|
||||
PYTHON_REQUIRES = (3, 7)
|
||||
# Copied from pyproject.toml
|
||||
PYTHON_REQUIRES = (3, 8)
|
||||
|
||||
|
||||
def version_str(version): # type: ignore
|
||||
|
||||
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user