Skip to content

Commit

Permalink
chore: Add ruff lint configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
jpmckinney committed Sep 15, 2024
1 parent 45fd890 commit 2b4887e
Show file tree
Hide file tree
Showing 11 changed files with 156 additions and 141 deletions.
20 changes: 8 additions & 12 deletions ocdsextensionregistry/api.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
"""
Complex operations making use of this library's classes are organized into this API module.
"""
"""Complex operations making use of this library's classes are organized into this API module."""

import csv
import json
Expand All @@ -17,13 +15,13 @@
def build_profile(basedir, standard_tag, extension_versions, registry_base_url=None, standard_base_url=None,
schema_base_url=None, update_codelist_urls=None):
"""
Pulls extensions into a profile.
Pull extensions into a profile.
- Merges extensions' JSON Merge Patch files for OCDS' release-schema.json (schema/profile/release-schema.json)
- Writes extensions' codelist files (schema/profile/codelists)
- Patches OCDS' release-schema.json with extensions' JSON Merge Patch files (schema/patched/release-schema.json)
- Patches OCDS' codelist files with extensions' codelist files (schema/patched/codelists)
- Updates the "codelists" field in extension.json
- Merge extensions' JSON Merge Patch files for OCDS' release-schema.json (schema/profile/release-schema.json)
- Write extensions' codelist files (schema/profile/codelists)
- Patch OCDS' release-schema.json with extensions' JSON Merge Patch files (schema/patched/release-schema.json)
- Patch OCDS' codelist files with extensions' codelist files (schema/patched/codelists)
- Update the "codelists" field in extension.json
The profile's codelists exclude deprecated codes and add an Extension column.
Expand All @@ -41,9 +39,7 @@ def build_profile(basedir, standard_tag, extension_versions, registry_base_url=N
"""
@contextmanager
def open_file(name, mode='r'):
"""
Creates the directory if it doesn't exist.
"""
"""Create the directory if it doesn't exist."""
os.makedirs(os.path.dirname(name), exist_ok=True)

with open(name, mode) as f:
Expand Down
42 changes: 12 additions & 30 deletions ocdsextensionregistry/codelist.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"""
Create or update an OCDS codelist.
.. code:: python
from ocdsextensionregistry import Codelist
Expand Down Expand Up @@ -72,29 +74,21 @@ def __repr__(self):
return f'Codelist(name={self.name!r}, rows={self.rows!r})'

def extend(self, rows, extension_name=None):
"""
Adds rows to the codelist.
"""
"""Add rows to the codelist."""
for row in rows:
self.rows.append(CodelistCode(row, extension_name))

def add_extension_column(self, field_name):
"""
Adds a column for the name of the extension from which codes originate.
"""
"""Add a column for the name of the extension from which codes originate."""
for row in self.rows:
row[field_name] = row.extension_name

def remove_deprecated_codes(self):
"""
Removes deprecated codes and the Deprecated column.
"""
"""Remove deprecated codes and the ``Deprecated`` column."""
self.rows = [row for row in self.rows if not row.pop('Deprecated', None)]

def to_csv(self):
"""
Returns the codelist as CSV content.
"""
"""Return the codelist as CSV content."""
io = StringIO()

writer = csv.DictWriter(io, fieldnames=self.fieldnames, lineterminator='\n', extrasaction='ignore')
Expand All @@ -105,16 +99,12 @@ def to_csv(self):

@property
def codes(self):
"""
Returns the codes in the codelist.
"""
"""Returns the codes in the codelist."""
return [row['Code'] for row in self.rows]

@property
def fieldnames(self):
"""
Returns all fieldnames used in any rows.
"""
"""Returns all fieldnames used in any rows."""
fieldnames = {} # sets are unordered
for row in self.rows:
for field in row:
Expand All @@ -123,30 +113,22 @@ def fieldnames(self):

@property
def basename(self):
"""
If the codelist modifies another codelist, returns the latter's name. Otherwise, returns its own name.
"""
"""If the codelist modifies another codelist, returns the latter's name. Otherwise, returns its own name."""
if self.patch:
return self.name[1:]
return self.name

@property
def patch(self):
"""
Returns whether the codelist modifies another codelist.
"""
"""Returns whether the codelist modifies another codelist."""
return self.name.startswith(('+', '-'))

@property
def addend(self):
"""
Returns whether the codelist adds codes to another codelist.
"""
"""Returns whether the codelist adds codes to another codelist."""
return self.name.startswith('+')

@property
def subtrahend(self):
"""
Returns whether the codelist removes codes from another codelist.
"""
"""Returns whether the codelist removes codes from another codelist."""
return self.name.startswith('-')
8 changes: 2 additions & 6 deletions ocdsextensionregistry/commands/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@

class BaseCommand:
def __init__(self, subparsers):
"""
Initializes the subparser and adds arguments.
"""
"""Initialize the subparser and add arguments."""
self.subparser = subparsers.add_parser(self.name, description=self.help)
self.add_argument('--no-frozen', action='store_true', help='exclude frozen versions')
self.add_arguments()
Expand All @@ -17,9 +15,7 @@ def add_arguments(self):
pass

def add_argument(self, *args, **kwargs):
"""
Adds an argument to the subparser.
"""
"""Add an argument to the subparser."""
self.subparser.add_argument(*args, **kwargs)

def handle(self):
Expand Down
7 changes: 5 additions & 2 deletions ocdsextensionregistry/commands/generate_pot_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,11 @@ def handle(self):
raise SphinxError(str(outdir)) from e

