#219 Revert the automatic reformatting with black
Closed a year ago by decathorpe. Opened 2 years ago by zbyszek.
fedora-rust/ zbyszek/rust2rpm unblackify  into  main

file modified
+1 -1
@@ -1,3 +1,3 @@ 

  from . import licensing

  

- __version__ = "22"

+ __version__ = '22'

file modified
+133 -236
@@ -25,60 +25,49 @@ 

  CACHEDIR = os.path.join(XDG_CACHE_HOME, "rust2rpm")

  API_URL = "https://crates.io/api/v1/"

  DIST_GIT_URL = "https://src.fedoraproject.org/api/0/"

- LICENSES = re.compile(

-     r"""

-     COPYING(?:[.-].*)?|COPYRIGHT(?:[.-].*)?|

-     EULA(?:[.-].*)?|[Ll]icen[cs]e|[Ll]icen[cs]e.*|

-     (?:.*[.-])?(?:UN)?LICEN[CS]E(?:[.-].*)?|NOTICE(?:[.-].*)?|

-     PATENTS(?:[.-].*)?|

-     (?:agpl|l?gpl)[.-].*|CC-BY-.*|

-     (?:AGPL|APACHE|BSD|GFDL|GNU|L?GPL|MIT|MPL|OFL)-.*[0-9].*

-     """,

-     re.VERBOSE,

- )

+ LICENSES = re.compile(r"""

+          COPYING(?:[.-].*)?|COPYRIGHT(?:[.-].*)?|

+          EULA(?:[.-].*)?|[Ll]icen[cs]e|[Ll]icen[cs]e.*|

+          (?:.*[.-])?(?:UN)?LICEN[CS]E(?:[.-].*)?|NOTICE(?:[.-].*)?|

+          PATENTS(?:[.-].*)?|

+          (?:agpl|l?gpl)[.-].*|CC-BY-.*|

+          (?:AGPL|APACHE|BSD|GFDL|GNU|L?GPL|MIT|MPL|OFL)-.*[0-9].*

+          """, re.VERBOSE)

  

  # [target.'cfg(not(any(target_os="windows", target_os="macos")))'.dependencies]

  # [target."cfg(windows)".dependencies.winapi]

  # [target."cfg(target_arch = \"wasm32\")".dev-dependencies.wasm-bindgen-test]

  

- TARGET_DEPENDENCY_LINE = re.compile(

-     r"""

-     ^ \[ target\.(?P<cfg>(?P<quote>['"])cfg\(.*\)(?P=quote))

-     \.

-     (?P<type> dependencies|build-dependencies|dev-dependencies)

-     (?:\. (?P<feature>[a-zA-Z0-9_-]+) )?

-     \] \s* $

-     """,

-     re.VERBOSE,

- )

- 

+ TARGET_DEPENDENCY_LINE = re.compile(r'''

+          ^ \[ target\.(?P<cfg>(?P<quote>['"])cfg\(.*\)(?P=quote))

+              \.

+              (?P<type> dependencies|build-dependencies|dev-dependencies)

+              (?:\. (?P<feature>[a-zA-Z0-9_-]+) )?

+          \] \s* $

+          ''', re.VERBOSE)

  

  def sortify(func):

      """Return a sorted list from a generator"""

- 

      def wrapper(*args, **kwargs):

          return sorted(func(*args, **kwargs))

- 

      return functools.update_wrapper(wrapper, func)

  

- 

  def read_os_release():

      try:

-         f = open("/etc/os-release")

+         f = open('/etc/os-release')

      except FileNotFoundError:

-         f = open("/usr/lib/os-release")

+         f = open('/usr/lib/os-release')

  

      for line in f:

          line = line.rstrip()

-         if not line or line.startswith("#"):

+         if not line or line.startswith('#'):

              continue

-         if m := re.match(r"([A-Z][A-Z_0-9]+)=(.*)", line):

+         if m := re.match(r'([A-Z][A-Z_0-9]+)=(.*)', line):

              name, val = m.groups()

-             if val and val[0] in "\"'":

+             if val and val[0] in '"\'':

                  val = ast.literal_eval(val)

              yield name, val

  

- 

  def get_default_target():

      os_release = dict(read_os_release())

      os_id = os_release.get("ID")
@@ -95,15 +84,12 @@ 

      else:

          return "plain"

  

- 

  def file_mtime(path):

      return datetime.fromtimestamp(os.stat(path).st_mtime, timezone.utc).isoformat()

  

- 

  def package_name_suffixed(name, suffix):

-     joiner = "_" if suffix and name[-1].isdigit() else ""

-     return "rust-" + name + joiner + (suffix or "")

- 

+     joiner = '_' if suffix and name[-1].isdigit() else ''

+     return 'rust-' + name + joiner + (suffix or '')

  

  def local_toml(toml, version):

      if os.path.isdir(toml):
@@ -116,12 +102,10 @@ 

  

      return toml, None, version, doc_files, license_files

  

- 

  def local_crate(crate, version):

      cratename, version = os.path.basename(crate)[:-6].rsplit("-", 1)

      return crate, cratename, version

  

- 

  def query_newest_version(crate):

      url = requests.compat.urljoin(API_URL, f"crates/{crate}/versions")

      req = requests.get(url, headers={"User-Agent": "rust2rpm"})
@@ -130,16 +114,15 @@ 

      for struct in versions:

          version = struct["num"]

          if struct["yanked"]:

-             log.info(f"Ignoring yanked version {version!r}.")

-         elif re.search("alpha|beta|rc|pre", version):

-             log.info(f"Ignoring pre-release version {version!r}.")

+             log.info(f'Ignoring yanked version {version!r}.')

+         elif re.search('alpha|beta|rc|pre', version):

+             log.info(f'Ignoring pre-release version {version!r}.')

          else:

-             log.success(f"Using latest stable version {version!r}.")

+             log.success(f'Using latest stable version {version!r}.')

              return version

  

      raise ValueError("Couldn't find any release versions. Specify a version explicitly.")

  

- 

  def download(crate, version):

      if version is None:

          # Now we need to get latest version
@@ -154,17 +137,11 @@ 

          req.raise_for_status()

          total = int(req.headers["Content-Length"])

          with util.remove_on_error(cratef), open(cratef, "wb") as f:

-             for chunk in tqdm.tqdm(

-                 req.iter_content(),

-                 f"Downloading {cratef_base}",

-                 total=total,

-                 unit="B",

-                 unit_scale=True,

-             ):

+             for chunk in tqdm.tqdm(req.iter_content(), f"Downloading {cratef_base}",

+                                    total=total, unit="B", unit_scale=True):

                  f.write(chunk)

      return cratef, crate, version

  

- 

  @contextlib.contextmanager

  def files_from_crate(cratef, crate, version):

      """Unpacks cratef and returns path to toml file, list of doc files, list of license files"""
@@ -183,24 +160,18 @@ 

          license_files = get_license_files(root_path)

          yield toml, doc_files, license_files

  

- 

  def filter_out_features_re(dropped_features):

      # This is a bit simplistic. But it doesn't seem worth the trouble to write

      # a grammar for this. Can be always done later. If we parse this using a

      # grammar, we beget the question how to preserve formatting idiosyncrasies.

      # Regexp replacement makes it trivial to minimize changes.

-     match_features = "|".join(dropped_features)

-     match_suffix = f"(?:/[{cfg.IDENT_CHARS[1]}]+)?"

- 

-     return re.compile(

-         rf"""

-         (?P<comma> ,)? \s* (?P<quote>['"])

-         ({match_features}) {match_suffix}

-         (?P=quote) \s* (?(comma) |,?) \s*

-         """,

-         re.VERBOSE,

-     )

+     match_features = '|'.join(dropped_features)

+     match_suffix = f'(?:/[{cfg.IDENT_CHARS[1]}]+)?'

  

+     return re.compile(fr'''(?P<comma> ,)? \s* (?P<quote>['"])

+                            ({match_features}) {match_suffix}

+                            (?P=quote) \s* (?(comma) |,?) \s*

+                       ''', re.VERBOSE)

  

  def drop_foreign_dependencies(lines):

      dropped_lines = 0
@@ -210,20 +181,20 @@ 

      value = True

      for line in lines:

          if m := TARGET_DEPENDENCY_LINE.match(line):

-             expr = m.group("cfg")

+             expr = m.group('cfg')

              expr = ast.literal_eval(expr)

              try:

                  value = cfg.parse_and_evaluate(expr)

              except (ValueError, cfg.ParseException):

-                 log.warn(f"Could not evaluate {expr!r}, treating as true.")

+                 log.warn(f'Could not evaluate {expr!r}, treating as true.')

                  value = True

  

              if not value:

-                 feature = m.group("feature")

-                 log.info(f"Dropping target-specific dependency on {feature!r}.")

+                 feature = m.group('feature')

+                 log.info(f'Dropping target-specific dependency on {feature!r}.')

                  dropped_features.add(feature)

  

-         elif line.startswith("["):

+         elif line.startswith('['):

              # previous section ended, let's keep printing lines again

              value = True

  
@@ -240,12 +211,12 @@ 

      in_features = False

      filt = filter_out_features_re(dropped_features)

      for line in good_lines:

-         if line.rstrip() == "[features]":

+         if line.rstrip() == '[features]':

              in_features = True

-         elif line.startswith("["):

+         elif line.startswith('['):

              in_features = False

          elif in_features:

-             line = re.sub(filt, "", line)

+             line = re.sub(filt, '', line)

              if not line:

                  continue

  
@@ -255,9 +226,9 @@ 

  

  

  def make_diff(path, lines1, mtime1, lines2, mtime2):

-     return list(

-         difflib.unified_diff(lines1, lines2, fromfile=path, tofile=path, fromfiledate=mtime1, tofiledate=mtime2)

-     )

+     return list(difflib.unified_diff(lines1, lines2,

+                                      fromfile=path, tofile=path,

+                                      fromfiledate=mtime1, tofiledate=mtime2))

  

  

  def make_patches(args, version, toml):
@@ -304,15 +275,15 @@ 

          mtime_after2 = file_mtime(toml)

          toml_after2 = open(toml).readlines()

  

-         diff2 = make_diff(toml_path, toml_after, mtime_before, toml_after2, mtime_after2)

+         diff2 = make_diff(toml_path,

+                           toml_after, mtime_before,

+                           toml_after2, mtime_after2)

  

      return diff1, diff2

  

- 

  def _is_path(path):

      return "/" in path or path in {".", ".."}

  

- 

  @sortify

  def get_license_files(path):

      """Heuristic match on file names to detect license files"""
@@ -335,18 +306,15 @@ 

              if LICENSES.match(f):

                  yield os.path.relpath(os.path.join(root, f), path)

  

- 

  @sortify

  def get_doc_files(path):

      """Heuristic match on file names to detect documentation files"""

