mtg-ssm 2.6.7.dev2__tar.gz → 2.6.8__tar.gz

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.
Files changed (65) hide show
  1. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/PKG-INFO +2 -1
  2. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm/_version.py +2 -2
  3. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm/containers/indexes.py +3 -3
  4. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm/scryfall/models.py +57 -49
  5. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm/serialization/__init__.py +1 -0
  6. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm/serialization/xlsx.py +2 -2
  7. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm.egg-info/PKG-INFO +2 -1
  8. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm.egg-info/requires.txt +1 -0
  9. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/pyproject.toml +6 -3
  10. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/conftest.py +13 -0
  11. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/data/bulk_data.json +2 -2
  12. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/data/cards.json +1096 -936
  13. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/data/sets.json +42 -42
  14. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/data/sets1.json +21 -21
  15. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/data/sets2.json +21 -21
  16. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/serialization/__snapshots__/test_xlsx.ambr +50 -50
  17. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/.editorconfig +0 -0
  18. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/.github/dependabot.yml +0 -0
  19. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/.github/workflows/integration.yml +0 -0
  20. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/.github/workflows/pre-commit.yml +0 -0
  21. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/.github/workflows/publish.yml +0 -0
  22. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/.github/workflows/run-tests.yml +0 -0
  23. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/.gitignore +0 -0
  24. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/.pre-commit-config.yaml +0 -0
  25. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/LICENSE.txt +0 -0
  26. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/README.rst +0 -0
  27. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/TODO.md +0 -0
  28. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm/__init__.py +0 -0
  29. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm/containers/__init__.py +0 -0
  30. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm/containers/bundles.py +0 -0
  31. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm/containers/collection.py +0 -0
  32. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm/containers/counts.py +0 -0
  33. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm/containers/legacy.py +0 -0
  34. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm/mtg/__init__.py +0 -0
  35. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm/mtg/util.py +0 -0
  36. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm/py.typed +0 -0
  37. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm/scryfall/__init__.py +0 -0
  38. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm/scryfall/fetcher.py +0 -0
  39. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm/serialization/csv.py +0 -0
  40. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm/serialization/interface.py +0 -0
  41. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm/ssm.py +0 -0
  42. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm.egg-info/SOURCES.txt +0 -0
  43. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm.egg-info/dependency_links.txt +0 -0
  44. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm.egg-info/entry_points.txt +0 -0
  45. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/mtg_ssm.egg-info/top_level.txt +0 -0
  46. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/setup.cfg +0 -0
  47. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/__init__.py +0 -0
  48. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/containers/__init__.py +0 -0
  49. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/containers/test_bundles.py +0 -0
  50. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/containers/test_counts.py +0 -0
  51. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/containers/test_indexes.py +0 -0
  52. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/containers/test_legacy.py +0 -0
  53. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/data/LICENSE.txt +0 -0
  54. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/data/migrations.json +0 -0
  55. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/gen_testdata.py +0 -0
  56. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/mtg/__init__.py +0 -0
  57. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/mtg/test_util.py +0 -0
  58. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/scryfall/__init__.py +0 -0
  59. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/scryfall/test_fetcher.py +0 -0
  60. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/serialization/__init__.py +0 -0
  61. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/serialization/__snapshots__/test_csv.ambr +0 -0
  62. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/serialization/test_csv.py +0 -0
  63. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/serialization/test_interface.py +0 -0
  64. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/serialization/test_xlsx.py +0 -0
  65. {mtg_ssm-2.6.7.dev2 → mtg_ssm-2.6.8}/tests/test_ssm.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mtg_ssm
3
- Version: 2.6.7.dev2
3
+ Version: 2.6.8
4
4
  Summary: A tool to manage Magic: the Gathering collection spreadsheets
5
5
  Author-email: George Leslie-Waksman <waksman@gmail.com>
6
6
  License: MIT
@@ -40,6 +40,7 @@ Provides-Extra: dev
40
40
  Requires-Dist: black; extra == "dev"
41
41
  Requires-Dist: coverage[toml]; extra == "dev"
42
42
  Requires-Dist: doc8; extra == "dev"
43
+ Requires-Dist: exceptiongroup; extra == "dev"
43
44
  Requires-Dist: freezegun; extra == "dev"
44
45
  Requires-Dist: lxml; extra == "dev"
