Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code to import from gist now breaks with AttributeError: 'list' object has no attribute 'endswith' #47

Closed
LukasWallrich opened this issue Feb 14, 2023 · 5 comments

Comments

@LukasWallrich
Copy link

Thanks for this wonderful package. Until recently, I could use the following code to load a module from a gist:

url = "https://gist.githubusercontent.com/LukasWallrich/42dea3211f0bde452781dd9b69c8199a/raw/"

with httpimport.remote_repo(["Gmodel"], url):
    from Gmodel import GProblem

After updating various modules, it now it fails with AttributeError: 'list' object has no attribute 'endswith' - not sure what changed and how I can work around this ...

@LukasWallrich
Copy link
Author

To get this to work again, I had to go all the way back to version 0.7.2 ...

@operatorequals
Copy link
Owner

operatorequals commented Feb 14, 2023

Hello @LukasWallrich

Thanks a lot for making this Issue! It is the proper chance to document this and make it searchable for others that will certainly have the same problem!

So, after 0.7.2 the syntax of all function signatures changed (for reasons documented here: #39 (comment)). In this answer I'll demonstrate the difference and the way to fix it.

0.7.2

You code snippet should work:

>>> import httpimport
>>> httpimport.__version__
'0.7.2'
>>> url = "https://gist.githubusercontent.com/LukasWallrich/42dea3211f0bde452781dd9b69c8199a/raw/"
>>> 
>>> with httpimport.remote_repo(["Gmodel"], url):
...     from Gmodel import GProblem
... 
>>> GProblem
<class 'Gmodel.GProblem'>

>=1.0.0

Your code should fail with the error in the title:

>>> import httpimport
>>> httpimport.__version__
'1.0.0'
>>> url = "https://gist.githubusercontent.com/LukasWallrich/42dea3211f0bde452781dd9b69c8199a/raw/"
>>> 
>>> with httpimport.remote_repo(["Gmodel"], url):
...     from Gmodel import GProblem
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.8/contextlib.py", line 113, in __enter__
    return next(self.gen)
[...]
line 254, in __init__
    self.url = url if not url.endswith('/') else url[:-1]
AttributeError: 'list' object has no attribute 'endswith'

So what happens?

The remote_repo function used to accept a list as a mandatory parameter and a str (the url). After 1.0.0, the list parameter was removed. So now it only accepts the url.

The Fix

Just removing the ["Gmodel"] (the first parameter) from your code *would fix it:

>>> import httpimport
>>> httpimport.__version__
'1.3.0'
>>> url = "https://gist.githubusercontent.com/LukasWallrich/42dea3211f0bde452781dd9b69c8199a/raw/"
>>> with httpimport.remote_repo(url): # <-------------- check out the new syntax
...     from Gmodel import GProblem
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ImportError: cannot import name 'GProblem' from 'Gmodel' (https://gist.githubusercontent.com/LukasWallrich/42dea3211f0bde452781dd9b69c8199a/raw/Gmodel.py)
>>> 

Yet, you are using the same syntax in the Gist code itself, as shown below:
https://gist.githubusercontent.com/LukasWallrich/42dea3211f0bde452781dd9b69c8199a/raw/Gmodel.py - line 1:

# Used this to avoid duplicating files
import httpimport
url = "https://gist.githubusercontent.com/LukasWallrich/05f445821fbae694b37a205dc08b2b4f/raw/"

with httpimport.remote_repo(["HPmodel"], url):
     from HPmodel import HPProblem, PSAgent
[...]

so it fails to import the module using >=1.0.0 as it fetches the Gist code, tries to execute it (to load the new module) and halts with a syntax error in the module code itself.

If you also remove the ["HPmodel"] parameter from the Gist code, it will be able to run using the latest version (1.3.0 at time of writing).

I hope I helped! This is what breaking changes do to a project...

@LukasWallrich
Copy link
Author

Ah, ok - that makes sense. Thank you!

Unfortunately, it still does not work.

If I run

import httpimport
url = "https://gist.githubusercontent.com/LukasWallrich/05f445821fbae694b37a205dc08b2b4f/raw/"

with httpimport.remote_repo(url):
     from HPmodel import HPProblem, PSAgent

I get Exception: Plain HTTP URL provided with 'httpimport.INSECURE' not set - which is rather confusing since the URL is obviously not plain HTML ...

@operatorequals
Copy link
Owner

operatorequals commented Feb 14, 2023

Plain HTTP URL provided with 'httpimport.INSECURE' not set

This log message doesn't even exist in the >=1.0.0 version! Try updating to 1.3.0 and running again!

What actually happened:

This comes from 0.7.2:
https://github.com/operatorequals/httpimport/blob/0.7.2/httpimport.py#L97

and happens as remote_repo in this version has a default value for the url parameter, which is http://... (you can see here: https://github.com/operatorequals/httpimport/blob/0.7.2/httpimport.py#L329). The whole API is unusable - that's why I changed it!

@LukasWallrich
Copy link
Author

Thanks - there I confused myself with package versions and virtual environments - with the new version, everything works fine!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants