libres 0.10.0__py3-none-any.whl → 0.10.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
libres/__init__.py CHANGED
@@ -5,7 +5,7 @@ from libres.db import new_scheduler
5
5
 
6
6
  registry = create_default_registry() # noqa: RUF067
7
7
 
8
- __version__ = '0.10.0'
8
+ __version__ = '0.10.2'
9
9
  __all__ = (
10
10
  'new_scheduler',
11
11
  'registry'
libres/context/session.py CHANGED
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from sqlalchemy import create_engine
3
+ from sqlalchemy import create_engine, text
4
4
  from sqlalchemy.pool import QueuePool
5
5
  from sqlalchemy.orm import scoped_session, sessionmaker
6
6
 
@@ -34,12 +34,12 @@ class SessionProvider(StoppableService):
34
34
 
35
35
  self.engine = create_engine(
36
36
  dsn, poolclass=QueuePool, pool_size=5, max_overflow=5,
37
- isolation_level=SERIALIZABLE,
37
+ isolation_level=SERIALIZABLE, future=True,
38
38
  **(engine_config or {})
39
39
  )
40
40
 
41
41
  self.session = scoped_session(sessionmaker(
42
- bind=self.engine, **(session_config or {})
42
+ bind=self.engine, future=True, **(session_config or {}),
43
43
  ))
44
44
 
45
45
  def stop_service(self) -> None:
@@ -58,20 +58,21 @@ class SessionProvider(StoppableService):
58
58
  def get_postgres_version(self, dsn: str) -> tuple[str, int]:
59
59
  """ Returns the postgres version as a tuple (string, integer).
60
60
 
61
- Uses it's own connection to be independent from any session.
61
+ Uses its own connection to be independent from any session.
62
62
 
63
63
  """
64
64
  assert 'postgres' in dsn, 'Not a postgres database'
65
65
 
66
- query = """
66
+ query = text("""
67
67
  SELECT current_setting('server_version'),
68
68
  current_setting('server_version_num')
69
- """
69
+ """)
70
70
 
71
- engine = create_engine(dsn)
71
+ engine = create_engine(dsn, future=True)
72
72
 
73
73
  try:
74
- result = engine.execute(query).first()
74
+ with engine.connect() as conn:
75
+ result = conn.execute(query).first()
75
76
  assert result is not None
76
77
  version, number = result
77
78
  return version, int(number)
@@ -84,7 +84,7 @@ class Allocation(TimestampMixin, ORMBase, OtherModels):
84
84
  resource: Column[uuid.UUID] = Column(UUID(), nullable=False)
85
85
 
86
86
  #: the polymorphic type of the allocation
87
- type: Column[str | None] = Column(types.Text(), nullable=True)
87
+ type: Column[str] = Column(types.Text(), nullable=False, default='generic')
88
88
 
89
89
  #: resource of which this allocation is a mirror. If the mirror_of
90
90
  #: attribute equals the resource, this is a real resource
@@ -153,7 +153,7 @@ class Allocation(TimestampMixin, ORMBase, OtherModels):
153
153
  )
154
154
 
155
155
  __mapper_args__ = {
156
- 'polymorphic_identity': None,
156
+ 'polymorphic_identity': 'generic',
157
157
  'polymorphic_on': type
158
158
  }
159
159
 
libres/db/models/base.py CHANGED
@@ -1,5 +1,11 @@
1
1
  from __future__ import annotations
2
2
 
3
- from sqlalchemy.ext import declarative
4
3
 
5
- ORMBase = declarative.declarative_base()
4
+ from typing import TYPE_CHECKING
5
+ if TYPE_CHECKING:
6
+ from sqlalchemy.ext.declarative import declarative_base
7
+ else:
8
+ # FIXME: Move this import out when dropping 1.4 support
9
+ from sqlalchemy.orm import declarative_base
10
+
11
+ ORMBase = declarative_base()
@@ -60,7 +60,8 @@ class Reservation(TimestampMixin, ORMBase, OtherModels):
60
60
 
61
61
  type: Column[str | None] = Column(
62
62
  types.Text(),
63
- nullable=True
63
+ nullable=False,
64
+ default='generic'
64
65
  )
65
66
 
66
67
  resource: Column[uuid.UUID] = Column(
@@ -117,7 +118,7 @@ class Reservation(TimestampMixin, ORMBase, OtherModels):
117
118
  )
118
119
 