45
46
  Requires-Dist: mypy; extra == "dev"
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '2.6.7.dev2'
16
- __version_tuple__ = version_tuple = (2, 6, 7, 'dev2')
15
+ __version__ = version = '2.6.8'
16
+ __version_tuple__ = version_tuple = (2, 6, 8)
@@ -103,9 +103,9 @@ class ScryfallDataIndex:
103
103
  migration.migration_strategy == ScryMigrationStrategy.MERGE
104
104
  and migration.new_scryfall_id
105
105
  ):
106
- self.migrate_old_id_to_new_id[
107
- migration.old_scryfall_id
108
- ] = migration.new_scryfall_id
106
+ self.migrate_old_id_to_new_id[migration.old_scryfall_id] = (
107
+ migration.new_scryfall_id
108
+ )
109
109
 
110
110
 
111
111
  class Oracle:
@@ -1,4 +1,5 @@
1
1
  """Scryfall object models."""
2
+
2
3
  # ruff: noqa: A003
3
4
 
4
5
  import datetime as dt
@@ -54,29 +55,30 @@ class ScrySetType(str, Enum):
54
55
  class ScryCardLayout(str, Enum):
55
56
  """Enum for https://scryfall.com/docs/api/layouts#layout."""
56
57
 
57
- NORMAL = "normal"
58
- SPLIT = "split"
59
- FLIP = "flip"
60
- TRANSFORM = "transform"
61
- MODAL_DFC = "modal_dfc"
62
- MELD = "meld"
63
- LEVELER = "leveler"
64
- CLASS = "class"
65
- SAGA = "saga"
66
58
  ADVENTURE = "adventure"
67
- PLANAR = "planar"
68
- SCHEME = "scheme"
69
- VANGUARD = "vanguard"
70
- TOKEN = "token" # noqa: S105
59
+ ART_SERIES = "art_series"
60
+ AUGMENT = "augment"
61
+ CASE = "case"
62
+ CLASS = "class"
71
63
  DOUBLE_FACED_TOKEN = "double_faced_token" # noqa: S105
64
+ DOUBLE_SIDED = "double_sided"
72
65
  EMBLEM = "emblem"
73
- AUGMENT = "augment"
66
+ FLIP = "flip"
74
67
  HOST = "host"
75
- ART_SERIES = "art_series"
76
- DOUBLE_SIDED = "double_sided"
77
- REVERSIBLE_CARD = "reversible_card"
68
+ LEVELER = "leveler"
69
+ MELD = "meld"
70
+ MODAL_DFC = "modal_dfc"
78
71
  MUTATE = "mutate"
72
+ NORMAL = "normal"
73
+ PLANAR = "planar"
79
74
  PROTOTYPE = "prototype"
75
+ REVERSIBLE_CARD = "reversible_card"
76
+ SAGA = "saga"
77
+ SCHEME = "scheme"
78
+ SPLIT = "split"
79
+ TOKEN = "token" # noqa: S105
80
+ TRANSFORM = "transform"
81
+ VANGUARD = "vanguard"
80
82
 
81
83
 
82
84
  class ScryCardFrame(str, Enum):
@@ -93,38 +95,42 @@ class ScryFrameEffect(str, Enum):
93
95
  """Enum for https://scryfall.com/docs/api/layouts#frame-effects."""
94
96
 
95
97
  NONE = ""
98
+
99
+ BORDERLESS = "borderless"
100
+ COLORSHIFTED = "colorshifted"
101
+ COMPANION = "companion"
102
+ COMPASSLANDDFC = "compasslanddfc"
103
+ CONVERTDFC = "convertdfc"
104
+ DEVOID = "devoid"
105
+ DRAFT = "draft"
106
+ ETCHED = "etched"
107
+ EXTENDEDART = "extendedart"
108
+ FANDFC = "fandfc"
109
+ FULLART = "fullart"
110
+ GILDED = "gilded"
111
+ GRAVESTONE = "gravestone"
112
+ INVERTED = "inverted"
96
113
  LEGENDARY = "legendary"
114
+ LESSON = "lesson"
97
115
  MIRACLE = "miracle"
116
+ MOONELDRAZIDFC = "mooneldrazidfc"
117
+ MOONREVERSEMOONDFC = "moonreversemoondfc"
98
118
  NYXBORN = "nyxborn"
99
119
  NYXTOUCHED = "nyxtouched"