# https://stackoverflow.com/questions/15408348
content = subprocess.run(['msgcat', *glob(str(outdir / '*.pot'))],
check=True, stdout=subprocess.PIPE).stdout
content = subprocess.run( # noqa: S603 # trusted input
['msgcat', *glob(str(outdir / '*.pot'))], # noqa: S607
check=True,
stdout=subprocess.PIPE,
).stdout

with open(outdir / 'docs.pot', 'wb') as f:
f.write(content)
16 changes: 8 additions & 8 deletions ocdsextensionregistry/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
class OCDSExtensionRegistryError(Exception):
"""Base class for exceptions from within this package"""
"""Base class for exceptions from within this package."""


class DoesNotExist(OCDSExtensionRegistryError): # noqa: N818
"""Raised if an object wasn't found for the given parameters"""
"""Raised if an object wasn't found for the given parameters."""


class MissingExtensionMetadata(OCDSExtensionRegistryError): # noqa: N818
"""Raised if a method call requires extensions metadata, with which the extension registry was not initialized"""
"""Raised if a method call requires extensions metadata, with which the extension registry was not initialized."""


class NotAvailableInBulk(OCDSExtensionRegistryError): # noqa: N818
"""Raised if files are required to be available in bulk, but are not"""
"""Raised if files are required to be available in bulk, but are not."""


class UnknownLatestVersion(OCDSExtensionRegistryError): # noqa: N818
"""Raised if the latest version of an extension can't be determined"""
"""Raised if the latest version of an extension can't be determined."""


class CommandError(OCDSExtensionRegistryError):
"""Errors from within this package's CLI"""
"""Errors from within this package's CLI."""


class SphinxError(OCDSExtensionRegistryError):
"""Raised if Sphinx produces a warning"""
"""Raised if Sphinx produces a warning."""


class OCDSExtensionRegistryWarning(UserWarning):
"""Base class for warnings from within this package"""
"""Base class for warnings from within this package."""


# The attributes are used by lib-cove-ocds.
Expand Down
6 changes: 2 additions & 4 deletions ocdsextensionregistry/extension.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
class Extension:
def __init__(self, data):
"""
Accepts a row from extensions.csv and assigns values to properties.
"""
"""Accept a row from ``extensions.csv`` and assign values to properties."""
#: The Id cell.
self.id = data['Id']
#: The Category cell.
Expand All @@ -15,7 +13,7 @@ def __repr__(self):

def as_dict(self):
"""
Returns the object's properties as a dictionary.
Return the object's properties as a dictionary.
This method is defined to match the method in `ExtensionVersion`.
"""
Expand Down
24 changes: 12 additions & 12 deletions ocdsextensionregistry/extension_registry.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
Filter the versions of extensions in the registry, and access information about matching versions:
r"""
Filter the versions of extensions in the registry, and access information about matching versions.
.. code:: python
Expand All @@ -12,7 +12,7 @@
for version in registry.filter(core=True, version='v1.1.4', category='tender'):
print(f'The {version.metadata[name][en]} extension ("{version.id}") is maintained at {version.repository_html_page}')
print(f'Run `git clone {version.repository_url}` to make a local copy in a {version.repository_name} directory')
print(f'Get its patch at {version.base_url}release-schema.json\\n')
print(f'Get its patch at {version.base_url}release-schema.json\n')
Output::
Expand Down Expand Up @@ -43,9 +43,11 @@
class ExtensionRegistry:
def __init__(self, extension_versions_data, extensions_data=None):
"""
Accepts extension_versions.csv and, optionally, extensions.csv as either URLs or data (as string) and reads
them into ExtensionVersion objects. If extensions_data is not provided, the extension versions will not have
category or core properties. URLs starting with ``file://`` will be read from the filesystem.
Accept ``extension_versions.csv`` and, optionally, ``extensions.csv`` as either URLs or data (as string) and
read them into :class:`~ocdsextensionregistry.extension_version.ExtensionVersion` objects.
If extensions_data is not provided, the extension versions will not have category or core properties.
URLs starting with ``file://`` will be read from the filesystem.
"""
self.versions = []

Expand All @@ -66,7 +68,7 @@ def __init__(self, extension_versions_data, extensions_data=None):

def filter(self, **kwargs):
"""
Returns the extension versions in the registry that match the keyword arguments.
Return the extension versions in the registry that match the keyword arguments.
:raises MissingExtensionMetadata: if the keyword arguments refer to extensions data, but the extension registry
was not initialized with extensions data
Expand All @@ -78,7 +80,7 @@ def filter(self, **kwargs):

def get(self, **kwargs):
"""
Returns the first extension version in the registry that matches the keyword arguments.
Return the first extension version in the registry that matches the keyword arguments.
:raises DoesNotExist: if no extension version matches
:raises MissingExtensionMetadata: if the keyword arguments refer to extensions data, but the extension registry
Expand All @@ -93,7 +95,7 @@ def get(self, **kwargs):

def get_from_url(self, url):
"""
Returns the first extension version in the registry whose base URL matches the given URL.
Return the first extension version in the registry whose base URL matches the given URL.
:raises DoesNotExist: if no extension version matches
"""
Expand All @@ -102,9 +104,7 @@ def get_from_url(self, url):
return self.get(base_url=parsed._replace(path=path).geturl())

def __iter__(self):
"""
Iterates over the extension versions in the registry.
"""
"""Iterate over the extension versions in the registry."""
yield from self.versions

def _handle_attribute_error(self, e):
Expand Down
Loading

0 comments on commit 2b4887e

Please sign in to comment.