Python Mypy attribute error - python

I have a python3.4 project and I recently decided to use mypy for better understanding.
This chunk of code works but checking with mypy pops out an error :
import zipfile
def zip_to_txt(zip: typing.IO[bytes]) -> BytesIO:
zz = zipfile.ZipFile(zip)
output = BytesIO()
for line, info in enumerate(zz.filelist):
date = "%d-%02d-%02d %02d:%02d:%02d" % info.date_time[:6]
output.write(str.encode("%-46s %s %12d\n" % (info.filename, date, info.file_size)))
output.seek(0, 0)
return output
The error :
PyPreviewGenerator/file_converter.py:170: error: "ZipFile" has no attribute "filelist" (corresponds to this line : for line, info in enumerate(zz.filelist):)
But when I look inside the ZipFile class, I can clearly see that the attribute exists. 
So why does the error occurs ? and is there a way I can resolve it ?

In short, the reason is because the filelist attribute is not documented within Typeshed, the collection of type stubs for the stdlib/various 3rd party libraries. You can see this for yourself here.
Why is filelist not included? Well, because it doesn't actually appear to be a documented part of the API. If you search through the document, you'll see filelist is not mentioned anywhere.
Instead, you should call the infolist() method, which returns exactly what you want (see implementation here if you're curious). You'll notice infolist() is indeed listed within typeshed.

Related

Locally patch missing Python type annotations?

Python now supports type hinting, so... yay! It seems like a great method to avoid some of the more obscure runtime bugs.
Sadly, third-party library support remains an issue. Though partially solved by the typeshed project, which is also used by mypy, when trying to port some of my code to use type hints, I ran into issues due to missing stubs.
E.g.
# file:mypytest.py
import lxml.etree as et
tree = et.fromstring('<root><a>1</a><b>2</b><a>3</a></root>')
items = tree.xpath('/root/a')
print([i.text for i in items])
will work perfectly well, but mypy will produce the spurious error message
>>> mypy mypytest.py
mypytest.py:3: error: "_Element" has no attribute "xpath"
because the stub is currently incomplete.
For a larger project, downloading the stub from typeshed, adding the missing entries, and maybe even submitting the corresponding pull request is a no-brainer.
But is there some method to monkey-patch the missing information in quick-and-dirty scenarios?
Bad workaround
The best I was able to come up with was
items = tree.xpath('/root/a') # type: ignore
which silences the error, but also disables type-checking where the variable items is used afterwards. E.g. items[0] + 1 will not cause a warning anymore.
In order to preserve type-checking it is possible to use
items_tmp = tree.xpath('/root/a') # type: ignore
items = items_tmp # type: List[et._Element]
but this seems hackish; It also has to be repeated everywhere the .xpath method is used.
Update from 2017-09-12: Alternatively one can use the syntax
items_tmp : List[et._Element] = tree.xpath('/root/a') # type: ignore

PTVS IntelliSense not working for Built-in Function

class Class:
def __init__(self, path):
self._path = path
string = open(self._path, 'r'). #HERE
When I try to type read() intelliSense says no completions.
However, I know open() function returns file object, which has read() function. I want to see all supported function after typing a dot.
PyCharm shows me recommanded function list, but PTVS does not support.
I want to know this is casual things in PTVS or only happening to me.
My current Python Enviroment is Anaconda 4.3.0 (Python 3.5.3)
How can I fix it?
We've already fixed the specific case of open for our upcoming update (not the one that released today - the next one), but in short the problem is that you don't really know what open is going to return. In our fix, we guess one of two likely types, which should cover most use cases.
To work around it right now, your best option is to assign the result of open to a variable and force it to a certain type using an assert statement. For example:
f = open(self._path, 'r')
import io
assert isinstance(f, io.TextIOWrapper)
f = open(self._path, 'rb')
import io
assert isinstance(f, io.BufferedIOBase)
Note that your code will now fail if the variable is not the expected type, and that the code for Python 2 would be different from this, but until you can get the update where we embed this knowledge into our code it is the best you can do.

Module Instantiation in myhdl

I'm currently looking into myHdl to see if it's worth using or not. However, I've come across a hiccup regarding the instantiation of modules. I've got two files, one that's a module and one that's the testbench. Inside the testbench, I've instantiated the module following the example they have on the website:
http://www.myhdl.org/examples/flipflops.html
The instantiation specifically is this line: dff_inst = dff(q, d, clk)
However, I get an error when I try to run the testbench:
Exception TypeError: 'isinstance() arg 2 must be a class, type, or tuple of classes and types' in <generator object _LabelGenerator at 0x7f6070b2ea50> ignored
I assume this has something to do with the fact that I have two separate files, so my guess is that python isn't finding the dff module(since it's in a separate file). I tried adding in an import dff line, but that simply gave me a 'module' object is not callable type error, which makes sense.
Looking in the documentation, they don't have a full .py file, so I'm not sure how they're linking these testbenches with the module. They specifically mention a hierarchy system and being able to instantiate other modules, but I can't seem to get it to work.
From what I understand from documentation, it looks like they're just writing the testbench and the module in the same file. However, to my understanding, it looks like they imply you can import modules, but I can't figure out how that's done. Is there just some simple thing I'm overlooking?
After experimenting a bit, it seems like I just need to use the following command: from dff import dff,
which makes a lot of sense.

