Merge pull request #1692 from Exiv2/hassec_canon_lens_test
New Canon Lens Identification + Automatic Test of all Lenses
This commit is contained in:
+340
-467
File diff suppressed because it is too large
Load Diff
+5
-1
@@ -2577,7 +2577,11 @@ namespace Exiv2 {
|
||||
|
||||
float fnumber(float apertureValue)
|
||||
{
|
||||
return std::exp(std::log(2.0F) * apertureValue / 2.F);
|
||||
float result = std::exp(std::log(2.0F) * apertureValue / 2.F);
|
||||
if (std::abs(result - 3.5) < 0.1) {
|
||||
result = 3.5;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
URational exposureTime(float shutterSpeedValue)
|
||||
|
||||
+10
-10
@@ -1093,7 +1093,7 @@ File 6/16: 20030925_201850.jpg
|
||||
20030925_201850.jpg Exif.CanonCs.0x0015 Short 1 32767
|
||||
20030925_201850.jpg Exif.CanonCs.LensType Short 1 n/a
|
||||
20030925_201850.jpg Exif.CanonCs.Lens Short 3 18.0 - 55.0 mm
|
||||
20030925_201850.jpg Exif.CanonCs.MaxAperture Short 1 F3.6
|
||||
20030925_201850.jpg Exif.CanonCs.MaxAperture Short 1 F3.5
|
||||
20030925_201850.jpg Exif.CanonCs.MinAperture Short 1 F22
|
||||
20030925_201850.jpg Exif.CanonCs.FlashActivity Short 1 Did not fire
|
||||
20030925_201850.jpg Exif.CanonCs.FlashDetails Short 1
|
||||
@@ -1906,7 +1906,7 @@ File 14/16: 20001004_015404.jpg
|
||||
20001004_015404.jpg Exif.CanonCs.AFPoint Short 1 Auto-selected
|
||||
20001004_015404.jpg Exif.CanonCs.ExposureProgram Short 1 Aperture priority (Av)
|
||||
20001004_015404.jpg Exif.CanonCs.0x0015 Short 1 0
|
||||
20001004_015404.jpg Exif.CanonCs.LensType Short 1 Canon EF 28-70mm f/2.8L USM
|
||||
20001004_015404.jpg Exif.CanonCs.LensType Short 1 Canon EF 28-70mm f/2.8L USM *OR* Sigma 28-70mm f/2.8 EX
|
||||
20001004_015404.jpg Exif.CanonCs.Lens Short 3 28.0 - 70.0 mm
|
||||
20001004_015404.jpg Exif.CanonCs.MaxAperture Short 1 F2.8
|
||||
20001004_015404.jpg Exif.CanonCs.MinAperture Short 1 F22
|
||||
@@ -2734,7 +2734,7 @@ Compare image data and extracted data ------------------------------------
|
||||
< 20030925_201850.jpg Exif.CanonCs.0x0015 Short 1 32767
|
||||
< 20030925_201850.jpg Exif.CanonCs.LensType Short 1 n/a
|
||||
< 20030925_201850.jpg Exif.CanonCs.Lens Short 3 18.0 - 55.0 mm
|
||||
< 20030925_201850.jpg Exif.CanonCs.MaxAperture Short 1 F3.6
|
||||
< 20030925_201850.jpg Exif.CanonCs.MaxAperture Short 1 F3.5
|
||||
< 20030925_201850.jpg Exif.CanonCs.MinAperture Short 1 F22
|
||||
< 20030925_201850.jpg Exif.CanonCs.FlashActivity Short 1 Did not fire
|
||||
< 20030925_201850.jpg Exif.CanonCs.FlashDetails Short 1
|
||||
@@ -3546,7 +3546,7 @@ Compare image data and extracted data ------------------------------------
|
||||
< 20001004_015404.jpg Exif.CanonCs.AFPoint Short 1 Auto-selected
|
||||
< 20001004_015404.jpg Exif.CanonCs.ExposureProgram Short 1 Aperture priority (Av)
|
||||
< 20001004_015404.jpg Exif.CanonCs.0x0015 Short 1 0
|
||||
< 20001004_015404.jpg Exif.CanonCs.LensType Short 1 Canon EF 28-70mm f/2.8L USM
|
||||
< 20001004_015404.jpg Exif.CanonCs.LensType Short 1 Canon EF 28-70mm f/2.8L USM *OR* Sigma 28-70mm f/2.8 EX
|
||||
< 20001004_015404.jpg Exif.CanonCs.Lens Short 3 28.0 - 70.0 mm
|
||||
< 20001004_015404.jpg Exif.CanonCs.MaxAperture Short 1 F2.8
|
||||
< 20001004_015404.jpg Exif.CanonCs.MinAperture Short 1 F22
|
||||
@@ -4297,7 +4297,7 @@ Compare image data and extracted data ------------------------------------
|
||||
> 20030925_201850.exv Exif.CanonCs.0x0015 Short 1 32767
|
||||
> 20030925_201850.exv Exif.CanonCs.LensType Short 1 n/a
|
||||
> 20030925_201850.exv Exif.CanonCs.Lens Short 3 18.0 - 55.0 mm
|
||||
> 20030925_201850.exv Exif.CanonCs.MaxAperture Short 1 F3.6
|
||||
> 20030925_201850.exv Exif.CanonCs.MaxAperture Short 1 F3.5
|
||||
> 20030925_201850.exv Exif.CanonCs.MinAperture Short 1 F22
|
||||
> 20030925_201850.exv Exif.CanonCs.FlashActivity Short 1 Did not fire
|
||||
> 20030925_201850.exv Exif.CanonCs.FlashDetails Short 1
|
||||
@@ -5109,7 +5109,7 @@ Compare image data and extracted data ------------------------------------
|
||||
> 20001004_015404.exv Exif.CanonCs.AFPoint Short 1 Auto-selected
|
||||
> 20001004_015404.exv Exif.CanonCs.ExposureProgram Short 1 Aperture priority (Av)
|
||||
> 20001004_015404.exv Exif.CanonCs.0x0015 Short 1 0
|
||||
> 20001004_015404.exv Exif.CanonCs.LensType Short 1 Canon EF 28-70mm f/2.8L USM
|
||||
> 20001004_015404.exv Exif.CanonCs.LensType Short 1 Canon EF 28-70mm f/2.8L USM *OR* Sigma 28-70mm f/2.8 EX
|
||||
> 20001004_015404.exv Exif.CanonCs.Lens Short 3 28.0 - 70.0 mm
|
||||
> 20001004_015404.exv Exif.CanonCs.MaxAperture Short 1 F2.8
|
||||
> 20001004_015404.exv Exif.CanonCs.MinAperture Short 1 F22
|
||||
@@ -6098,7 +6098,7 @@ Compare original and inserted image data ---------------------------------
|
||||
< 20030925_201850.jpg Exif.CanonCs.0x0015 Short 1 32767
|
||||
< 20030925_201850.jpg Exif.CanonCs.LensType Short 1 n/a
|
||||
< 20030925_201850.jpg Exif.CanonCs.Lens Short 3 18.0 - 55.0 mm
|
||||
< 20030925_201850.jpg Exif.CanonCs.MaxAperture Short 1 F3.6
|
||||
< 20030925_201850.jpg Exif.CanonCs.MaxAperture Short 1 F3.5
|
||||
< 20030925_201850.jpg Exif.CanonCs.MinAperture Short 1 F22
|
||||
< 20030925_201850.jpg Exif.CanonCs.FlashActivity Short 1 Did not fire
|
||||
< 20030925_201850.jpg Exif.CanonCs.FlashDetails Short 1
|
||||
@@ -6910,7 +6910,7 @@ Compare original and inserted image data ---------------------------------
|
||||
< 20001004_015404.jpg Exif.CanonCs.AFPoint Short 1 Auto-selected
|
||||
< 20001004_015404.jpg Exif.CanonCs.ExposureProgram Short 1 Aperture priority (Av)
|
||||
< 20001004_015404.jpg Exif.CanonCs.0x0015 Short 1 0
|
||||
< 20001004_015404.jpg Exif.CanonCs.LensType Short 1 Canon EF 28-70mm f/2.8L USM
|
||||
< 20001004_015404.jpg Exif.CanonCs.LensType Short 1 Canon EF 28-70mm f/2.8L USM *OR* Sigma 28-70mm f/2.8 EX
|
||||
< 20001004_015404.jpg Exif.CanonCs.Lens Short 3 28.0 - 70.0 mm
|
||||
< 20001004_015404.jpg Exif.CanonCs.MaxAperture Short 1 F2.8
|
||||
< 20001004_015404.jpg Exif.CanonCs.MinAperture Short 1 F22
|
||||
@@ -7661,7 +7661,7 @@ Compare original and inserted image data ---------------------------------
|
||||
> 20030925_201850.exv Exif.CanonCs.0x0015 Short 1 32767
|
||||
> 20030925_201850.exv Exif.CanonCs.LensType Short 1 n/a
|
||||
> 20030925_201850.exv Exif.CanonCs.Lens Short 3 18.0 - 55.0 mm
|
||||
> 20030925_201850.exv Exif.CanonCs.MaxAperture Short 1 F3.6
|
||||
> 20030925_201850.exv Exif.CanonCs.MaxAperture Short 1 F3.5
|
||||
> 20030925_201850.exv Exif.CanonCs.MinAperture Short 1 F22
|
||||
> 20030925_201850.exv Exif.CanonCs.FlashActivity Short 1 Did not fire
|
||||
> 20030925_201850.exv Exif.CanonCs.FlashDetails Short 1
|
||||
@@ -8473,7 +8473,7 @@ Compare original and inserted image data ---------------------------------
|
||||
> 20001004_015404.exv Exif.CanonCs.AFPoint Short 1 Auto-selected
|
||||
> 20001004_015404.exv Exif.CanonCs.ExposureProgram Short 1 Aperture priority (Av)
|
||||
> 20001004_015404.exv Exif.CanonCs.0x0015 Short 1 0
|
||||
> 20001004_015404.exv Exif.CanonCs.LensType Short 1 Canon EF 28-70mm f/2.8L USM
|
||||
> 20001004_015404.exv Exif.CanonCs.LensType Short 1 Canon EF 28-70mm f/2.8L USM *OR* Sigma 28-70mm f/2.8 EX
|
||||
> 20001004_015404.exv Exif.CanonCs.Lens Short 3 28.0 - 70.0 mm
|
||||
> 20001004_015404.exv Exif.CanonCs.MaxAperture Short 1 F2.8
|
||||
> 20001004_015404.exv Exif.CanonCs.MinAperture Short 1 F22
|
||||
|
||||
Binary file not shown.
@@ -9,7 +9,7 @@ class Sigma24_105mmRecognization(metaclass=system_tests.CaseMeta):
|
||||
|
||||
filename = "$data_path/exiv2-g45.exv"
|
||||
commands = ["$exiv2 -pa --grep lens/i " + filename]
|
||||
stdout = ["""Exif.CanonCs.LensType Short 1 Sigma 24-105mm F4 DG OS HSM | A
|
||||
stdout = ["""Exif.CanonCs.LensType Short 1 Sigma 24-105mm f/4 DG OS HSM | A
|
||||
Exif.CanonCs.Lens Short 3 24.0 - 105.0 mm
|
||||
Exif.CanonCf.LensAFStopButton Short 1 0
|
||||
Exif.Canon.LensModel Ascii 74 24-105mm F4 DG OS HSM | Art 013
|
||||
|
||||
@@ -10,7 +10,7 @@ class CheckTokina11_20mm(metaclass=system_tests.CaseMeta):
|
||||
|
||||
commands = [ "$exiv2 -pa --grep lens/i $filename" ]
|
||||
|
||||
stdout = [ """Exif.CanonCs.LensType Short 1 Tokina AT-X 11-20 F2.8 PRO DX Aspherical 11-20mm f/2.8
|
||||
stdout = [ """Exif.CanonCs.LensType Short 1 Tokina AT-X 11-20 f/2.8 PRO DX Aspherical 11-20mm f/2.8
|
||||
Exif.CanonCs.Lens Short 3 11.0 - 20.0 mm
|
||||
Exif.Canon.LensModel Ascii 74 11-20mm
|
||||
Exif.Photo.LensSpecification Rational 4 11/1 20/1 0/1 0/1
|
||||
|
||||
@@ -10,7 +10,7 @@ class CheckSigma35mm(metaclass=system_tests.CaseMeta):
|
||||
|
||||
commands = [ "$exiv2 -pa --grep lens/i $filename" ]
|
||||
|
||||
stdout = [ """Exif.CanonCs.LensType Short 1 Sigma 35mm f/1.4 DG HSM
|
||||
stdout = [ """Exif.CanonCs.LensType Short 1 Sigma 35mm f/1.4 DG HSM *OR* Sigma 35mm f/1.5 FF High-Speed Prime | 017
|
||||
Exif.CanonCs.Lens Short 3 35.0 mm
|
||||
Exif.Canon.LensModel Ascii 74 35mm
|
||||
Exif.Photo.LensSpecification Rational 4 35/1 35/1 0/1 0/1
|
||||
|
||||
@@ -16,7 +16,7 @@ class CanonLenses(metaclass=system_tests.CaseMeta):
|
||||
"$exiv2 -pa --grep lens/i " + filenames[1],
|
||||
]
|
||||
|
||||
stdout = ["""Exif.CanonCs.LensType Short 1 Sigma APO 120-300mm f/2.8 EX DG OS HSM
|
||||
stdout = ["""Exif.CanonCs.LensType Short 1 Sigma APO 120-300mm f/2.8 EX DG OS HSM *OR* Sigma 120-300mm f/2.8 DG OS HSM S013
|
||||
Exif.CanonCs.Lens Short 3 120.0 - 300.0 mm
|
||||
Exif.Canon.LensModel Ascii 74 120-300mm
|
||||
Exif.Photo.LensSpecification Rational 4 120/1 300/1 0/1 0/1
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import os
|
||||
import system_tests
|
||||
from lens_tests.utils import extract_lenses_from_cpp, make_test_cases, aperture_to_raw_exif
|
||||
|
||||
# NOTE
|
||||
# Normally the canon maker note holds the max aperture of the lens at the focal length
|
||||
# the picture was taken at. Thus for a f/4-6.3 lens, this value could be anywhere in that range.
|
||||
# For the below tests we only test the scenario where the lens was used at it's shortest focal length.
|
||||
# Thus we always pick the 'aperture_max_short' of a lens as the value to write into the
|
||||
# Exif.CanonCs.MaxAperture field.
|
||||
|
||||
# get directory of the current file
|
||||
file_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
# to get the canon maker note cpp file that contains list of all supported lenses
|
||||
canon_lens_file = os.path.abspath(os.path.join(file_dir, "./../../src/canonmn_int.cpp"))
|
||||
# tell the below function what the start of the lens array looks like
|
||||
startpattern = "constexpr TagDetails canonCsLensType[] = {"
|
||||
# use utils function to extract all lenses
|
||||
lenses = extract_lenses_from_cpp(canon_lens_file, startpattern)
|
||||
# use utils function to define test case data
|
||||
test_cases = make_test_cases(lenses)
|
||||
|
||||
for lens_tc in test_cases:
|
||||
|
||||
testname = lens_tc["id"] + "_" + lens_tc["desc"]
|
||||
|
||||
globals()[testname] = system_tests.CaseMeta(
|
||||
"canon_lenses." + testname,
|
||||
tuple(),
|
||||
{
|
||||
"filename": "$data_path/template.exv",
|
||||
"commands": [
|
||||
'$exiv2 -M"set Exif.CanonCs.LensType $lens_id" -M"set Exif.CanonCs.Lens $focal_length_max $focal_length_min 1" -M"set Exif.CanonCs.MaxAperture $aperture_max" $filename && $exiv2 -pa -K Exif.CanonCs.LensType $filename'
|
||||
],
|
||||
"stderr": [""],
|
||||
"stdout": ["Exif.CanonCs.LensType Short 1 $lens_description\n"],
|
||||
"retval": [0],
|
||||
"lens_id": lens_tc["id"],
|
||||
"lens_description": lens_tc["target"],
|
||||
"aperture_max": aperture_to_raw_exif(lens_tc["aperture_max_short"] * lens_tc["tc"]),
|
||||
"focal_length_min": int(lens_tc["focal_length_min"] * lens_tc["tc"]),
|
||||
"focal_length_max": int(lens_tc["focal_length_max"] * lens_tc["tc"]),
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,203 @@
|
||||
import re
|
||||
import os
|
||||
import logging
|
||||
import math
|
||||
from itertools import groupby
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
LENS_ENTRY_DEFAULT_RE = re.compile('^\{\s*(?P<lens_id>[0-9]+),\s*"(?P<lens_description>.*)"')
|
||||
|
||||
LENS_META_DEFAULT_RE = re.compile(
|
||||
(
|
||||
# anything at the start
|
||||
".*?"
|
||||
# maybe min focal length and hyphen, surely max focal length e.g.: 24-70mm
|
||||
"(?:(?P<focal_length_min>[0-9]+)-)?(?P<focal_length_max>[0-9]+)mm"
|
||||
# anything in-between
|
||||
".*?"
|
||||
# maybe short focal length max aperture and hyphen, surely at least single max aperture e.g.: f/4.5-5.6
|
||||
# short and tele indicate apertures at the short (focal_length_min) and tele (focal_length_max) position of the lens
|
||||
"(?:(?:f\/)|T)(?:(?P<aperture_max_short>[0-9]+(?:\.[0-9]+)?)-)?(?P<aperture_max_tele>[0-9]+(?:\.[0-9])?)"
|
||||
# check if there is a teleconverter pattern e.g. + 1.4x
|
||||
"(?:.*?\+.*?(?P<tc>[0-9.]+)x)?"
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def aperture_to_raw_exif(aperture):
|
||||
# see https://github.com/exiftool/exiftool/blob/master/lib/Image/ExifTool/Canon.pm#L9678
|
||||
"""Transform aperture value to Canon maker note style hex format."""
|
||||
# for apertures < 1 the below is negative
|
||||
num = math.log(aperture) * 2 / math.log(2)
|
||||
|
||||
# temporarily make the number positive
|
||||
if num < 0:
|
||||
num = -num
|
||||
sign = -1
|
||||
else:
|
||||
sign = 1
|
||||
|
||||
val = int(num)
|
||||
frac = num - val
|
||||
|
||||
if abs(frac - 0.33) < 0.05:
|
||||
frac = 0x0C
|
||||
elif abs(frac - 0.67) < 0.05:
|
||||
frac = 0x14
|
||||
else:
|
||||
frac = int(frac * 0x20 + 0.5)
|
||||
|
||||
return sign * (val * 0x20 + frac)
|
||||
|
||||
|
||||
def raw_exif_to_aperture(raw):
|
||||
"""The inverse operation of aperture_to_raw_exif"""
|
||||
val = raw
|
||||
if val < 0:
|
||||
val = -val
|
||||
sign = -1
|
||||
else:
|
||||
sign = 1
|
||||
|
||||
frac = val & 0x1F
|
||||
val -= frac
|
||||
# Convert 1/3 and 2/3 codes
|
||||
if frac == 0x0C:
|
||||
frac = 0x20 / 3
|
||||
elif frac == 0x14:
|
||||
frac = 0x40 / 3
|
||||
|
||||
ev = sign * (val + frac) / 0x20
|
||||
return math.exp(ev * math.log(2) / 2)
|
||||
|
||||
|
||||
def parse_lens_entry(text, pattern=LENS_ENTRY_DEFAULT_RE):
|
||||
"""
|
||||
get the ID, and description from a lens entry field
|
||||
|
||||
Expected input format:
|
||||
{ 748, "Canon EF 100-400mm f/4.5-5.6L IS II USM + 1.4x" }
|
||||
We return a dict of:
|
||||
lens_id = 748
|
||||
lens_description = "Canon EF 100-400mm f/4.5-5.6L IS II USM + 1.4x"
|
||||
"""
|
||||
result = pattern.match(text)
|
||||
return result.groups() if result else None
|
||||
|
||||
|
||||
def extract_meta(text, pattern=LENS_META_DEFAULT_RE):
|
||||
"""
|
||||
Extract metadata from lens description.
|
||||
|
||||
Input expected in the form of e.g. "Canon EF 100-400mm f/4.5-5.6L IS II USM + 1.4x"
|
||||
We return a dict of:
|
||||
focal_length_min = 100
|
||||
focal_length_max = 400
|
||||
aperture_max_short = 4.5
|
||||
aperture_max_tele = 5.6
|
||||
tc = 1.4
|
||||
"""
|
||||
result = pattern.match(text)
|
||||
|
||||
if not result:
|
||||
# didn't match
|
||||
return None
|
||||
|
||||
ret = result.groupdict()
|
||||
# set min to max value if we didn't get a range but a single value
|
||||
ret["focal_length_min"] = int(ret["focal_length_min"] or ret["focal_length_max"])
|
||||
ret["focal_length_max"] = int(ret["focal_length_max"])
|
||||
ret["aperture_max_short"] = float(ret["aperture_max_short"] or ret["aperture_max_tele"])
|
||||
ret["aperture_max_tele"] = float(ret["aperture_max_tele"])
|
||||
ret["tc"] = float(ret["tc"] or 1)
|
||||
return ret
|
||||
|
||||
|
||||
def lens_is_match(l1, l2):
|
||||
"""
|
||||
Test if lens l2 is compatible with lens l1
|
||||
|
||||
This assumes we write l1's metadata and pick its 'aperture_max_short' value
|
||||
as the maximum aperture value to write into exif.
|
||||
Normally the canon maker note holds the max aperture of the lens at the focal length
|
||||
the picture was taken at. Thus for a f/4-6.3 lens, this value could be anywhere in that range.
|
||||
"""
|
||||
# the problem is that the round trip transformation isn't exact
|
||||
# so we need to account for this here as well to not define a target
|
||||
# which isn't achievable for exiv2
|
||||
reconstructed_aperture = raw_exif_to_aperture(aperture_to_raw_exif(l1["aperture_max_short"] * l1["tc"]))
|
||||
return all(
|
||||
[
|
||||
l1["focal_length_min"] * l1["tc"] == l2["focal_length_min"] * l2["tc"],
|
||||
l1["focal_length_max"] * l1["tc"] == l2["focal_length_max"] * l2["tc"],
|
||||
(l2["aperture_max_short"] * l2["tc"]) - 0.1
|
||||
<= reconstructed_aperture
|
||||
<= (l2["aperture_max_tele"] * l2["tc"]) + 0.1,
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def make_test_cases(lenses):
|
||||
"""
|
||||
Creates a test case for each lens
|
||||
Main job of this function is to collect all ambiguous lenses and define a test target
|
||||
as the " *OR* " joined string of all ambiguous lens descriptions
|
||||
"""
|
||||
test_cases = []
|
||||
for lens_id, group in groupby(lenses, lambda x: x["id"]):
|
||||
lens_group = list(group)
|
||||
test_cases += [
|
||||
{
|
||||
**lens["meta"],
|
||||
"id": lens["id"],
|
||||
"desc": lens["desc"],
|
||||
"target": " *OR* ".join([l["desc"] for l in lens_group if lens_is_match(lens["meta"], l["meta"])]),
|
||||
}
|
||||
for lens in lens_group
|
||||
]
|
||||
return test_cases
|
||||
|
||||
|
||||
def extract_lenses_from_cpp(filename, start_pattern):
|
||||
"""
|
||||
Extract lens information from the lens descriptions array in a maker note cpp file
|
||||
filename: path to cpp file
|
||||
start_pattern: start_pattern == line.strip() should return True for
|
||||
the starting line of the array containing the lenses.
|
||||
returns: a list of lens entries containing a tuple of the form:
|
||||
(lens ID, lens description, metadata dictionary)
|
||||
for content of metadata see extract_meta() function.
|
||||
"""
|
||||
lenses = []
|
||||
with open(filename, "r") as f:
|
||||
in_lens_array = False
|
||||
|
||||
for line in f.readlines():
|
||||
stripped = line.strip()
|
||||
|
||||
if stripped == start_pattern:
|
||||
in_lens_array = True
|
||||
continue
|
||||
|
||||
if stripped == "};":
|
||||
in_lens_array = False
|
||||
continue
|
||||
|
||||
if in_lens_array:
|
||||
lens_entry = parse_lens_entry(stripped)
|
||||
if not lens_entry:
|
||||
log.error(f"Failure parsing lens entry: {stripped}.")
|
||||
continue
|
||||
|
||||
if lens_entry[1] == "n/a":
|
||||
continue
|
||||
|
||||
meta = extract_meta(lens_entry[1])
|
||||
if not meta:
|
||||
log.error(f"Failure extracting metadata from lens description: {lens_entry[0]}: {lens_entry[1]}.")
|
||||
continue
|
||||
|
||||
lenses.append({"id": lens_entry[0], "desc": lens_entry[1], "meta": meta})
|
||||
return lenses
|
||||
+2
-17
@@ -5,33 +5,18 @@ import os
|
||||
import inspect
|
||||
import subprocess
|
||||
import threading
|
||||
import shlex
|
||||
import sys
|
||||
import shutil
|
||||
import string
|
||||
import unittest
|
||||
|
||||
|
||||
from bash_tests import utils as BT
|
||||
|
||||
|
||||
if sys.platform in [ 'win32', 'msys', 'cygwin' ]:
|
||||
#: invoke subprocess.Popen with shell=True on Windows
|
||||
_SUBPROCESS_SHELL = True
|
||||
|
||||
def _cmd_splitter(cmd):
|
||||
return cmd
|
||||
|
||||
def _process_output_post(output):
|
||||
return output.replace('\r\n', '\n')
|
||||
|
||||
else:
|
||||
#: invoke subprocess.Popen with shell=False on Unix
|
||||
_SUBPROCESS_SHELL = False
|
||||
|
||||
def _cmd_splitter(cmd):
|
||||
return shlex.split(cmd)
|
||||
|
||||
def _process_output_post(output):
|
||||
return output
|
||||
|
||||
@@ -586,13 +571,13 @@ def test_run(self):
|
||||
)
|
||||
|
||||
proc = subprocess.Popen(
|
||||
_cmd_splitter(command),
|
||||
command,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
stdin=subprocess.PIPE if stdin is not None else None,
|
||||
env=self._get_env(),
|
||||
cwd=self.work_dir,
|
||||
shell=_SUBPROCESS_SHELL
|
||||
shell=True,
|
||||
)
|
||||
|
||||
# Setup a threading.Timer which will terminate the command if it takes
|
||||
|
||||
Reference in New Issue
Block a user