diff --git a/CHANGELOG.md b/CHANGELOG.md index acbaac9..20e80f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- `python_version` attribute ## [1.0] - 2022-12-14 ### Added - `Marker` enum diff --git a/samila/functions.py b/samila/functions.py index df3bd97..2dff476 100644 --- a/samila/functions.py +++ b/samila/functions.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- """Samila functions.""" +import sys import requests import io import os @@ -438,6 +439,7 @@ def _GI_initializer(g, function1, function2): :return: None """ g.matplotlib_version = matplotlib.__version__ + g.python_version = get_python_version() g.function1 = function1 g.function1_str = None g.function2 = function2 @@ -515,6 +517,19 @@ def save_data_file(g, file_adr): return result +def get_python_version(): + """ + Get Python's version. + + :return: python's version as 'major.minor.micro' + """ + return "{}.{}.{}".format( + sys.version_info.major, + sys.version_info.minor, + sys.version_info.micro + ) + + def get_data(g): """ Return data. @@ -524,6 +539,7 @@ def get_data(g): :return: data as a dict """ matplotlib_version = matplotlib.__version__ + python_version = get_python_version() data = {} if g.data1 is None or g.data2 is None: raise samilaDataError(SAVE_NO_DATA_ERROR) @@ -541,6 +557,7 @@ def get_data(g): "depth": g.depth } data['matplotlib_version'] = matplotlib_version + data['python_version'] = python_version return data @@ -553,6 +570,7 @@ def get_config(g): :return: config as a dict """ matplotlib_version = matplotlib.__version__ + python_version = get_python_version() config = {} if g.function1_str is None or g.function2_str is None: raise samilaConfigError(CONFIG_NO_STR_FUNCTION_ERROR) @@ -576,6 +594,7 @@ def get_config(g): "depth": g.depth } config['matplotlib_version'] = matplotlib_version + config['python_version'] = python_version return config @@ -747,6 +766,8 @@ def load_data(g, data): raise samilaDataError(DATA_FORMAT_ERROR) if 'matplotlib_version' in data: g.matplotlib_version = data['matplotlib_version'] + if 'python_version' in data: + g.python_version = data['python_version'] plot_config = data.get("plot") if plot_config is not None: g.color = plot_config.get("color", DEFAULT_COLOR) @@ -780,6 +801,8 @@ def load_config(g, config): raise samilaConfigError(CONFIG_FORMAT_ERROR) if 'matplotlib_version' in data: g.matplotlib_version = data['matplotlib_version'] + if 'python_version' in data: + g.python_version = data['python_version'] generate_config = data.get("generate") if generate_config is not None: g.seed = generate_config.get("seed") diff --git a/samila/genimage.py b/samila/genimage.py index f902d5c..94c6ca8 100644 --- a/samila/genimage.py +++ b/samila/genimage.py @@ -7,7 +7,7 @@ import itertools import matplotlib import matplotlib.pyplot as plt from .functions import _GI_initializer, plot_params_filter, generate_params_filter, save_params_filter -from .functions import get_config, get_data +from .functions import get_config, get_data, get_python_version from .functions import float_range, save_data_file, save_fig_file, save_fig_buf, save_config_file from .functions import load_data, load_config, random_equation_gen, nft_storage_upload from .functions import set_background @@ -44,10 +44,12 @@ class GenerativeImage: load_config(self, config) elif data is not None: load_data(self, data) - if self.matplotlib_version != matplotlib.__version__: + if self.matplotlib_version != matplotlib.__version__ or \ + self.python_version != get_python_version(): warn( - MATPLOTLIB_VERSION_WARNING.format( - self.matplotlib_version), + VERSION_WARNING.format( + self.matplotlib_version, + self.python_version), RuntimeWarning) if self.function1 is None: if self.function1_str is None: diff --git a/samila/params.py b/samila/params.py index 565b665..525dcbd 100644 --- a/samila/params.py +++ b/samila/params.py @@ -47,7 +47,7 @@ PLOT_DATA_ERROR = "Plotting process can't be Done because data{0} is empty. Use COLOR_SIZE_ERROR = "Color list size is not equal to the data size." SAVE_NO_DATA_ERROR = "Data file can't be saved. At least one of the data1 or data2 is None." INVALID_COLOR_TYPE_ERROR = "Given color/bgcolor type is not supported." -MATPLOTLIB_VERSION_WARNING = "Source matplotlib version({0}) is different from yours, plots may be different." +VERSION_WARNING = "Source matplotlib version({0}) or Python version({1}) is different from yours, plots may be different." CALCULATION_EXCEPTION_WARNING = "The given functions are undefined at some points. Your plot may not be complete." BOTH_COLOR_COMPLEMENT_WARNING = "It is not possible to set color and bgcolor to 'complement' at the same time! Both are automatically set to the previous or default selection." COLOR_NOT_FOUND_WARNING = "color '{0}' not found. Replacing it with '{1}'" diff --git a/test/function_test.py b/test/function_test.py index 747418e..effd86a 100644 --- a/test/function_test.py +++ b/test/function_test.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- """ >>> import random +>>> import sys >>> from samila.functions import * >>> is_valid_color("blue") True @@ -90,6 +91,8 @@ False 1 >>> distance_calc("test12","test234") 3 +>>> get_python_version() == sys.version.split()[0] +True >>> samila_help() Samila is a generative art generator written in Python, Samila let's you diff --git a/test/overall_test.py b/test/overall_test.py index 63d92ed..788bff4 100644 --- a/test/overall_test.py +++ b/test/overall_test.py @@ -6,6 +6,7 @@ >>> import pickle >>> import socket >>> import json +>>> import sys >>> from matplotlib.colors import Colormap, ListedColormap >>> def guard(*args, **kwargs): ... raise Exception("No internet connection!") @@ -23,6 +24,8 @@ True >>> g.function2 == f2 True +>>> g.python_version == sys.version.split()[0] +True >>> g.fig >>> g.generate() >>> isinstance(g.data1, list) diff --git a/test/warning_test.py b/test/warning_test.py index 3973b25..0ceeb5b 100644 --- a/test/warning_test.py +++ b/test/warning_test.py @@ -13,12 +13,20 @@ True >>> g_.data2 == g.data2 True >>> with open('data.json', 'w') as fp: +... json.dump({'data1': [0], 'data2': [0], 'python_version': '0'}, fp) +>>> with warns(RuntimeWarning, match=r"Source matplotlib version(.*) or Python version(.*) is different from yours, plots may be different."): +... g = GenerativeImage(data=open('data.json', 'r')) +>>> with open('config.json', 'w') as fp: +... json.dump({'f1': 'x', 'f2': 'y', 'python_version': '0'}, fp) +>>> with warns(RuntimeWarning, match=r"Source matplotlib version(.*) or Python version(.*) is different from yours, plots may be different."): +... g = GenerativeImage(config=open('config.json', 'r')) +>>> with open('data.json', 'w') as fp: ... json.dump({'data1': [0], 'data2': [0], 'matplotlib_version': '0'}, fp) ->>> with warns(RuntimeWarning, match=r"Source matplotlib version(.*) is different from yours, plots may be different."): -... g = GenerativeImage(lambda x,y: 0, lambda x,y: 0, data=open('data.json', 'r')) +>>> with warns(RuntimeWarning, match=r"Source matplotlib version(.*) or Python version(.*) is different from yours, plots may be different."): +... g = GenerativeImage(data=open('data.json', 'r')) >>> with open('config.json', 'w') as fp: ... json.dump({'f1': 'x', 'f2': 'y', 'matplotlib_version': '0'}, fp) ->>> with warns(RuntimeWarning, match=r"Source matplotlib version(.*) is different from yours, plots may be different."): +>>> with warns(RuntimeWarning, match=r"Source matplotlib version(.*) or Python version(.*) is different from yours, plots may be different."): ... g = GenerativeImage(config=open('config.json', 'r')) >>> g = GenerativeImage(lambda x, y: 1 / x, lambda x, y: 1 / (y - 1)) >>> with warns(RuntimeWarning, match=r"The given functions are undefined at some points. Your plot may not be complete."):