119
120
  __mapper_args__ = {
120
- 'polymorphic_identity': None,
121
+ 'polymorphic_identity': 'generic',
121
122
  'polymorphic_on': type
122
123
  }
123
124
 
@@ -25,6 +25,7 @@ class JSON(_Base):
25
25
  """
26
26
 
27
27
  impl = JSONB
28
+ cache_ok = True
28
29
 
29
30
  def process_bind_param( # type:ignore[override]
30
31
  self,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: libres
3
- Version: 0.10.0
3
+ Version: 0.10.2
4
4
  Summary: A library to reserve things
5
5
  Home-page: http://github.com/seantis/libres/
6
6
  Author: Denis Krienbühl
@@ -142,6 +142,34 @@ After this, create a new release on Github.
142
142
  Changelog
143
143
  ---------
144
144
 
145
+ 0.10.2 (05.02.2026)
146
+ ~~~~~~~~~~~~~~~~~~~
147
+
148
+ - Prepares for SQLAlchemy 2.0 support
149
+ [Daverball]
150
+
151
+ 0.10.1 (21.01.2026)
152
+ ~~~~~~~~~~~~~~~~~~~
153
+
154
+ - Adds proper support for SQLAlchemy 1.4. As a result of this
155
+ `Allocation.type` and `Reservation.type` are no longer nullable
156
+ and have a default value of 'generic', you may use the following
157
+ recipe using an alembic `Operations` object to migrate existing
158
+ databases::
159
+
160
+ context.operations.execute("""
161
+ UPDATE allocations
162
+ SET type = 'generic'
163
+ WHERE type IS NULL;
164
+ """)
165
+ context.operations.alter_column('allocations', 'type', nullable=False)
166
+ context.operations.execute("""
167
+ UPDATE reservations
168
+ SET type = 'generic'
169
+ WHERE type IS NULL;
170
+ """)
171
+ context.operations.alter_column('reservations', 'type', nullable=False)
172
+
145
173
  0.10.0 (15.01.2026)
146
174
  ~~~~~~~~~~~~~~~~~~~
147
175
 
@@ -1,26 +1,26 @@
1
1
  libres/.gitignore,sha256=tyWYoDW7-zMdsfiJIVONRWJ5JmqJCTHzBOsi_rkIYZg,49
2
- libres/__init__.py,sha256=9v-iLfER2w_g4fiTMUPafUATTCY4gPd72_57PqtTeog,260
2
+ libres/__init__.py,sha256=owV-Xu87GRHQXxvYXPK2BO6MeN4ZtDx0BciN5RMn5-o,260
3
3
  libres/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  libres/context/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  libres/context/core.py,sha256=AZMmFVqTVSkK3pomhoamLWOeqynY23g_uf32yjhgrRQ,7353
6
6
  libres/context/exposure.py,sha256=0krsky3XYplG7Uf5oLlQgdXp6XuEDjN2JGe3ljgLM14,287
7
7
  libres/context/registry.py,sha256=JfV-QccpDbAEq154aHu7_-hznr5kXYY58czZ-0-m8vA,4986
8
- libres/context/session.py,sha256=bVvZ7cvSKffGrzxpDM7vKrGgwAPWRoS4No6HK1--xlg,2488
8
+ libres/context/session.py,sha256=1iFsnXidRzUUPI6sHgKEOfw59oET2nddP9x03AxFpSY,2584
9
9
  libres/context/settings.py,sha256=IkdG67QUUuk_sQMXiwsJgelrsbx6M-7f72uJBA2JoJA,1374
10
10
  libres/db/__init__.py,sha256=Fks6T8aEacYVvXB9U1v182zKX7SuEUAkC5hTK50AuQk,145
11
11
  libres/db/queries.py,sha256=EqsrKL5x5OlTWefvcESs5zg7ZyneXavTC-sGARX4OxM,11043
12
12
  libres/db/scheduler.py,sha256=mPuA-48VWQvzHQVy0VsXz4Be_f1YDVlElXWjwGaI6hA,77373
13
13
  libres/db/models/__init__.py,sha256=ESy82b2y6YX_D143QP2cns1MRsXxO32fQUvrc7DE6VY,408
14
- libres/db/models/allocation.py,sha256=4n6zjHWUSzxICjkap1s0pQgDOMki1vkO4l1MI65Ynk8,30699
15
- libres/db/models/base.py,sha256=Y2Lc60vJ1Du73D0sLozVNi1TfhtrQ3i_64NV7hsnc4g,117
14
+ libres/db/models/allocation.py,sha256=BzDE7SDvcP1AH_T_P2g5JmcWop06b2rYIUbno8OtXPY,30717
15
+ libres/db/models/base.py,sha256=Lr1INBdHl_e32EvXbTWBH_3FAKbRVZmWXWfghl7E-8k,292
16
16
  libres/db/models/blocker.py,sha256=P30FLf-ILqT03ZHnbFBVykY37xFAuCeOglhIH6B_1-c,4488
17
17
  libres/db/models/other.py,sha256=XRdyLo1gFY-Sg4iBSPBwOxeqZSpL5PerZISexcAQyDg,853
18
- libres/db/models/reservation.py,sha256=NnsH1PL_Tu2zt-fHMl_KURfj0RsvJzCPj-SmE-GR86Q,5819
18
+ libres/db/models/reservation.py,sha256=3hLIgyIAAi1f5HuQekLx1FVyZeVn0jMc6tKm4p8cGKM,5852
19
19
  libres/db/models/reserved_slot.py,sha256=nVggmkPBB4oR1f5dEH-bsLggX5hAUNqfH7CApcRoApw,3263
20
20
  libres/db/models/timespan.py,sha256=uo6Xjie5rzm8JklsdCp0CyjeUPYOSHO9tOZI3b1oShs,220
21
21
  libres/db/models/timestamp.py,sha256=EsuxdQSUsPCkHb1F7HdrDevWZ5wDWerDFRIhqfhefNw,1301
22
22
  libres/db/models/types/__init__.py,sha256=8fx7ecDasCKsCJxGjt4qP5BbDJCG88dJRa0nzD6IetY,186
23
- libres/db/models/types/json_type.py,sha256=ko6K4YRWERWCpg0wYzuwJ_u-VLJ4K3j3ksJ7cGyiMzw,1137
23
+ libres/db/models/types/json_type.py,sha256=yDRc0RQfVRLGfXH_hKDqPaVUkdy8m9XYrr5PU8GPdeU,1157
24
24
  libres/db/models/types/utcdatetime.py,sha256=4Wlk0Yc6e3PljOjngUGuYvo8jps76RYVkCEwmPygzsY,1285
25
25
  libres/db/models/types/uuid_type.py,sha256=sesgyF65JV0Zh2ty7rSeALpZxKjVg1Y68_Pv7gJAuAo,1675
26
26
  libres/modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -28,8 +28,8 @@ libres/modules/errors.py,sha256=afcvKDfu7XYnGt6CfTG1gpmCaoMTPgtxwmTe2Cyz9qc,2146
28
28
  libres/modules/events.py,sha256=-YHwFJKory8RSIRTths5LBn92sodEPkhARH_a1Xml3c,5299
29
29
  libres/modules/rasterizer.py,sha256=-KYG03YkaPNnyohl_HrEJZqdHrhmGesbLgxxPahNTCc,3155
30
30
  libres/modules/utils.py,sha256=W5Kuu9LhhUWZMKLAhw7DmQEuNYb9aXWpW_HXCn62lhU,1871
31
- libres-0.10.0.dist-info/licenses/LICENSE,sha256=w1rojULT3naueSnr4r62MSQipL4VPtsfEcTFmSKpVuI,1069
32
- libres-0.10.0.dist-info/METADATA,sha256=f3P6JcW2iBhZb666Qj1BDmttM6Z1YQiILrOGTsabres,10924
33
- libres-0.10.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
34
- libres-0.10.0.dist-info/top_level.txt,sha256=Exs6AnhZc0UTcsD5Ylyx1P89j19hJ4Dy13jxQyZwi3k,7
35
- libres-0.10.0.dist-info/RECORD,,
31
+ libres-0.10.2.dist-info/licenses/LICENSE,sha256=w1rojULT3naueSnr4r62MSQipL4VPtsfEcTFmSKpVuI,1069
32
+ libres-0.10.2.dist-info/METADATA,sha256=EaqYg7H2bzc_gQ0Zy5ECWdSyybZ7ynB_mE3NJlYMtBo,11740
33
+ libres-0.10.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
34
+ libres-0.10.2.dist-info/top_level.txt,sha256=Exs6AnhZc0UTcsD5Ylyx1P89j19hJ4Dy13jxQyZwi3k,7
35
+ libres-0.10.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5