'module' object is not callable typeerror django

So I have a module that I successfully use. But now I added another file to module and it gives me this error.
I have a file generate_bags_uk that has method:
def generate_bags(bags, price):
And I use it like this:
from excelgenerator import generate_bags_uk
...
uk_bag = generate_bags_uk.generate_bags(tshirts, form.cleaned_data['price_uk_bag'])
And I get TypeError: module is not callable. What am I doing wrong here ?
Try the following code instead -
from excelgenerator.generate_bags_uk import generate_bags
...
uk_bag = generate_bags(tshirts, form.cleaned_data['price_uk_bag'])
and make sure excelgenerator folder has a __init__.py inside it, otherwise it will not be dealt as a python package.
Also, I guess the method has a body, if it does not then at least give it a definition -
def generate_bags(bags, price):
pass
COMMENT : From the looks of this error, the error is happening in file /home/marijus/workspace/tshirtnation/excelgenerator/generate_bags_uk.py. I think your other calls are also of similar format and thus causing error. Please change them as I mentioned. The problem should be solved.

python info function: where is it?

From Dive into Python:
Python has a function called info. Try it yourself and skim through
the list now.
>>> from apihelper import info
>>> import __builtin__
>>> info(__builtin__, 20)
ArithmeticError Base class for arithmetic errors.
AssertionError Assertion failed.
AttributeError Attribute not found.
EOFError Read beyond end of file.
EnvironmentError Base class for I/O related errors.
Exception Common base class for all exceptions.
FloatingPointError Floating point operation failed.
IOError I/O operation failed.
It turns out that Python does not have a function called info. What was the book referring to?
I don't know why Dive Into Python claims that "Python has a function called info", but it's obviously not true.
apihelper.py (from which info is imported) is described earlier in the book, in section 4.1, and is just a module that Mark Pilgrim wrote for use with Dive Into Python. That apihelper module apparently does contain an info function that does what is claimed in section 4.3.3, which you linked.
apihelper is a module from the book. You have to download it.
I found this link for this exemple and many others: http://www.diveintopython.net/download/diveintopython-examples-5.4.zip
Python don't have that module i.e. apihelper.py but diveintopython made that function in their tutorial
def info(object,spacing=10,collapse=1):
availableMethod = [method for method in dir(object) if callable(getattr(object,method))];
processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)
print "\n".join(["%s %s" % (method.ljust(spacing),processFunc(getattr(object, method).__doc__)) for method in availableMethod])
This is the function they have developed, that what they are referring to its in the file apihelper.py that's why
from apihelper import info
hope it helps. :)

Categories