my.fbmessenger: move fbmessenger.py into fbmessenger/export.py
keeping it backwards compatible + conditional warning similar to https://github.com/karlicoss/HPI/pull/179 follow up for https://github.com/seanbreckenridge/HPI/pull/18 for now without the __path__ hacking, will do it in bulk later too lazy to run test_import_warnings.sh on CI for now, but figured I'd commit it for the reference anyway
This commit is contained in:
parent
e30953195c
commit
d1f791dee8
3 changed files with 121 additions and 2 deletions
56
my/fbmessenger/__init__.py
Normal file
56
my/fbmessenger/__init__.py
Normal file
|
@ -0,0 +1,56 @@
|
|||
"""
|
||||
This is here temporarily, for backwards compatibility purposes
|
||||
It should be removed in the future, and you should replace any imports
|
||||
like:
|
||||
from my.fbmessenger import ...
|
||||
to:
|
||||
from my.fbmessenger.export import ...
|
||||
since that allows for easier overriding using namespace packages
|
||||
https://github.com/karlicoss/HPI/issues/102
|
||||
"""
|
||||
# TODO ^^ later, replace the above with from my.fbmessenger.all, when we add more data sources
|
||||
|
||||
# For now, including this here, since importing the module
|
||||
# causes .export to be imported, which requires fbmessengerexport
|
||||
REQUIRES = [
|
||||
'git+https://github.com/karlicoss/fbmessengerexport',
|
||||
]
|
||||
|
||||
import re
|
||||
import inspect
|
||||
|
||||
|
||||
mname = 'fbmessenger' # todo infer from __name__?
|
||||
|
||||
|
||||
# allow stuff like 'import my.module.submodule' and such
|
||||
imported_as_parent = False
|
||||
|
||||
# allow stuff like 'from my.module import submodule'
|
||||
importing_submodule = False
|
||||
|
||||
# some hacky traceback to inspect the current stack
|
||||
# to see if the user is using the old style of importing
|
||||
for f in inspect.stack():
|
||||
# seems that when a submodule is imported, at some point it'll call some internal import machinery
|
||||
# with 'parent' set to the parent module
|
||||
# if parent module is imported first (i.e. in case of deprecated usage), it won't be the case
|
||||
args = inspect.getargvalues(f.frame)
|
||||
if args.locals.get('parent') == f'my.{mname}':
|
||||
imported_as_parent = True
|
||||
|
||||
# this we can only detect from the code I guess
|
||||
line = '\n'.join(f.code_context or [])
|
||||
if re.match(rf'from\s+my\.{mname}\s+import\s+export', line):
|
||||
# todo 'export' is hardcoded, not sure how to infer allowed objects anutomatically..
|
||||
importing_submodule = True
|
||||
|
||||
warn = not (imported_as_parent or importing_submodule)
|
||||
|
||||
if warn:
|
||||
from my.core import warnings as W
|
||||
# TODO: add link to instructions to migrate
|
||||
W.high("DEPRECATED! Instead of my.fbmessengerexport, import from my.fbmessengerexport.export")
|
||||
|
||||
|
||||
from .export import *
|
|
@ -10,11 +10,12 @@ REQUIRES = [
|
|||
from pathlib import Path
|
||||
from typing import Iterator
|
||||
|
||||
from .core import PathIsh
|
||||
from ..core import PathIsh
|
||||
|
||||
import fbmessengerexport.dal as messenger
|
||||
|
||||
from my.config import fbmessenger as config
|
||||
# TODO migrate this config to my.fbmessenger.export
|
||||
|
||||
|
||||
def _dal() -> messenger.DAL:
|
||||
|
@ -28,7 +29,7 @@ def messages() -> Iterator[messenger.Message]:
|
|||
yield from t.iter_messages()
|
||||
|
||||
|
||||
from .core import stat, Stats
|
||||
from ..core import stat, Stats
|
||||
def stats() -> Stats:
|
||||
return stat(messages)
|
||||
|
62
tests/test_import_warnings.sh
Normal file
62
tests/test_import_warnings.sh
Normal file
|
@ -0,0 +1,62 @@
|
|||
#!/bin/bash
|
||||
set -eu
|
||||
|
||||
errors=0
|
||||
function expect_warn () {
|
||||
echo "check: " "$@"
|
||||
[[ $(2>&1 "$@" | grep -c DEPRECATED) -gt 0 ]] || {
|
||||
echo "ERROR: " "$@"
|
||||
errors=1
|
||||
}
|
||||
}
|
||||
|
||||
function expect_ok () {
|
||||
echo "check: " "$@"
|
||||
[[ $(2>&1 "$@" | grep -c DEPRECATED) -eq 0 ]] || {
|
||||
echo "ERROR: " "$@"
|
||||
errors=1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# TODO actually this one might be ok? nothing wrong with it in principle
|
||||
expect_warn python3 -c 'from my import fbmessenger'
|
||||
echo 'from my import fbmessenger' > /tmp/script.py
|
||||
expect_warn python3 /tmp/script.py
|
||||
|
||||
expect_warn python3 -c 'from my.fbmessenger import messages'
|
||||
echo 'from my.fbmessenger import messages' > /tmp/script.py
|
||||
expect_warn python3 /tmp/script.py
|
||||
|
||||
expect_warn python3 -c 'from my.fbmessenger import *'
|
||||
echo 'from my.fbmessenger import *' > /tmp/script.py
|
||||
expect_warn python3 /tmp/script.py
|
||||
|
||||
expect_warn python3 -c 'import my.fbmessenger'
|
||||
echo 'import my.fbmessenger' > /tmp/script.py
|
||||
expect_warn python3 /tmp/script.py
|
||||
|
||||
expect_warn python3 -m my.core query my.fbmessenger.messages
|
||||
expect_warn python3 -m my.core doctor my.fbmessenger
|
||||
|
||||
|
||||
expect_ok python3 -c 'from my.fbmessenger.export import *'
|
||||
echo 'from my.fbmessenger.export import *' > /tmp/script.py
|
||||
expect_ok python3 /tmp/script.py
|
||||
|
||||
|
||||
# TODO kinda annoying: this doesn't work, and doesn't seem like traceback has anything
|
||||
# guess it's fine, kind of a border case
|
||||
# expect_ok python3 -c 'from my.fbmessenger import export'
|
||||
echo 'from my.fbmessenger import export' > /tmp/script.py
|
||||
expect_ok python3 /tmp/script.py
|
||||
|
||||
expect_ok python3 -c 'import my.fbmessenger.export'
|
||||
echo 'import my.fbmessenger.export' > /tmp/script.py
|
||||
expect_ok python3 /tmp/script.py
|
||||
|
||||
expect_ok python3 -m my.core query my.fbmessenger.export.messages
|
||||
expect_ok python3 -m my.core doctor my.fbmessenger.export
|
||||
|
||||
|
||||
exit $errors
|
Loading…
Add table
Reference in a new issue