Merge pull request #1123 from zas/const.sys

Introduce picard.const.sys: IS_WIN, IS_MACOS, IS_LINUX, IS_FROZEN
This commit is contained in:
Philipp Wolfer
2019-03-06 14:10:11 +01:00
committed by GitHub
22 changed files with 151 additions and 90 deletions

View File

@@ -28,9 +28,9 @@ from picard import (
)
from picard.acoustid.json_helpers import parse_recording
from picard.const import FPCALC_NAMES
from picard.const.sys import IS_FROZEN
from picard.util import (
find_executable,
is_frozen,
)
@@ -45,7 +45,7 @@ class AcoustIDClient(QtCore.QObject):
# The second condition is checked because in case of a packaged build of picard
# the temp directory that pyinstaller decompresses picard into changes on every
# launch, thus we need to ignore the existing config values.
if not config.setting["acoustid_fpcalc"] or is_frozen:
if not config.setting["acoustid_fpcalc"] or IS_FROZEN:
fpcalc_path = find_executable(*FPCALC_NAMES)
if fpcalc_path:
config.setting["acoustid_fpcalc"] = fpcalc_path

View File

@@ -26,12 +26,12 @@ from heapq import (
import ntpath
from operator import itemgetter
import re
import sys
from PyQt5 import QtCore
from picard import config
from picard.const import QUERY_LIMIT
from picard.const.sys import IS_WIN
from picard.metadata import Metadata
from picard.similarity import similarity
from picard.util import (
@@ -248,7 +248,7 @@ class Cluster(QtCore.QObject, Item):
@staticmethod
def cluster(files, threshold):
win_compat = config.setting["windows_compatibility"] or sys.platform == "win32"
win_compat = config.setting["windows_compatibility"] or IS_WIN
artist_dict = ClusterDict()
album_dict = ClusterDict()
tracks = []

29
picard/const/sys.py Normal file
View File

@@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
#
# Picard, the next-generation MusicBrainz tagger
# Copyright (C) 2019 Laurent Monin
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import sys
IS_WIN = sys.platform == 'win32'
IS_LINUX = sys.platform == 'linux'
IS_MACOS = sys.platform == 'darwin'
# These variables are set by pyinstaller if running from a packaged build
# See http://pyinstaller.readthedocs.io/en/stable/runtime-information.html
IS_FROZEN = getattr(sys, 'frozen', False)
FROZEN_TEMP_PATH = getattr(sys, '_MEIPASS', '')

View File

@@ -26,7 +26,6 @@ import os
import os.path
import re
import shutil
import sys
import unicodedata
from PyQt5 import QtCore
@@ -37,6 +36,10 @@ from picard import (
log,
)
from picard.const import QUERY_LIMIT
from picard.const.sys import (
IS_MACOS,
IS_WIN,
)
from picard.metadata import Metadata
from picard.util import (
decode_filename,
@@ -351,14 +354,14 @@ class File(QtCore.QObject, Item):
# TODO: move following logic under util.filenaming
# (and reconsider its necessity)
# win32 compatibility fixes
if settings['windows_compatibility'] or sys.platform == 'win32':
if settings['windows_compatibility'] or IS_WIN:
new_filename = new_filename.replace('./', '_/').replace('.\\', '_\\')
# replace . at the beginning of file and directory names
new_filename = new_filename.replace('/.', '/_').replace('\\.', '\\_')
if new_filename and new_filename[0] == '.':
new_filename = '_' + new_filename[1:]
# Fix for precomposed characters on OSX
if sys.platform == "darwin":
if IS_MACOS:
new_filename = unicodedata.normalize("NFD", new_filename)
new_path = os.path.join(new_dirname, new_filename)

View File

@@ -21,10 +21,14 @@ import builtins
import gettext
import locale
import os.path
import sys
from PyQt5.QtCore import QLocale
from picard.const.sys import (
IS_MACOS,
IS_WIN,
)
builtins.__dict__['N_'] = lambda a: a
@@ -40,7 +44,7 @@ def setup_gettext(localedir, ui_language=None, logger=None):
except Exception as e:
logger(e)
else:
if sys.platform == 'win32':
if IS_WIN:
from ctypes import windll
try:
current_locale = locale.windows_locale[windll.kernel32.GetUserDefaultUILanguage()]
@@ -53,7 +57,7 @@ def setup_gettext(localedir, ui_language=None, logger=None):
logger(e)
except Exception as e:
logger(e)
elif sys.platform == 'darwin':
elif IS_MACOS:
try:
import Foundation
defaults = Foundation.NSUserDefaults.standardUserDefaults()

View File

@@ -58,6 +58,11 @@ from picard.cluster import (
)
from picard.collection import load_user_collections
from picard.config_upgrade import upgrade_config
from picard.const.sys import (
IS_FROZEN,
IS_MACOS,
IS_WIN,
)
from picard.const import (
USER_DIR,
USER_PLUGIN_DIR,
@@ -130,7 +135,7 @@ class Tagger(QtWidgets.QApplication):
# Use the new fusion style from PyQt5 for a modern and consistent look
# across all OSes.
if sys.platform != "darwin":
if not IS_MACOS:
self.setStyle('Fusion')
# Set the WM_CLASS to 'MusicBrainz-Picard' so desktop environments
@@ -171,7 +176,7 @@ class Tagger(QtWidgets.QApplication):
self.save_thread_pool = QtCore.QThreadPool(self)
self.save_thread_pool.setMaxThreadCount(1)
if not sys.platform == "win32":
if not IS_WIN:
# Set up signal handling
# It's not possible to call all available functions from signal
# handlers, therefore we need to set up a QSocketNotifier to listen
@@ -194,7 +199,7 @@ class Tagger(QtWidgets.QApplication):
signal.signal(signal.SIGINT, self.signal)
signal.signal(signal.SIGTERM, self.signal)
if sys.platform == "darwin":
if IS_MACOS:
# On macOS it is not common that the global menu shows icons
self.setAttribute(QtCore.Qt.AA_DontShowIconsInMenus)
@@ -233,7 +238,7 @@ class Tagger(QtWidgets.QApplication):
# Load plugins
self.pluginmanager = PluginManager()
if not self._no_plugins:
if hasattr(sys, "frozen"):
if IS_FROZEN:
self.pluginmanager.load_plugindir(os.path.join(os.path.dirname(sys.argv[0]), "plugins"))
else:
mydir = os.path.dirname(os.path.abspath(__file__))

View File

@@ -19,7 +19,6 @@
#
import os
import sys
from PyQt5 import (
QtCore,
@@ -28,6 +27,7 @@ from PyQt5 import (
from PyQt5.QtCore import QStandardPaths
from picard import config
from picard.const.sys import IS_MACOS
from picard.formats import supported_formats
from picard.util import find_existing_path
@@ -73,7 +73,7 @@ class FileBrowser(QtWidgets.QTreeView):
self.model.setNameFilterDisables(False)
self.model.sort(0, QtCore.Qt.AscendingOrder)
self.setModel(self.model)
if sys.platform == "darwin":
if IS_MACOS:
self.setRootIndex(self.model.index("/Volumes"))
header = self.header()
header.hideSection(1)

View File

@@ -21,7 +21,6 @@ from collections import OrderedDict
import datetime
from functools import partial
import os.path
import sys
from PyQt5 import (
QtCore,
@@ -36,6 +35,9 @@ from picard import (
from picard.album import Album
from picard.cluster import Cluster
from picard.const import PROGRAM_UPDATE_LEVELS
from picard.const.sys import (
IS_MACOS,
)
from picard.file import File
from picard.formats import supported_formats
from picard.plugin import ExtensionPoint
@@ -122,14 +124,14 @@ class MainWindow(QtWidgets.QMainWindow, PreserveGeometry):
icon.addFile(":/images/256x256/org.musicbrainz.Picard.png", QtCore.QSize(256, 256))
self.setWindowIcon(icon)
self.show_close_window = sys.platform == "darwin"
self.show_close_window = IS_MACOS
self.create_actions()
self.create_statusbar()
self.create_toolbar()
self.create_menus()
if sys.platform == "darwin":
if IS_MACOS:
self.setUnifiedTitleAndToolBarOnMac(True)
self.toolbar.setMovable(False)
self.search_toolbar.setMovable(False)
@@ -174,7 +176,7 @@ class MainWindow(QtWidgets.QMainWindow, PreserveGeometry):
def keyPressEvent(self, event):
# On macOS Command+Backspace triggers the so called "Forward Delete".
# It should be treated the same as the Delete button.
is_forward_delete = sys.platform == 'darwin' and \
is_forward_delete = IS_MACOS and \
event.key() == QtCore.Qt.Key_Backspace and \
event.modifiers() & QtCore.Qt.ControlModifier
if event.matches(QtGui.QKeySequence.Delete) or is_forward_delete:

View File

@@ -23,7 +23,6 @@
from functools import partial
from operator import attrgetter
import os.path
import sys
from PyQt5 import (
QtCore,
@@ -36,10 +35,12 @@ from picard import (
config,
log,
)
from picard.const import (
PLUGINS_API,
USER_PLUGIN_DIR,
)
from picard.const.sys import IS_WIN
from picard.util import reconnect
from picard.ui import HashableTreeWidgetItem
@@ -633,7 +634,7 @@ class PluginsOptionsPage(OptionsPage):
@staticmethod
def open_plugin_dir():
if sys.platform == 'win32':
if IS_WIN:
url = 'file:///' + USER_PLUGIN_DIR
else:
url = 'file://' + USER_PLUGIN_DIR

View File

@@ -19,7 +19,6 @@
from locale import strxfrm
from operator import itemgetter
import sys
from PyQt5 import (
QtCore,
@@ -27,12 +26,14 @@ from PyQt5 import (
)
from picard import config
from picard.const import (
RELEASE_COUNTRIES,
RELEASE_FORMATS,
RELEASE_PRIMARY_GROUPS,
RELEASE_SECONDARY_GROUPS,
)
from picard.const.sys import IS_WIN
from picard.i18n import gettext_attr
from picard.ui.options import (
@@ -67,12 +68,12 @@ class TipSlider(QtWidgets.QSlider):
def showEvent(self, event):
super().showEvent(event)
if sys.platform != 'win32':
if not IS_WIN:
self.valueChanged.connect(self.show_tip)
def hideEvent(self, event):
super().hideEvent(event)
if sys.platform != 'win32':
if not IS_WIN:
self.valueChanged.disconnect(self.show_tip)
def show_tip(self, value):

View File

@@ -20,7 +20,6 @@
from functools import partial
import os.path
import sys
from PyQt5 import QtWidgets
from PyQt5.QtCore import QStandardPaths
@@ -28,6 +27,7 @@ from PyQt5.QtGui import QPalette
from picard import config
from picard.const import PICARD_URLS
from picard.const.sys import IS_WIN
from picard.file import File
from picard.script import (
ScriptError,
@@ -125,7 +125,7 @@ class RenamingOptionsPage(OptionsPage):
self.ui.file_naming_format_default.setEnabled(state)
self.ui.ascii_filenames.setEnabled(state)
self.ui.file_naming_format_group.setEnabled(state)
if not sys.platform == "win32":
if not IS_WIN:
self.ui.windows_compatibility.setEnabled(state)
if self.ui.file_naming_format.isEnabled():
@@ -171,7 +171,7 @@ class RenamingOptionsPage(OptionsPage):
self.ui.example_filename_va.setText(example2)
def load(self):
if sys.platform == "win32":
if IS_WIN:
self.ui.windows_compatibility.setChecked(True)
self.ui.windows_compatibility.setEnabled(False)
else:

View File

@@ -17,8 +17,6 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import sys
from PyQt5 import (
QtCore,
QtGui,
@@ -26,6 +24,10 @@ from PyQt5 import (
)
from picard import config
from picard.const.sys import (
IS_MACOS,
IS_WIN,
)
from picard.util import (
find_existing_path,
icontheme,
@@ -49,7 +51,7 @@ class StandardButton(QtWidgets.QPushButton):
def __init__(self, btntype):
label = _(self.__types[btntype][0])
args = [label]
if sys.platform != 'win32' and sys.platform != 'darwin':
if not IS_WIN and not IS_MACOS:
iconname = self.__types[btntype][1]
if hasattr(QtWidgets.QStyle, iconname):
icon = self.tagger.style().standardIcon(getattr(QtWidgets.QStyle, iconname))
@@ -87,7 +89,7 @@ class MultiDirsSelectDialog(QtWidgets.QFileDialog):
super().__init__(*args)
self.setFileMode(self.Directory)
self.setOption(self.ShowDirsOnly)
if sys.platform in ["darwin", "win32"]:
if IS_WIN or IS_MACOS:
# The native dialog doesn't allow selecting >1 directory
self.setOption(self.DontUseNativeDialog)
for view in self.findChildren((QtWidgets.QListView, QtWidgets.QTreeView)):

View File

@@ -31,17 +31,18 @@ from PyQt5 import QtCore
# Required for compatibility with lastfmplus which imports this from here rather than loading it direct.
from picard.const import MUSICBRAINZ_SERVERS
from picard.const.sys import (
FROZEN_TEMP_PATH,
IS_FROZEN,
IS_MACOS,
IS_WIN,
)
if sys.platform == 'win32':
if IS_WIN:
from ctypes import windll
# These variables are set by pyinstaller if running from a packaged build
# See http://pyinstaller.readthedocs.io/en/stable/runtime-information.html
is_frozen = getattr(sys, 'frozen', False)
frozen_temp_path = getattr(sys, '_MEIPASS', '')
class LockableObject(QtCore.QObject):
"""Read/write lockable object."""
@@ -142,7 +143,7 @@ def replace_win32_incompat(string, repl="_"):
"""Replace win32 filename incompatible characters from ``string`` by
``repl``."""
# Don't replace : with _ for windows drive
if sys.platform == "win32" and os.path.isabs(string):
if IS_WIN and os.path.isabs(string):
drive, rest = ntpath.splitdrive(string)
return drive + _re_win32_incompat.sub(repl, rest)
else:
@@ -200,13 +201,13 @@ def find_existing_path(path):
def find_executable(*executables):
if sys.platform == 'win32':
if IS_WIN:
executables = [e + '.exe' for e in executables]
paths = [os.path.dirname(sys.executable)] if sys.executable else []
paths += os.environ.get('PATH', '').split(os.pathsep)
# This is for searching for executables bundled in packaged builds
if is_frozen:
paths += [frozen_temp_path]
if IS_FROZEN:
paths += [FROZEN_TEMP_PATH]
for path in paths:
for executable in executables:
f = os.path.join(path, executable)
@@ -317,7 +318,7 @@ def tracknum_from_filename(base_filename):
# Provide os.path.samefile equivalent which is missing in Python under Windows
if sys.platform == 'win32':
if IS_WIN:
def os_path_samefile(p1, p2):
ap1 = os.path.abspath(p1)
ap2 = os.path.abspath(p2)
@@ -332,12 +333,12 @@ def is_hidden(filepath):
on non-Windows systems or if it has the "hidden" flag
set on Windows."""
name = os.path.basename(os.path.abspath(filepath))
return (name.startswith('.') and sys.platform != 'win32') \
return (not IS_WIN and name.startswith('.')) \
or _has_hidden_attribute(filepath)
def _has_hidden_attribute(filepath):
if sys.platform != 'win32':
if not IS_WIN:
return False
# FIXME: On OSX detecting hidden files involves more
# than just checking for dot files, see

View File

@@ -18,17 +18,19 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import sys
from PyQt5.QtCore import (
QFile,
QIODevice,
)
from picard import config
from picard.const.sys import (
IS_LINUX,
IS_WIN,
)
from picard.util import uniqify
if sys.platform == 'win32':
if IS_WIN:
from ctypes import windll
@@ -50,9 +52,9 @@ if discid is not None:
LINUX_CDROM_INFO = '/proc/sys/dev/cdrom/info'
# if get_cdrom_drives() lists ALL drives available on the machine
if sys.platform == 'win32':
if IS_WIN:
AUTO_DETECT_DRIVES = True
elif sys.platform == 'linux' and QFile.exists(LINUX_CDROM_INFO):
elif IS_LINUX and QFile.exists(LINUX_CDROM_INFO):
AUTO_DETECT_DRIVES = True
else:
# There might be more drives we couldn't detect
@@ -66,7 +68,7 @@ def get_cdrom_drives():
# add default drive from libdiscid to the list
drives = list(DEFAULT_DRIVES)
if sys.platform == 'win32':
if IS_WIN:
GetLogicalDrives = windll.kernel32.GetLogicalDrives
GetDriveType = windll.kernel32.GetDriveTypeW
DRIVE_CDROM = 5
@@ -77,7 +79,7 @@ def get_cdrom_drives():
if GetDriveType(drive) == DRIVE_CDROM:
drives.append(drive)
elif sys.platform == 'linux' and QFile.exists(LINUX_CDROM_INFO):
elif IS_LINUX and QFile.exists(LINUX_CDROM_INFO):
# Read info from /proc/sys/dev/cdrom/info
cdinfo = QFile(LINUX_CDROM_INFO)
if cdinfo.open(QIODevice.ReadOnly | QIODevice.Text):

View File

@@ -25,6 +25,10 @@ import unicodedata
from PyQt5.QtCore import QStandardPaths
from picard.const.sys import (
IS_MACOS,
IS_WIN,
)
from picard.util import (
_io_encoding,
decode_filename,
@@ -324,7 +328,7 @@ def make_short_filename(basedir, relpath, win_compat=False, relative_to=""):
# always strip the relpath parts
relpath = os.path.join(*[part.strip() for part in relpath.split(os.path.sep)])
# if we're on windows, delegate the work to a windows-specific function
if sys.platform == "win32":
if IS_WIN:
reserved = len(basedir)
if not basedir.endswith(os.path.sep):
reserved += 1
@@ -345,7 +349,7 @@ def make_short_filename(basedir, relpath, win_compat=False, relative_to=""):
relpath = _make_win_short_filename(relpath, reserved)
# on *nix we can consider there is no path limit, but there is
# a filename length limit.
if sys.platform == "darwin":
if IS_MACOS:
# on OS X (i.e. HFS+), this is expressed in UTF-16 code points,
# in NFD normalization form
relpath = shorten_path(relpath, 255, mode=SHORTEN_UTF16_NFD)

View File

@@ -18,11 +18,13 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import os.path
import sys
from PyQt5 import QtGui
if sys.platform == 'win32':
from picard.const.sys import IS_WIN
if IS_WIN:
_search_paths = []
else:
_search_paths = [

View File

@@ -19,9 +19,8 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import sys
from picard import config
from picard.const.sys import IS_WIN
from picard.script import ScriptParser
from picard.util import (
replace_win32_incompat,
@@ -42,7 +41,7 @@ def script_to_filename(naming_format, metadata, file=None, settings=None):
if settings["ascii_filenames"]:
filename = replace_non_ascii(filename, pathsave=True)
# replace incompatible characters
if settings["windows_compatibility"] or sys.platform == "win32":
if settings["windows_compatibility"] or IS_WIN:
filename = replace_win32_incompat(filename)
# remove null characters
filename = filename.replace("\x00", "")

View File

@@ -11,7 +11,6 @@ import glob
from io import StringIO
import os
from os import path
import platform
import re
import sys
import tempfile
@@ -27,6 +26,11 @@ from picard import (
PICARD_VERSION,
__version__,
)
from picard.const.sys import (
IS_LINUX,
IS_WIN,
)
if sys.version_info < (3, 5):
sys.exit("ERROR: You need Python 3.5 or higher to use Picard.")
@@ -213,7 +217,7 @@ class picard_build(build):
def run(self):
log.info('generating scripts/%s from scripts/picard.in', PACKAGE_NAME)
generate_file('scripts/picard.in', 'scripts/' + PACKAGE_NAME, {'localedir': self.localedir, 'autoupdate': not self.disable_autoupdate})
if platform.system() == 'Windows':
if IS_WIN:
# Temporarily setting it to this value to generate a nice name for Windows app
args['name'] = 'MusicBrainz Picard'
file_version = PICARD_VERSION[0:3] + PICARD_VERSION[4:]
@@ -225,7 +229,7 @@ class picard_build(build):
}
generate_file('win-version-info.txt.in', 'win-version-info.txt', {**args, **version_args})
args['name'] = 'picard'
elif platform.system() == 'Linux':
elif IS_LINUX:
self.run_command('build_appdata')
build.run(self)
@@ -734,7 +738,7 @@ args['data_files'] = [
('share/applications', ('org.musicbrainz.Picard.desktop',)),
]
if platform.system() == 'Linux':
if IS_LINUX:
args['data_files'].append(('share/metainfo', ['org.musicbrainz.Picard.appdata.xml']))
setup(**args)

View File

@@ -4,11 +4,16 @@ import os.path
import sys
from picard.const.sys import (
FROZEN_TEMP_PATH,
IS_FROZEN,
IS_WIN,
)
# On Windows try to attach to the console as early as possible in order
# to get stdout / stderr logged to console. This needs to happen before
# logging gets imported.
# See https://stackoverflow.com/questions/54536/win32-gui-app-that-writes-usage-text-to-stdout-when-invoked-as-app-exe-help
if sys.platform == "win32":
if IS_WIN:
from ctypes import windll
if windll.kernel32.AttachConsole(-1):
sys.stdout = open('CON', 'w')
@@ -16,16 +21,12 @@ if sys.platform == "win32":
from picard.tagger import main
from picard.util import (
frozen_temp_path,
is_frozen,
)
sys.path.insert(0, '.')
# This is needed to find resources when using pyinstaller
if is_frozen:
basedir = frozen_temp_path
if IS_FROZEN:
basedir = FROZEN_TEMP_PATH
else:
basedir = os.path.dirname(os.path.abspath(__file__))

View File

@@ -1,8 +1,7 @@
import sys
from test.picardtestcase import PicardTestCase
from picard import config
from picard.const.sys import IS_WIN
from picard.file import File
from picard.metadata import Metadata
from picard.script import register_script_function
@@ -68,7 +67,7 @@ class ScriptToFilenameTest(PicardTestCase):
expect_orig = '*:?'
expect_compat = '___'
filename = script_to_filename('%artist%?', metadata, settings=settings)
self.assertEqual(expect_compat if sys.platform == 'win32' else expect_orig, filename)
self.assertEqual(expect_compat if IS_WIN else expect_orig, filename)
settings['windows_compatibility'] = True
filename = script_to_filename('%artist%?', metadata, settings=settings)
self.assertEqual(expect_compat, filename)

View File

@@ -6,28 +6,30 @@ import sys
from test.picardtestcase import PicardTestCase
import unittest
from picard.const.sys import (
IS_MACOS,
IS_WIN,
)
from picard.util.filenaming import make_short_filename
class ShortFilenameTest(PicardTestCase):
def __init__(self, *args, **kwargs):
self.maxDiff = None
is_win32 = sys.platform == "win32"
self.root = os.path.join(is_win32 and "X:\\" or "/", "x" * 10)
if is_win32:
self.root = os.path.join(IS_WIN and "X:\\" or "/", "x" * 10)
if IS_WIN:
self.max_len = 255
else:
self.max_len = os.statvfs("/").f_namemax
super().__init__(*args, **kwargs)
@unittest.skipUnless(sys.platform in ("win32", "darwin"), "windows / os x test")
@unittest.skipUnless(IS_WIN or IS_MACOS, "windows / os x test")
def test_bmp_unicode_on_unicode_fs(self):
char = u"\N{LATIN SMALL LETTER SHARP S}"
fn = make_short_filename(self.root, os.path.join(*[char * 120] * 2))
self.assertEqual(fn, os.path.join(*[char * 120] * 2))
@unittest.skipUnless(sys.platform not in ("win32", "darwin"), "non-windows, non-osx test")
@unittest.skipUnless(not IS_WIN and not IS_MACOS, "non-windows, non-osx test")
def test_bmp_unicode_on_nix(self):
char = u"\N{LATIN SMALL LETTER SHARP S}"
max_len = self.max_len
@@ -35,28 +37,28 @@ class ShortFilenameTest(PicardTestCase):
fn = make_short_filename(self.root, os.path.join(*[char * 200] * 2))
self.assertEqual(fn, os.path.join(*[char * (max_len // divisor)] * 2))
@unittest.skipUnless(sys.platform == "darwin", "os x test")
@unittest.skipUnless(IS_MACOS, "os x test")
def test_precomposed_unicode_on_osx(self):
char = u"\N{LATIN SMALL LETTER A WITH BREVE}"
max_len = self.max_len
fn = make_short_filename(self.root, os.path.join(*[char * 200] * 2))
self.assertEqual(fn, os.path.join(*[char * (max_len // 2)] * 2))
@unittest.skipUnless(sys.platform == "win32", "windows test")
@unittest.skipUnless(IS_WIN, "windows test")
def test_nonbmp_unicode_on_windows(self):
char = u"\N{MUSICAL SYMBOL G CLEF}"
remaining = 259 - (3 + 10 + 1 + 200 + 1)
fn = make_short_filename(self.root, os.path.join(*[char * 100] * 2))
self.assertEqual(fn, os.path.join(char * 100, char * (remaining // 2)))
@unittest.skipUnless(sys.platform == "darwin", "os x test")
@unittest.skipUnless(IS_MACOS, "os x test")
def test_nonbmp_unicode_on_osx(self):
char = u"\N{MUSICAL SYMBOL G CLEF}"
max_len = self.max_len
fn = make_short_filename(self.root, os.path.join(*[char * 200] * 2))
self.assertEqual(fn, os.path.join(*[char * (max_len // 2)] * 2))
@unittest.skipUnless(sys.platform not in ("win32", "darwin"), "non-windows, non-osx test")
@unittest.skipUnless(not IS_WIN and not IS_MACOS, "non-windows, non-osx test")
def test_nonbmp_unicode_on_nix(self):
char = u"\N{MUSICAL SYMBOL G CLEF}"
max_len = self.max_len
@@ -64,7 +66,7 @@ class ShortFilenameTest(PicardTestCase):
fn = make_short_filename(self.root, os.path.join(*[char * 100] * 2))
self.assertEqual(fn, os.path.join(*[char * (max_len // divisor)] * 2))
@unittest.skipUnless(sys.platform not in ("win32", "darwin"), "non-windows, non-osx test")
@unittest.skipUnless(not IS_WIN and not IS_MACOS, "non-windows, non-osx test")
def test_nonbmp_unicode_on_nix_with_windows_compat(self):
char = u"\N{MUSICAL SYMBOL G CLEF}"
max_len = self.max_len
@@ -77,7 +79,7 @@ class ShortFilenameTest(PicardTestCase):
fn = make_short_filename(self.root, os.path.join("a" * 200, "b" * 200, "c" * 200 + ".ext"), win_compat=True)
self.assertEqual(fn, os.path.join("a" * 116, "b" * 116, "c" * 7 + ".ext"))
@unittest.skipUnless(sys.platform != "win32", "non-windows test")
@unittest.skipUnless(not IS_WIN, "non-windows test")
def test_windows_shortening_with_ancestor_on_nix(self):
root = os.path.join(self.root, "w" * 10, "x" * 10, "y" * 9, "z" * 9)
fn = make_short_filename(

View File

@@ -2,11 +2,11 @@
import builtins
import os.path
import sys
from test.picardtestcase import PicardTestCase
import unittest
from picard import util
from picard.const.sys import IS_WIN
from picard.util import imageinfo
# ensure _() is defined
@@ -16,14 +16,14 @@ if '_' not in builtins.__dict__:
class ReplaceWin32IncompatTest(PicardTestCase):
@unittest.skipUnless(sys.platform == "win32", "windows test")
@unittest.skipUnless(IS_WIN, "windows test")
def test_correct_absolute_win32(self):
self.assertEqual(util.replace_win32_incompat("c:\\test\\te\"st/2"),
"c:\\test\\te_st/2")
self.assertEqual(util.replace_win32_incompat("c:\\test\\d:/2"),
"c:\\test\\d_/2")
@unittest.skipUnless(sys.platform != "win32", "non-windows test")
@unittest.skipUnless(not IS_WIN, "non-windows test")
def test_correct_absolute_non_win32(self):
self.assertEqual(util.replace_win32_incompat("/test/te\"st/2"),
"/test/te_st/2")
@@ -89,7 +89,7 @@ class FormatTimeTest(PicardTestCase):
class HiddenFileTest(PicardTestCase):
@unittest.skipUnless(sys.platform != "win32", "non-windows test")
@unittest.skipUnless(not IS_WIN, "non-windows test")
def test(self):
self.assertTrue(util.is_hidden('/a/b/.c.mp3'))
self.assertTrue(util.is_hidden('/a/.b/.c.mp3'))