Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
sbws
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
juga
sbws
Commits
d3e1025b
Commit
d3e1025b
authored
6 years ago
by
Matt Traudt
Browse files
Options
Downloads
Patches
Plain Diff
Add State class and 100% test coverage for it
GH: ref #166
parent
a7816baf
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
sbws/util/state.py
+62
-0
62 additions, 0 deletions
sbws/util/state.py
tests/unit/util/test_state.py
+120
-0
120 additions, 0 deletions
tests/unit/util/test_state.py
with
182 additions
and
0 deletions
sbws/util/state.py
0 → 100644
+
62
−
0
View file @
d3e1025b
from
sbws.util.filelock
import
FileLock
import
os
import
json
class
State
:
_ALLOWED_TYPES
=
(
int
,
float
,
str
,
bool
,
type
(
None
))
def
__init__
(
self
,
fname
):
self
.
_fname
=
fname
self
.
_state
=
self
.
_read
()
def
_read
(
self
):
with
FileLock
(
self
.
_fname
):
if
not
os
.
path
.
exists
(
self
.
_fname
):
return
{}
with
open
(
self
.
_fname
,
'
rt
'
)
as
fd
:
return
json
.
load
(
fd
)
def
_write
(
self
):
with
FileLock
(
self
.
_fname
):
with
open
(
self
.
_fname
,
'
wt
'
)
as
fd
:
return
json
.
dump
(
self
.
_state
,
fd
)
def
__len__
(
self
):
self
.
_state
=
self
.
_read
()
return
self
.
_state
.
__len__
()
def
__getitem__
(
self
,
key
):
if
not
isinstance
(
key
,
str
):
raise
TypeError
(
'
Keys must be strings. %s is a %s
'
%
(
key
,
type
(
key
)))
self
.
_state
=
self
.
_read
()
return
self
.
_state
.
__getitem__
(
key
)
def
__delitem__
(
self
,
key
):
if
not
isinstance
(
key
,
str
):
raise
TypeError
(
'
Keys must be strings. %s is a %s
'
%
(
key
,
type
(
key
)))
self
.
_state
=
self
.
_read
()
self
.
_state
.
__delitem__
(
key
)
self
.
_write
()
def
__setitem__
(
self
,
key
,
value
):
if
not
isinstance
(
key
,
str
):
raise
TypeError
(
'
Keys must be strings. %s is a %s
'
%
(
key
,
type
(
key
)))
if
type
(
value
)
not
in
State
.
_ALLOWED_TYPES
:
raise
TypeError
(
'
May only store value with type in %s, not %s
'
%
(
State
.
_ALLOWED_TYPES
,
type
(
value
)))
self
.
_state
=
self
.
_read
()
self
.
_state
.
__setitem__
(
key
,
value
)
self
.
_write
()
def
__iter__
(
self
):
self
.
_state
=
self
.
_read
()
return
self
.
_state
.
__iter__
()
def
__contains__
(
self
,
item
):
self
.
_state
=
self
.
_read
()
return
self
.
_state
.
__contains__
(
item
)
This diff is collapsed.
Click to expand it.
tests/unit/util/test_state.py
0 → 100644
+
120
−
0
View file @
d3e1025b
from
sbws.util.state
import
State
import
os
# from tempfile import NamedTemporaryFile as NTF
def
test_state_set_allowed_key_types
(
tmpdir
):
state
=
State
(
os
.
path
.
join
(
tmpdir
,
'
statefoo
'
))
attempt_keys
=
(
'
k
'
)
for
key
in
attempt_keys
:
state
[
key
]
=
4
assert
state
[
key
]
==
4
def
test_state_set_bad_key_types
(
tmpdir
):
state
=
State
(
os
.
path
.
join
(
tmpdir
,
'
statefoo
'
))
attempt_keys
=
(
15983
,
None
,
True
,
-
1.2
,
[],
{},
set
())
for
key
in
attempt_keys
:
try
:
state
[
key
]
=
4
except
TypeError
:
pass
else
:
assert
None
,
'
Should not have been able to use %s %s as a key
'
%
\
(
key
,
type
(
key
))
try
:
state
[
key
]
except
TypeError
:
pass
else
:
assert
None
,
'
%s %s is not a valid key type, so should have got
'
\
'
TypeError when giving it
'
%
(
key
,
type
(
key
))
def
test_state_set_allowed_value_types
(
tmpdir
):
state
=
State
(
os
.
path
.
join
(
tmpdir
,
'
statefoo
'
))
attempt_vals
=
(
15983
,
None
,
True
,
-
1.2
,
'
loooooool
'
)
for
val
in
attempt_vals
:
state
[
'
foo
'
]
=
val
assert
state
[
'
foo
'
]
==
val
def
test_state_set_bad_value_types
(
tmpdir
):
state
=
State
(
os
.
path
.
join
(
tmpdir
,
'
statefoo
'
))
attempt_vals
=
([],
{},
set
())
for
val
in
attempt_vals
:
try
:
state
[
'
foo
'
]
=
val
except
TypeError
:
pass
else
:
assert
None
,
'
Should not have been able to use %s %s as a value
'
%
\
(
val
,
type
(
val
))
def
test_state_del
(
tmpdir
):
state
=
State
(
os
.
path
.
join
(
tmpdir
,
'
statefoo
'
))
d
=
{
'
a
'
:
1
,
'
b
'
:
2
,
'
c
'
:
3
,
'
d
'
:
4
}
for
key
in
d
:
state
[
key
]
=
d
[
key
]
assert
len
(
state
)
==
len
(
d
)
del
d
[
'
a
'
]
del
state
[
'
a
'
]
assert
len
(
state
)
==
len
(
d
)
for
key
in
d
:
assert
d
[
key
]
==
state
[
key
]
attempt_keys
=
(
15983
,
None
,
True
,
-
1.2
,
[],
{},
set
())
for
key
in
attempt_keys
:
try
:
del
state
[
False
]
except
TypeError
:
pass
else
:
assert
None
,
'
Should not have been allowed to delete %s %s
'
\
'
because it is not a valid key type
'
%
(
key
,
type
(
key
))
d
[
'
e
'
]
=
5
state
[
'
e
'
]
=
5
d
[
'
e
'
]
=
5.5
state
[
'
e
'
]
=
5.5
assert
len
(
state
)
==
len
(
d
)
def
test_state_get_len
(
tmpdir
):
state
=
State
(
os
.
path
.
join
(
tmpdir
,
'
statefoo
'
))
d
=
{
'
a
'
:
1
,
'
b
'
:
2
,
'
c
'
:
3
,
'
d
'
:
4
}
for
key
in
d
:
state
[
key
]
=
d
[
key
]
assert
len
(
state
)
==
len
(
d
)
del
d
[
'
a
'
]
del
state
[
'
a
'
]
assert
len
(
state
)
==
len
(
d
)
d
[
'
e
'
]
=
5
state
[
'
e
'
]
=
5
d
[
'
e
'
]
=
5.5
state
[
'
e
'
]
=
5.5
assert
len
(
state
)
==
len
(
d
)
def
test_state_contains
(
tmpdir
):
state
=
State
(
os
.
path
.
join
(
tmpdir
,
'
statefoo
'
))
d
=
{
'
a
'
:
1
,
'
b
'
:
2
,
'
c
'
:
3
,
'
d
'
:
4
}
for
key
in
d
:
state
[
key
]
=
d
[
key
]
assert
'
a
'
in
state
assert
'
e
'
not
in
state
def
test_state_iter
(
tmpdir
):
state
=
State
(
os
.
path
.
join
(
tmpdir
,
'
statefoo
'
))
for
key
in
state
:
pass
d
=
{
'
a
'
:
1
,
'
b
'
:
2
,
'
c
'
:
3
,
'
d
'
:
4
}
for
key
in
d
:
state
[
key
]
=
d
[
key
]
for
key
in
state
:
pass
This diff is collapsed.
Click to expand it.
juga
@juga
mentioned in commit
bdf732a7
·
6 months ago
mentioned in commit
bdf732a7
mentioned in commit bdf732a7d1ec949dac957221e00b9a6bdca1e173
Toggle commit list
juga
@juga
mentioned in commit
0594e838
·
6 months ago
mentioned in commit
0594e838
mentioned in commit 0594e8386dd25ff7bbb7647445c1b04b83165d66
Toggle commit list
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment