-
Notifications
You must be signed in to change notification settings - Fork 269
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is an example of a versioned system of development that makes previous versions still available for usage. This style would be most useful for things such as an API where different versions of the API may be desirable (e.g. exposing the legacy SickBeard API and the future Medusa API) It has the benefit that older methods can be deprecated with minimal, or at least delayed, impact. It can also be beneficial for providing multiple "program flows" for different use-cases. Some "gotchas" regarding mutables are also shown, however it should be noted that the issues with mutables are not specific to versioned imports, but might be less likely to be noticed in some situations. Run test.py to test
- Loading branch information
Showing
9 changed files
with
84 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
|
||
from __future__ import absolute_import, print_function | ||
from medusa import ver | ||
|
||
print('\nSimple display of versions') | ||
print(ver.version) # current version can be imported into the package namespace to make it directly available | ||
print(ver.test.version) # or it can be merged as a package without an explicit version name for the "current" version | ||
print(ver.test_v0.version) # or you can have each available version imported separately | ||
print(ver.test_v1.version) | ||
print(ver.test_v1_0.version) | ||
print(ver.test_v1.version) # this shows that the modification in v1_0 did not change the v1 version | ||
|
||
print('\nBe careful with mutables!!') | ||
print(ver.failed_list) | ||
print(ver.test.failed_list) # not a mutable, so no modification | ||
print(ver.test_v0.failed_list) # all the changes to the mutable, though... | ||
print(ver.test_v1.failed_list) # have been mirrored to all the modules | ||
print(ver.test_v1_0.failed_list) | ||
print(ver.test_v1.failed_list) | ||
|
||
print('\nSafer mutables using typecasting') | ||
# typecasting the mutable is a safer alternative as it makes it a copy of the original | ||
print(ver.better_list) | ||
print(ver.test.better_list) | ||
print(ver.test_v0.better_list) | ||
print(ver.test_v1.better_list) | ||
print(ver.test_v1_0.better_list) | ||
print(ver.test_v1.better_list) | ||
|
||
print('\nStill be careful with nested mutables!!!') # the nested mutable is not a copy! it is just a shared reference across all the mutables | ||
# nest a mutable | ||
ver.better_list.append(['g', 'h', 'i']) | ||
# both change | ||
print(ver.better_list) | ||
print(ver.test_v1_0.better_list) | ||
|
||
print('\nThinking that the typecast will fix all problems...') | ||
be_careful = list(ver.better_list) | ||
be_careful.append('z') | ||
|
||
print(be_careful) | ||
print(ver.better_list) | ||
print(ver.test_v1_0.better_list) | ||
|
||
print('\n...may lead to some surprising problems!') | ||
ver.better_list[-1].append('WTF?!?') | ||
print(be_careful) | ||
print(ver.better_list) | ||
print(ver.test_v1_0.better_list) | ||
|
||
print('\nKeep in mind these problems with mutables are not exclusive to these types of imports,' | ||
'\nbut these imports can mask the source problem, making it difficult to notice these issues.') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
|
||
from __future__ import absolute_import, print_function | ||
|
||
from ver.v0 import test as test | ||
from ver.v0 import test as test_v0 | ||
from ver.v1 import test as test_v1 | ||
from ver.v1.v1_0 import test as test_v1_0 | ||
|
||
from ver.v1.v1_0.test import version, failed_list, better_list |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
|
||
from __future__ import absolute_import, print_function | ||
version = 'v0' | ||
failed_list = 1 # not a list in v0 | ||
better_list = 'a' # not a list in v0 |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
|
||
from __future__ import absolute_import, print_function | ||
version = 'v1' | ||
failed_list = [1, 2, 3] # now a list in v1 | ||
better_list = ['a', 'b', 'c'] # now a list in v1 |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
|
||
from __future__ import absolute_import, print_function | ||
|
||
from medusa.ver.v1.test import version, failed_list, better_list | ||
|
||
version += '.0' | ||
|
||
# here's where problems start... lists are mutable so mutable imported from other package also gets changed | ||
failed_list.extend([4, 5, 6]) | ||
|
||
# typecasting it with list() is a better approach as it makes a copy | ||
better_list = list(better_list) | ||
better_list.extend(['d', 'e', 'f']) |