Skip to content

Commit 67ce2fd

Browse files
author
Marin Visscher
committed
Switch to loguru
1 parent cc8da6b commit 67ce2fd

8 files changed

Lines changed: 34 additions & 46 deletions

File tree

bw_functional/__init__.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@
1212
"update",
1313
)
1414

15-
from importlib import metadata
16-
# import os
17-
from logging import getLogger
15+
from loguru import logger
1816

1917
from bw2data import labels
2018
from bw2data.subclass_mapping import DATABASE_BACKEND_MAPPING, NODE_PROCESS_CLASS_MAPPING
@@ -26,8 +24,6 @@
2624
from .convert import convert_sqlite_to_functional_sqlite, convert_functional_sqlite_to_sqlite
2725
from .update import update, latest
2826

29-
log = getLogger(__name__)
30-
3127
DATABASE_BACKEND_MAPPING["functional_sqlite"] = FunctionalSQLiteDatabase
3228
NODE_PROCESS_CLASS_MAPPING["functional_sqlite"] = FunctionalSQLiteDatabase.node_class
3329

@@ -63,7 +59,7 @@ def _check_parameterized_exchange_for_allocation(_, name):
6359
for key in process_keys:
6460
process = bd.get_activity(key)
6561
if not isinstance(process, Process):
66-
log.warning(f"Process {key} is not an instance of Process, skipping allocation check.")
62+
logger.warning(f"Process {key} is not an instance of Process, skipping allocation check.")
6763
continue
6864
process.allocate()
6965

@@ -75,7 +71,7 @@ def _check_and_update(dataset):
7571
current = dataset.data.get("bw_functional_version")
7672

7773
if current != latest:
78-
log.info(f"Updating {dataset.name} to latest bw_functional datastructure version {latest}")
74+
logger.info(f"Updating {dataset.name} to latest bw_functional datastructure version {latest}")
7975
dataset.data["bw_functional_version"] = update(current)
8076
dataset.save()
8177

bw_functional/allocation.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
from functools import partial
2-
from typing import Callable, List
3-
from logging import getLogger
2+
from typing import Callable
3+
from loguru import logger
44

55
from .node_classes import Process, Product
66

7-
log = getLogger(__name__)
8-
97