100
- DRAFT = "draft"
101
- DEVOID = "devoid"
102
- TOMBSTONE = "tombstone"
103
- COLORSHIFTED = "colorshifted"
104
- INVERTED = "inverted"
105
- SUNMOONDFC = "sunmoondfc"
106
- COMPASSLANDDFC = "compasslanddfc"
107
120
  ORIGINPWDFC = "originpwdfc"
108
- MOONELDRAZIDFC = "mooneldrazidfc"
109
- MOONREVERSEMOONDFC = "moonreversemoondfc"
110
- WAXINGANDWANINGMOONDFC = "waxingandwaningmoondfc"
121
+ PROMO = "promo"
122
+ SHATTEREDGLASS = "shatteredglass"
111
123
  SHOWCASE = "showcase"
112
- EXTENDEDART = "extendedart"
113
- COMPANION = "companion"
114
- FULLART = "fullart"
115
- ETCHED = "etched"
116
124
  SNOW = "snow"
117
- LESSON = "lesson"
125
+ SPREE = "spree"
126
+ STAMPED = "stamped"
127
+ SUNMOONDFC = "sunmoondfc"
118
128
  TEXTLESS = "textless"
119
- SHATTEREDGLASS = "shatteredglass"
120
- CONVERTDFC = "convertdfc"
121
- FANDFC = "fandfc"
122
- UPSIDEDOWNDFC = "upsidedowndfc"
123
- GILDED = "gilded"
124
- BORDERLESS = "borderless"
125
129
  THICK = "thick"
126
- GRAVESTONE = "gravestone"
130
+ TOMBSTONE = "tombstone"
131
+ UPSIDEDOWNDFC = "upsidedowndfc"
127
132
  VEHICLE = "vehicle"
133
+ WAXINGANDWANINGMOONDFC = "waxingandwaningmoondfc"
128
134
 
129
135
 
130
136
  class ScryBorderColor(str, Enum):
@@ -190,28 +196,30 @@ class ScrySecurityStamp(str, Enum):
190
196
  class ScryFormat(str, Enum):
191
197
  """Enum for card legalities keys."""
192
198
 
199
+ ALCHEMY = "alchemy"
193
200
  BRAWL = "brawl"
194
201
  COMMANDER = "commander"
195
202
  DUEL = "duel"
203
+ EXPLORER = "explorer"
196
204
  FRONTIER = "frontier"
197
205
  FUTURE = "future"
206
+ GLADIATOR = "gladiator"
207
+ HISTORIC = "historic"
208
+ HISTORICBRAWL = "historicbrawl"
198
209
  LEGACY = "legacy"
199
210
  MODERN = "modern"
211
+ OATHBREAKER = "oathbreaker"
200
212
  OLDSCHOOL = "oldschool"
201
213
  PAUPER = "pauper"
214
+ PAUPERCOMMANDER = "paupercommander"
202
215
  PENNY = "penny"
203
- STANDARD = "standard"
204
- VINTAGE = "vintage"
205
- HISTORIC = "historic"
206
216
  PIONEER = "pioneer"
207
- GLADIATOR = "gladiator"
208
- EXPLORER = "explorer"
209
- HISTORICBRAWL = "historicbrawl"
210
- ALCHEMY = "alchemy"
211
- PAUPERCOMMANDER = "paupercommander"
212
- PREMODERN = "premodern"
213
217
  PREDH = "predh"
214
- OATHBREAKER = "oathbreaker"
218
+ PREMODERN = "premodern"
219
+ STANDARD = "standard"
220
+ STANDARDBRAWL = "standardbrawl"
221
+ TIMELESS = "timeless"
222
+ VINTAGE = "vintage"
215
223
 
216
224
 
217
225
  class ScryLegality(str, Enum):
@@ -1,4 +1,5 @@
1
1
  """Ensure that all serializers are imported to properly set up interface."""
2
+
2
3
  from . import csv, interface, xlsx
3
4
 
4
5
  __all__ = ["csv", "interface", "xlsx"]
@@ -137,8 +137,8 @@ def get_references(
137
137
  set_to_haveref,
138
138
  key=lambda setcode: _card_set_sort_key(index.setcode_to_set[setcode]),
139
139
  ):
