tis-python3
3.9.7-28
Python is an interpreted, high-level, general-purpose programming language
8556 downloads

Description
- package : tis-python3
- name : Python 3
- version : 3.9.7-28
- categories : Development
- maintainer : WAPT Team,Tranquil IT,Jimmy PELÉ
- installed_size :
- editor : Python Software Foundation
- licence : Python Software Foundation License
- signature_date : 2021-08-31T17:08:46.966223
- size : 28.63 Mo
- locale : all
- target_os : windows
- impacted_process :
- architecture : x64
- Homepage : https://www.python.org/
- Depends :
- Conflicts :
control
package : tis-python3
version : 3.9.7-28
architecture : x64
section : base
priority : optional
name : Python 3
categories : Development
maintainer : WAPT Team,Tranquil IT,Jimmy PELÉ
description : Python is an interpreted, high-level, general-purpose programming language
depends : tis-vcredist
conflicts : tis-python3-32
maturity : PROD
locale : all
target_os : windows
min_wapt_version : 1.8
sources : https://www.python.org/downloads/windows/
installed_size :
impacted_process :
description_fr : Python est un langage de programmation interprété, multi-paradigme et multiplateformes
description_pl :
description_de :
description_es :
description_pt :
description_it :
description_nl :
description_ru :
audit_schedule :
editor : Python Software Foundation
keywords : python,3,3.8,3.9,programming,language,interpreted,py,.py,code,coding,language,object-oriented
licence : Python Software Foundation License
homepage : https://www.python.org/
package_uuid : 6468e383-ae37-4038-9252-671caf4dc19e
valid_from :
valid_until :
forced_install_on :
changelog : https://docs.python.org/3/whatsnew/changelog.html
min_os_version : 6.2
max_os_version :
icon_sha256sum : b55b23fa81945c6cd4c2f4f114188aa9f8f3d0c3cbb9fb353b2803ffbb67b43b
signer : Tranquil IT
signer_fingerprint: 8c5127a75392be9cc9afd0dbae1222a673072c308c14d88ab246e23832e8c6bb
signature : F+cHL33EgjwPQuPdNLml/grfa8gbf8rMIfDN64UFkevMiRX3W2AYjJsdRPrxC3V/vbM9VVXkAd674zYV9JjfEoBREzBaiw5CYbY+mxYa6XcM2UntXoOLIltq/4EEaRxzsxrUb4ubzgGGluieHQIh/aE0xpUyFnbeVqem04Rwctvx1LQwAYpmfDMbgJEhq07vZSEWmRZ+XV4CmaLmZo9gK+U1D7Kz4bommqxDpOZ2NGuBBwl4wZUw7utwMAPnSKJ7vmBRzr+TO/i7LjF1D0yMSo1TW/Tu6vfdCJ0IkjgiMjqTYBiAZowe4ZsJDGMfI3oM1aYX4Tz2hD8EZmLEAfrroQ==
signature_date : 2021-08-31T17:08:46.966223
signed_attributes : package,version,architecture,section,priority,name,categories,maintainer,description,depends,conflicts,maturity,locale,target_os,min_wapt_version,sources,installed_size,impacted_process,description_fr,description_pl,description_de,description_es,description_pt,description_it,description_nl,description_ru,audit_schedule,editor,keywords,licence,homepage,package_uuid,valid_from,valid_until,forced_install_on,changelog,min_os_version,max_os_version,icon_sha256sum,signer,signer_fingerprint,signature_date,signed_attributes
Setup.py
# -*- coding: utf-8 -*-
from setuphelpers import *
import platform
import bs4 as BeautifulSoup
# Installation procedure: https://docs.python.org/3/using/windows.html
# Usable WAPT package functions: install(), uninstall(), session_setup(), audit(), update_package()
# Declaring global variables - Warnings: 1) WAPT context is only available in package functions; 2) Global variables are not persistent between calls
bin_contains = 'python-'
app_dir_sub = makepath(programfiles, 'Python%s')
app_uninstallkey = '' # Let it empty because it change every versions
silent_uninst_args = '/uninstall /quiet'
def install():
# Declaring local variables
package_version = control.get_software_version()
short_version = '.'.join(package_version.split('.')[:2])
two_digit_version = ''.join(package_version.split('.')[:2])
app_dir = app_dir_sub % two_digit_version
bin_name = glob.glob('*%s*.exe' % bin_contains)[0]
app_name = control.name
app_installer_path = makepath(app_dir, bin_name)
product_name = get_file_properties(bin_name)['ProductName']
silent_args = '/quiet InstallAllUsers=1 PrependPath=1 AssociateFiles=1 Include_launcher=0 InstallLauncherAllUsers=0 TargetDir="%s"' % app_dir
#silent_args = '/quiet InstallAllUsers=1 PrependPath=1 AssociateFiles=1 Include_launcher=0 InstallLauncherAllUsers=0'
# Repairing if older installation is incomplete
python_app = installed_softwares(name='Python %s' % short_version)
if python_app and len(python_app) < 9:
print("Repairing: %s at: %s" % (product_name, app_dir))
run('"%s" /repair %s' % (bin_name, silent_args))
# Installing the package
if need_install(name='Python %s' % short_version, min_version=get_version_from_binary(bin_name), force=force):
print("Installing: %s to: %s" % (product_name, app_dir))
install_exe_if_needed(bin_name,
silentflags=silent_args,
key=app_uninstallkey,
min_version=package_version,
)
else:
print("%s is already installed and up-to-date" % app_name)
# Copying installer for future uninstall
if not isfile(app_installer_path):
filecopyto(bin_name,app_installer_path)
def uninstall():
# Declaring local variables
package_version = control.get_software_version()
two_digit_version = ''.join(package_version.split('.')[:2])
app_dir = app_dir_sub % two_digit_version
bin_name = glob.glob(r'%s\%s*.exe' % (app_dir, bin_contains))[0]
app_installer_path = makepath(app_dir,bin_name)
# Uninstalling the package
run('"%s" %s' % (app_installer_path, silent_uninst_args))
# Removing remaining files of this Python version
try:
if isdir(app_dir):
print("Removing remaining folder: %s" % app_dir)
remove_tree(app_dir)
except:
print("Unable to remove Python %s remaining folder: %s" % (package_version, app_dir))
# Removing system environment variables
remove_from_system_path(app_dir)
remove_from_system_path(makepath(app_dir, 'Scripts'))
def update_package():
# Declaring local variables
result = False
proxies = get_proxies()
if not proxies:
proxies = get_proxies_from_wapt_console()
app_name = control.name
url = 'https://www.python.org/downloads/windows/'
if control.architecture == 'x64':
arch = '64-bit'
else:
arch = '32-bit'
# Getting latest version from official sources
for bs_search in bs_find_all(url, 'a', proxies=proxies):
if bs_search['href'].startswith('https://www.python.org/ftp/python/3.') and bs_search.string.startswith('Windows installer (%s)' % arch):
version = bs_search['href'].split('/')[-2]
latest_bin = bs_search['href'].split('/')[-1]
url_dl = bs_search['href']
break
print("Latest %s version is: %s" % (app_name, version))
print("Download url is: %s" % url_dl)
# Downloading latest binaries
if not isfile(latest_bin):
print("Downloading: %s" % latest_bin)
wget(url_dl, latest_bin, proxies=proxies)
# Checking version from file
version_from_file = get_version_from_binary(latest_bin, 'ProductName').split(' (')[0].split(' ')[-1]
if Version(version) != Version(version_from_file) and version_from_file != '':
print("Changing version to the version number of the binary (from: %s to: %s)" % (version, version_from_file))
os.rename(latest_bin, bin_contains + version_from_file + latest_bin.split(version)[-1])
version = version_from_file
# Changing version of the package
if Version(version) > Version(control.get_software_version()):
print("Software version updated (from: %s to: %s)" % (control.get_software_version(), Version(version)))
result = True
control.version = '%s-%s' % (Version(version), control.version.split('-', 1)[-1])
#control.set_software_version(Version(version))
control.save_control_to_wapt()
# Deleting outdated binaries
remove_outdated_binaries(version)
# Validating or not update-package-sources
return result
def need_install(key='', min_version=None, force=False, get_version=None, keywords='', name=''):
"""Return True if the software with key can be found in uninstall registry
and the registred version is equal or greater than min_version
Args:
key (str): uninstall key
min_version (str): minimum version or None if don't check version (like when key is specific for each soft version)
get_version (callable): optional func to get installed software version from one installed_softwares item
if not provided, version is taken from 'version' attribute in uninstall registry
keywords (str or list): string to lookup in key, display_name or publisher fields
name (str regexp) : filter on a regular expression on software name
Returns:
boolean
.. versionchanged:: 2.1
added keywords and name
"""
if force or (not bool(key) and not bool(keywords) and not bool(name)):
return True
elif len([i for i in [key, name, keywords] if i]) >= 2:
error("Please only specify key or keywords or name")
else:
if key:
current = installed_softwares(uninstallkey=key)
if keywords:
current = installed_softwares(keywords=keywords)
if name:
current = installed_softwares(name=name)
for soft in current:
if min_version is None:
return False
if get_version is not None:
installed_version = get_version(soft)
else:
installed_version = soft['version']
if Version(min_version) <= installed_version:
return False
return True
def get_proxies():
r"""Return system proxy with the urllib python library
>>> get_proxies()
{'http': 'http://srvproxy.ad.domain.lan:8080',
'https': 'http://srvproxy.ad.domain.lan:8080'}
"""
if platform.python_version_tuple()[0] == '3':
from urllib.request import getproxies
else:
from urllib import getproxies
return getproxies()
def get_proxies_from_wapt_console():
r"""Return proxy information from the current user WAPT console
>>> get_proxies_from_wapt_console()
{'http': 'http://srvproxy.ad.domain.lan:8080',
'https': 'http://srvproxy.ad.domain.lan:8080'}
"""
proxies = {}
if platform.system() == 'Windows':
waptconsole_ini_path = makepath(user_local_appdata(), 'waptconsole', 'waptconsole.ini')
else:
waptconsole_ini_path = makepath(user_home_directory(), '.config', 'waptconsole', 'waptconsole.ini')
if isfile(waptconsole_ini_path):
proxy_wapt = inifile_readstring(waptconsole_ini_path, 'global', 'http_proxy')
if proxy_wapt:
proxies = {'http': proxy_wapt, 'https': proxy_wapt}
return proxies
def bs_find_all(url, element, attribute=None, value=None, user_agent=None, proxies=None, features='html.parser', **kwargs):
r""""Parse html web page with BeautifulSoup and get a list of the result
Args:
url (str): url of the web page to parse
element (str): searched element
attribute (str): selected attribute of the element
value (str): value of the selected attribute
user_agent (str): specify a user-agent if needed
proxies (dict): specify your proxy if needed
**kwargs (str): joker for requests parameters
features (str): bs feature to use
>>> bs_find_all('https://www.w3.org/', 'a', 'title', 'Open Web Platform testing')[0]['href']
'https://web-platform-tests.org/'
>>> bs_find_all('https://www.w3.org/', 'span', 'class', 'alt-logo')[0].string
'W3C'
.. versionadded:: 2.0
"""
import requests
if user_agent:
page = requests.get(url, proxies=proxies, headers={'User-Agent':'%s' % user_agent}, **kwargs).text
else:
page = requests.get(url, proxies=proxies, **kwargs).text
soup = BeautifulSoup.BeautifulSoup(page, features=features)
if value:
return soup.find_all(element, {attribute:value})
else:
return soup.find_all(element)
def get_version_from_binary(filename, property_name='ProductVersion'):
r""" Get installer version from file informations, for now, only exe and msi files are compatibles
Args:
filename (str): path to the file
property_name (str): selected property
Returns:
str: version number
"""
if filename.endswith('.msi'):
return get_msi_properties(filename)[property_name]
else:
return get_file_properties(filename)[property_name]
def remove_outdated_binaries(version, filename_contains=None, list_extensions=['exe','msi','deb','rpm','dmg','pkg']):
r"""Remove files based on the version contained in his filename
Args:
version (str): version number of keeped files
filename_contains (str or list of str): Part of the filename that must be contained (useful for distinguishing architecture and os)
list_extensions (str or list of str): file extensions of verified files
Returns:
None
.. versionadded:: 2.0
"""
if type(list_extensions) != list:
list_extensions = [list_extensions]
if filename_contains:
if type(filename_contains) != list:
filename_contains = [filename_contains]
list_extensions = ['.' + ext for ext in list_extensions if ext[0] != '.']
for file_ext in list_extensions:
for bin_in_dir in glob.glob('*%s' % file_ext):
if not version in bin_in_dir:
remove_file(bin_in_dir)
if filename_contains:
for filename_contain in filename_contains:
if not filename_contain in bin_in_dir:
remove_file(bin_in_dir)
3f63f4c77a6da13f9bae715eb6644a48bd5f900601e0f1f233862e8ca1a96dd8 : python-3.9.7-amd64.exe
ad4b652bd3c7881365c79e5693c3202520ec274eaeefc5a3a0267e6e7729f9f5 : setup.py
a5a97261381e1d0ad46ee15916abec9c2631d0201f5cc50ceb0197a165a0bbbf : WAPT/certificate.crt
b55b23fa81945c6cd4c2f4f114188aa9f8f3d0c3cbb9fb353b2803ffbb67b43b : WAPT/icon.png
068b9a3608ced2512aeeb5ca8a33b8450eaa5ae9f5682a8e4b31d2fae964f092 : WAPT/control