pypi / warehouse

The Python Package Index
https://pypi.org
Apache License 2.0
3.58k stars 965 forks source link

`long_description_content_type` missing. defaulting to `text/x-rst`. #7821

Closed OverLordGoldDragon closed 4 years ago

OverLordGoldDragon commented 4 years ago

It isn't missing; checked some existing Issues, haven't found a fix. Details below; anything unique or did I miss a solution?


Win OS, Anaconda Powershell Prompt, conda virtual env. README.md, setup.py

(viz) PS C:\see-rnn> python setup.py sdist bdist_wheel
Build logs ``` running sdist running egg_info writing see_rnn.egg-info\PKG-INFO writing dependency_links to see_rnn.egg-info\dependency_links.txt writing requirements to see_rnn.egg-info\requires.txt writing top-level names to see_rnn.egg-info\top_level.txt reading manifest file 'see_rnn.egg-info\SOURCES.txt' reading manifest template 'MANIFEST.in' writing manifest file 'see_rnn.egg-info\SOURCES.txt' running check creating see-rnn-1.1 creating see-rnn-1.1\see_rnn creating see-rnn-1.1\see_rnn.egg-info copying files to see-rnn-1.1... copying LICENSE -> see-rnn-1.1 copying MANIFEST.in -> see-rnn-1.1 copying README.md -> see-rnn-1.1 copying requirements.txt -> see-rnn-1.1 copying setup.py -> see-rnn-1.1 copying see_rnn\__init__.py -> see-rnn-1.1\see_rnn copying see_rnn\inspect_gen.py -> see-rnn-1.1\see_rnn copying see_rnn\inspect_rnn.py -> see-rnn-1.1\see_rnn copying see_rnn\utils.py -> see-rnn-1.1\see_rnn copying see_rnn\visuals_gen.py -> see-rnn-1.1\see_rnn copying see_rnn\visuals_rnn.py -> see-rnn-1.1\see_rnn copying see_rnn.egg-info\PKG-INFO -> see-rnn-1.1\see_rnn.egg-info copying see_rnn.egg-info\SOURCES.txt -> see-rnn-1.1\see_rnn.egg-info copying see_rnn.egg-info\dependency_links.txt -> see-rnn-1.1\see_rnn.egg-info copying see_rnn.egg-info\requires.txt -> see-rnn-1.1\see_rnn.egg-info copying see_rnn.egg-info\top_level.txt -> see-rnn-1.1\see_rnn.egg-info copying see_rnn.egg-info\zip-safe -> see-rnn-1.1\see_rnn.egg-info Writing see-rnn-1.1\setup.cfg creating dist Creating tar archive removing 'see-rnn-1.1' (and everything under it) running bdist_wheel running build running build_py installing to build\bdist.win-amd64\wheel running install running install_lib creating build\bdist.win-amd64\wheel creating build\bdist.win-amd64\wheel\see_rnn copying build\lib\see_rnn\inspect_gen.py -> build\bdist.win-amd64\wheel\.\see_rnn copying build\lib\see_rnn\inspect_rnn.py -> build\bdist.win-amd64\wheel\.\see_rnn copying build\lib\see_rnn\utils.py -> build\bdist.win-amd64\wheel\.\see_rnn copying build\lib\see_rnn\visuals_gen.py -> build\bdist.win-amd64\wheel\.\see_rnn copying build\lib\see_rnn\visuals_rnn.py -> build\bdist.win-amd64\wheel\.\see_rnn copying build\lib\see_rnn\__init__.py -> build\bdist.win-amd64\wheel\.\see_rnn running install_egg_info Copying see_rnn.egg-info to build\bdist.win-amd64\wheel\.\see_rnn-1.1-py3.7.egg-info running install_scripts adding license file "LICENSE" (matched pattern "LICEN[CS]E*") creating build\bdist.win-amd64\wheel\see_rnn-1.1.dist-info\WHEEL creating 'dist\see_rnn-1.1-py3-none-any.whl' and adding 'build\bdist.win-amd64\wheel' to it adding 'see_rnn/__init__.py' adding 'see_rnn/inspect_gen.py' adding 'see_rnn/inspect_rnn.py' adding 'see_rnn/utils.py' adding 'see_rnn/visuals_gen.py' adding 'see_rnn/visuals_rnn.py' adding 'see_rnn-1.1.dist-info/LICENSE' adding 'see_rnn-1.1.dist-info/METADATA' adding 'see_rnn-1.1.dist-info/WHEEL' adding 'see_rnn-1.1.dist-info/top_level.txt' adding 'see_rnn-1.1.dist-info/zip-safe' adding 'see_rnn-1.1.dist-info/RECORD' removing build\bdist.win-amd64\wheel ```
(viz) PS C:\see-rnn> twine check dist/*
Checking dist\see_rnn-1.1-py3-none-any.whl: PASSED, with warnings
  warning: `long_description_content_type` missing.  defaulting to `text/x-rst`.
Checking dist\see-rnn-1.1.tar.gz: FAILED
  `long_description` has syntax errors in markup and would not be rendered on PyPI.
    line 99: Warning: Inline literal start-string without end-string.
  warning: `long_description_content_type` missing.  defaulting to `text/x-rst`.
setup(...
    long_description=read_file('README.md'),
    long_description_content_type='text/markdown', ...)
wheel                     0.34.2                     py_1    conda-forge
twine                     3.1.1                    py37_0    conda-forge
setuptools                46.1.3           py37hc8dfbb8_0    conda-forge
di commented 4 years ago

I was able to make source and built distributions of the current master branch of your package that passed twine check. It seems like the issue is likely that the versions of wheel/twine/setuptools available to your build command are not the same as what you're reporting here.

Can you give us some details about how exactly you're building the distributions? Are you running python setup.py sdist bdist_wheel? If so, what's the output of python -m pip freeze? If you run python -m pip install -U setuptools twine wheel, can you make distributions that pass twine check?

OverLordGoldDragon commented 4 years ago

@di I build with the first code blob in the question, having first cd'd into a local copy of see-rnn. python -m pip freeze --all shows (I presume only these are of interest):

wheel==0.34.2
twine==3.1.1
setuptools==46.1.3.post20200325

setuptools seems to be the only one to differ, installed via consta install -c conda-forge. Running python -m pip install -U setuptools twine wheel and then 'freeze' again, above output doesn't change. I then again ran python setup.py sdist bdist_wheel and then twine check dist/* - same results. How would I check if the build command uses different versions of these libs?


Additional info: tried to debug twine check to see why it's not detecting long_description_content_type; breakpointing here (which is line 76 on my twine install), which proceeds to here (line 1429 locally), the output is as follows:

>> fp
<zipfile.ZipExtFile name='see_rnn-1.1.dist-info/METADATA' mode='r' compress_type=deflate>
>> print(fp.read().decode('utf-8'))
Metadata-Version: 2.1
Name: see-rnn
Version: 1.1
Summary: RNN weights, gradients, & activations visualization in Keras & TensorFlow
Home-page: https://github.com/OverLordGoldDragon/see-rnn
Author: OverLordGoldDragon
Author-email: 16495490+OverLordGoldDragon@users.noreply.github.com
License: MIT
Requires-Dist: numpy
Requires-Dist: matplotlib
Requires-Dist: tensorflow

# See RNN

So it and many others are also missing, though unsure how to dig further. Debug main script is

import os
from twine import cli

os.chdir(r"C:\see-rnn")
cli.dispatch("check dist/*".split())

Relevant flow logic is as: twine/package.py (L61 local) -->pkginfo /distribution.py :: def extractMetadata(self): data = self.read() --> first "here" above -> second "here".

OverLordGoldDragon commented 4 years ago

Also breakpointing setup in setup.py (and debugging it as __main__), and here (same line locally) attrs output is as expected:

`[print(k,v) for k,v in attrs.items()]` name see-rnn version 1.1 packages ['see_rnn'] url https://github.com/OverLordGoldDragon/see-rnn license MIT author OverLordGoldDragon author_email 16495490+OverLordGoldDragon@users.noreply.github.com description RNN weights, gradients, & activations visualization in Keras & TensorFlow long_description # See RNN [![Build Status](https://travis-ci.com/OverLordGoldDragon/see-rnn.svg?token=dGKzzAxzJjaRLzddNsCd&branch=master)](https://travis-ci.com/OverLordGoldDragon/see-rnn) [![Coverage Status](https://coveralls.io/repos/github/OverLordGoldDragon/see-rnn/badge.svg?branch=master&service=github&kill_cache=1)](https://coveralls.io/github/OverLordGoldDragon/see-rnn?branch=master) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/e15b1b772c3f4dc9ba7988784a2b9bf6)](https://www.codacy.com/manual/OverLordGoldDragon/see-rnn?utm_source=github.com&utm_medium=referral&utm_content=OverLordGoldDragon/see-rnn&utm_campaign=Badge_Grade) [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT) ![](https://img.shields.io/badge/keras-tensorflow-blue.svg) ![](https://img.shields.io/badge/keras-tf.keras-blue.svg) ![](https://img.shields.io/badge/keras-tf.keras/eager-blue.svg) ![](https://img.shields.io/badge/keras-tf.keras/2.0-blue.svg) RNN weights, gradients, & activations visualization in Keras & TensorFlow (LSTM, GRU, SimpleRNN, CuDNN, & all others) ## Features - **Weights, gradients, activations** visualization - **Kernel visuals**: kernel, recurrent kernel, and bias shown explicitly - **Gate visuals**: gates in gated architectures (LSTM, GRU) shown explicitly - **Channel visuals**: cell units (feature extractors) shown explicitly - **General visuals**: methods also applicable to CNNs & others ## Why use? Introspection is a powerful tool for debugging, regularizing, and understanding neural networks; this repo's methods enable: - Monitoring **weights & activations progression** - how each changes epoch-to-epoch, iteration-to-iteration - Evaluating **learning effectiveness** - how well gradient backpropagates layer-to-layer, timestep-to-timestep - Assessing **layer health** - what percentage of neurons are "dead" or "exploding" It enables answering questions such as: - Is my RNN learning **long-term dependencies**? >> Monitor gradients: if a non-zero gradient flows through every timestep, then _every timestep contributes to learning_ - i.e., resultant gradients stem from accounting for every input timestep, so the _entire sequence influences weight updates_. Hence, an RNN _no longer ignores portions of long sequences_, and is forced to _learn from them_ - Is my RNN learning **independent representations**? >> Monitor activations: if each channel's outputs are distinct and decorrelated, then the RNN extracts richly diverse features. - Why do I have **validation loss spikes**? >> Monitor all: val. spikes may stem from sharp changes in layer weights due to large gradients, which will visibly alter activation patterns; seeing the details can help inform a correction For further info on potential uses, see [this SO](https://stackoverflow.com/questions/48714407/rnn-regularization-which-component-to-regularize/58868383#58868383). ## To-do Will possibly implement: - [ ] Weight norm inspection (all layers); see [here](https://github.com/OverLordGoldDragon/see-rnn/issues/10#issuecomment-590537205) - [ ] Interpretability visuals (e.g. saliency maps, adversarial attacks) - [ ] Tools for better probing backprop of `return_sequences=False` ## Examples ```python # for all examples grads = get_layer_gradients(model, x, y, layer_idx=1) # return_sequences=True grads = get_layer_gradients(model, x, y, layer_idx=2) # return_sequences=False outs = get_layer_outputs(model, x, layer_idx=1) # return_sequences=True # all examples use timesteps=100 # NOTE: `title_mode` kwarg below was omitted for simplicity; for Gradient visuals, would set to 'grads' ```
**EX 1: bi-LSTM, 32 units** - activations, `activation='relu'`
`show_features_1D(outs[:1], equate_axes=False)`
`show-features_1D(outs[:1], equate_axes=True, show_y_zero=True)` - Each subplot is an independent RNN channel's output (`return_sequences=True`) - In this example, each channel/filter appears to extract complex independent features of varying bias, frequency, and probabilistic distribution - Note that `equate_axes=False` better pronounces features' _shape_, whereas `=True` allows for an even comparison - but may greatly 'shrink' waveforms to appear flatlined (not shown here)
**EX 2: one sample, uni-LSTM, 6 units** - gradients, `return_sequences=True`, trained for 20 iterations
`show_features_1D(grads[:1], n_rows=2)` - _Note_: gradients are to be read _right-to-left_, as they're computed (from last timestep to first) - Rightmost (latest) timesteps consistently have a higher gradient - **Vanishing gradient**: ~75% of leftmost timesteps have a zero gradient, indicating poor time dependency learning [![enter image description here][1]][1]
**EX 3: all (16) samples, uni-LSTM, 6 units** -- `return_sequences=True`, trained for 20 iterations
`show_features_1D(grads, n_rows=2)`
`show_features_2D(grads, n_rows=4, norm=(-.01, .01))` - Each sample shown in a different color (but same color per sample across channels) - Some samples perform better than one shown above, but not by much - The heatmap plots channels (y-axis) vs. timesteps (x-axis); blue=-0.01, red=0.01, white=0 (gradient values) [![enter image description here][2]][2] [![enter image description here][3]][3]
**EX 4: all (16) samples, uni-LSTM, 6 units** -- `return_sequences=True`, trained for 200 iterations
`show_features_1D(grads, n_rows=2)`
`show_features_2D(grads, n_rows=4, norm=(-.01, .01))` - Both plots show the LSTM performing clearly better after 180 additional iterations - Gradient still vanishes for about half the timesteps - All LSTM units better capture time dependencies of one particular sample (blue curve, first plot) - which we can tell from the heatmap to be the first sample. We can plot that sample vs. other samples to try to understand the difference [![enter image description here][4]][4] [![enter image description here][5]][5]
**EX 5: 2D vs. 1D, uni-LSTM**: 256 units, `return_sequences=True`, trained for 200 iterations
`show_features_1D(grads[0, :, :])`
`show_features_2D(grads[:, :, 0], norm=(-.0001, .0001))` - 2D is better suited for comparing many channels across few samples - 1D is better suited for comparing many samples across a few channels [![enter image description here][6]][6]
**EX 6: bi-GRU, 256 units (512 total)** -- `return_sequences=True`, trained for 400 iterations
`show_features_2D(grads[0], norm=(-.0001, .0001), reflect_half=True)` - Backward layer's gradients are flipped for consistency w.r.t. time axis - Plot reveals a lesser-known advantage of Bi-RNNs - _information utility_: the collective gradient covers about twice the data. _However_, this isn't free lunch: each layer is an independent feature extractor, so learning isn't really complemented - Lower `norm` for more units is expected, as approx. the same loss-derived gradient is being distributed across more parameters (hence the squared numeric average is less)
**EX 7: 0D, all (16) samples, uni-LSTM, 6 units** -- `return_sequences=False`, trained for 200 iterations
`show_features_0D(grads)` - `return_sequences=False` utilizes only the last timestep's gradient (which is still derived from all timesteps, unless using truncated BPTT), requiring a new approach - Plot color-codes each RNN unit consistently across samples for comparison (can use one color instead) - Evaluating gradient flow is less direct and more theoretically involved. One simple approach is to compare distributions at beginning vs. later in training: if the difference isn't significant, the RNN does poorly in learning long-term dependencies
**EX 8: LSTM vs. GRU vs. SimpleRNN, unidir, 256 units** -- `return_sequences=True`, trained for 250 iterations
`show_features_2D(grads, n_rows=8, norm=(-.0001, .0001), show_xy_ticks=[0,0], title_mode=False)` - _Note_: the comparison isn't very meaningful; each network thrives w/ different hyperparameters, whereas same ones were used for all. LSTM, for one, bears the most parameters per unit, drowning out SimpleRNN - In this setup, LSTM definitively stomps GRU and SimpleRNN [![enter image description here][7]][7]
**EX 9: uni-LSTM, 256 units, weights** -- `batch_shape = (16, 100, 20)` (input)
`rnn_histogram(model, 'lstm', equate_axes=False, show_bias=False)`
`rnn_histogram(model, 'lstm', equate_axes=True, show_bias=False)`
`rnn_heatmap(model, 'lstm')` - Top plot is a histogram subplot grid, showing weight distributions per kernel, and within each kernel, per gate - Second plot sets `equate_axes=True` for an even comparison across kernels and gates, improving quality of comparison, but potentially degrading visual appeal - Last plot is a heatmap of the same weights, with gate separations marked by vertical lines, and bias weights also included - Unlike histograms, the heatmap _preserves channel/context information_: input-to-hidden and hidden-to-hidden transforming matrices can be clearly distinguished - Note the large concentration of maximal values at the Forget gate; as trivia, in Keras (and usually), bias gates are all initialized to zeros, except the Forget bias, which is initialized to ones
**EX 10: bi-CuDNNLSTM, 256 units, weights** -- `batch_shape = (16, 100, 16)` (input)
`rnn_histogram(model, 'bidir', equate_axes=2)`
`rnn_heatmap(model, 'bidir', norm=(-.8, .8))` - Bidirectional is supported by both; biases included in this example for histograms - Note again the bias heatmaps; they no longer appear to reside in the same locality as in EX 1. Indeed, `CuDNNLSTM` (and `CuDNNGRU`) biases are defined and initialized differently - something that can't be inferred from histograms
**EX 11: uni-CuDNNGRU, 64 units, weights gradients** -- `batch_shape = (16, 100, 16)` (input)
`rnn_heatmap(model, 'gru', mode='grads', input_data=x, labels=y, cmap=None, absolute_value=True)` - We may wish to visualize _gradient intensity_, which can be done via `absolute_value=True` and a greyscale colormap - Gate separations are apparent even without explicit separating lines in this example: - `New` is the most active kernel gate (input-to-hidden), suggesting more error correction on _permitting information flow_ - `Reset` is the least active recurrent gate (hidden-to-hidden), suggesting least error correction on memory-keeping
**EX 12: NaN detection: LSTM, 512 units, weights** -- `batch_shape = (16, 100, 16)` (input) - Both the heatmap and the histogram come with built-in NaN detection - kernel-, gate-, and direction-wise - Heatmap will print NaNs to console, whereas histogram will mark them directly on the plot - Both will set NaN values to zero before plotting; in example below, all related non-NaN weights were already zero
**EX 13: Sparse Conv1D autoencoder weights** -- `w = layer.get_weights()[0]; w.shape == (16, 64, 128)`
`show_features_2D(w, n_rows=16, norm=(-.1, .1), tight=True, borderwidth=1, title_mode=title)`
`# title = "((Layer Channels vs. Kernels) vs. Weights) vs. Input Channels -- norm = (-0.1, 0.1)"` - One of stacked `Conv1D` sparse autoencoder layers; network trained with `Dropout(0.5, noise_shape=(batch_size, 1, channels))` (Spatial Dropout), encouraging sparse features which may benefit classification - Weights are seen to be 'sparse'; some are uniformly low, others uniformly large, others have bands of large weights among lows ## Usage **QUICKSTART**: run [rnn_sandbox.py](https://github.com/OverLordGoldDragon/see-rnn/blob/master/rnn_sandbox.py), which includes all major examples and allows easy exploration of various plot configs. _Note_: if using `tensorflow.keras` imports, set `import os; os.environ["TF_KERAS"]='1'`. Minimal example below. [visuals_gen.py](https://github.com/OverLordGoldDragon/see-rnn/blob/master/see_rnn/visuals_gen.py) functions can also be used to visualize `Conv1D` activations, gradients, or any other meaningfully-compatible data formats. Likewise, [inspect_gen.py](https://github.com/OverLordGoldDragon/see-rnn/blob/master/see_rnn/inspect_gen.py) also works for non-RNN layers. ```python import numpy as np from keras.layers import Input, LSTM from keras.models import Model from keras.optimizers import Adam from see_rnn import get_layer_gradients, show_features_1D, show_features_2D from see_rnn import show_features_0D def make_model(rnn_layer, batch_shape, units): ipt = Input(batch_shape=batch_shape) x = rnn_layer(units, activation='tanh', return_sequences=True)(ipt) out = rnn_layer(units, activation='tanh', return_sequences=False)(x) model = Model(ipt, out) model.compile(Adam(4e-3), 'mse') return model def make_data(batch_shape): return np.random.randn(*batch_shape), \ np.random.uniform(-1, 1, (batch_shape[0], units)) def train_model(model, iterations, batch_shape): x, y = make_data(batch_shape) for i in range(iterations): model.train_on_batch(x, y) print(end='.') # progbar if i % 40 == 0: x, y = make_data(batch_shape) units = 6 batch_shape = (16, 100, 2*units) model = make_model(LSTM, batch_shape, units) train_model(model, 300, batch_shape) x, y = make_data(batch_shape) grads_all = get_layer_gradients(model, x, y, layer_idx=1) # return_sequences=True grads_last = get_layer_gradients(model, x, y, layer_idx=2) # return_sequences=False show_features_1D(grads_all, n_rows=2, show_xy_ticks=[1,1]) show_features_2D(grads_all, n_rows=8, show_xy_ticks=[1,1], norm=(-.01, .01)) show_features_0D(grads_last) ``` [1]: https://i.stack.imgur.com/PVoU0.png [2]: https://i.stack.imgur.com/OaX6I.png [3]: https://i.stack.imgur.com/RW24R.png [4]: https://i.stack.imgur.com/SUIN3.png [5]: https://i.stack.imgur.com/nsNR1.png [6]: https://i.stack.imgur.com/Ci2AP.png [7]: https://i.stack.imgur.com/vWgc8.png long_description_content_type text/markdown keywords rnn tensorflow keras visualization deep-learning lstm gru install_requires ['numpy', 'matplotlib', 'tensorflow'] include_package_data True zip_safe True tests_require ['pytest>=4.0', 'pytest-cov'] classifiers ['Programming Language :: Python :: 3.6', 'License :: MIT License', 'Operating System :: OS Independent', 'Intended Audience :: Developers', 'Intended Audience :: Education', 'Intended Audience :: Information Technology', 'Intended Audience :: Science/Research', 'Topic :: Utilities', 'Topic :: Scientific/Engineering', 'Topic :: Scientific/Engineering :: Artificial Intelligence', 'Topic :: Scientific/Engineering :: Information Analysis', 'Topic :: Software Development', 'Topic :: Software Development :: Libraries :: Python Modules']

With this and previous comment, it seems something goes awry at the build stage, not twine check

di commented 4 years ago

@OverLordGoldDragon Can you share the distributions you built that are failing the check by attaching them here?

OverLordGoldDragon commented 4 years ago

Sure: see-rnn.zip

di commented 4 years ago

Here's the issue:

$ file README.md
README.md: ASCII text, with very long lines, with CRLF line terminators

Those Windows-style line terminators are leaking into the metadata and causing it to be misformatted.

Can you try doing the following in your setup.py instead:


def read_file(*parts):
-    with codecs.open(os.path.join(current_path, *parts), 'r', 'utf8') as reader:
+    with open(os.path.join(current_path, *parts), encoding='utf-8') as reader:
        return reader.read()
OverLordGoldDragon commented 4 years ago

@di So much trouble over something so simple (but subtle) - thank you. P.S., how did you color lines in your code blob?

di commented 4 years ago

@OverLordGoldDragon Github's fenced code blocks allow you to specify the syntax highlighter, which includes languages like python and other things like diff. Here's the "source" for that comment:

    Here's the issue:

    ```console
    $ file README.md
    README.md: ASCII text, with very long lines, with CRLF line terminators
    ```

    Those Windows-style line terminators are leaking into the metadata and causing it to be misformatted.

    ```diff
    def read_file(*parts):
    -    with codecs.open(os.path.join(current_path, *parts), 'r', 'utf8') as reader:
    +    with open(os.path.join(current_path, *parts), encoding='utf-8') as reader:
            return reader.read()
    ```
jamadden commented 4 years ago

TIL that the syntax highlight portion called the "info string" is allowed to be separated by spaces:

``` console
$ file README.md
README.md: ASCII text, with very long lines, with CRLF line terminators
```

github has a very long list of available syntax highlighters.

ahmadfebrianto commented 3 years ago

@OverLordGoldDragon Can you share the distributions you built that are failing the check by attaching them here?

Hi, there. I have the same exact problem with my package. The long_description_content_type cannot be detected although it's clearly stated in the setup.py file. Would you mind taking look at my dist package?

di commented 3 years ago

@ahmadfebrianto Sure, where can I see it?

ahmadfebrianto commented 3 years ago

@ahmadfebrianto Sure, where can I see it?

Here it is : moodle-kit

di commented 3 years ago

@ahmadfebrianto That distribution seems old, here's what I see in that setup.py:

from distutils.core import setup

setup(
    name='moodle-kit',
    packages=['moodle_kit'],
    version='0.1.3',
    license='GNU',
    description='A simple Python package with some functionalities to interact with moodle-based LMS.',
    author='Ahmad Febrianto',
    author_email='achmadfebryanto@gmail.com',
    url='https://github.com/ahmadfebrianto/moodle-kit',
    download_url='https://github.com/ahmadfebrianto/moodle-kit/archive/v0.1.3.tar.gz',
    keywords=['moodle'],
    install_requires=[
        'requests',
    ],
    classifiers=[
        'Development Status :: 5 - Production/Stable',
        'Intended Audience :: Developers',
        'Topic :: Software Development :: Build Tools',
        'Programming Language :: Python :: 3.6',
    ],
)

I don't see a long_description or a long_description_content_type.

Looking at https://github.com/ahmadfebrianto/moodle-kit/blob/887ed5267ba7580cd204ec04f3d104e839ec2d07/setup.py#L1, I see that you're using from distutils.core import setup. I would recommend using from setuptools import setup instead, as distutils is unable to support the newer metadata that description_content_type requires.

In the future I'd also recommend using https://github.com/pypa/sampleproject as a template for best practices for structuring a Python package!

ahmadfebrianto commented 3 years ago

@ahmadfebrianto That distribution seems old, here's what I see in that setup.py:

from distutils.core import setup

setup(
    name='moodle-kit',
    packages=['moodle_kit'],
    version='0.1.3',
    license='GNU',
    description='A simple Python package with some functionalities to interact with moodle-based LMS.',
    author='Ahmad Febrianto',
    author_email='achmadfebryanto@gmail.com',
    url='https://github.com/ahmadfebrianto/moodle-kit',
    download_url='https://github.com/ahmadfebrianto/moodle-kit/archive/v0.1.3.tar.gz',
    keywords=['moodle'],
    install_requires=[
        'requests',
    ],
    classifiers=[
        'Development Status :: 5 - Production/Stable',
        'Intended Audience :: Developers',
        'Topic :: Software Development :: Build Tools',
        'Programming Language :: Python :: 3.6',
    ],
)

I don't see a long_description or a long_description_content_type.

Looking at https://github.com/ahmadfebrianto/moodle-kit/blob/887ed5267ba7580cd204ec04f3d104e839ec2d07/setup.py#L1, I see that you're using from distutils.core import setup. I would recommend using from setuptools import setup instead, as distutils is unable to support the newer metadata that description_content_type requires.

In the future I'd also recommend using https://github.com/pypa/sampleproject as a template for best practices for structuring a Python package!

Problem solved. It turned out that setup function from distutils.core was the cause. After I used setup function from setuptools, the problem went away. Thank you

Mohit-robo commented 1 year ago

Use Pandoc and PyPandoc to convert your Markdown(md) files into RestructuredText(rst) before uploading them into PyPi. To accomplish this, add the following to your setup.py file: pip install pypandoc

try:
   import pypandoc
   long_description = pypandoc.convert_file('README.md', 'rst')
except(IOError, ImportError):
   long_description = open('README.md').read()

setup(
name='blah',
version=find_version('blah.py'),
description='Short description',
long_description=long_description,
)