108
def generic_allocation(
119
process: Process,
@@ -49,7 +47,7 @@ def generic_allocation(
4947
products.append(product)
5048

5149
if not products:
52-
log.warning(f"No products to allocate in process {process}")
50+
logger.warning(f"No products to allocate in process {process}")
5351
return
5452

5553
# Calculate the total value for allocation
@@ -110,7 +108,7 @@ def get_property_value(
110108
raise KeyError(f"Product {product} from {product.processor} missing property {property_label}")
111109

112110
if isinstance(prop, float):
113-
log.warning("Property using legacy float format")
111+
logger.warning("Property using legacy float format")
114112
return prop
115113

116114
if prop.get("normalize", False):

bw_functional/convert.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
import tqdm
2-
from logging import getLogger
3-
2+
from loguru import logger
43
import bw2data as bd
5-
from bw2data.backends import SQLiteBackend
64

75
from .database import FunctionalSQLiteDatabase
86

9-
log = getLogger(__name__)
10-
117

128
def convert_sqlite_to_functional_sqlite(database_dict: dict) -> dict:
139
return SQLiteToFunctionalSQLite.convert(database_dict)
@@ -145,15 +141,15 @@ def convert_function(cls, key, ds, processor):
145141
continue
146142

147143
if exc["type"] != "production" and ds.get("allocation_factor"):
148-
log.info(f"Allocating exchange from {exc['input']} to {ds['name']} "
144+
logger.info(f"Allocating exchange from {exc['input']} to {ds['name']} "
149145
f"with factor {ds['allocation_factor']}")
150146
exc["amount"] = exc["amount"] * ds['allocation_factor']
151147
if exc.get("formula"):
152-
log.info(f"Allocating formula from {exc['input']} to {ds['name']}: "
148+
logger.info(f"Allocating formula from {exc['input']} to {ds['name']}: "
153149
f"{exc['formula']} * {ds['allocation_factor']}")
154150
exc["formula"] = f"{exc['formula']} * {ds['allocation_factor']}"
155151
if exc.get("uncertainty type"):
156-
log.warning(f"Exchange from {exc['input']} to {ds['name']} has an uncertainty distribution that "
152+
logger.warning(f"Exchange from {exc['input']} to {ds['name']} has an uncertainty distribution that "
157153
f"will not be allocated")
158154

159155
ds["exchanges"].append(exc)

bw_functional/database.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import sqlite3
22
import pickle
33
import datetime
4-
from logging import getLogger
54
from time import time
65

7-
import numpy as np
8-
import pandas as pd
6+
from loguru import logger
97
from fsspec.implementations.zip import ZipFileSystem
108

9+
import numpy as np
10+
import pandas as pd
1111
import stats_arrays as sa
1212

1313
from bw_processing import clean_datapackage_name, create_datapackage
@@ -17,8 +17,6 @@
1717

1818
from .node_classes import Process, Product
1919

20-
log = getLogger(__name__)
21-
2220
UNCERTAINTY_FIELDS = ["uncertainty_type", "loc", "scale", "shape", "minimum", "maximum"]
2321

2422

@@ -238,7 +236,7 @@ def id_mapper(key) -> NAType | int:
238236
# Close the SQLite connection
239237
con.close()
240238

241-
log.debug(f"Processing: built tables from SQL in {time() - t:.2f} seconds")
239+
logger.debug(f"Processing: built tables from SQL in {time() - t:.2f} seconds")
242240

243241
return node_df, exc_df, dependents
244242

bw_functional/edge_classes.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
from logging import getLogger
1+
from loguru import logger
22
from copy import deepcopy
33

44
from bw2data import projects, databases, errors
55
from bw2data.backends.proxies import Exchange, Exchanges, ExchangeDataset
66

7-
log = getLogger(__name__)
8-
97

108
class MFExchanges(Exchanges):
119
"""
@@ -106,7 +104,7 @@ def save(self, signal: bool = True, data_already_set: bool = False, force_insert
106104
NotImplementedError: If parameterization is attempted for production exchanges.
107105
"""
108106
from .node_classes import Process, Product
109-
log.debug(f"Saving {self['type']} Exchange: {self}")
107+
logger.debug(f"Saving {self['type']} Exchange: {self}")
110108

111109
created = self.id is None # the exchange is new if it has no id
112110
old = ExchangeDataset.get_by_id(self.id) if not created else None
@@ -150,11 +148,11 @@ def delete(self, signal: bool = True):
150148
function = self.input
151149
process = self.output
152150
except errors.UnknownObject:
153-
log.warning(f"Could not retrieve input or output for exchange deletion. {self['input']=}, {self['output']=}")
151+
logger.warning(f"Could not retrieve input or output for exchange deletion. {self['input']=}, {self['output']=}")
154152
super().delete(signal)
155153
return
156154

157-
log.debug(f"Deleting {self['type']} Exchange: {self}")
155+
logger.debug(f"Deleting {self['type']} Exchange: {self}")
158156

159157
super().delete(signal)
160158

bw_functional/node_classes.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
1-
from typing import Optional, Union
2-
from logging import getLogger
1+
from typing import Optional
2+
3+
from loguru import logger
34

45
from bw2data import databases, get_node, labels
5-
from bw2data.backends import ExchangeDataset
66
from bw2data.errors import UnknownObject, ValidityError
77
from bw2data.backends.proxies import Activity, ActivityDataset
88

99
from .edge_classes import MFExchanges, MFExchange
1010

11-
log = getLogger(__name__)
12-
1311

1412
INHERITED_FIELDS = [
1513
"database",
@@ -41,7 +39,7 @@ def save(self, signal: bool = True, data_already_set: bool = False, force_insert
4139
data_already_set (bool, optional): Whether the data is already set. Defaults to False.
4240
force_insert (bool, optional): Whether to force an insert operation. Defaults to False.
4341
"""
44-
log.debug(f"Saving {self.__class__.__name__}: {self}")
42+
logger.debug(f"Saving {self.__class__.__name__}: {self}")
4543
super().save(signal, data_already_set, force_insert)
4644

4745
def delete(self, signal: bool = True):
@@ -53,7 +51,7 @@ def delete(self, signal: bool = True):
5351
Args:
5452
signal (bool, optional): Whether to send a signal after deletion. Defaults to True.
5553
"""
56-
log.debug(f"Deleting {self.__class__.__name__}: {self}")
54+
logger.debug(f"Deleting {self.__class__.__name__}: {self}")
5755
super().delete(signal)
5856

5957
@property
@@ -206,7 +204,7 @@ def save(self, signal: bool = True, data_already_set: bool = False, force_insert
206204
self.allocate()
207205

208206
if changed_fields := [field for field in INHERITED_FIELDS if self.get(field) != old.data.get(field)]:
209-
log.info(f"Updating inherited fields {changed_fields} for products of process {self}")
207+
logger.info(f"Updating inherited fields {changed_fields} for products of process {self}")
210208
for product in self.products():
211209
for field in changed_fields:
212210
product._set_inherited(field, self.get(field))
@@ -305,7 +303,7 @@ def property_template(self, name: str, amount=1.0) -> dict:
305303
normalize = set(prop.get("normalize", True) for prop in properties)
306304

307305
if len(units) > 1 or len(normalize) > 1:
308-
log.warning(f"Property {name} has inconsistent units or normalization across products.")
306+
logger.warning(f"Property {name} has inconsistent units or normalization across products.")
309307

310308
return {
311309
"unit": units.pop() if units else "unitless",
@@ -360,7 +358,7 @@ def allocate(self, strategy_label: Optional[str] = None) -> None:
360358
ValueError: If no allocation strategy is found.
361359
"""
362360
if self.get("skip_allocation"):
363-
log.debug(f"Skipping allocation for {repr(self)} (id: {self.id})")
361+
logger.debug(f"Skipping allocation for {repr(self)} (id: {self.id})")
364362
return
365363

366364
from . import allocation_strategies, property_allocation
@@ -376,7 +374,7 @@ def allocate(self, strategy_label: Optional[str] = None) -> None:
376374
"Can't find `default_allocation` in input arguments, or process/database metadata."
377375
)
378376

379-
log.debug(f"Allocating {repr(self)} (id: {self.id}) with strategy {strategy_label}")
377+
logger.debug(f"Allocating {repr(self)} (id: {self.id}) with strategy {strategy_label}")
380378

381379
alloc_function = allocation_strategies.get(strategy_label, property_allocation(strategy_label))
382380
alloc_function(self)
@@ -439,7 +437,7 @@ def save(self, signal: bool = True, data_already_set: bool = False, force_insert
439437

440438
# Check if the `processor` is the same as the one in the production edge otherwise update it
441439
if not created and edge.output != self["processor"]:
442-
log.info(f"Switching processor for {self}")
440+
logger.info(f"Switching processor for {self}")
443441
edge.output = self["processor"]
444442
edge.save()
445443

@@ -500,7 +498,7 @@ def processing_edge(self) -> MFExchange | None:
500498
excs = self.exchanges(kinds=["production"], reverse=True)
501499

502500
if len(excs) > 1:
503-
log.warning(f"Multiple processing edges found for product {self['code']}.")
501+
logger.warning(f"Multiple processing edges found for product {self['code']}.")
504502
return None
505503
if len(excs) == 0:
506504
return None

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ dependencies = [
3333
"bw2data>=4.0.1",
3434
"bw2io>=0.9.1",
3535
"bw_processing>=0.9.6",
36+
"loguru",
37+
"pandas",
3638
]
3739

3840
[project.urls]

recipe/meta.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ requirements:
2121
run:
2222
- python >=3.10
2323
- blinker
24+
- loguru
25+
- pandas
2426
- bw2data >=4.0.1
2527
- bw2io >=0.9.1
2628
- bw_processing >=0.9.6

0 commit comments

Comments
 (0)