140
- reference = 'IF({count}>0,"{setcode}:"&{count},"")'.format(
141
- setcode=card_set.upper(), count=set_to_haveref[card_set]
140
+ reference = (
141
+ f'IF({set_to_haveref[card_set]}>0,"{card_set.upper()}:"&{set_to_haveref[card_set]},"")'
142
142
  )
143
143
  references.append(reference)
144
144
  if not references:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mtg_ssm
3
- Version: 2.6.7.dev2
3
+ Version: 2.6.8
4
4
  Summary: A tool to manage Magic: the Gathering collection spreadsheets
5
5
  Author-email: George Leslie-Waksman <waksman@gmail.com>
6
6
  License: MIT
@@ -40,6 +40,7 @@ Provides-Extra: dev
40
40
  Requires-Dist: black; extra == "dev"
41
41
  Requires-Dist: coverage[toml]; extra == "dev"
42
42
  Requires-Dist: doc8; extra == "dev"
43
+ Requires-Dist: exceptiongroup; extra == "dev"
43
44
  Requires-Dist: freezegun; extra == "dev"
44
45
  Requires-Dist: lxml; extra == "dev"
45
46
  Requires-Dist: mypy; extra == "dev"
@@ -9,6 +9,7 @@ typing_extensions~=4.8.0
9
9
  black
10
10
  coverage[toml]
11
11
  doc8
12
+ exceptiongroup
12
13
  freezegun
13
14
  lxml
14
15
  mypy
@@ -54,6 +54,7 @@ dev = [
54
54
  "black",
55
55
  "coverage[toml]",
56
56
  "doc8",
57
+ "exceptiongroup",
57
58
  "freezegun",
58
59
  "lxml",
59
60
  "mypy",
@@ -105,6 +106,8 @@ target-version = ["py38"]
105
106
  [tool.ruff]
106
107
  target-version = "py38"
107
108
  line-length = 99
109
+
110
+ [tool.ruff.lint]
108
111
  select = [
109
112
  "F",
110
113
  "E",
@@ -152,7 +155,7 @@ ignore = [
152
155
  "T201", # `print` found; ignoring for now because I don't want to set up logging
153
156
  ]
154
157
 
155
- [tool.ruff.per-file-ignores]
158
+ [tool.ruff.lint.per-file-ignores]
156
159
  "__init__.py" = [
157
160
  "D104", # missing docstring in public package
158
161
  ]
@@ -164,9 +167,9 @@ ignore = [
164
167
  "S101", # tests should use assert
165
168
  ]
166
169
 
167
- [tool.ruff.isort]
170
+ [tool.ruff.lint.isort]
168
171
  known-first-party = ["mtg_ssm"]
169
172
 
170
- [tool.ruff.pylint]
173
+ [tool.ruff.lint.pylint]
171
174
  max-args = 7
172
175
  max-returns = 8
@@ -1,5 +1,6 @@
1
1
  """pytest test configuration file."""
2
2
 
3
+ import time
3
4
  from pathlib import Path
4
5
  from typing import Dict, Generator, List
5
6
  from uuid import UUID
@@ -18,6 +19,18 @@ CARDS_DATA_FILE = TEST_DATA_DIR / "cards.json"
18
19
  MIGRATIONS_DATA_FILE = TEST_DATA_DIR / "migrations.json"
19
20
 
20
21
 
22
+ @pytest.fixture(autouse=True)
23
+ def _set_timezone(monkeypatch: pytest.MonkeyPatch) -> Generator[None, None, None]:
24
+ """Set timezone to UTC for testing."""
25
+ try:
26
+ with monkeypatch.context() as m:
27
+ m.setenv("TZ", "UTC")
28
+ time.tzset()
29
+ yield
30
+ finally:
31
+ time.tzset()
32
+
33
+
21
34
  @pytest.fixture(autouse=True)
22
35
  def _fetcher_disable_cache() -> Generator[None, None, None]:
23
36
  """Patch fetcher cache dirs for testing."""
@@ -8,8 +8,8 @@
8
8
  "type": "default_cards",
9
9
  "name": "Default Cards",
10
10
  "description": "A JSON file containing every card object on Scryfall in English or the printed language if the card is only available in one language.",
11
- "download_uri": "https://data.scryfall.io/default-cards/default-cards-20230906210610.json",
12
- "updated_at": "2023-09-06T21:06:10.414000Z",
11
+ "download_uri": "https://data.scryfall.io/default-cards/default-cards-20240510210636.json",
12
+ "updated_at": "2024-05-10T21:06:36.150000Z",
13
13
  "content_type": "application/json",
14
14
  "content_encoding": "gzip"
15
15
  }