-     plus = re.compile(

-         r"""

+     plus = re.compile(r"""

          .*\.(?:md|markdown|mdown|mkdn|rst|txt)|AUTHORS|

          AUTHORS[.-].*|CONTRIBUTORS|CONTRIBUTORS[.-].*|README|

          README[.-].*|CHANGELOG|CHANGELOG[.-].*|TODO|TODO[.-].*

          """,

-         re.IGNORECASE | re.VERBOSE,

-     )

+         re.IGNORECASE | re.VERBOSE)

      minus = re.compile(r"CMakeLists\.txt|.*\.tpl|.*\.in")

  

      for root, dirs, files in os.walk(path, topdown=True):
@@ -355,7 +323,6 @@ 

              if plus.fullmatch(f) and not LICENSES.fullmatch(f) and not minus.fullmatch(f):

                  yield os.path.relpath(os.path.join(root, f), path)

  

- 

  def get_package_info(package):

      """Download information about package from dist-git.

  
@@ -372,12 +339,12 @@ 

      url = requests.compat.urljoin(DIST_GIT_URL, f"rpms/{package}")

      req = requests.get(url, headers={"User-Agent": "rust2rpm"})

      json = req.json()

-     if "name" not in json:

+     if 'name' not in json:

          return None

  

      # E.g. https://src.fedoraproject.org/rpms/rust-tiny_http0.6/blob/rawhide/f/rust-tiny_http0.6.spec

-     full_url = json["full_url"]

-     spec_url = requests.compat.urljoin(full_url, f"blob/rawhide/f/rust-{package}.spec")

+     full_url = json['full_url']

+     spec_url = requests.compat.urljoin(full_url, f'blob/rawhide/f/rust-{package}.spec')

      req = requests.head(spec_url, headers={"User-Agent": "rust2rpm"})

  

      if not req.ok:
@@ -387,7 +354,6 @@ 

  

      return json

  

- 

  def make_diff_metadata(args, crate, version):

      if _is_path(crate):

          # Only things that look like a paths are considered local arguments
@@ -454,13 +420,11 @@ 

      but a compat package would almost always be created from an existing

      dist-git directory, hence there'd be a spec file, so we can ignore this.

      """

-     specs = glob.glob("*.spec")

+     specs = glob.glob('*.spec')

  

      if len(specs) > 1:

-         log.error(

-             f"Found multiple spec files in the current working directory; "

-             + "unable to determine crate name automatically."

-         )

+         log.error('Found multiple spec files in the current working directory;'

+                   ' unable to determine crate name automatically.')

          return None

  

      if len(specs) == 1:
@@ -468,138 +432,79 @@ 

          spec = specs[0]

  

          for line in open(spec):

-             if m := re.match(r"^%(?:global|define)\s+crate\s+(\S+)\s+", line):

+             if m := re.match(r'^%(?:global|define)\s+crate\s+(\S+)\s+', line):

                  if crate:

-                     log.error(

-                         f"Found multiple definitions of the '%crate' macro in {spec!r}; "

-                         + f"unable to determine crate name automatically."

-                     )

+                     log.error(f"Found multiple definitions of the '%crate' macro in {spec!r};"

+                               " unable to determine crate name automatically.")

                      return None

                  crate = m.group(1)

-                 if "%" in crate:

-                     log.error(f"The value of the %crate macro appears to contain other macros and cannot be parsed.")

+                 if '%' in crate:

+                     log.error('The value of the %crate macro appears to contain other macros and cannot be parsed.')

                      return None

          if crate:

-             log.success(f"Found valid spec file {spec!r} for the {crate!r} crate.")

+             log.success(f'Found valid spec file {spec!r} for the {crate!r} crate.')

          else:

-             log.error(f"Invalid spec file {spec!r}; unable to determine crate name automatically.")

+             log.error(f'Invalid spec file {spec!r}; unable to determine crate name automatically.')

          return crate

  

      dirname = os.path.basename(os.getcwd())

-     if m := re.match("^rust-([a-z+0-9_-]+)$", dirname):

+     if m := re.match('^rust-([a-z+0-9_-]+)$', dirname):

          crate = m.group(1)

-         log.info(f"Continuing with crate name {crate!r} based on the current working directory.")

+         log.info(f'Continuing with crate name {crate!r} based on the current working directory.')

          return crate

  

      return None

  

- 

  def get_parser():

      default_target = get_default_target()

  

-     parser = argparse.ArgumentParser("rust2rpm", formatter_class=argparse.RawTextHelpFormatter)

-     parser.add_argument(

-         "--show-license-map",

-         action="store_true",

-         help="Print license mappings and exit",

-     )

-     parser.add_argument(

-         "--translate-license",

-         action="store_true",

-         help="Print mapping for specified license and exit",

-     )

-     parser.add_argument(

-         "--no-auto-changelog-entry",

-         action="store_false",

-         default=True,

-         dest="auto_changelog_entry",

-         help="Do not generate a changelog entry",

-     )

-     parser.add_argument(

-         "--no-existence-check",

-         action="store_false",

-         default=True,

-         dest="existence_check",

-         help="Do not check whether the package already exists in dist-git",

-     )

-     parser.add_argument("-", "--stdout", action="store_true", help="Print spec and patches into stdout")

-     parser.add_argument(

-         "-t",

-         "--target",

-         action="store",

-         choices=("plain", "fedora", "mageia", "opensuse"),

-         default=default_target,

-         help="Distribution target",

-     )

-     parser.add_argument(

-         "--no-patch-foreign",

-         action="store_false",

-         default=True,

-         dest="patch_foreign",

-         help="Do not automatically drop foreign dependencies in Cargo.toml",

-     )

-     parser.add_argument(

-         "-p",

-         "--patch",

-         action="store_true",

-         help="Do manual patching of Cargo.toml",

-     )

-     parser.add_argument(

-         "-s",

-         "--store-crate",

-         action="store_true",

-         help="Store crate in current directory",

-     )

-     parser.add_argument(

-         "-a",

-         "--rpmautospec",

-         action="store_true",

-         default=None,

-         help="Use autorelease and autochangelog features",

-     )

-     parser.add_argument(

-         "--no-rpmautospec",

-         action="store_false",

-         dest="rpmautospec",

-         help="Do not use rpmautospec",

-     )

-     parser.add_argument(

-         "--relative-license-paths",

-         action="store_true",

-         help="Put all license files in main license directory",

-     )

-     parser.add_argument(

-         "--all-features",

-         action="store_true",

-         help="Activate all available features",

-     )

-     parser.add_argument(

-         "--dynamic-buildrequires",

-         action="store_true",

-         default=None,

-         help="Use dynamic BuildRequires feature",

-     )

-     parser.add_argument(

-         "--no-dynamic-buildrequires",

-         action="store_false",

-         dest="dynamic_buildrequires",

-         help="Do not use dynamic BuildRequires feature",

-     )

-     parser.add_argument(

-         "--suffix",

-         action="store",

-         help="Package suffix",

-     )

-     parser.add_argument(

-         "crate",

-         help="crates.io name\n" "path/to/local.crate\n" "path/to/project/",

-         nargs="?",

-     )

-     parser.add_argument(

-         "version",

-         nargs="?",

-         help="crates.io version",

-     )

+     parser = argparse.ArgumentParser("rust2rpm",

+                                      formatter_class=argparse.RawTextHelpFormatter)

+     parser.add_argument("--show-license-map", action="store_true",

+                         help="Print license mappings and exit")

+     parser.add_argument("--translate-license", action="store_true",

+                         help="Print mapping for specified license and exit")

+     parser.add_argument("--no-auto-changelog-entry", action="store_false",

+                         default=True, dest="auto_changelog_entry",

+                         help="Do not generate a changelog entry")

+     parser.add_argument("--no-existence-check", action="store_false",

+                         default=True, dest="existence_check",

+                         help="Do not check whether the package already exists in dist-git")

+     parser.add_argument("-", "--stdout", action="store_true",

+                         help="Print spec and patches into stdout")

+     parser.add_argument("-t", "--target", action="store",

+                         choices=("plain", "fedora", "mageia", "opensuse"), default=default_target,

+                         help="Distribution target")

+     parser.add_argument("--no-patch-foreign", action="store_false",

+                         default=True, dest="patch_foreign",

+                         help="Do not automatically drop foreign dependencies in Cargo.toml")

+     parser.add_argument("-p", "--patch", action="store_true",

+                         help="Do manual patching of Cargo.toml")

+     parser.add_argument("-s", "--store-crate", action="store_true",

+                         help="Store crate in current directory")

+     parser.add_argument("-a", "--rpmautospec", action="store_true",

+                         default=None,

+                         help="Use autorelease and autochangelog features")

+     parser.add_argument("--no-rpmautospec", action="store_false",

+                         dest="rpmautospec",

+                         help="Do not use rpmautospec")

+     parser.add_argument("--relative-license-paths", action="store_true",

+                         help="Put all license files in main license directory")

+     parser.add_argument("--all-features", action="store_true",

+                         help="Activate all available features")

+     parser.add_argument("--dynamic-buildrequires", action="store_true",

+                         default=None,

+                         help="Use dynamic BuildRequires feature")

+     parser.add_argument("--no-dynamic-buildrequires", action="store_false",

+                         dest="dynamic_buildrequires",

+                         help="Do not use dynamic BuildRequires feature")

+     parser.add_argument("--suffix", action="store",

+                         help="Package suffix")

+     parser.add_argument("crate", help="crates.io name\n"

+                                       "path/to/local.crate\n"

+                                       "path/to/project/",

+                         nargs="?")

+     parser.add_argument("version", nargs="?", help="crates.io version")

  

      return parser

  
@@ -630,10 +535,8 @@ 

  

      pkg_name = package_name_suffixed(metadata.name, args.suffix)

  

-     patch_files = (

-         f"{metadata.name}-fix-metadata-auto.diff" if diffs[0] else None,

-         f"{metadata.name}-fix-metadata.diff" if diffs[1] else None,

-     )

+     patch_files = (f"{metadata.name}-fix-metadata-auto.diff" if diffs[0] else None,

+                    f"{metadata.name}-fix-metadata.diff" if diffs[1] else None)

  

      spec_file = pathlib.Path(f"{pkg_name}.spec")

  
@@ -641,12 +544,11 @@ 

          # No specfile, so this is probably a new package

          if package_info := get_package_info(pkg_name):

              if args.suffix:

-                 log.warn(

-                     f"Version {args.suffix}.* of the crate {metadata.name!r} is already "

-                     + f"packaged for Fedora: {package_info['full_url']}"

-                 )

+                 log.warn(f"Version {args.suffix}.* of the crate {metadata.name!r} is already"

+                          f" packaged for Fedora: {package_info['full_url']}")

              else:

-                 log.warn(f"Crate {metadata.name!r} is already packaged for Fedora: {package_info['full_url']}")

+                 log.warn(f"Crate {metadata.name!r} is already packaged for Fedora:"

+                          f" {package_info['full_url']}")

  

              log.info("Re-run with --no-existence-check to create a new spec file from scratch.")

              sys.exit(1)
@@ -664,10 +566,8 @@ 

  

      # clean up configuration files with deprecated names

      if len(confs) > 1:

-         log.error(

-             "More than one *rust2rpm.conf file is present in this directory. "

-             + "Ensure that there is only one, and that it has the correct contents."

-         )

+         log.error("More than one *rust2rpm.conf file is present in this directory."

+                   " Ensure that there is only one, and that it has the correct contents.")

          sys.exit(1)

  

      if ".rust2rpm.conf" in confs and "rust2rpm.conf" not in confs:
@@ -683,23 +583,21 @@ 

  

      conf_all_features = conf[args.target].getboolean("all-features")

      if conf_all_features is False and args.all_features:

-         log.warn(

-             'Conflicting settings for enabling all features: The setting is "false"'

-             + 'in rust2rpm.conf but it was enabled with the "--all-features" CLI flag.'

-         )

+         log.warn("Conflicting settings for enabling all features: The setting is \"false\""

+                  " in rust2rpm.conf but it was enabled with the \"--all-features\" CLI flag.")

  

      spec_contents = generator.spec_file_render(

-         args=args,

-         pkg_name=pkg_name,

-         crate=crate,

-         metadata=metadata,

+         args = args,

+         pkg_name = pkg_name,

+         crate = crate,

+         metadata = metadata,

          patch_file_automatic=patch_files[0],

          patch_file_manual=patch_files[1],

-         packager=packager,

-         doc_files=doc_files,

-         license_files=license_files,

-         distconf=conf[args.target],

-         all_features=conf_all_features or args.all_features,

+         packager = packager,

+         doc_files = doc_files,

+         license_files = license_files,

+         distconf = conf[args.target],

+         all_features = conf_all_features or args.all_features,

      )

  

      if args.stdout:
@@ -712,13 +610,12 @@ 

      else:

          with open(spec_file, "w") as fobj:

              fobj.write(spec_contents)

-         log.success(f"Generated: {fobj.name}")

+         log.success(f'Generated: {fobj.name}')

          for fname, diff in zip(patch_files, diffs):

              if fname:

                  with open(fname, "w") as fobj:

                      fobj.writelines(diff)

-                 log.success(f"Generated: {fobj.name}")

- 

+                 log.success(f'Generated: {fobj.name}')

  

  if __name__ == "__main__":

      main()

file modified
+35 -41
@@ -29,78 +29,75 @@ 

  # cfg(all(unix, target_pointer_width = "32"))

  # cfg(not(foo))

  

- IDENT_CHARS = pp.alphas + "_", pp.alphanums + "_"

- 

+ IDENT_CHARS = pp.alphas + '_', pp.alphanums + '_'

  

  def _call(word, arg):

-     return pp.Group(pp.Literal(word) + pp.Suppress("(") + arg + pp.Suppress(")"))

- 

+     return pp.Group(pp.Literal(word) + pp.Suppress('(') + arg + pp.Suppress(')'))

  

  @functools.cache

  def cfg_grammar():

      pred = pp.Forward()

  

      ident = pp.Word(IDENT_CHARS[0], IDENT_CHARS[1])

-     option = pp.Group(ident + pp.Optional(pp.Suppress("=") + pp.quotedString))

+     option = pp.Group(ident + pp.Optional(pp.Suppress('=') + pp.quotedString))

  

-     not_ = _call("not", pred)

+     not_ = _call('not', pred)

  

      # pp.pyparsing_common.comma_separated_list?

      # any_ = _call('any', pp.pyparsing_common.comma_separated_list(pred))

      # all_ = _call('all', pp.pyparsing_common.comma_separated_list(pred))

      # all_ = _call('all', pp.delimited_list(pred))

  

-     any_ = _call("any", pred + pp.ZeroOrMore(pp.Suppress(",") + pred))

-     all_ = _call("all", pred + pp.ZeroOrMore(pp.Suppress(",") + pred))

+     any_ = _call('any', pred + pp.ZeroOrMore(pp.Suppress(',') + pred))

+     all_ = _call('all', pred + pp.ZeroOrMore(pp.Suppress(',') + pred))

  

      pred <<= not_ | any_ | all_ | option

  

-     grammar = _call("cfg", pred)

+     grammar = _call('cfg', pred)

      return grammar

  

- 

  @functools.cache

  def evaluate_predicate(name: str, value: str) -> bool:

      # based on: https://doc.rust-lang.org/reference/conditional-compilation.html

  

      match name:

-         case "target_arch":

+         case 'target_arch':

              # Needs to be ignored, as we cannot generate patches that are

              # different depending on the host architecture - except if the

-             # target architecture is "wasm32", which we don't support.

-             return value != "wasm32"

+             # target architecture is 'wasm32', which we don't support.

+             return value != 'wasm32'

  

-         case "target_feature":

-             # The "target_feature" predicate can be ignored as well, since the

+         case 'target_feature':

+             # The 'target_feature' predicate can be ignored as well, since the

              # valid values for this predicate are architecture-dependent.

              return True

  

-         case "target_os":

-             return value == "linux"

+         case 'target_os':

+             return value == 'linux'

  

-         case "target_family":

-             return value == "unix"

+         case 'target_family':

+             return value == 'unix'

  

-         case "target_env":

-             # The "target_env" predicate is used to disambiguate target

+         case 'target_env':

+             # The 'target_env' predicate is used to disambiguate target

              # platforms based on its C library / C ABI (i.e. we can ignore

-             # "msvc" and "musl"), and if there's no need to disambiguate, the

+             # 'msvc' and 'musl'), and if there's no need to disambiguate, the

              # value can be the empty string.

-             return value in ["", "gnu"]

+             return value in ['', 'gnu']

  

-         case "target_endian":

+         case 'target_endian':

              # Needs to be ignored, as we cannot generate patches that are

              # different depending on the host architecture.

              return True

  

-         case "target_pointer_width":

+         case 'target_pointer_width':

              # Needs to be ignored, as we cannot generate patches that are

              # different depending on the host architecture.

              return True

  

-         case "target_vendor":

-             # On linux systems, "target_vendor" is always "unknown".

-             return value == "unknown"

+         case 'target_vendor':

+             # On linux systems, 'target_vendor' is always 'unknown'.

+             return value == 'unknown'

  

          case _:

              log.warn(f'Ignoring invalid predicate \'"{name}" = "{value}"\' in cfg-expression.')
@@ -110,30 +107,28 @@ 

  @functools.cache

  def evaluate_atom(name: str) -> bool:

      match name:

-         case "unix":

+         case 'unix':

              return True

-         case "windows":

+         case 'windows':

              return False

          case _:

-             log.warn(

-                 f"Ignoring unknown identifier {name!r} in cfg-expression. "

-                 + 'Only "unix" and "windows" are standard identifiers, '

-                 + 'any non-standard "--cfg" flags are not supported.'

-             )

+             log.warn(f'Ignoring unknown identifier {name!r} in cfg-expression.'

+                      ' Only "unix" and "windows" are standard identifiers,'

+                      ' any non-standard "--cfg" flags are not supported.')

              return False

  

  

  def evaluate(expr, nested=False) -> bool:

-     if hasattr(expr, "asList"):

+     if hasattr(expr, 'asList'):

          expr = expr.asList()  # compat with pyparsing 2.7.x

      match expr:

-         case ["cfg", subexpr] if not nested:

+         case ['cfg', subexpr] if not nested:

              return evaluate(subexpr, True)

-         case ["not", subexpr] if nested:

+         case ['not', subexpr] if nested:

              return not evaluate(subexpr, True)

-         case ["all", *args] if nested:

+         case ['all', *args] if nested:

              return all(evaluate(arg, True) for arg in args)

-         case ["any", *args] if nested:

+         case ['any', *args] if nested:

              return any(evaluate(arg, True) for arg in args)

          case [variable, value] if nested:

              v = ast.literal_eval(value)
@@ -143,7 +138,6 @@ 

          case _:

              raise ValueError

  

- 

  def parse_and_evaluate(expr):

      parsed = cfg_grammar().parseString(expr)

      return evaluate(parsed[0])

file modified
+10 -7
@@ -10,7 +10,9 @@ 

  

  def _get_binaries(cargo_toml):

      manifest = Metadata.manifest(cargo_toml, check=False)

-     return [t["name"] for t in manifest.get("targets", []) if "bin" in t["kind"]]

+     return [

+         t['name'] for t in manifest.get('targets', []) if 'bin' in t['kind']

+     ]

  

  

  def _cargo_toml(source_path, path, exclude_vendor=True):
@@ -34,17 +36,18 @@ 

  

      # If path is already a Cargo.toml file, we are done

      binary_or_cargo_toml = os.path.basename(path)

-     if binary_or_cargo_toml == "Cargo.toml":

+     if binary_or_cargo_toml == 'Cargo.toml':

          return os.path.join(source_path, path)

  

-     cargo_tomls = glob.glob(os.path.join(source_path, "**/Cargo.toml"), recursive=True)

+     cargo_tomls = glob.glob(os.path.join(source_path, '**/Cargo.toml'),

+                             recursive=True)

      for cargo_toml in cargo_tomls:

-         if exclude_vendor and "vendor" in cargo_toml.split(os.sep):

+         if exclude_vendor and 'vendor' in cargo_toml.split(os.sep):

              continue

          if binary_or_cargo_toml in _get_binaries(cargo_toml):

              return cargo_toml

  

-     raise FileNotFoundError(f"Cargo.toml not found for binary {binary_or_cargo_toml}")

+     raise FileNotFoundError(f'Cargo.toml not found for binary {binary_or_cargo_toml}')

  

  

  def main():
@@ -94,7 +97,7 @@ 

              data.extend(md.provides(f) for f in features)

          if args.requires:

              # Someone should own /usr/share/cargo/registry

-             data.append("cargo")

+             data.append('cargo')

              if args.all_features:

                  data.extend(md.all_dependencies)

              else:
@@ -112,7 +115,7 @@ 

          if args.provides_vendor:

              # Print the vendoring providers only if the 'vendor'

              # directory is present

-             if args.vendor or os.path.isdir("vendor"):

+             if args.vendor or os.path.isdir('vendor'):

                  data.extend(md.resolved_dependencies())

          return data

  

file modified
+127 -115
@@ -8,51 +8,63 @@ 

  import subprocess

  from urllib.parse import urlparse

  

- Requirement = collections.namedtuple("Requirement", ("kind", "version"))

- Version = collections.namedtuple("Version", ("major", "minor", "patch", "pre_release", "build"))

+ 

+ Requirement = collections.namedtuple('Requirement', ('kind',

+                                                      'version'))

+ 

+ 

+ Version = collections.namedtuple('Version', ('major', 'minor',

+                                              'patch', 'pre_release',

+                                              'build'))

  

  

  class CargoSemVer:

      """Cargo semantic versioning parser"""

- 

-     KIND_ANY = "*"

-     KIND_LT = "<"

-     KIND_LTE = "<="

-     KIND_SHORTEQ = "="

-     KIND_EQUAL = "=="

-     KIND_EMPTY = ""

-     KIND_GTE = ">="

-     KIND_GT = ">"

-     KIND_NEQ = "!="

-     KIND_CARET = "^"

-     KIND_TILDE = "~"

-     KIND_COMPATIBLE = "~="

+     KIND_ANY = '*'

+     KIND_LT = '<'

+     KIND_LTE = '<='

+     KIND_SHORTEQ = '='

+     KIND_EQUAL = '=='

+     KIND_EMPTY = ''

+     KIND_GTE = '>='

+     KIND_GT = '>'

+     KIND_NEQ = '!='

+     KIND_CARET = '^'

+     KIND_TILDE = '~'

+     KIND_COMPATIBLE = '~='

  

      def __init__(self, requirement):

-         requirements = requirement.replace(" ", "").split(",")

+         requirements = requirement.replace(' ', '').split(',')

          self.requirements = [self.parse(i) for i in requirements]

-         self.normalized = [j for i in self.requirements for j in self.normalize(i)]

+         self.normalized = [j for i in self.requirements

+                            for j in self.normalize(i)]

  

      @staticmethod

      def parse(requirement):

          if not requirement:

-             raise ValueError(f"Invalid empty requirement " f"specification: {requirement}")

+             raise ValueError(f'Invalid empty requirement '

+                              f'specification: {requirement}')

  

-         match = re.match(r"^(?:([\d.\*]*\*))$|^(?:(<|<=|=|==|>=|>||!=|\^|~|~=)(\d.*))$", requirement)

+         match = re.match(

+             r'^(?:([\d.\*]*\*))$|^(?:(<|<=|=|==|>=|>||!=|\^|~|~=)(\d.*))$',

+             requirement)

          if not match:

-             raise ValueError(f"Invalid requirement " f"specification: {requirement}")

+             raise ValueError(f'Invalid requirement '

+                              f'specification: {requirement}')

  

          wildcard, kind, version = match.groups()

          if wildcard:

-             version = wildcard.replace(".*", "").replace("*", "")

+             version = wildcard.replace('.*', '').replace('*', '')

              kind = CargoSemVer.KIND_ANY

          return Requirement(kind, CargoSemVer.parse_version(version))

  

      @staticmethod

      def parse_version(version):

-         match = re.match(r"^(\d+)?(?:\.(\d+))?(?:\.(\d+))?(?:-([\w.-]+))?(?:\+([\w.-]+))?$", version)

+         match = re.match(

+             r'^(\d+)?(?:\.(\d+))?(?:\.(\d+))?(?:-([\w.-]+))?(?:\+([\w.-]+))?$',

+             version)

          if not match:

-             raise ValueError(f"Invalid version string: {version}")

+             raise ValueError(f'Invalid version string: {version}')

  

          major, minor, patch, pre_release, build = match.groups()

          major = int(major) if major else major
@@ -61,8 +73,9 @@ 

          return Version(major, minor, patch, pre_release, build)

  

      @staticmethod

-     def unparse_version(version, sep="-"):

-         version_str = f"{version.major}.{version.minor or 0}.{version.patch or 0}"

+     def unparse_version(version, sep='-'):

+         version_str = f'{version.major}.{version.minor or 0}' \

+             f'.{version.patch or 0}'

          if version.pre_release:

              version_str = f'{version_str}{sep}{version.pre_release.replace("-", "_")}'

          if version.build:
@@ -71,13 +84,11 @@ 

  

      @staticmethod

      def coerce(version):

-         return Version(

-             version.major or 0,

-             version.minor or 0,

-             version.patch or 0,

-             version.pre_release,

-             version.build,

-         )

+         return Version(version.major or 0,

+                        version.minor or 0,

+                        version.patch or 0,

+                        version.pre_release,

+                        version.build)

  

      @staticmethod

      def next_major(version):
@@ -105,7 +116,7 @@ 

          normalized = []

          kind, version = requirement

          if kind == CargoSemVer.KIND_NEQ:

-             raise ValueError(f"Kind not supported: {requirement}")

+             raise ValueError(f'Kind not supported: {requirement}')

  

          if kind == CargoSemVer.KIND_EQUAL:

              kind = CargoSemVer.KIND_SHORTEQ
@@ -115,22 +126,21 @@ 

              version = CargoSemVer.next_patch(version)

  

          if kind == CargoSemVer.KIND_ANY:

-             normalized.append((CargoSemVer.KIND_GTE, CargoSemVer.coerce(version)))

+             normalized.append((CargoSemVer.KIND_GTE,

+                                CargoSemVer.coerce(version)))

              if version.major is not None:

                  if version.minor is not None:

                      upper_version = CargoSemVer.next_minor(version)

                  else:

                      upper_version = CargoSemVer.next_major(version)

                  normalized.append((CargoSemVer.KIND_LT, upper_version))

-         elif kind in (

-             CargoSemVer.KIND_SHORTEQ,

-             CargoSemVer.KIND_GT,

-             CargoSemVer.KIND_GTE,

-             CargoSemVer.KIND_LT,

-             CargoSemVer.KIND_LTE,

-         ):

+         elif kind in (CargoSemVer.KIND_SHORTEQ,

+                       CargoSemVer.KIND_GT, CargoSemVer.KIND_GTE,

+                       CargoSemVer.KIND_LT, CargoSemVer.KIND_LTE):

              normalized.append((kind, coerced_version))

-         elif kind in (CargoSemVer.KIND_CARET, CargoSemVer.KIND_COMPATIBLE, CargoSemVer.KIND_EMPTY):

+         elif kind in (CargoSemVer.KIND_CARET,

+                       CargoSemVer.KIND_COMPATIBLE,

+                       CargoSemVer.KIND_EMPTY):

              if version.major == 0:

                  if version.minor is not None:

                      if version.minor != 0 or version.patch is None:
@@ -151,39 +161,37 @@ 

              normalized.append((CargoSemVer.KIND_GTE, coerced_version))

              normalized.append((CargoSemVer.KIND_LT, upper_version))

          else:

-             raise ValueError(f"Found unhandled kind: {requirement}")

+             raise ValueError(f'Found unhandled kind: {requirement}')

          return normalized

  

      @staticmethod

      def eval_(v1, op, v2):

          if op == CargoSemVer.KIND_SHORTEQ:

-             return all((v1.major == v2.major, v1.minor == v2.minor, v1.patch == v2.patch))

+             return all((v1.major == v2.major,

+                         v1.minor == v2.minor,

+                         v1.patch == v2.patch))

          elif op == CargoSemVer.KIND_GT:

-             return (

-                 (v1.major > v2.major)

-                 or (v1.major == v2.major and v1.minor > v2.minor)

-                 or (v1.major == v2.major and v1.minor == v2.minor and v1.patch > v2.patch)

-             )

+             return ((v1.major > v2.major) or

+                     (v1.major == v2.major and v1.minor > v2.minor) or

+                     (v1.major == v2.major and v1.minor == v2.minor and

+                      v1.patch > v2.patch))

          elif op == CargoSemVer.KIND_GTE:

-             return (

-                 (v1.major >= v2.major)

-                 or (v1.major == v2.major and v1.minor >= v2.minor)

-                 or (v1.major == v2.major and v1.minor == v2.minor and v1.patch >= v2.patch)

-             )

+             return ((v1.major >= v2.major) or

+                     (v1.major == v2.major and v1.minor >= v2.minor) or

+                     (v1.major == v2.major and v1.minor == v2.minor and

+                      v1.patch >= v2.patch))

          elif op == CargoSemVer.KIND_LT:

-             return (

-                 (v1.major < v2.major)

-                 or (v1.major == v2.major and v1.minor < v2.minor)

-                 or (v1.major == v2.major and v1.minor == v2.minor and v1.patch < v2.patch)

-             )

+             return ((v1.major < v2.major) or

+                     (v1.major == v2.major and v1.minor < v2.minor) or

+                     (v1.major == v2.major and v1.minor == v2.minor and

+                      v1.patch < v2.patch))

          elif op == CargoSemVer.KIND_LTE:

-             return (

-                 (v1.major <= v2.major)

-                 or (v1.major == v2.major and v1.minor <= v2.minor)

-                 or (v1.major == v2.major and v1.minor == v2.minor and v1.patch <= v2.patch)

-             )

+             return ((v1.major <= v2.major) or

+                     (v1.major == v2.major and v1.minor <= v2.minor) or

+                     (v1.major == v2.major and v1.minor == v2.minor and

+                      v1.patch <= v2.patch))

          else:

-             raise ValueError(f"Cannot evaluate operator: {op}")

+             raise ValueError(f'Cannot evaluate operator: {op}')

  

  

  class Target:
@@ -196,7 +204,8 @@ 

  

  

  class Dependency:

-     def __init__(self, name, req=None, features=(), optional=False, bundled=False):

+     def __init__(self, name, req=None, features=(), optional=False,

+                  bundled=False):

          self.name = name

          self.req = req

          self.features = features
@@ -208,12 +217,10 @@ 

          features = set(metadata["features"])

          if metadata["uses_default_features"]:

              features.add("default")

-         kwargs = {

-             "name": metadata["name"],

-             "req": metadata["req"],

-             "optional": metadata["optional"],

-             "features": features,

-         }

+         kwargs = {"name": metadata["name"],

+                   "req": metadata["req"],

+                   "optional": metadata["optional"],

+                   "features": features}

          return cls(**kwargs)

  

      @staticmethod
@@ -224,10 +231,9 @@ 

              cap = f"bundled({cap})"

          if not reqs:

              return cap

-         deps = " with ".join(

+         deps = ' with '.join(

              f'{cap} {op} {CargoSemVer.unparse_version(version, sep="~")}{"~" if op == CargoSemVer.KIND_LT else ""}'

-             for op, version in reqs

-         )

+             for op, version in reqs)

          if len(reqs) > 1:

              return f"({deps})"

          else:
@@ -235,10 +241,9 @@ 

  

      def normalize(self):

          semver = CargoSemVer(self.req)

-         return [

-             self._apply_reqs(self.name, semver.normalized, feature, self.bundled)

-             for feature in self.features or (None,)

-         ]

+         return [self._apply_reqs(self.name, semver.normalized, feature,

+                                  self.bundled)

+                 for feature in self.features or (None,)]

  

      def __repr__(self):

          features = sorted(feature for feature in self.features if feature)
@@ -279,28 +284,23 @@ 

          if description is None:

              self._description = self._summary = None

              return

-         description = description.replace("\n\n", "\r").replace("\n", " ").replace("\r", "\n").strip()

-         description = re.sub(

-             rf"^(?:{self.name}|This(?:\s+\w+)?)(?:\s*,|\s+is|\s+provides)\s+",

-             "",

-             description,

-             flags=re.I,

-         )

-         description = re.sub(r"^(?:a|an|the)\s+", "", description, flags=re.I)

-         description = f"{description[0].upper()}{description[1:]}"

-         if description[-1] != ".":

-             description = f"{description}."

- 

-         p1 = description.find(".")

-         p2 = description.find(".\n")

+         description = description.replace('\n\n', '\r').replace('\n', ' ').replace('\r', '\n').strip()

+         description = re.sub(rf'^(?:{self.name}|This(?:\s+\w+)?)(?:\s*,|\s+is|\s+provides)\s+', '', description, flags=re.I)

+         description = re.sub(r'^(?:a|an|the)\s+', '', description, flags=re.I)

+         description = f'{description[0].upper()}{description[1:]}'

+         if description[-1] != '.':

+             description = f'{description}.'

+ 

+         p1 = description.find('.')

+         p2 = description.find('.\n')

          if p2 != -1:

              p1 = max(p1, p2)

          else:

              p1 = len(description) - 1

-         p2 = description.find(". ")

+         p2 = description.find('. ')

          if p2 != -1:

              p1 = min(p1, p2)

-         p2 = description.find("\n")

+         p2 = description.find('\n')

          if p2 != -1:

              p = min(p1, p2)

          else:
@@ -332,7 +332,9 @@ 

          # c.f. https://pagure.io/fedora-rust/rust2rpm/issue/186

  

          deps_by_feature = {}

-         local_features = set(md["features"]) | set(d["rename"] for d in md["dependencies"] if d["rename"] is not None)

+         local_features = set(md["features"]) | set(

+             d["rename"] for d in md["dependencies"] if d["rename"] is not None

+         )

          for feature, f_deps in md["features"].items():

              features = {None}

              deps = set()
@@ -364,9 +366,12 @@ 

              deps_by_feature["default"] = ({None}, set())

  

          self.dependencies = deps_by_feature

-         self.dev_dependencies = {Dependency.from_json(dep) for dep in md["dependencies"] if dep["kind"] == "dev"}

+         self.dev_dependencies = {Dependency.from_json(dep)

+                                  for dep in md["dependencies"]

+                                  if dep["kind"] == "dev"}

  

-         self.targets = {Target(tgt["name"], tgt["kind"][0]) for tgt in md["targets"]}

+         self.targets = {Target(tgt["name"], tgt["kind"][0])

+                         for tgt in md["targets"]}

  

          return self

  
@@ -374,14 +379,17 @@ 

      def from_file(cls, path, include_members=False):

          instances = []

          members = Metadata.members(path) if include_members else []

-         for member in members or [path]:

+         for member in (members or [path]):

              instance = cls.from_json(Metadata.manifest(member), member)

              instances.append(instance)

          return instances

  

      @staticmethod

      def manifest(path, check=True):

-         output = subprocess.run(["cargo", "read-manifest", f"--manifest-path={path}"], check=check, capture_output=True)

+         output = subprocess.run(

+             ["cargo", "read-manifest", f"--manifest-path={path}"],

+             check=check, capture_output=True

+         )

          try:

              result = json.loads(output.stdout)

          except json.decoder.JSONDecodeError:
@@ -392,7 +400,8 @@ 

  

      @staticmethod

      def metadata(path, deps=False):

-         cmd = ["cargo", "metadata", "--format-version=1", f"--manifest-path={path}"]

+         cmd = ["cargo", "metadata", "--format-version=1",

+                f"--manifest-path={path}"]

          if not deps:

              cmd.append("--no-deps")

          return json.loads(subprocess.check_output(cmd))
@@ -401,9 +410,9 @@ 

      def members(path):

          members = []

          metadata = Metadata.metadata(path)

-         for workspace in metadata.get("workspace_members", []):

-             path = re.search(r"\((.*)\)", workspace).group(1)

-             members.append(os.path.join(urlparse(path).path, "Cargo.toml"))

+         for workspace in metadata.get('workspace_members', []):

+             path = re.search(r'\((.*)\)', workspace).group(1)

+             members.append(os.path.join(urlparse(path).path, 'Cargo.toml'))

          return members

  

      @property
@@ -433,13 +442,14 @@ 

              return self._resolve(self.dependencies, feature)[1]

          else:

              features, deps = self.dependencies[feature]

-             fdeps = set(Dependency(self.name, f"={self._version}", features={feature}) for feature in features)

+             fdeps = set(Dependency(self.name, f"={self._version}", features={feature})

+                         for feature in features)

              return fdeps | deps

  

      @staticmethod

      def _match_crate(dependency, metadata):

-         for crate in metadata["resolve"]["nodes"]:

-             name, version, _ = crate["id"].split()

+         for crate in metadata['resolve']['nodes']:

+             name, version, _ = crate['id'].split()

              if name != dependency.name:

                  continue

              v1 = CargoSemVer.parse_version(version)
@@ -449,8 +459,8 @@ 

  

      @staticmethod

      def _find_crate(dependency, metadata):

-         for crate in metadata["resolve"]["nodes"]:

-             if dependency == crate["id"]:

+         for crate in metadata['resolve']['nodes']:

+             if dependency == crate['id']:

                  return crate

  

      @staticmethod
@@ -472,28 +482,30 @@ 

          for dep in dependencies:

              crate = Metadata._match_crate(dep, metadata)

              if not crate:

-                 raise ValueError(f"Cannot find crate for {dep}")

+                 raise ValueError(f'Cannot find crate for {dep}')

              closure.append(crate)

  

          # Close over the initial packages

          for crate in closure:

-             for dep in crate["dependencies"]:

+             for dep in crate['dependencies']:

                  crate = Metadata._find_crate(dep, metadata)

                  if not crate:

-                     raise ValueError(f"Cannot find crate for {dep}")

+                     raise ValueError(f'Cannot find crate for {dep}')

                  if crate not in closure:

                      closure.append(crate)

  

          # Transform the crate information to a dependency

          dependencies = []

          for crate in closure:

-             name, version, _ = crate["id"].split()

-             dependencies.append(Dependency(name, f"={version}", crate["features"] or ("default",), bundled=True))

+             name, version, _ = crate['id'].split()

+             dependencies.append(Dependency(name, f'={version}',

+                                            crate['features'] or ('default',),

+                                            bundled=True))

          return dependencies

  

      def resolved_dependencies(self, feature=None):

          if not self._path:

-             raise ValueError("Metadata instance without Cargo.toml associated")

+             raise ValueError('Metadata instance without Cargo.toml associated')

  

          initial_deps = self._resolve(self.dependencies, feature)[1]

          metadata = Metadata.metadata(self._path, deps=True)

file modified
+63 -69
@@ -5,45 +5,39 @@ 

  from . import __version__, licensing

  from .core import metadata

  

- 

  def to_list(s):

      if not s:

          return []

      return list(filter(None, (l.strip() for l in s.splitlines())))

  

- 

  def spec_file_template():

      env = jinja2.Environment(

-         loader=jinja2.ChoiceLoader(

-             [

-                 jinja2.FileSystemLoader(["/"]),

-                 jinja2.PackageLoader("rust2rpm", "templates"),

-             ]

-         ),

-         extensions=["jinja2.ext.do"],

+         loader=jinja2.ChoiceLoader([

+             jinja2.FileSystemLoader(['/']),

+             jinja2.PackageLoader('rust2rpm', 'templates'),

+         ]),

+         extensions=['jinja2.ext.do'],

          trim_blocks=True,

-         lstrip_blocks=True,

-     )

- 

-     env.globals["normalize_deps"] = metadata.normalize_deps

-     env.globals["to_list"] = to_list

+         lstrip_blocks=True)

  

-     return env.get_template("main.spec")

+     env.globals['normalize_deps'] = metadata.normalize_deps

+     env.globals['to_list'] = to_list

  

+     return env.get_template('main.spec')

  

  def spec_file_render(

-     args,

-     pkg_name,

-     crate,

-     metadata,

-     patch_file_manual,

-     patch_file_automatic,

-     packager,

-     doc_files,

-     license_files,

-     distconf,

-     all_features,

-     date=None,

+         args,

+         pkg_name,

+         crate,

+         metadata,

+         patch_file_manual,

+         patch_file_automatic,

+         packager,

+         doc_files,

+         license_files,

+         distconf,

+         all_features,

+         date=None,

  ):

      template = spec_file_template()

  
@@ -53,57 +47,58 @@ 

      is_lib = len(libs) > 0

  

      kwargs = {

-         "generator_version": __version__,

-         "target": args.target,

-         "crate": crate,

-         "include_devel": is_lib,

-         "pkg_name": pkg_name,

-         "auto_changelog_entry": args.auto_changelog_entry,

-         "rpmautospec": args.rpmautospec,

-         "relative_license_paths": args.relative_license_paths,

-         "generate_buildrequires": args.dynamic_buildrequires,

-         "doc_files": doc_files,

-         "license_files": license_files,

-         "distconf": distconf,

-         "all_features": all_features,

+         'generator_version': __version__,

+         'target': args.target,

+         'crate': crate,

+         'include_devel': is_lib,

+         'pkg_name': pkg_name,

+         'auto_changelog_entry': args.auto_changelog_entry,

+         'rpmautospec': args.rpmautospec,

+         'relative_license_paths': args.relative_license_paths,

+         'generate_buildrequires': args.dynamic_buildrequires,

+         'doc_files': doc_files,

+         'license_files': license_files,

+         'distconf': distconf,

+         'all_features': all_features,

      }

  

      if is_bin:

-         kwargs["include_main"] = True

-         kwargs["bins"] = bins

+         kwargs['include_main'] = True

+         kwargs['bins'] = bins

      elif is_lib:

-         kwargs["include_main"] = False

+         kwargs['include_main'] = False

      else:

-         raise ValueError("No bins and no libs")

- 

-     if args.target in {"fedora", "mageia", "opensuse"}:

-         kwargs["include_build_requires"] = True

-         kwargs["include_provides"] = False

-         kwargs["include_requires"] = False

-     elif args.target == "plain":

-         kwargs["include_build_requires"] = True

-         kwargs["include_provides"] = True

-         kwargs["include_requires"] = True

+         raise ValueError('No bins and no libs')

+ 

+     if args.target in {'fedora', 'mageia', 'opensuse'}:

+         kwargs['include_build_requires'] = True

+         kwargs['include_provides'] = False

+         kwargs['include_requires'] = False

+     elif args.target == 'plain':

+         kwargs['include_build_requires'] = True

+         kwargs['include_provides'] = True

+         kwargs['include_requires'] = True

      else:

-         assert False, f"Unknown target {args.target!r}"

- 

-     if args.target == "mageia":

-         kwargs["pkg_release"] = "%mkrel 1"

-         kwargs["rust_group"] = "Development/Rust"

-     elif args.target == "opensuse":

-         kwargs["spec_copyright_year"] = time.strftime("%Y")

-         kwargs["pkg_release"] = "0"

-         kwargs["rust_group"] = "Development/Libraries/Rust"

+         assert False, f'Unknown target {args.target!r}'

+ 

+     if args.target == 'mageia':

+         kwargs['pkg_release'] = '%mkrel 1'

+         kwargs['rust_group'] = 'Development/Rust'

+     elif args.target == 'opensuse':

+         kwargs['spec_copyright_year'] = time.strftime('%Y')

+         kwargs['pkg_release'] = '0'

+         kwargs['rust_group'] = 'Development/Libraries/Rust'

      elif args.rpmautospec:

-         kwargs["pkg_release"] = "%autorelease"

+         kwargs['pkg_release'] = '%autorelease'

      else:

-         kwargs["pkg_release"] = "1%{?dist}"

+         kwargs['pkg_release'] = '1%{?dist}'

  

-     time_args = ["%a %b %d %T %Z %Y" if args.target in {"opensuse"} else "%a %b %d %Y"] + ([date] if date else [])

-     kwargs["date"] = time.strftime(*time_args)

+     time_args = (['%a %b %d %T %Z %Y' if args.target in {'opensuse'} else '%a %b %d %Y'] +

+                  ([date] if date else []))

+     kwargs['date'] = time.strftime(*time_args)

  

      if packager is not None:

-         kwargs["packager"] = packager

+         kwargs['packager'] = packager

  

      if metadata.license is not None:

          license, comments = licensing.translate_license(args.target, metadata.license)
@@ -114,8 +109,7 @@ 

          metadata=metadata,

          patch_file_manual=patch_file_manual,

          patch_file_automatic=patch_file_automatic,

-         **kwargs,

-     )

+         **kwargs)

  

      if not spec_contents.endswith("\n"):

          spec_contents += "\n"

file modified
+19 -28
@@ -4,65 +4,56 @@ 

  

  from . import log

  

- SPDX_TO_FEDORA_CSV = os.path.dirname(__file__) + "/spdx_to_fedora.csv"

- 

+ SPDX_TO_FEDORA_CSV = os.path.dirname(__file__) + '/spdx_to_fedora.csv'

  

  def translate_slashes(license):

      "Replace all slashes with OR, emit warning"

      split = [l.strip() for l in license.split("/")]

      if len(split) > 1:

          log.info('Upstream uses deprecated "/" syntax. Replacing with "OR"')

-     return " OR ".join(split)

- 

+     return ' OR '.join(split)

  

  @functools.lru_cache()

  def spdx_to_fedora_map():

-     with open(SPDX_TO_FEDORA_CSV, newline="") as f:

+     with open(SPDX_TO_FEDORA_CSV, newline='') as f:

          reader = csv.DictReader(f)

-         return {

-             line["SPDX License Identifier"]: line["Fedora Short Name"]

-             for line in reader

-             if line["SPDX License Identifier"]

-         }

- 

+         return {line['SPDX License Identifier']: line['Fedora Short Name']

+                 for line in reader

+                 if line['SPDX License Identifier']}

  

  def dump_sdpx_to_fedora_map(file):

      for k, v in spdx_to_fedora_map().items():

          print(f"{k} → {v}", file=file)

  

- 

  def translate_license_fedora(license):

      comments = []

      final = []

      for tag in license.split():

          # We accept all variant cases, but output lowercase which is what Fedora LicensingGuidelines specify

-         if tag.upper() == "OR":

-             final.append("or")

-         elif tag.upper() == "AND":

-             final.append("and")

+         if tag.upper() == 'OR':

+             final.append('or')

+         elif tag.upper() == 'AND':

+             final.append('and')

          else:

-             if tag.endswith("+"):

-                 key = tag[:-1] + "-or-later"

-                 fulltag = f"{tag} ({key})"

+             if tag.endswith('+'):

+                 key = tag[:-1] + '-or-later'

+                 fulltag = f'{tag} ({key})'

              else:

                  key = fulltag = tag

  

              mapped = spdx_to_fedora_map().get(key, None)

              if mapped is None:

-                 comments += [f"# FIXME: Upstream uses unknown SPDX tag {fulltag}!"]

+                 comments += [f'# FIXME: Upstream uses unknown SPDX tag {fulltag}!']

                  final.append(tag)

-             elif mapped == "":

-                 comments += [

-                     f"# FIXME: Upstream SPDX tag {fulltag} not listed in Fedora's good licenses list.",

-                     "# FIXME: This package might not be allowed in Fedora!",

-                 ]

+             elif mapped == '':

+                 comments += [f"# FIXME: Upstream SPDX tag {fulltag} not listed in Fedora's good licenses list.",

+                              "# FIXME: This package might not be allowed in Fedora!"]

                  final.append(tag)

              else:

                  final.append(mapped)

                  if mapped != tag:

-                     log.info(f"Upstream license tag {fulltag!r} translated to {mapped!r}.")

-     return (" ".join(final), "\n".join(comments) or None)

- 

+                     log.info(f'Upstream license tag {fulltag!r} translated to {mapped!r}.')

+     return (' '.join(final), '\n'.join(comments) or None)

  

  def translate_license(target, license):

      license = translate_slashes(license)

file modified
+1 -1
@@ -15,7 +15,7 @@ 

  

  

  def _wrap(message, prefix):

-     return textwrap.wrap(message, 80, initial_indent=f"{prefix} ", subsequent_indent=" " * (len(prefix) + 1))

+     return textwrap.wrap(message, 80, initial_indent=f"{prefix} ", subsequent_indent=" "*(len(prefix) + 1))

  

  

  def success(message):

file modified
+16 -19
@@ -2,35 +2,32 @@ 

  

  from rust2rpm import cfg

  

- 

  def test_pyparsing_run_tests():

      g = cfg.cfg_grammar()

  

-     g.runTests(

-         """\

-         cfg(target_os = "macos")

-         cfg(any(foo, bar))

-         cfg(all(unix, target_pointer_width = "32"))

-         cfg(not(foo))

-         """

-     )

+     g.runTests("""\

+     cfg(target_os = "macos")

+     cfg(any(foo, bar))

+     cfg(all(unix, target_pointer_width = "32"))

+     cfg(not(foo))

+     """)

  

  

  @pytest.mark.parametrize(

      "expr, expected",

      [

          ('cfg(target_os = "macos")', False),

-         ("cfg(any(foo, bar))", False),

+         ('cfg(any(foo, bar))', False),

          ('cfg(all(unix, target_pointer_width = "16"))', True),

-         ("cfg(not(foo))", True),

-         ("cfg(unix)", True),

-         ("cfg(not(unix))", False),

-         ("cfg(windows)", False),

-         ("cfg(linux)", False),  # not defined

-         ("cfg(not(windows))", True),

-         ("cfg(any(unix, windows))", True),

-         ("cfg(any(windows, unix))", True),

-         ("cfg(any(windows, windows, windows))", False),

+         ('cfg(not(foo))', True),

+         ('cfg(unix)', True),

+         ('cfg(not(unix))', False),

+         ('cfg(windows)', False),

+         ('cfg(linux)', False),  # not defined

+         ('cfg(not(windows))', True),

+         ('cfg(any(unix, windows))', True),

+         ('cfg(any(windows, unix))', True),

+         ('cfg(any(windows, windows, windows))', False),

          ('cfg(target_os = "linux")', True),

          ('cfg(any(target_os = "linux"))', True),

          ('cfg(all(target_os = "linux"))', True),

@@ -7,14 +7,18 @@ 

  import pytest

  

  from rust2rpm.generator import to_list, spec_file_render

- from rust2rpm.__main__ import Metadata, get_parser, package_name_suffixed, drop_foreign_dependencies

+ from rust2rpm.__main__ import (

+     Metadata,

+     get_parser,

+     package_name_suffixed,

+     drop_foreign_dependencies)

  

  

  def test_to_list():

-     assert to_list("1\n2") == ["1", "2"]

-     assert to_list("1\n\n   2") == ["1", "2"]

-     assert to_list("   2   ") == ["2"]

-     assert to_list("\n\n") == []

+     assert to_list('1\n2') == ['1', '2']

+     assert to_list('1\n\n   2'   ) == ['1', '2']

+     assert to_list('   2   ') == ['2']

+     assert to_list('\n\n') == []

  

  

  # How to add new tests samples:
@@ -27,56 +31,59 @@ 

  

  FIXED_DATE = time.gmtime(12345)

  

- tomlfiles = [p for p in resources.files("rust2rpm.tests.samples").iterdir() if p.suffix == ".toml"]

- 

+ tomlfiles = [p

+              for p in resources.files('rust2rpm.tests.samples').iterdir()

+              if p.suffix == '.toml']

  

  def mock_spec_file_render(crate, tomlfile, target, tmpdir):

      tmpdir = pathlib.Path(tmpdir)

      # sadly we need to do this because cargo insists on looking for files

-     tmpdir.joinpath("src").mkdir()

-     tmpdir.joinpath("src/lib.rs").write_text("# hello!")

-     tmpdir.joinpath("src/main.rs").write_text("# hello!")

+     tmpdir.joinpath('src').mkdir()

+     tmpdir.joinpath('src/lib.rs').write_text('# hello!')

+     tmpdir.joinpath('src/main.rs').write_text('# hello!')

  

-     args = get_parser().parse_args(["foobar", f"--target={target}", "-a" if target == "fedora" else "--no-rpmautospec"])

+     args = get_parser().parse_args(['foobar',

+                                     f'--target={target}',

+                                     '-a' if target == 'fedora' else '--no-rpmautospec'])

      pkg_name = package_name_suffixed(crate, args.suffix)

  

      toml_before = open(tomlfile).readlines()

      toml_after = drop_foreign_dependencies(toml_before) or toml_before

  

-     fake_toml = tmpdir / "Cargo.toml"

-     fake_toml.write_text("\n".join(toml_after))

+     fake_toml = tmpdir / 'Cargo.toml'

+     fake_toml.write_text('\n'.join(toml_after))

  

-     (metadata,) = Metadata.from_file(fake_toml)

+     metadata, = Metadata.from_file(fake_toml)

  

      return spec_file_render(

-         args=args,

-         pkg_name=pkg_name,

-         crate=crate,

-         metadata=metadata,

-         patch_file_automatic=f"{crate}-patch1.diff",

-         patch_file_manual=f"{crate}-patch2.diff",

-         packager="Jane Jane <jane@jane.org>",

-         doc_files=["DOC1", "DOC2"],

-         license_files=["LIC1", "LIC2"],

-         distconf={},

-         all_features=False,

+         args = args,

+         pkg_name = pkg_name,

+         crate = crate,

+         metadata = metadata,

+         patch_file_automatic = f'{crate}-patch1.diff',

+         patch_file_manual = f'{crate}-patch2.diff',

+         packager = 'Jane Jane <jane@jane.org>',

+         doc_files = ['DOC1', 'DOC2'],

+         license_files = ['LIC1', 'LIC2'],

+         distconf = {},

+         all_features = False,

          date=FIXED_DATE,

      )

  

- 

- @pytest.mark.parametrize("tomlfile", tomlfiles)

- @pytest.mark.parametrize("target", ["plain", "fedora", "mageia", "opensuse"])

+ @pytest.mark.parametrize('tomlfile', tomlfiles)

+ @pytest.mark.parametrize('target', ['plain', 'fedora', 'mageia', 'opensuse'])

  def test_spec(tomlfile, target, tmpdir):

-     crate = tomlfile.with_suffix("").name

+     crate = tomlfile.with_suffix('').name

  

      spec = mock_spec_file_render(crate, tomlfile, target, tmpdir)

-     spec = re.sub("^(# Generated by rust2rpm) .*", r"\1 NNN", spec)

+     spec = re.sub('^(# Generated by rust2rpm) .*', r'\1 NNN', spec)

  

-     if os.getenv("SAVE_SPECS") == "1":

+     if os.getenv('SAVE_SPECS') == '1':

          # helper mode to create test data

-         path = resources.path("rust2rpm.tests.samples", f"{crate}.{target}.spec")

+         path = resources.path('rust2rpm.tests.samples',

+                               f'{crate}.{target}.spec')

          path.write_text(spec)

  

      else:

-         expected = resources.files("rust2rpm.tests.samples").joinpath(f"{crate}.{target}.spec").read_text()

+         expected = resources.files('rust2rpm.tests.samples').joinpath(f'{crate}.{target}.spec').read_text()

          assert spec == expected

file modified
+208 -187
@@ -4,237 +4,258 @@ 

  from rust2rpm.core.metadata import Version, CargoSemVer, Dependency

  

  

- @pytest.mark.parametrize(

-     "req, rpmdep",

-     [

-         ("^1.2.3", "(crate(test) >= 1.2.3 with crate(test) < 2.0.0~)"),

-         ("^1.2", "(crate(test) >= 1.2.0 with crate(test) < 2.0.0~)"),

-         ("^1", "(crate(test) >= 1.0.0 with crate(test) < 2.0.0~)"),

-         ("^0.2.3", "(crate(test) >= 0.2.3 with crate(test) < 0.3.0~)"),

-         ("^0.2", "(crate(test) >= 0.2.0 with crate(test) < 0.3.0~)"),

-         ("^0.0.3", "(crate(test) >= 0.0.3 with crate(test) < 0.0.4~)"),

-         ("^0.0", "(crate(test) >= 0.0.0 with crate(test) < 0.1.0~)"),

-         ("^0", "(crate(test) >= 0.0.0 with crate(test) < 1.0.0~)"),

-         ("~1.2.3", "(crate(test) >= 1.2.3 with crate(test) < 1.3.0~)"),

-         ("~1.2", "(crate(test) >= 1.2.0 with crate(test) < 1.3.0~)"),

-         ("~1", "(crate(test) >= 1.0.0 with crate(test) < 2.0.0~)"),

-         ("*", "crate(test) >= 0.0.0"),

-         ("0.*", "(crate(test) >= 0.0.0 with crate(test) < 1.0.0~)"),

-         ("0.0.*", "(crate(test) >= 0.0.0 with crate(test) < 0.1.0~)"),

-         ("0.1.*", "(crate(test) >= 0.1.0 with crate(test) < 0.2.0~)"),

-         ("0.*.*", "(crate(test) >= 0.0.0 with crate(test) < 1.0.0~)"),

-         ("1.*", "(crate(test) >= 1.0.0 with crate(test) < 2.0.0~)"),

-         ("1.2.*", "(crate(test) >= 1.2.0 with crate(test) < 1.3.0~)"),

-         ("1.*.*", "(crate(test) >= 1.0.0 with crate(test) < 2.0.0~)"),

-         (">= 1.2.0", "crate(test) >= 1.2.0"),

-         ("> 1", "crate(test) > 1.0.0"),

-         ("< 2", "crate(test) < 2.0.0~"),

-         ("= 1.2.3", "crate(test) = 1.2.3"),

-         (">= 1.2, < 1.5", "(crate(test) >= 1.2.0 with crate(test) < 1.5.0~)"),

-         ("^1.0.0-alpha.6", "(crate(test) >= 1.0.0~alpha.6 with crate(test) < 2.0.0~)"),

-         ("^0.1.0-alpha.6", "(crate(test) >= 0.1.0~alpha.6 with crate(test) < 0.2.0~)"),

-         ("^0.0.1-alpha.6", "(crate(test) >= 0.0.1~alpha.6 with crate(test) < 0.0.2~)"),

-         ("^0.0.0-alpha.6", "(crate(test) >= 0.0.0~alpha.6 with crate(test) < 0.0.1~)"),

-     ],

- )

+ @pytest.mark.parametrize("req, rpmdep", [

+     ("^1.2.3",

+      "(crate(test) >= 1.2.3 with crate(test) < 2.0.0~)"),

+     ("^1.2",

+      "(crate(test) >= 1.2.0 with crate(test) < 2.0.0~)"),

+     ("^1",

+      "(crate(test) >= 1.0.0 with crate(test) < 2.0.0~)"),

+     ("^0.2.3",

+      "(crate(test) >= 0.2.3 with crate(test) < 0.3.0~)"),

+     ("^0.2",

+      "(crate(test) >= 0.2.0 with crate(test) < 0.3.0~)"),

+     ("^0.0.3",

+      "(crate(test) >= 0.0.3 with crate(test) < 0.0.4~)"),

+     ("^0.0",

+      "(crate(test) >= 0.0.0 with crate(test) < 0.1.0~)"),

+     ("^0",

+      "(crate(test) >= 0.0.0 with crate(test) < 1.0.0~)"),

+     ("~1.2.3",

+      "(crate(test) >= 1.2.3 with crate(test) < 1.3.0~)"),

+     ("~1.2",

+      "(crate(test) >= 1.2.0 with crate(test) < 1.3.0~)"),

+     ("~1",

+      "(crate(test) >= 1.0.0 with crate(test) < 2.0.0~)"),

+     ("*",

+      "crate(test) >= 0.0.0"),

+     ("0.*",

+      "(crate(test) >= 0.0.0 with crate(test) < 1.0.0~)"),

+     ("0.0.*",

+      "(crate(test) >= 0.0.0 with crate(test) < 0.1.0~)"),

+     ("0.1.*",

+      "(crate(test) >= 0.1.0 with crate(test) < 0.2.0~)"),

+     ("0.*.*",

+      "(crate(test) >= 0.0.0 with crate(test) < 1.0.0~)"),

+     ("1.*",

+      "(crate(test) >= 1.0.0 with crate(test) < 2.0.0~)"),

+     ("1.2.*",

+      "(crate(test) >= 1.2.0 with crate(test) < 1.3.0~)"),

+     ("1.*.*",

+      "(crate(test) >= 1.0.0 with crate(test) < 2.0.0~)"),

+     (">= 1.2.0",

+      "crate(test) >= 1.2.0"),

+     ("> 1",

+      "crate(test) > 1.0.0"),

+     ("< 2",

+      "crate(test) < 2.0.0~"),

+     ("= 1.2.3",

+      "crate(test) = 1.2.3"),

+     (">= 1.2, < 1.5",

+      "(crate(test) >= 1.2.0 with crate(test) < 1.5.0~)"),

+     ("^1.0.0-alpha.6",

+      "(crate(test) >= 1.0.0~alpha.6 with crate(test) < 2.0.0~)"),

+     ("^0.1.0-alpha.6",

+      "(crate(test) >= 0.1.0~alpha.6 with crate(test) < 0.2.0~)"),

+     ("^0.0.1-alpha.6",

+      "(crate(test) >= 0.0.1~alpha.6 with crate(test) < 0.0.2~)"),

+     ("^0.0.0-alpha.6",

+      "(crate(test) >= 0.0.0~alpha.6 with crate(test) < 0.0.1~)"),

+ ])

  def test_dependency(req, rpmdep):

      dep = Dependency("test", req)

      assert str(dep) == rpmdep

  

  

- @pytest.mark.parametrize(

-     "version, parsed_version",

-     [

-         ("", (None, None, None, None, None)),

-         ("0", (0, None, None, None, None)),

-         ("1.0", (1, 0, None, None, None)),

-         ("2.1.0", (2, 1, 0, None, None)),

-         ("2.1.0+build1", (2, 1, 0, None, "build1")),

-         ("2.1.0-alpha1", (2, 1, 0, "alpha1", None)),

-         ("2.1.0-alpha1+build1", (2, 1, 0, "alpha1", "build1")),

-     ],

- )

+ @pytest.mark.parametrize('version, parsed_version', [

+     ('', (None, None, None, None, None)),

+     ('0', (0, None, None, None, None)),

+     ('1.0', (1, 0, None, None, None)),

+     ('2.1.0', (2, 1, 0, None, None)),

+     ('2.1.0+build1', (2, 1, 0, None, 'build1')),

+     ('2.1.0-alpha1', (2, 1, 0, 'alpha1', None)),

+     ('2.1.0-alpha1+build1', (2, 1, 0, 'alpha1', 'build1')),

+ ])

  def test_parse_version(version, parsed_version):

      result = CargoSemVer.parse_version(version)

      assert result == parsed_version

  

  

- @pytest.mark.parametrize(

-     "parsed_version, version",

-     [

-         (Version(0, None, None, None, None), "0.0.0"),

-         (Version(1, 0, None, None, None), "1.0.0"),

-         (Version(2, 1, 0, None, None), "2.1.0"),

-         (Version(2, 1, 0, None, "build1"), "2.1.0+build1"),

-         (Version(2, 1, 0, None, "snapshot-preview-build1"), "2.1.0+snapshot_preview_build1"),

-         (Version(2, 1, 0, "alpha1", None), "2.1.0-alpha1"),

-         (Version(2, 1, 0, "snapshot-preview-alpha1", None), "2.1.0-snapshot_preview_alpha1"),

-         (Version(2, 1, 0, "alpha1", "build1"), "2.1.0-alpha1+build1"),

-         (

-             Version(2, 1, 0, "snapshot-preview-alpha1", "snapshot-preview-build1"),

-             "2.1.0-snapshot_preview_alpha1+snapshot_preview_build1",

-         ),

-     ],

- )

+ @pytest.mark.parametrize('parsed_version, version', [

+     (Version(0, None, None, None, None), '0.0.0'),

+     (Version(1, 0, None, None, None), '1.0.0'),

+     (Version(2, 1, 0, None, None), '2.1.0'),

+     (Version(2, 1, 0, None, 'build1'), '2.1.0+build1'),

+     (Version(2, 1, 0, None, 'snapshot-preview-build1'), '2.1.0+snapshot_preview_build1'),

+     (Version(2, 1, 0, 'alpha1', None), '2.1.0-alpha1'),

+     (Version(2, 1, 0, 'snapshot-preview-alpha1', None), '2.1.0-snapshot_preview_alpha1'),

+     (Version(2, 1, 0, 'alpha1', 'build1'), '2.1.0-alpha1+build1'),

+     (Version(2, 1, 0, 'snapshot-preview-alpha1', 'snapshot-preview-build1'), '2.1.0-snapshot_preview_alpha1+snapshot_preview_build1'),

+ ])

  def test_unparse_version(parsed_version, version):

      result = CargoSemVer.unparse_version(parsed_version)

      assert result == version

  

  

- @pytest.mark.parametrize(

-     "parsed_version, version",

-     [

-         (Version(2, 1, 0, None, None), "2.1.0"),

-         (Version(2, 1, 0, None, "build1"), "2.1.0+build1"),

-         (Version(2, 1, 0, None, "snapshot-preview-build1"), "2.1.0+snapshot_preview_build1"),

-         (Version(2, 1, 0, "alpha1", None), "2.1.0~alpha1"),

-         (Version(2, 1, 0, "snapshot-preview-alpha1", None), "2.1.0~snapshot_preview_alpha1"),

-         (Version(2, 1, 0, "alpha1", "build1"), "2.1.0~alpha1+build1"),

-         (

-             Version(2, 1, 0, "snapshot-preview-alpha1", "snapshot-preview-build1"),

-             "2.1.0~snapshot_preview_alpha1+snapshot_preview_build1",

-         ),

-     ],

- )

+ @pytest.mark.parametrize('parsed_version, version', [

+     (Version(2, 1, 0, None, None), '2.1.0'),

+     (Version(2, 1, 0, None, 'build1'), '2.1.0+build1'),

+     (Version(2, 1, 0, None, 'snapshot-preview-build1'), '2.1.0+snapshot_preview_build1'),

+     (Version(2, 1, 0, 'alpha1', None), '2.1.0~alpha1'),

+     (Version(2, 1, 0, 'snapshot-preview-alpha1', None), '2.1.0~snapshot_preview_alpha1'),

+     (Version(2, 1, 0, 'alpha1', 'build1'), '2.1.0~alpha1+build1'),

+     (Version(2, 1, 0, 'snapshot-preview-alpha1', 'snapshot-preview-build1'), '2.1.0~snapshot_preview_alpha1+snapshot_preview_build1'),

+ ])

  def test_unparse_version_sep(parsed_version, version):

-     result = CargoSemVer.unparse_version(parsed_version, sep="~")

+     result = CargoSemVer.unparse_version(

+         parsed_version, sep='~')

      assert result == version

  

  

- @pytest.mark.parametrize(

-     "requirement, parsed_requirement",

-     [

-         ("*", ("*", (None, None, None, None, None))),

-         ("0.*", ("*", (0, None, None, None, None))),

-         ("0.1.*", ("*", (0, 1, None, None, None))),

-         ("0.*.*", ("*", (0, None, None, None, None))),

-         ("<0", ("<", (0, None, None, None, None))),

-         ("<0.1", ("<", (0, 1, None, None, None))),

-         ("<0.1.2", ("<", (0, 1, 2, None, None))),

-         ("<0.1.2-alpha1", ("<", (0, 1, 2, "alpha1", None))),

-         ("<=0.1.2", ("<=", (0, 1, 2, None, None))),

-         ("=0.1.2", ("=", (0, 1, 2, None, None))),

-         ("==0.1.2", ("==", (0, 1, 2, None, None))),

-         (">=0.1.2", (">=", (0, 1, 2, None, None))),

-         (">0.1.2", (">", (0, 1, 2, None, None))),

-         ("0.1.2", ("", (0, 1, 2, None, None))),

-         ("!=0.1.2", ("!=", (0, 1, 2, None, None))),

-         ("^0.1.2", ("^", (0, 1, 2, None, None))),

-         ("~0.1.2", ("~", (0, 1, 2, None, None))),

-         ("~=0.1.2", ("~=", (0, 1, 2, None, None))),

-     ],

- )

+ @pytest.mark.parametrize('requirement, parsed_requirement', [

+     ('*', ('*', (None, None, None, None, None))),

+     ('0.*', ('*', (0, None, None, None, None))),

+     ('0.1.*', ('*', (0, 1, None, None, None))),

+     ('0.*.*', ('*', (0, None, None, None, None))),

+     ('<0', ('<', (0, None, None, None, None))),

+     ('<0.1', ('<', (0, 1, None, None, None))),

+     ('<0.1.2', ('<', (0, 1, 2, None, None))),

+     ('<0.1.2-alpha1', ('<', (0, 1, 2, 'alpha1', None))),

+     ('<=0.1.2', ('<=', (0, 1, 2, None, None))),

+     ('=0.1.2', ('=', (0, 1, 2, None, None))),

+     ('==0.1.2', ('==', (0, 1, 2, None, None))),

+     ('>=0.1.2', ('>=', (0, 1, 2, None, None))),

+     ('>0.1.2', ('>', (0, 1, 2, None, None))),

+     ('0.1.2', ('', (0, 1, 2, None, None))),

+     ('!=0.1.2', ('!=', (0, 1, 2, None, None))),

+     ('^0.1.2', ('^', (0, 1, 2, None, None))),

+     ('~0.1.2', ('~', (0, 1, 2, None, None))),

+     ('~=0.1.2', ('~=', (0, 1, 2, None, None))),

+ ])

  def test_parse(requirement, parsed_requirement):

      result = CargoSemVer.parse(requirement)

      assert result == parsed_requirement

  

  

- @pytest.mark.parametrize(

-     "version, coerced_version",

-     [

-         (Version(0, None, None, None, None), (0, 0, 0, None, None)),

-         (Version(1, 0, None, None, None), (1, 0, 0, None, None)),

-         (Version(2, 1, 0, None, None), (2, 1, 0, None, None)),

-         (Version(2, 1, 0, None, "build1"), (2, 1, 0, None, "build1")),

-         (Version(2, 1, 0, "alpha1", None), (2, 1, 0, "alpha1", None)),

-         (Version(2, 1, 0, "alpha1", "build1"), (2, 1, 0, "alpha1", "build1")),

-     ],

- )

+ @pytest.mark.parametrize('version, coerced_version', [

+     (Version(0, None, None, None, None),

+      (0, 0, 0, None, None)),

+     (Version(1, 0, None, None, None),

+      (1, 0, 0, None, None)),

+     (Version(2, 1, 0, None, None),

+      (2, 1, 0, None, None)),

+     (Version(2, 1, 0, None, 'build1'),

+      (2, 1, 0, None, 'build1')),

+     (Version(2, 1, 0, 'alpha1', None),

+      (2, 1, 0, 'alpha1', None)),

+     (Version(2, 1, 0, 'alpha1', 'build1'),

+      (2, 1, 0, 'alpha1', 'build1')),

+ ])

  def test_coerce(version, coerced_version):

      result = CargoSemVer.coerce(version)

      assert result == coerced_version

  

  

- @pytest.mark.parametrize(

-     "version, next_version",

-     [

-         ((0, None, None, None, None), (1, 0, 0, None, None)),

-         ((1, 0, None, None, None), (2, 0, 0, None, None)),

-         ((2, 1, 0, None, None), (3, 0, 0, None, None)),

-         ((2, 0, 0, None, "build1"), (3, 0, 0, None, None)),

-         ((2, None, None, "alpha1", None), (2, 0, 0, None, None)),

-         ((2, 0, None, "alpha1", None), (2, 0, 0, None, None)),

-         ((2, 0, 0, "alpha1", None), (2, 0, 0, None, None)),

-         ((2, 1, None, "alpha1", None), (3, 0, 0, None, None)),

-         ((2, 1, 0, "alpha1", None), (3, 0, 0, None, None)),

-         ((2, 1, 1, "alpha1", None), (3, 0, 0, None, None)),

-         ((2, 0, 1, "alpha1", "build1"), (3, 0, 0, None, None)),

-     ],

- )

+ @pytest.mark.parametrize('version, next_version', [

+     ((0, None, None, None, None), (1, 0, 0, None, None)),

+     ((1, 0, None, None, None), (2, 0, 0, None, None)),

+     ((2, 1, 0, None, None), (3, 0, 0, None, None)),

+     ((2, 0, 0, None, 'build1'), (3, 0, 0, None, None)),

+     ((2, None, None, 'alpha1', None), (2, 0, 0, None, None)),

+     ((2, 0, None, 'alpha1', None), (2, 0, 0, None, None)),

+     ((2, 0, 0, 'alpha1', None), (2, 0, 0, None, None)),

+     ((2, 1, None, 'alpha1', None), (3, 0, 0, None, None)),

+     ((2, 1, 0, 'alpha1', None), (3, 0, 0, None, None)),

+     ((2, 1, 1, 'alpha1', None), (3, 0, 0, None, None)),

+     ((2, 0, 1, 'alpha1', 'build1'), (3, 0, 0, None, None)),

+ ])

  def test_next_major(version, next_version):

      result = CargoSemVer.next_major(version)

      assert result == next_version

  

  

- @pytest.mark.parametrize(

-     "version, next_version",

-     [

-         ((0, None, None, None, None), (0, 1, 0, None, None)),

-         ((1, 0, None, None, None), (1, 1, 0, None, None)),

-         ((2, 1, 0, None, None), (2, 2, 0, None, None)),

-         ((2, 1, 0, None, "build1"), (2, 2, 0, None, None)),

-         ((2, None, None, "alpha1", None), (2, 0, 0, None, None)),

-         ((2, 0, None, "alpha1", None), (2, 0, 0, None, None)),

-         ((2, 0, 0, "alpha1", None), (2, 0, 0, None, None)),

-         ((2, 1, None, "alpha1", None), (2, 1, 0, None, None)),

-         ((2, 1, 0, "alpha1", None), (2, 1, 0, None, None)),

-         ((2, 1, 1, "alpha1", None), (2, 2, 0, None, None)),

-         ((2, 1, 0, "alpha1", "build1"), (2, 1, 0, None, None)),

-     ],

- )

+ @pytest.mark.parametrize('version, next_version', [

+     ((0, None, None, None, None), (0, 1, 0, None, None)),

+     ((1, 0, None, None, None), (1, 1, 0, None, None)),

+     ((2, 1, 0, None, None), (2, 2, 0, None, None)),

+     ((2, 1, 0, None, 'build1'), (2, 2, 0, None, None)),

+     ((2, None, None, 'alpha1', None), (2, 0, 0, None, None)),

+     ((2, 0, None, 'alpha1', None), (2, 0, 0, None, None)),

+     ((2, 0, 0, 'alpha1', None), (2, 0, 0, None, None)),

+     ((2, 1, None, 'alpha1', None), (2, 1, 0, None, None)),

+     ((2, 1, 0, 'alpha1', None), (2, 1, 0, None, None)),

+     ((2, 1, 1, 'alpha1', None), (2, 2, 0, None, None)),

+     ((2, 1, 0, 'alpha1', 'build1'), (2, 1, 0, None, None)),

+ ])

  def test_next_minor(version, next_version):

      result = CargoSemVer.next_minor(version)

      assert result == next_version

  

  

- @pytest.mark.parametrize(

-     "version, next_version",

-     [

-         ((0, None, None, None, None), (0, 0, 1, None, None)),

-         ((1, 0, None, None, None), (1, 0, 1, None, None)),

-         ((2, 1, 0, None, None), (2, 1, 1, None, None)),

-         ((2, 1, 0, None, "build1"), (2, 1, 1, None, None)),

-         ((2, None, None, "alpha1", None), (2, 0, 0, None, None)),

-         ((2, 0, None, "alpha1", None), (2, 0, 0, None, None)),

-         ((2, 0, 0, "alpha1", None), (2, 0, 0, None, None)),

-         ((2, 1, None, "alpha1", None), (2, 1, 0, None, None)),

-         ((2, 1, 0, "alpha1", None), (2, 1, 0, None, None)),

-         ((2, 1, 1, "alpha1", None), (2, 1, 1, None, None)),

-         ((2, 1, 0, "alpha1", "build1"), (2, 1, 0, None, None)),

-     ],

- )

+ @pytest.mark.parametrize('version, next_version', [

+     ((0, None, None, None, None), (0, 0, 1, None, None)),

+     ((1, 0, None, None, None), (1, 0, 1, None, None)),

+     ((2, 1, 0, None, None), (2, 1, 1, None, None)),

+     ((2, 1, 0, None, 'build1'), (2, 1, 1, None, None)),

+     ((2, None, None, 'alpha1', None), (2, 0, 0, None, None)),

+     ((2, 0, None, 'alpha1', None), (2, 0, 0, None, None)),

+     ((2, 0, 0, 'alpha1', None), (2, 0, 0, None, None)),

+     ((2, 1, None, 'alpha1', None), (2, 1, 0, None, None)),

+     ((2, 1, 0, 'alpha1', None), (2, 1, 0, None, None)),

+     ((2, 1, 1, 'alpha1', None), (2, 1, 1, None, None)),

+     ((2, 1, 0, 'alpha1', 'build1'), (2, 1, 0, None, None)),

+ ])

  def test_next_patch(version, next_version):

      result = CargoSemVer.next_patch(version)

      assert result == next_version

  

  

- @pytest.mark.parametrize(

-     "requirement, normalized_requirement",

-     [

-         (("^", Version(1, 2, 3, None, None)), [(">=", (1, 2, 3, None, None)), ("<", (2, 0, 0, None, None))]),

-         (("^", Version(1, 2, None, None, None)), [(">=", (1, 2, 0, None, None)), ("<", (2, 0, 0, None, None))]),

-         (("^", Version(1, None, None, None, None)), [(">=", (1, 0, 0, None, None)), ("<", (2, 0, 0, None, None))]),

-         (("^", Version(0, 2, 3, None, None)), [(">=", (0, 2, 3, None, None)), ("<", (0, 3, 0, None, None))]),

-         (("^", Version(0, 2, None, None, None)), [(">=", (0, 2, 0, None, None)), ("<", (0, 3, 0, None, None))]),

-         (("^", Version(0, 0, 3, None, None)), [(">=", (0, 0, 3, None, None)), ("<", (0, 0, 4, None, None))]),

-         (("^", Version(0, 0, None, None, None)), [(">=", (0, 0, 0, None, None)), ("<", (0, 1, 0, None, None))]),

-         (("^", Version(0, None, None, None, None)), [(">=", (0, 0, 0, None, None)), ("<", (1, 0, 0, None, None))]),

-         (("~", Version(1, 2, 3, None, None)), [(">=", (1, 2, 3, None, None)), ("<", (1, 3, 0, None, None))]),

-         (("~", Version(1, 2, None, None, None)), [(">=", (1, 2, 0, None, None)), ("<", (1, 3, 0, None, None))]),

-         (("~", Version(1, None, None, None, None)), [(">=", (1, 0, 0, None, None)), ("<", (2, 0, 0, None, None))]),

-         (("*", Version(None, None, None, None, None)), [(">=", (0, 0, 0, None, None))]),

-         (("*", Version(1, None, None, None, None)), [(">=", (1, 0, 0, None, None)), ("<", (2, 0, 0, None, None))]),

-         (("*", Version(1, 2, None, None, None)), [(">=", (1, 2, 0, None, None)), ("<", (1, 3, 0, None, None))]),

-         ((">=", Version(1, 2, 0, None, None)), [(">=", (1, 2, 0, None, None))]),

-         ((">", Version(1, None, None, None, None)), [(">", (1, 0, 0, None, None))]),

-         (("<", Version(2, None, None, None, None)), [("<", (2, 0, 0, None, None))]),

-         (("=", Version(1, 2, 3, None, None)), [("=", (1, 2, 3, None, None))]),

-         (("^", Version(1, 0, 0, "alpha.6", None)), [(">=", (1, 0, 0, "alpha.6", None)), ("<", (2, 0, 0, None, None))]),

-         (("^", Version(0, 1, 0, "alpha.6", None)), [(">=", (0, 1, 0, "alpha.6", None)), ("<", (0, 2, 0, None, None))]),

-         (("^", Version(0, 0, 1, "alpha.6", None)), [(">=", (0, 0, 1, "alpha.6", None)), ("<", (0, 0, 2, None, None))]),

-         (("^", Version(0, 0, 0, "alpha.6", None)), [(">=", (0, 0, 0, "alpha.6", None)), ("<", (0, 0, 1, None, None))]),

-     ],

- )

+ @pytest.mark.parametrize("requirement, normalized_requirement", [

+     (('^', Version(1, 2, 3, None, None)),

+      [('>=', (1, 2, 3, None, None)), ('<', (2, 0, 0, None, None))]),

+     (('^', Version(1, 2, None, None, None)),

+      [('>=', (1, 2, 0, None, None)), ('<', (2, 0, 0, None, None))]),

+     (('^', Version(1, None, None, None, None)),

+      [('>=', (1, 0, 0, None, None)), ('<', (2, 0, 0, None, None))]),

+     (('^', Version(0, 2, 3, None, None)),

+      [('>=', (0, 2, 3, None, None)), ('<', (0, 3, 0, None, None))]),

+     (('^', Version(0, 2, None, None, None)),

+      [('>=', (0, 2, 0, None, None)), ('<', (0, 3, 0, None, None))]),

+     (('^', Version(0, 0, 3, None, None)),

+      [('>=', (0, 0, 3, None, None)), ('<', (0, 0, 4, None, None))]),

+     (('^', Version(0, 0, None, None, None)),

+      [('>=', (0, 0, 0, None, None)), ('<', (0, 1, 0, None, None))]),

+     (('^', Version(0, None, None, None, None)),

+      [('>=', (0, 0, 0, None, None)), ('<', (1, 0, 0, None, None))]),

+     (('~', Version(1, 2, 3, None, None)),

+      [('>=', (1, 2, 3, None, None)), ('<', (1, 3, 0, None, None))]),

+     (('~', Version(1, 2, None, None, None)),

+      [('>=', (1, 2, 0, None, None)), ('<', (1, 3, 0, None, None))]),

+     (('~', Version(1, None, None, None, None)),

+      [('>=', (1, 0, 0, None, None)), ('<', (2, 0, 0, None, None))]),

+     (('*', Version(None, None, None, None, None)),

+      [('>=', (0, 0, 0, None, None))]),

+     (('*', Version(1, None, None, None, None)),

+      [('>=', (1, 0, 0, None, None)), ('<', (2, 0, 0, None, None))]),

+     (('*', Version(1, 2, None, None, None)),

+      [('>=', (1, 2, 0, None, None)), ('<', (1, 3, 0, None, None))]),

+     (('>=', Version(1, 2, 0, None, None)),

+      [('>=', (1, 2, 0, None, None))]),

+     (('>', Version(1, None, None, None, None)),

+      [('>', (1, 0, 0, None, None))]),

+     (('<', Version(2, None, None, None, None)),

+      [('<', (2, 0, 0, None, None))]),

+     (('=', Version(1, 2, 3, None, None)),

+      [('=', (1, 2, 3, None, None))]),

+     (('^', Version(1, 0, 0, 'alpha.6', None)),

+      [('>=', (1, 0, 0, 'alpha.6', None)), ('<', (2, 0, 0, None, None))]),

+     (('^', Version(0, 1, 0, 'alpha.6', None)),

+      [('>=', (0, 1, 0, 'alpha.6', None)), ('<', (0, 2, 0, None, None))]),

+     (('^', Version(0, 0, 1, 'alpha.6', None)),

+      [('>=', (0, 0, 1, 'alpha.6', None)), ('<', (0, 0, 2, None, None))]),

+     (('^', Version(0, 0, 0, 'alpha.6', None)),

+      [('>=', (0, 0, 0, 'alpha.6', None)), ('<', (0, 0, 1, None, None))]),

+ ])

  def test_normalize(requirement, normalized_requirement):

      result = CargoSemVer.normalize(requirement)

      assert result == normalized_requirement

file modified
+15 -19
@@ -8,62 +8,58 @@ 

  

  DEFAULT_EDITOR = "vi"

  

- 

  @contextlib.contextmanager

  def remove_on_error(path):

      try:

          yield

-     except:  # this is supposed to include ^C

+     except: # this is supposed to include ^C

          os.unlink(path)

          raise

  

- 

  @contextlib.contextmanager

  def exit_on_common_errors():

      """Suppress tracebacks on common "expected" exceptions"""

      try:

          yield

      except requests.exceptions.HTTPError as e:

-         sys.exit(f"Failed to download metadata: {e}")

+         sys.exit(f'Failed to download metadata: {e}')

      except subprocess.CalledProcessError as e:

          cmd = shlex.join(e.cmd)

-         sys.exit(f"Subcommand failed with code {e.returncode}: {cmd}")

+         sys.exit(f'Subcommand failed with code {e.returncode}: {cmd}')

      except FileNotFoundError as e:

          sys.exit(str(e))

  

- 

  def detect_editor():

-     terminal = os.getenv("TERM")

-     terminal_is_dumb = not terminal or terminal == "dumb"

+     terminal = os.getenv('TERM')

+     terminal_is_dumb = not terminal or terminal == 'dumb'

      editor = None

      if not terminal_is_dumb:

-         editor = os.getenv("VISUAL")

+         editor = os.getenv('VISUAL')

      if not editor:

-         editor = os.getenv("EDITOR")

+         editor = os.getenv('EDITOR')

      if not editor:

          if terminal_is_dumb:

-             raise Exception("Terminal is dumb, but $EDITOR unset")

+             raise Exception('Terminal is dumb, but $EDITOR unset')

          editor = DEFAULT_EDITOR

      return editor

  

- 

  def detect_packager():

      # If we're forcing the fallback...

-     if os.getenv("RUST2RPM_NO_DETECT_PACKAGER"):

+     if os.getenv('RUST2RPM_NO_DETECT_PACKAGER'):

          return None

  

      # If we're supplying packager identity through an environment variable...

-     if packager := os.getenv("RUST2RPM_PACKAGER"):

+     if packager := os.getenv('RUST2RPM_PACKAGER'):

          return packager

  

      # If we're detecting packager identity through rpmdev-packager...

-     if rpmdev_packager := shutil.which("rpmdev-packager"):

+     if rpmdev_packager := shutil.which('rpmdev-packager'):

          return subprocess.check_output(rpmdev_packager, text=True).strip()

  

      # If we're detecting packager identity through git configuration...

-     if git := shutil.which("git"):

-         name = subprocess.check_output([git, "config", "user.name"], text=True).strip()

-         email = subprocess.check_output([git, "config", "user.email"], text=True).strip()

-         return f"{name} <{email}>"

+     if git := shutil.which('git'):

+         name = subprocess.check_output([git, 'config', 'user.name'], text=True).strip()

+         email = subprocess.check_output([git, 'config', 'user.email'], text=True).strip()

+         return f'{name} <{email}>'

  

      return None

no initial comment

Please see the commit message description.

I disagree with almost all of those "problems" you listed.

I also went through the entire "reformatting" commit to verify that it did the correct thing, and manually reformatted some code to be more consistent, to prevent some of the issues you point out.

Regarding double quotes: Consensus seems to have shifted here, and most people use double quotes by default. Previous to the reformatting commit, we used both, inconsistently.

When doing the revert, I unstaged some parts of the revert where that made sense. (I forgot to mention this in the commit message). But in most places the black formatting made things worse. The one place where it does the right thing is actually those parts of the code which were formatted with black, just an older version (inspector.py iirc).

I also went through the entire "reformatting" commit to verify that it did the correct thing, and manually reformatted some code to be more consistent

Sorry, but many of the changes were making things clearly worse.

Consensus seems to have shifted here

I think that's arguable. There's a billion lines of python code out there, so it's unlikely that a (hopefully temporary) fad like black can make a significant change quickly.

If we are to merge a reformatting change, I think it should be treated as any other feature: submit a pull request, let other people review it and discuss merits and point out shortcomings if any.

So you want to revert all the work I put into this just because you don't like the way it looks?

The whole point of a code formatter is that it enforces a standard that nobody is entirely happy with, but which almost everybody can live with. That's in contrast to subjective "nice looking code" that's hand crafted by individuals ...

So you want to revert all the work I put into this just because you don't like the way it looks?

Reverting your work is obviously not the point. But I don't think this argument is fair: you might just as well say that the work that was done previously to format the code in a nice way is being "undone" by the automatic reformatting. This kind of sweeping change should be based on consensus. And clearly there's no consensus here. Those changes clearly make the code less readable, and I don't think we want to keep them.

The whole point of a code formatter is that it enforces a standard that nobody is entirely happy with, but which almost everybody can live with.

Well, I think we can do gradual improvements to formatting, also using black as a helper, so that the formatting is both consistent and nice. Black gives us formatting that is rule-based and actually quite inconsistent and therefore ugly [when used across the codebase].

Black gives us formatting that is rule-based and actually quite inconsistent and therefore ugly

This kind of subjective statement doesn't really help with anything.

So should we ask other Rust SIG members chime in here?

This kind of subjective statement doesn't really help with anything.

It's not subjective. In the commit message I give very explicit examples of inconsistency.

So should we ask other Rust SIG members chime in here?

I think this mostly matters for people working on the code. We can ask other folks for opinions, but ultimately it's between you and me, since we're the only ones contributing patches in the recent times.

I'm in favor of retaining black, as even though I disagree with some of its opinions (mostly on 4-space indentation), the alternative of having to deal with pyflakes is just too burdensome to consider.

I'm not why you're bringing up pyflakes. Pyflakes is linter for errors, it doesn't care about code style.

The whole point of a code formatter is that it enforces a standard that nobody is entirely happy with, but which almost everybody can live with. That's in contrast to subjective "nice looking code" that's hand crafted by individuals ...

+1. Specifically, black entirely removes the cognitive load of having to deal with formatting (in the same way that the golang and rust formatters do). You write your code however you want, you run black, done. No need to think about how quotes should be, line breaks, how many spaces, etc. It's not perfect, but IMO it's almost always good enough to be the better alternative.

I'm going to close this PR. Even if we wanted to un-do- the black formatting, the code base has now changed so much that this PR no longer applies anyway.

Pull-Request has been closed by decathorpe

a year ago