
Pyggester - (Python + Suggester) fonctionne à la fois comme un analyseur dynamique et statique. Son objectif principal réside dans l'offre de suggestions pour améliorer l'efficacité du code Python en abordant l'utilisation sous-optimale des structures de données.
Pyggester propose une interface CLI assez décente pour ses fonctionnalités. La CLI est construite sur Typer
Execution command :
pyggest output :
_____
_____________ ________ _______ ______________ /_____________
___ __ _ / / /_ __ `/_ __ `/ _ _ ___/ __/ _ _ ___/
__ /_/ / /_/ /_ /_/ /_ /_/ // __/(__ )/ /_ / __/ /
_ .___/___, / ___, / ___, / ___//____/ __/ ___//_/
/_/ /____/ /____/ /____/
Usage: pyggest [OPTIONS] COMMAND [ARGS]...
╭─ Options ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --install-completion Install completion for the current shell. │
│ --show-completion Show completion for the current shell, to copy it or customize the installation. │
│ --help Show this message and exit. │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ static Perform static analysis using PyggestStatic. │
│ transform Perform dynamic transformation using PyggesterDynamic. │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
La CLI de Pyggerster présente deux caractéristiques distinctes:
Analyse statique: Cette fonctionnalité examine de manière approfondie votre code sans l'exécuter, fournissant des informations approfondies sur sa structure et ses améliorations potentielles.
Execution command
[! Remarque] La sous-commande «statique» existe, mais n'a pas de fonctionnalité implémentée, car nous avons déjà de bons analyseurs statiques (Pylint, Ruff, Flake8). Dans les itérations futures, si nous identifions des suggestions qui peuvent être établies par analyse statique, nous les incorporerons dans cette fonctionnalité.
pyggest staticTransformation dynamique / automatique: cette fonctionnalité ajoute du code supplémentaire à vos fichiers Python pour analyser vos structures de données lors de l'exécution. Votre code d'origine reste le même; il ne sera pas changé. Un nouveau fichier est créé, c'est comme l'original mais avec un code supplémentaire. Cela fonctionne pour les fichiers uniques et les répertoires entiers (structures de projet complètes).
Execution command
pyggest transform[! Info] Pyggester propose une documentation intégrée pour une utilisation détaillée
pyggest transform --help
pyggest static --help # NOT IMPLEMENTEDVous pouvez facilement installer la bibliothèque Python à l'aide de PIP. Ouvrez votre terminal et exécutez la commande suivante:
pip install pyggesterClone le référentiel: ouvrez votre terminal et exécutez la commande suivante pour cloner le référentiel GitHub à votre machine locale:
git clone [email protected]:ValdonVitija/pyggester.gitAccédez au référentiel: modifiez votre répertoire de travail dans le référentiel cloné:
cd pyggesterInstallez Pyggerster en tant que Pacakge localement:
[! IMPORTANT] Envisagez de le faire dans un environnement virtuel (VENV) si possible.
pip install .Supposons que vous ayez un seul fichier python que vous souhaitez analyser dynamiquement (analyse d'exécution)
Avant la transformation du code avec Pyggester:
(venv) root@user: ~ /my_app > ls
app.pyContenu de App.py:
def sum_of_integers ( integer_list ):
total = sum ( integer_list )
return total
my_list = [ 1 , 2 , 3 , 4 , 5 ]
print ( sum_of_integers ( my_list ))Important
Assurez-vous que vous êtes dans un environnement virtuel avec Pyggester installé avant de passer à l'étape suivante.
(venv) root@devs04: ~ /my_app > pyggest transform app.py
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ File transformed successfully ! │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯(venv) root@devs04: ~ /my_app > ls
app.py app_transformed.pyContenu de App_Transformed.py:
from pyggester . observable_collector import OBSERVABLE_COLLECTOR
from pyggester . observables import ObservableNumpyArray , ObservableNamedTuple , ObservableSet , ObservablePandasDataFrame , ObservableList , ObservableDict , ObservableTuple
def sum_of_integers ( integer_list ):
total = sum ( integer_list )
return total
my_list = ObservableList ([ 1 , 2 , 3 , 4 , 5 ])
OBSERVABLE_COLLECTOR . append ( my_list )
print ( sum_of_integers ( my_list ))
for observable in OBSERVABLE_COLLECTOR :
observable . run ()Important
Nous avons maintenant un nouveau fichier, créé automatiquement, qui reflète le fichier d'origine. Ce nouveau fichier comprend tous les contenus de l'original, plus le code supplémentaire pour analyser votre code pendant l'exécution. Au lieu d'exécuter l'original «app.py», vous devriez maintenant exécuter «app_transformed.py». Rassurez-vous, tout de «app.py» est conservé dans «app_transformed.py».
(venv) root@devs04: ~ /my_app > python3 app_transformed.py
15
╭────────────────────────────────────────────────────────────────────────────╮
│ 10 | Suggestions(/root/my_app/app_transformed.py): │
│ [ * ] Consider using an array.array instead of a list, for optimal │
│ memory consumption │
│ [ * ] Consider using a set instead of a list, because of unique elements │
╰────────────────────────────────────────────────────────────────────────────╯Supposons que vous ayez un projet Python (répertoire / repo) que vous souhaitez analyser dynamiquement (analyse de l'exécution)
Avant la transformation du code avec Pyggester:
(venv) root@devs04: ~ /python_demo/app_dir > ls
__pycache__ app.py temperature.py weather.pyContenu de App.py:
import weather
import temperature
def main ():
city = input ( 'Enter a city name: ' )
weather_condition = weather . get_weather ( city )
avg_temp = temperature . get_average_temperature ()
print ( f'Weather in { city } : { weather_condition } ' )
print ( f'Average temperature: { avg_temp } degrees Celsius' )
main ()Contenu de la température.py:
temperatures = list ([ 20 , 22 , 15 , 18 , 20 , 21 , 22 , 22 , 18 , 17 , 20 ])
def get_average_temperature ():
return sum ( temperatures ) / len ( temperatures )Contenu de Weather.py:
weather_conditions = [ 'Sunny' , 'Rainy' , 'Cloudy' , 'Windy' , 'Sunny' , 'Cloudy' ]
def get_weather ( city ):
return weather_conditions . pop ()Important
Assurez-vous que vous êtes dans un environnement virtuel avec Pyggester installé avant de passer à l'étape suivante.
(venv) root@devs04: ~ /python_demo > pyggest transform app_dir/
Enter the name of the main file: app.py
╭──────────────────────────────────────────────────────────────────────────╮
│ Directory transformed successfully ! │
╰──────────────────────────────────────────────────────────────────────────╯Important
Lorsqu'un répertoire ou un projet est spécifié comme un argument, Pyggeter nous invite à spécifier le fichier principal de notre projet. Ce fichier doit être le point d'entrée de votre projet, indiqué par son nom de fichier.
(venv) root@devs04: ~ /python_demo > ls
app_dir app_dir_transformedContenu de App_DIR_TRANSFORMED /:
( venv ) root @ devs04 : ~ / python_demo / app_dir_transformed > ls
app . py temperature . py weather . pyContenu de App.py:
from pyggester . observable_collector import OBSERVABLE_COLLECTOR
from pyggester . observables import ObservableNumpyArray , ObservableList , ObservablePandasDataFrame , ObservableNamedTuple , ObservableSet , ObservableDict , ObservableTuple
import weather
import temperature
def main ():
city = input ( 'Enter a city name: ' )
weather_condition = weather . get_weather ( city )
avg_temp = temperature . get_average_temperature ()
print ( f'Weather in { city } : { weather_condition } ' )
print ( f'Average temperature: { avg_temp } degrees Celsius' )
main ()
for observable in OBSERVABLE_COLLECTOR :
observable . run ()Contenu de la température.py:
from pyggester . observable_collector import OBSERVABLE_COLLECTOR
from pyggester . observables import ObservableNumpyArray , ObservableList , ObservablePandasDataFrame , ObservableNamedTuple , ObservableSet , ObservableDict , ObservableTuple
temperatures = ObservableList ( list ([ 20 , 22 , 15 , 18 , 20 , 21 , 22 , 22 , 18 , 17 ,
20 ]))
OBSERVABLE_COLLECTOR . append ( temperatures )
def get_average_temperature ():
return sum ( temperatures ) / len ( temperatures )Contenu de Weather.py:
from pyggester . observable_collector import OBSERVABLE_COLLECTOR
from pyggester . observables import ObservableNumpyArray , ObservableList , ObservablePandasDataFrame , ObservableNamedTuple , ObservableSet , ObservableDict , ObservableTuple
weather_conditions = ObservableList ([ 'Sunny' , 'Rainy' , 'Cloudy' , 'Windy' ,
'Sunny' , 'Cloudy' ])
OBSERVABLE_COLLECTOR . append ( weather_conditions )
def get_weather ( city ):
return weather_conditions . pop ()Important
Nous avons maintenant un nouveau répertoire, créé automatiquement, qui reflète le répertoire d'origine. Ce nouveau répertoire comprend tout le contenu de l'original, plus le code supplémentaire pour analyser votre code pendant l'exécution. Au lieu d'exécuter l'original 'app.py', vous devriez maintenant exécuter 'app.py' qui réside dans 'app_dir_transformed /'. Rassurez-vous, tout de «App_DIR» est conservé dans «App_DIR_TRANSFORMED /».
(venv) root@devs04: ~ /python_demo/app_dir_transformed > python3 app.py
Enter a city name: Pristina
Weather in Pristina: Cloudy
Average temperature: 19.545454545454547 degrees Celsius
╭─────────────────────────────────────────────────────────────────────────────────────╮
│ 3 | Suggestions(/root/python_demo/app_dir_transformed/temperature.py): │
│ [ * ] Consider using an array.array instead of a list, for optimal memory │
│ consumption │
╰─────────────────────────────────────────────────────────────────────────────────────╯ .
├── LICENSE
├── README.md # main readme file. The one you are currently reading.
├── VERSION # version of pyggester
├── contributing.md
├── pyggester # directory containing the full source code of pyggester
│ ├── __init__.py
│ ├── cli.py # defines the typer cli structure(command & options)
│ ├── command_handlers.py # Handles subcommands and every option variation per subcommand.
│ ├── data # data/config files related to pyggester.
│ │ └── help_files # build in help files for the pyggester cli
│ │ ├── __init__.py
│ │ ├── transform_helper.md # detailed built-in documentation for the transform subcommand of pyggest
│ │ └── static_helper.md # detailed built-in documentation for the static subcommand of pyggest
│ ├── helpers.py # helper functions to be used by other modules
│ ├── main.py # The entry point of pyggest execution. Initializes the typer cli app and prints the ascii logo of pyggester
│ ├── message_handler.py # Manages how the collected messages will be printed to the user.
│ ├── module_importer.py # Contains the mechanism to automatically import observables
│ ├── observable_collector.py # Contains the list that will be used to collect all observables.
│ ├── observable_transformations.py # Contains the mechanism that will automatically add code that collects observables and glues together all ast modules
│ ├── observables.py # Contains all the defined observables(enhanced version of python collections)
│ ├── pyggester.py # The 'engine' of pyggester. This module glues everything together
│ ├── text_formatters.py # Contains text formatters, to beautify text in stdout.
│ └── wrappers.py # Contains the mechanism that wrap each observable.
├── pyggester_abstract_execution_flow.png
├── pyggester_logo.png
├── pytest.ini # pytest config file
├── requirements.txt # Every pyggester dependecy resides here
├── setup.py # Creates the pyggester pacakge and defines pyggest as the entry point command to execute pyggester
└── tests
├── __init__.py
├── test_cli.py
├── test_command_handlers.py
├── test_file.py
├── test_file_transformed.py
├── test_helpers.py
├── test_main.py
├── test_message_handler.py
├── test_module_importer.py
├── test_observable_transformations.py
├── test_observables.py
├── test_pyggester.py
└── test_wrappers.pyLe diagramme d'écoulement suivant illustre les composants clés de Pyggester et fournit un aperçu complet de la séquence d'exécution.

Pour contribuer à ce projet, veuillez vous référer au Guide de contribution complet pour les instructions détaillées et les meilleures pratiques.
Licence MIT
Copyright (C) 2023 Valdonvitijaa
L'autorisation est accordée gratuitement à toute personne qui obtient une copie de ce logiciel et des fichiers de documentation associés (le "logiciel"), pour traiter le logiciel sans restriction, y compris sans limiter les droits d'utilisation, de copie, de modification, de fusion, de publication, de distribution, de sublince et / ou de vendre des copies des conditions suivantes.
L'avis de droit d'auteur ci-dessus et le présent avis d'autorisation sont inclus dans toutes les copies ou des parties substantielles du logiciel.
Le logiciel est fourni "tel quel", sans garantie d'aucune sorte, express ou implicite, y compris, mais sans s'y limiter, les garanties de qualité marchande, d'adéquation à un usage particulier et de non-contrefaçon. En aucun cas, les auteurs ou les détenteurs de droits d'auteur ne seront pas responsables de toute réclamation, dommage ou autre responsabilité, que ce soit dans une action de contrat, de délit ou autre, découlant de, hors du logiciel ou de l'utilisation ou d'autres relations dans le logiciel.